// SPDX-License-Identifier: Unlicense
#pragma once

#include <windows.h>

// WinRing0
#define OLS_TYPE 40000

// WinRing0.sys
#define WINRING0_ID							L"WinRing0_1_2_0"
#define WINRING0_NAME						L"WinRing0.sys"
#define WINRING0_NAME_X64					L"WinRing0x64.sys"
#define WINRING0_OBJ						L"\\\\.\\WinRing0_1_2_0"

// WinRing0

// 0x9C402084
#define IOCTL_OLS_READ_MSR \
	CTL_CODE(OLS_TYPE, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS)

// 0x9C402088
#define IOCTL_OLS_WRITE_MSR \
	CTL_CODE(OLS_TYPE, 0x822, METHOD_BUFFERED, FILE_ANY_ACCESS)

// 0x9C40208C
#define IOCTL_OLS_READ_PMC \
	CTL_CODE(OLS_TYPE, 0x823, METHOD_BUFFERED, FILE_ANY_ACCESS)

// 0x9C402090
#define IOCTL_OLS_HALT \
	CTL_CODE(OLS_TYPE, 0x824, METHOD_BUFFERED, FILE_ANY_ACCESS)

// 0x9C4060C4
#define IOCTL_OLS_READ_IO_PORT \
	CTL_CODE(OLS_TYPE, 0x831, METHOD_BUFFERED, FILE_READ_ACCESS)

// 0x9C40A0C8
#define IOCTL_OLS_WRITE_IO_PORT \
	CTL_CODE(OLS_TYPE, 0x832, METHOD_BUFFERED, FILE_WRITE_ACCESS)

// 0x9C4060CC
#define IOCTL_OLS_READ_IO_PORT_BYTE \
	CTL_CODE(OLS_TYPE, 0x833, METHOD_BUFFERED, FILE_READ_ACCESS)

// 0x9C4060D0
#define IOCTL_OLS_READ_IO_PORT_WORD \
	CTL_CODE(OLS_TYPE, 0x834, METHOD_BUFFERED, FILE_READ_ACCESS)

// 0x9C4060D4
#define IOCTL_OLS_READ_IO_PORT_DWORD \
	CTL_CODE(OLS_TYPE, 0x835, METHOD_BUFFERED, FILE_READ_ACCESS)

// 0x9C40A0D8
#define IOCTL_OLS_WRITE_IO_PORT_BYTE \
	CTL_CODE(OLS_TYPE, 0x836, METHOD_BUFFERED, FILE_WRITE_ACCESS)

// 0x9C40A0DC
#define IOCTL_OLS_WRITE_IO_PORT_WORD \
	CTL_CODE(OLS_TYPE, 0x837, METHOD_BUFFERED, FILE_WRITE_ACCESS)

// 0x9C40A0E0
#define IOCTL_OLS_WRITE_IO_PORT_DWORD \
	CTL_CODE(OLS_TYPE, 0x838, METHOD_BUFFERED, FILE_WRITE_ACCESS)

// 0x9C406104
#define IOCTL_OLS_READ_MEMORY \
	CTL_CODE(OLS_TYPE, 0x841, METHOD_BUFFERED, FILE_READ_ACCESS)

// 0x9C40A108
#define IOCTL_OLS_WRITE_MEMORY \
	CTL_CODE(OLS_TYPE, 0x842, METHOD_BUFFERED, FILE_WRITE_ACCESS)

// 0x9C406144
#define IOCTL_OLS_READ_PCI_CONFIG \
	CTL_CODE(OLS_TYPE, 0x851, METHOD_BUFFERED, FILE_READ_ACCESS)

// 0x9C40A148
#define IOCTL_OLS_WRITE_PCI_CONFIG \
	CTL_CODE(OLS_TYPE, 0x852, METHOD_BUFFERED, FILE_WRITE_ACCESS)

// HwRwDrv.sys
#define HWRWDRV_ID							L"HwRwDrv"
#define HWRWDRV_NAME						L"HwRwDrv.sys"
#define HWRWDRV_NAME_X64					L"HwRwDrvx64.sys"
#define HWRWDRV_OBJ							L"\\\\.\\HwRwDrv"

// HwRwDrv

// 0x9C402084
#define IOCTL_HRD_READ_MSR 0xFB000004

// 0x9C402088
#define IOCTL_HRD_WRITE_MSR 0xFB000008

// 0x9C40208C
#define IOCTL_HRD_READ_PMC 0xFB00000C

// 0x9C402090
#define IOCTL_HRD_HALT 0xFB000010

// 0x9C4060C4
#define IOCTL_HRD_READ_IO_PORT 0xFB004044

