#pragma once #include #include #include #include #include "byteswap.h" #ifdef _WIN32 #include #endif // real win32 handles will never use the upper bits unless something goes really wrong #define CHECK_GUEST_HANDLE(HANDLE) (((HANDLE) & 0x80000000) == 0x80000000) #define GUEST_HANDLE(HANDLE) ((HANDLE) | 0x80000000) #define HOST_HANDLE(HANDLE) ((HANDLE) & ~0x80000000) // Return true to free the associated memory typedef bool(*TypeDestructor_t)(void*); template bool DestroyObject(void* obj) { static_cast(obj)->~T(); return true; } template struct be { T value; be() : value(0) { } be(const T v) { set(v); } static T byteswap(T value) { if constexpr (std::is_same_v) { const uint64_t swapped = ByteSwap(*reinterpret_cast(&value)); return *reinterpret_cast(&swapped); } else if constexpr (std::is_same_v) { const uint32_t swapped = ByteSwap(*reinterpret_cast(&value)); return *reinterpret_cast(&swapped); } else if constexpr (std::is_enum_v) { const std::underlying_type_t swapped = ByteSwap(*reinterpret_cast*>(&value)); return *reinterpret_cast(&swapped); } else { return ByteSwap(value); } } void set(const T v) { value = byteswap(v); } T get() const { return byteswap(value); } be& operator| (T value) { set(get() | value); return *this; } be& operator& (T value) { set(get() & value); return *this; } operator T() const { return get(); } be& operator=(T v) { set(v); return *this; } }; extern "C" void* MmGetHostAddress(uint32_t ptr); template struct xpointer { be ptr; xpointer() : ptr(0) { } xpointer(T* p) : ptr(p != nullptr ? (reinterpret_cast(p) - reinterpret_cast(MmGetHostAddress(0))) : 0) { } T* get() const { if (!ptr.value) { return nullptr; } return reinterpret_cast(MmGetHostAddress(ptr)); } operator T* () const { return get(); } T* operator->() const { return get(); } }; template struct HostObject { typedef TGuest guest_type; }; struct _XLIST_ENTRY; typedef _XLIST_ENTRY XLIST_ENTRY; typedef xpointer PXLIST_ENTRY; typedef struct _IMAGE_CE_RUNTIME_FUNCTION { uint32_t BeginAddress; union { uint32_t Data; struct { uint32_t PrologLength : 8; uint32_t FunctionLength : 22; uint32_t ThirtyTwoBit : 1; uint32_t ExceptionFlag : 1; }; }; } IMAGE_CE_RUNTIME_FUNCTION; static_assert(sizeof(IMAGE_CE_RUNTIME_FUNCTION) == 8); typedef struct _XLIST_ENTRY { be Flink; be Blink; } XLIST_ENTRY; typedef struct _XDISPATCHER_HEADER { union { struct { uint8_t Type; union { uint8_t Abandoned; uint8_t Absolute; uint8_t NpxIrql; uint8_t Signalling; }; union { uint8_t Size; uint8_t Hand; }; union { uint8_t Inserted; uint8_t DebugActive; uint8_t DpcActive; }; }; be Lock; }; be SignalState; XLIST_ENTRY WaitListHead; } XDISPATCHER_HEADER, * XPDISPATCHER_HEADER; // These variables are never accessed in guest code, we can safely use them in little endian typedef struct _XRTL_CRITICAL_SECTION { XDISPATCHER_HEADER Header; int32_t LockCount; int32_t RecursionCount; uint32_t OwningThread; } XRTL_CRITICAL_SECTION; typedef struct _XANSI_STRING { be Length; be MaximumLength; xpointer Buffer; } XANSI_STRING; typedef struct _XOBJECT_ATTRIBUTES { be RootDirectory; xpointer Name; xpointer Attributes; } XOBJECT_ATTRIBUTES; typedef XDISPATCHER_HEADER XKEVENT; typedef struct _XIO_STATUS_BLOCK { union { be Status; be Pointer; }; be Information; } XIO_STATUS_BLOCK; typedef struct _XOVERLAPPED { be Internal; be InternalHigh; be Offset; be OffsetHigh; be hEvent; } XOVERLAPPED; // this name is so dumb typedef struct _XXOVERLAPPED { union { struct { be Error; be Length; }; struct { uint32_t InternalLow; uint32_t InternalHigh; }; }; uint32_t InternalContext; be hEvent; be pCompletionRoutine; be dwCompletionContext; be dwExtendedError; } XXOVERLAPPED, *PXXOVERLAPPED; static_assert(sizeof(_XXOVERLAPPED) == 0x1C); // https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-memorystatus typedef struct _XMEMORYSTATUS { be dwLength; be dwMemoryLoad; be dwTotalPhys; be dwAvailPhys; be dwTotalPageFile; be dwAvailPageFile; be dwTotalVirtual; be dwAvailVirtual; } XMEMORYSTATUS, * XLPMEMORYSTATUS; typedef struct _XVIDEO_MODE { be DisplayWidth; be DisplayHeight; be IsInterlaced; be IsWidescreen; be IsHighDefinition; be RefreshRate; be VideoStandard; be Unknown4A; be Unknown01; be reserved[3]; } XVIDEO_MODE; typedef struct _XKSEMAPHORE { XDISPATCHER_HEADER Header; be Limit; } XKSEMAPHORE; typedef struct _XUSER_SIGNIN_INFO { be xuid; be dwField08; be SigninState; be dwField10; be dwField14; char Name[16]; } XUSER_SIGNIN_INFO; typedef struct _XTIME_FIELDS { be Year; be Month; be Day; be Hour; be Minute; be Second; be Milliseconds; be Weekday; } XTIME_FIELDS, * PXTIME_FIELDS; // Content types #define XCONTENTTYPE_SAVEDATA 1 #define XCONTENTTYPE_DLC 2 #define XCONTENTTYPE_RESERVED 3 #define XCONTENT_NEW 1 #define XCONTENT_EXISTING 2 #define XCONTENT_MAX_DISPLAYNAME 128 #define XCONTENT_MAX_FILENAME 42 #define XCONTENTDEVICE_MAX_NAME 27 typedef struct _XCONTENT_DATA { be DeviceID; be dwContentType; be szDisplayName[XCONTENT_MAX_DISPLAYNAME]; char szFileName[XCONTENT_MAX_FILENAME]; } XCONTENT_DATA, * PXCONTENT_DATA; typedef struct _XHOSTCONTENT_DATA : _XCONTENT_DATA { // This is a host exclusive type so we don't care what goes on std::string szRoot{}; } XHOSTCONTENT_DATA, *PXHOSTCONTENT_DATA; #define XCONTENTDEVICETYPE_HDD 1 #define XCONTENTDEVICETYPE_MU 2 typedef struct _XDEVICE_DATA { be DeviceID; be DeviceType; be ulDeviceBytes; be ulDeviceFreeBytes; be wszName[XCONTENTDEVICE_MAX_NAME]; } XDEVICE_DATA, *PXDEVICE_DATA; // Direct reflection of XInput structures #define XAMINPUT_DEVTYPE_GAMEPAD 0x01 #define XAMINPUT_DEVSUBTYPE_GAMEPAD 0x01 #define XAMINPUT_GAMEPAD_DPAD_UP 0x0001 #define XAMINPUT_GAMEPAD_DPAD_DOWN 0x0002 #define XAMINPUT_GAMEPAD_DPAD_LEFT 0x0004 #define XAMINPUT_GAMEPAD_DPAD_RIGHT 0x0008 #define XAMINPUT_GAMEPAD_START 0x0010 #define XAMINPUT_GAMEPAD_BACK 0x0020 #define XAMINPUT_GAMEPAD_LEFT_THUMB 0x0040 #define XAMINPUT_GAMEPAD_RIGHT_THUMB 0x0080 #define XAMINPUT_GAMEPAD_LEFT_SHOULDER 0x0100 #define XAMINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200 #define XAMINPUT_GAMEPAD_A 0x1000 #define XAMINPUT_GAMEPAD_B 0x2000 #define XAMINPUT_GAMEPAD_X 0x4000 #define XAMINPUT_GAMEPAD_Y 0x8000 typedef struct _XAMINPUT_GAMEPAD { uint16_t wButtons; uint8_t bLeftTrigger; uint8_t bRightTrigger; int16_t sThumbLX; int16_t sThumbLY; int16_t sThumbRX; int16_t sThumbRY; } XAMINPUT_GAMEPAD, *PXAMINPUT_GAMEPAD; typedef struct _XAMINPUT_VIBRATION { uint16_t wLeftMotorSpeed; uint16_t wRightMotorSpeed; } XAMINPUT_VIBRATION, * PXAMINPUT_VIBRATION; typedef struct _XAMINPUT_CAPABILITIES { uint8_t Type; uint8_t SubType; uint16_t Flags; XAMINPUT_GAMEPAD Gamepad; XAMINPUT_VIBRATION Vibration; } XAMINPUT_CAPABILITIES, * PXAMINPUT_CAPABILITIES; typedef struct _XAMINPUT_STATE { uint32_t dwPacketNumber; XAMINPUT_GAMEPAD Gamepad; } XAMINPUT_STATE, * PXAMINPUT_STATE;