mirror of
				https://github.com/hedge-dev/XenonRecomp.git
				synced 2025-10-30 07:11:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			409 lines
		
	
	
	
		
			9.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			409 lines
		
	
	
	
		
			9.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#pragma once
 | 
						|
#include <cstdint>
 | 
						|
#include <type_traits>
 | 
						|
#include <bit>
 | 
						|
#include <string>
 | 
						|
#include "byteswap.h"
 | 
						|
 | 
						|
#ifdef _WIN32
 | 
						|
    #include <windows.h>
 | 
						|
#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<typename T>
 | 
						|
bool DestroyObject(void* obj)
 | 
						|
{
 | 
						|
    static_cast<T*>(obj)->~T();
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
template<typename T>
 | 
						|
struct be
 | 
						|
{
 | 
						|
    T value;
 | 
						|
 | 
						|
    be() : value(0)
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    be(const T v)
 | 
						|
    {
 | 
						|
        set(v);
 | 
						|
    }
 | 
						|
 | 
						|
    static T byteswap(T value)
 | 
						|
    {
 | 
						|
        if constexpr (std::is_same_v<T, double>)
 | 
						|
        {
 | 
						|
            const uint64_t swapped = ByteSwap(*reinterpret_cast<uint64_t*>(&value));
 | 
						|
            return *reinterpret_cast<const T*>(&swapped);
 | 
						|
        }
 | 
						|
        else if constexpr (std::is_same_v<T, float>)
 | 
						|
        {
 | 
						|
            const uint32_t swapped = ByteSwap(*reinterpret_cast<uint32_t*>(&value));
 | 
						|
            return *reinterpret_cast<const T*>(&swapped);
 | 
						|
        }
 | 
						|
        else if constexpr (std::is_enum_v<T>)
 | 
						|
        {
 | 
						|
            const std::underlying_type_t<T> swapped = ByteSwap(*reinterpret_cast<std::underlying_type_t<T>*>(&value));
 | 
						|
            return *reinterpret_cast<const T*>(&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<typename T>
 | 
						|
struct xpointer
 | 
						|
{
 | 
						|
    be<uint32_t> ptr;
 | 
						|
 | 
						|
    xpointer() : ptr(0)
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    xpointer(T* p) : ptr(p != nullptr ? (reinterpret_cast<size_t>(p) - reinterpret_cast<size_t>(MmGetHostAddress(0))) : 0)
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    T* get() const
 | 
						|
    {
 | 
						|
        if (!ptr.value)
 | 
						|
        {
 | 
						|
            return nullptr;
 | 
						|
        }
 | 
						|
 | 
						|
        return reinterpret_cast<T*>(MmGetHostAddress(ptr));
 | 
						|
    }
 | 
						|
 | 
						|
    operator T* () const
 | 
						|
    {
 | 
						|
        return get();
 | 
						|
    }
 | 
						|
 | 
						|
    T* operator->() const
 | 
						|
    {
 | 
						|
        return get();
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
template<typename TGuest>
 | 
						|
struct HostObject
 | 
						|
{
 | 
						|
    typedef TGuest guest_type;
 | 
						|
};
 | 
						|
 | 
						|
struct _XLIST_ENTRY;
 | 
						|
typedef _XLIST_ENTRY XLIST_ENTRY;
 | 
						|
typedef xpointer<XLIST_ENTRY> 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<uint32_t> Flink;
 | 
						|
    be<uint32_t> 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<uint32_t> Lock;
 | 
						|
    };
 | 
						|
 | 
						|
    be<uint32_t> 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<uint16_t> Length;
 | 
						|
    be<uint16_t> MaximumLength;
 | 
						|
    xpointer<char> Buffer;
 | 
						|
} XANSI_STRING;
 | 
						|
 | 
						|
typedef struct _XOBJECT_ATTRIBUTES
 | 
						|
{
 | 
						|
    be<uint32_t> RootDirectory;
 | 
						|
    xpointer<XANSI_STRING> Name;
 | 
						|
    xpointer<void> Attributes;
 | 
						|
} XOBJECT_ATTRIBUTES;
 | 
						|
 | 
						|
typedef XDISPATCHER_HEADER XKEVENT;
 | 
						|
 | 
						|
typedef struct _XIO_STATUS_BLOCK
 | 
						|
{
 | 
						|
    union {
 | 
						|
        be<uint32_t> Status;
 | 
						|
        be<uint32_t> Pointer;
 | 
						|
    };
 | 
						|
    be<uint32_t> Information;
 | 
						|
} XIO_STATUS_BLOCK;
 | 
						|
 | 
						|
typedef struct _XOVERLAPPED {
 | 
						|
    be<uint32_t> Internal;
 | 
						|
    be<uint32_t> InternalHigh;
 | 
						|
    be<uint32_t> Offset;
 | 
						|
    be<uint32_t> OffsetHigh;
 | 
						|
    be<uint32_t> hEvent;
 | 
						|
} XOVERLAPPED;
 | 
						|
 | 
						|
// this name is so dumb
 | 
						|
typedef struct _XXOVERLAPPED {
 | 
						|
    union
 | 
						|
    {
 | 
						|
        struct
 | 
						|
        {
 | 
						|
            be<uint32_t> Error;
 | 
						|
            be<uint32_t> Length;
 | 
						|
        };
 | 
						|
 | 
						|
        struct
 | 
						|
        {
 | 
						|
            uint32_t InternalLow;
 | 
						|
            uint32_t InternalHigh;
 | 
						|
        };
 | 
						|
    };
 | 
						|
    uint32_t InternalContext;
 | 
						|
    be<uint32_t> hEvent;
 | 
						|
    be<uint32_t> pCompletionRoutine;
 | 
						|
    be<uint32_t> dwCompletionContext;
 | 
						|
    be<uint32_t> 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<uint32_t> dwLength;
 | 
						|
    be<uint32_t> dwMemoryLoad;
 | 
						|
    be<uint32_t> dwTotalPhys;
 | 
						|
    be<uint32_t> dwAvailPhys;
 | 
						|
    be<uint32_t> dwTotalPageFile;
 | 
						|
    be<uint32_t> dwAvailPageFile;
 | 
						|
    be<uint32_t> dwTotalVirtual;
 | 
						|
    be<uint32_t> dwAvailVirtual;
 | 
						|
} XMEMORYSTATUS, * XLPMEMORYSTATUS;
 | 
						|
 | 
						|
typedef struct _XVIDEO_MODE
 | 
						|
{
 | 
						|
    be<uint32_t> DisplayWidth;
 | 
						|
    be<uint32_t> DisplayHeight;
 | 
						|
    be<uint32_t> IsInterlaced;
 | 
						|
    be<uint32_t> IsWidescreen;
 | 
						|
    be<uint32_t> IsHighDefinition;
 | 
						|
    be<uint32_t> RefreshRate;
 | 
						|
    be<uint32_t> VideoStandard;
 | 
						|
    be<uint32_t> Unknown4A;
 | 
						|
    be<uint32_t> Unknown01;
 | 
						|
    be<uint32_t> reserved[3];
 | 
						|
} XVIDEO_MODE;
 | 
						|
 | 
						|
typedef struct _XKSEMAPHORE
 | 
						|
{
 | 
						|
    XDISPATCHER_HEADER Header;
 | 
						|
    be<uint32_t> Limit;
 | 
						|
} XKSEMAPHORE;
 | 
						|
 | 
						|
typedef struct _XUSER_SIGNIN_INFO {
 | 
						|
    be<uint64_t> xuid;
 | 
						|
    be<uint32_t> dwField08;
 | 
						|
    be<uint32_t> SigninState;
 | 
						|
    be<uint32_t> dwField10;
 | 
						|
    be<uint32_t> dwField14;
 | 
						|
    char Name[16];
 | 
						|
} XUSER_SIGNIN_INFO;
 | 
						|
 | 
						|
typedef struct _XTIME_FIELDS
 | 
						|
{
 | 
						|
    be<uint16_t> Year;
 | 
						|
    be<uint16_t> Month;
 | 
						|
    be<uint16_t> Day;
 | 
						|
    be<uint16_t> Hour;
 | 
						|
    be<uint16_t> Minute;
 | 
						|
    be<uint16_t> Second;
 | 
						|
    be<uint16_t> Milliseconds;
 | 
						|
    be<uint16_t> 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<uint32_t> DeviceID;
 | 
						|
    be<uint32_t> dwContentType;
 | 
						|
    be<uint16_t> 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<uint32_t> DeviceID;
 | 
						|
    be<uint32_t> DeviceType;
 | 
						|
    be<uint64_t> ulDeviceBytes;
 | 
						|
    be<uint64_t> ulDeviceFreeBytes;
 | 
						|
    be<uint16_t> 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;
 |