// 0x9C40A0C8
#define IOCTL_HRD_WRITE_IO_PORT 0xFB008048

// 0x9C4060CC
#define IOCTL_HRD_READ_IO_PORT_BYTE 0xFB00404C

// 0x9C4060D0
#define IOCTL_HRD_READ_IO_PORT_WORD 0xFB004050

// 0x9C4060D4
#define IOCTL_HRD_READ_IO_PORT_DWORD 0xFB004054

// 0x9C40A0D8
#define IOCTL_HRD_WRITE_IO_PORT_BYTE 0xFB008058

// 0x9C40A0DC
#define IOCTL_HRD_WRITE_IO_PORT_WORD 0xFB00805C

// 0x9C40A0E0
#define IOCTL_HRD_WRITE_IO_PORT_DWORD 0xFB008060

// 0x9C406104
#define IOCTL_HRD_READ_MEMORY 0xFB004084

// 0x9C40A108
#define IOCTL_HRD_WRITE_MEMORY 0xFB008088

// 0x9C406144
#define IOCTL_HRD_READ_PCI_CONFIG 0xFB0040C4

// 0x9C40A148
#define IOCTL_HRD_WRITE_PCI_CONFIG 0xFB0080C8

// PCI Error Code
#define OLS_ERROR_PCI_BUS_NOT_EXIST		(0xE0000001L)
#define OLS_ERROR_PCI_NO_DEVICE			(0xE0000002L)
#define OLS_ERROR_PCI_WRITE_CONFIG		(0xE0000003L)
#define OLS_ERROR_PCI_READ_CONFIG		(0xE0000004L)

// Bus Number, Device Number and Function Number to PCI Device Address
#define PciBusDevFunc(Bus, Dev, Func)	((Bus&0xFF)<<8) | ((Dev&0x1F)<<3) | (Func&7)
// PCI Device Address to Bus Number
#define PciGetBus(address)				((address>>8) & 0xFF)
// PCI Device Address to Device Number
#define PciGetDev(address)				((address>>3) & 0x1F)
// PCI Device Address to Function Number
#define PciGetFunc(address)				(address&7)

#pragma pack(push,4)

typedef struct _OLS_WRITE_MSR_INPUT
{
	ULONG Register;
	ULARGE_INTEGER Value;
} OLS_WRITE_MSR_INPUT;

typedef struct _OLS_WRITE_IO_PORT_INPUT
{
	ULONG PortNumber;
	union
	{
		ULONG LongData;
		USHORT ShortData;
		UCHAR CharData;
	};
} OLS_WRITE_IO_PORT_INPUT;

typedef struct _OLS_READ_PCI_CONFIG_INPUT
{
	ULONG PciAddress;
	ULONG PciOffset;
} OLS_READ_PCI_CONFIG_INPUT;

typedef struct _OLS_WRITE_PCI_CONFIG_INPUT
{
	ULONG PciAddress;
	ULONG PciOffset;
	UCHAR Data[1];
} OLS_WRITE_PCI_CONFIG_INPUT;

typedef LARGE_INTEGER PHYSICAL_ADDRESS;

typedef struct _OLS_READ_MEMORY_INPUT
{
	PHYSICAL_ADDRESS Address;
	ULONG UnitSize;
	ULONG Count;
} OLS_READ_MEMORY_INPUT;

typedef struct _OLS_WRITE_MEMORY_INPUT
{
	PHYSICAL_ADDRESS Address;
	ULONG UnitSize;
	ULONG Count;
	UCHAR Data[1];
} OLS_WRITE_MEMORY_INPUT;

#pragma pack(pop)

// PawnIO
#define PIO_TYPE 41394

// PawnIO.sys
#define PAWNIO_ID							L"PawnIO"
#define PAWNIO_NAME							L"PawnIO.sys" // PawnIO.sys for x86 is not provided
#define PAWNIO_NAME_X64						L"PawnIOx64.sys"
#define PAWNIO_OBJ							L"\\\\.\\PawnIO"

// PawnIO
#define IOCTL_PIO_GET_REFCOUNT \
	CTL_CODE(PIO_TYPE, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_PIO_LOAD_BINARY \
	CTL_CODE(PIO_TYPE, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_PIO_EXECUTE_FN \
	CTL_CODE(PIO_TYPE, 0x841, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define PIO_FN_NAME_LEN 32

#pragma pack(push,1)

typedef struct _PIO_EXEC_INPUT
{
	CHAR Fn[PIO_FN_NAME_LEN];
	ULONG64 Params[0];
} PIO_EXEC_INPUT;

#pragma pack(pop)
