2427 lines
66 KiB
C
2427 lines
66 KiB
C
/***************************************************************************
|
|
*
|
|
* Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: dihid.h
|
|
* Content: DirectInput internal include file for HID
|
|
*
|
|
***************************************************************************/
|
|
|
|
#ifdef HID_SUPPORT
|
|
#ifndef _DIHID_H
|
|
#define _DIHID_H
|
|
|
|
#ifndef HID_USAGE_PAGE_PID
|
|
#define HID_USAGE_PAGE_PID ( (USAGE) 0x0000f )
|
|
#endif
|
|
|
|
#ifndef HID_USAGE_PAGE_VENDOR
|
|
#define HID_USAGE_PAGE_VENDOR ( (USAGE) 0xff00 )
|
|
#endif
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @struct HIDDEVICEINFO |
|
|
*
|
|
* Records information about a single hid device.
|
|
*
|
|
* @field DIOBJECTSTATICDATA | osd |
|
|
*
|
|
* Standard information that identifies the device crudely.
|
|
*
|
|
* The <e DIOBJECTSTATICDATA.dwDevType> field contains the
|
|
* device type code, used by
|
|
* <f CDIDEnum_Next>.
|
|
*
|
|
* If the device is a HID mouse, then the remaining fields
|
|
* are commandeered as follows:
|
|
*
|
|
* The <e DIOBJECTSTATICDATA.pcguid> field is the number
|
|
* of buttons on the mouse.
|
|
*
|
|
* The <e DIOBJECTSTATICDATA.CreateDcb> field is the number
|
|
* of axes on the mouse.
|
|
*
|
|
* See <f DIHid_ProbeMouse> for an explanation of why we
|
|
* need to do this.
|
|
*
|
|
* @field PSP_DEVICE_INTERFACE_DETAIL_DATA | pdidd |
|
|
*
|
|
* Pointer to name for device to be used in <f CreateFile>.
|
|
*
|
|
* @field HKEY | hk |
|
|
*
|
|
* Registry key that contains configuration information.
|
|
* Sadly, we must keep it open because there is no way to
|
|
* obtain the name of the key, and the only way to open the
|
|
* key is inside an enumeration.
|
|
*
|
|
* @field HKEY | hkOld |
|
|
*
|
|
* Registry key that contains configuration information.
|
|
* This key was originally used in Win2k Gold. It is to
|
|
* maintain compatibiltiy with Win2k Gold.
|
|
*
|
|
* @field LPTSTR | ptszId |
|
|
*
|
|
* Cached device ID that allows us to access other information
|
|
* about the device.
|
|
*
|
|
* @field GUID | guid |
|
|
*
|
|
* The instance GUID for the device.
|
|
*
|
|
* @field GUID | guidProduct |
|
|
*
|
|
* The product GUID for the device.
|
|
*
|
|
* @field WORD | ProductID |
|
|
*
|
|
* The PID for the device
|
|
*
|
|
* @field WORD | VendorID |
|
|
*
|
|
* The VID for the device
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef struct HIDDEVICEINFO
|
|
{
|
|
DIOBJECTSTATICDATA osd;
|
|
PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd;
|
|
HKEY hk;
|
|
HKEY hkOld;
|
|
LPTSTR ptszId;
|
|
GUID guid;
|
|
GUID guidProduct;
|
|
int idJoy;
|
|
WORD ProductID;
|
|
WORD VendorID;
|
|
BOOL fAttached;
|
|
} HIDDEVICEINFO, *PHIDDEVICEINFO;
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @struct HIDDEVICELIST |
|
|
*
|
|
* Records information about all the HID devices.
|
|
*
|
|
* @field int | chdi |
|
|
*
|
|
* Number of items in the list that are in use.
|
|
*
|
|
* @field int | chdiAlloc |
|
|
*
|
|
* Number of items allocated in the list.
|
|
*
|
|
* @field HIDDEVICEINFO | rghdi[0] |
|
|
*
|
|
* Variable-size array of device information structures.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef struct HIDDEVICELIST
|
|
{
|
|
|
|
int chdi;
|
|
int chdiAlloc;
|
|
int idMaxJoy;
|
|
HIDDEVICEINFO rghdi[0];
|
|
|
|
} HIDDEVICELIST, *PHIDDEVICELIST;
|
|
|
|
extern PHIDDEVICELIST g_phdl;
|
|
|
|
#define cbHdlChdi(chdi) FIELD_OFFSET(HIDDEVICELIST, rghdi[chdi])
|
|
|
|
/*
|
|
* We choose our starting point at 64 devices, since
|
|
* that's the maximum number of USB devices supported. This
|
|
* avoids needless reallocs.
|
|
*/
|
|
|
|
#define chdiMax 64
|
|
#define chdiInit 16
|
|
|
|
/*
|
|
* Tag for unused translation of object instance
|
|
*/
|
|
#define NOREGTRANSLATION (0x80000000)
|
|
|
|
/*
|
|
* VID/PID definitions used to handle analog devices
|
|
*/
|
|
#define MSFT_SYSTEM_VID (0x45E)
|
|
#define MSFT_SYSTEM_PID (0x100)
|
|
#define ANALOG_ID_ROOT TEXT("VID_045E&PID_01")
|
|
|
|
/*
|
|
* VID/PID template so that upper case hex is always used
|
|
*/
|
|
#define VID_PID_TEMPLATE TEXT("VID_%04X&PID_%04X")
|
|
|
|
/*
|
|
* Size of string in characters generated using VID_PID_TEMPLATE
|
|
*/
|
|
#define cbszVIDPID cA( VID_PID_TEMPLATE )
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* diextdll.c - Imports from optional external DLLs
|
|
*
|
|
* It is very important that HidD_GetHidGuid be the very last one.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#ifdef STATIC_DLLUSAGE
|
|
#define ExtDll_Init()
|
|
#else
|
|
void EXTERNAL ExtDll_Init(void);
|
|
#endif
|
|
void EXTERNAL ExtDll_Term(void);
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @struct MANUALIMPORT |
|
|
*
|
|
* Records a single manual import. If it hasn't
|
|
* yet been resolved, then the <e MANUALIMPORT.ptsz>
|
|
* points to the procedure name. If it has been resolved
|
|
* successfully, then <e MANUALIMPORT.pfn> points to
|
|
* the resolved address. If it has not been resolved
|
|
* successfully, then <e MANUALIMPORT.pfn> is garbage.
|
|
*
|
|
* @field LPCSTR | psz |
|
|
*
|
|
* Procdure name. Note that this is always an ANSI string.
|
|
*
|
|
* @field FARPROC | pfn |
|
|
*
|
|
* Procedure address.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef union MANUALIMPORT
|
|
{
|
|
FARPROC pfn; /* Procedure address */
|
|
} MANUALIMPORT, *PMANUALIMPORT;
|
|
|
|
#ifndef STATIC_DLLUSAGE
|
|
|
|
#ifndef WINNT
|
|
/*****************************************************************************
|
|
*
|
|
* CFGMGR32
|
|
*
|
|
* Note that this must match the CFGMGR32 section in diextdll.c
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef union CFGMGR32
|
|
{
|
|
|
|
MANUALIMPORT rgmi[6]; /* number of functions we import */
|
|
|
|
struct
|
|
{
|
|
CONFIGRET ( WINAPI * _CM_Get_Child)
|
|
(
|
|
OUT PDEVINST pdnDevInst,
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET ( WINAPI * _CM_Get_Sibling)
|
|
(
|
|
OUT PDEVINST pdnDevInst,
|
|
IN DEVINST DevInst,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET ( WINAPI * _CM_Get_Parent)
|
|
(
|
|
OUT PDEVINST pdnDevInst,
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET ( WINAPI * _CM_Get_DevNode_Registry_Property)
|
|
(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulProperty,
|
|
OUT PULONG pulRegDataType, OPTIONAL
|
|
OUT PVOID Buffer, OPTIONAL
|
|
IN OUT PULONG pulLength,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET ( WINAPI * _CM_Set_DevNode_Registry_Property)
|
|
(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulProperty,
|
|
IN PVOID Buffer, OPTIONAL
|
|
IN ULONG ulLength,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET( WINAPI * _CM_Get_Device_ID)
|
|
(
|
|
IN DEVINST dnDevInst,
|
|
OUT PTCHAR Buffer,
|
|
IN ULONG BufferLen,
|
|
IN ULONG ulFlags
|
|
);
|
|
};
|
|
|
|
} CFGMGR32, *PFGMGR32;
|
|
|
|
extern CFGMGR32 g_cfgmgr32;
|
|
|
|
#undef CM_Get_Child
|
|
#undef CM_Get_Sibling
|
|
#undef CM_Get_Parent
|
|
#undef CM_Get_DevNode_Registry_Property
|
|
#undef CM_Set_DevNode_Registry_Property
|
|
#undef CM_Get_Device_ID
|
|
|
|
#define CM_Get_Child \
|
|
g_cfgmgr32._CM_Get_Child
|
|
|
|
#define CM_Get_Sibling \
|
|
g_cfgmgr32._CM_Get_Sibling
|
|
|
|
#define CM_Get_Parent \
|
|
g_cfgmgr32._CM_Get_Parent
|
|
|
|
#define CM_Get_DevNode_Registry_Property \
|
|
g_cfgmgr32._CM_Get_DevNode_Registry_Property
|
|
|
|
#define CM_Set_DevNode_Registry_Property \
|
|
g_cfgmgr32._CM_Set_DevNode_Registry_Property
|
|
|
|
#define CM_Get_Device_ID \
|
|
g_cfgmgr32._CM_Get_Device_ID
|
|
#endif //#ifndef WINNT
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* SETUPAPI
|
|
*
|
|
* Note that this must match the SETUPAPI section in diextdll.c
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef union SETUPAPI
|
|
{
|
|
|
|
#ifdef WINNT
|
|
MANUALIMPORT rgmi[18]; /* number of functions we import */
|
|
#else
|
|
MANUALIMPORT rgmi[12]; /* number of functions we import */
|
|
#endif
|
|
|
|
struct
|
|
{
|
|
|
|
HDEVINFO (WINAPI *_SetupDiGetClassDevs)
|
|
(
|
|
IN LPGUID ClassGuid, OPTIONAL
|
|
IN LPCTSTR Enumerator, OPTIONAL
|
|
IN HWND hwndParent, OPTIONAL
|
|
IN DWORD Flags
|
|
);
|
|
|
|
BOOL (WINAPI *_SetupDiDestroyDeviceInfoList)
|
|
(
|
|
IN HDEVINFO DeviceInfoSet
|
|
);
|
|
|
|
BOOL (WINAPI *_SetupDiGetDeviceInterfaceDetail)
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN PSP_DEVICE_INTERFACE_DATA pdid,
|
|
OUT PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd, OPTIONAL
|
|
IN DWORD cbDidd,
|
|
OUT PDWORD RequiredSize, OPTIONAL
|
|
OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
|
|
);
|
|
|
|
BOOL (WINAPI *_SetupDiEnumDeviceInterfaces)
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL
|
|
IN LPGUID InterfaceClassGuid,
|
|
IN DWORD MemberIndex,
|
|
OUT PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
|
|
);
|
|
|
|
HKEY (WINAPI *_SetupDiCreateDeviceInterfaceRegKey)
|
|
(
|
|
IN HDEVINFO hdev,
|
|
IN PSP_DEVICE_INTERFACE_DATA pdid,
|
|
IN DWORD Reserved,
|
|
IN REGSAM samDesired,
|
|
IN HINF InfHandle, OPTIONAL
|
|
IN PCSTR InfSectionName OPTIONAL
|
|
);
|
|
|
|
BOOL (WINAPI *_SetupDiCallClassInstaller)
|
|
(
|
|
IN DI_FUNCTION InstallFunction,
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
|
|
);
|
|
|
|
BOOL (WINAPI *_SetupDiGetDeviceRegistryProperty)
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN PSP_DEVINFO_DATA DeviceInfoData,
|
|
IN DWORD Property,
|
|
OUT PDWORD PropertyRegDataType, OPTIONAL
|
|
OUT PBYTE PropertyBuffer,
|
|
IN DWORD PropertyBufferSize,
|
|
OUT PDWORD RequiredSize OPTIONAL
|
|
);
|
|
|
|
BOOL (WINAPI *_SetupDiSetDeviceRegistryProperty)
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN OUT PSP_DEVINFO_DATA DeviceInfoData,
|
|
IN DWORD Property,
|
|
IN CONST BYTE* PropertyBuffer,
|
|
IN DWORD PropertyBufferSize
|
|
);
|
|
|
|
BOOL (WINAPI *_SetupDiGetDeviceInstanceId)
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN PSP_DEVINFO_DATA DeviceInfoData,
|
|
OUT PTSTR DeviceInstanceId,
|
|
IN DWORD DeviceInstanceIdSize,
|
|
OUT PDWORD RequiredSize OPTIONAL
|
|
);
|
|
|
|
BOOL (WINAPI *_SetupDiOpenDeviceInfo)
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN LPCTSTR DeviceInstanceId,
|
|
IN HWND hwndParent, OPTIONAL
|
|
IN DWORD OpenFlags,
|
|
OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
|
|
);
|
|
|
|
HDEVINFO (WINAPI *_SetupDiCreateDeviceInfoList)
|
|
(
|
|
IN LPGUID ClassGuid, OPTIONAL
|
|
IN HWND hwndParent OPTIONAL
|
|
);
|
|
|
|
HKEY (WINAPI *_SetupDiOpenDevRegKey)
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN PSP_DEVINFO_DATA DeviceInfoData,
|
|
IN DWORD Scope,
|
|
IN DWORD HwProfile,
|
|
IN DWORD KeyType,
|
|
IN REGSAM samDesired
|
|
);
|
|
|
|
#ifdef WINNT
|
|
CONFIGRET ( WINAPI * _CM_Get_Child)
|
|
(
|
|
OUT PDEVINST pdnDevInst,
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET ( WINAPI * _CM_Get_Sibling)
|
|
(
|
|
OUT PDEVINST pdnDevInst,
|
|
IN DEVINST DevInst,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET ( WINAPI * _CM_Get_Parent)
|
|
(
|
|
OUT PDEVINST pdnDevInst,
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET ( WINAPI * _CM_Get_DevNode_Registry_Property)
|
|
(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulProperty,
|
|
OUT PULONG pulRegDataType, OPTIONAL
|
|
OUT PVOID Buffer, OPTIONAL
|
|
IN OUT PULONG pulLength,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET ( WINAPI * _CM_Set_DevNode_Registry_Property)
|
|
(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulProperty,
|
|
IN PVOID Buffer, OPTIONAL
|
|
IN ULONG ulLength,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET( WINAPI * _CM_Get_Device_ID)
|
|
(
|
|
IN DEVINST dnDevInst,
|
|
OUT PTCHAR Buffer,
|
|
IN ULONG BufferLen,
|
|
IN ULONG ulFlags
|
|
);
|
|
#endif //#ifdef WINNT
|
|
};
|
|
|
|
} SETUPAPI, *PSETUPAPI;
|
|
|
|
extern SETUPAPI g_setupapi;
|
|
|
|
#undef SetupDiGetClassDevs
|
|
#undef SetupDiDestroyDeviceInfoList
|
|
#undef SetupDiGetDeviceInterfaceDetail
|
|
#undef SetupDiEnumDeviceInterfaces
|
|
#undef SetupDiCreateDeviceInterfaceRegKey
|
|
#undef SetupDiCallClassInstaller
|
|
#undef SetupDiGetDeviceRegistryProperty
|
|
#undef SetupDiSetDeviceRegistryProperty
|
|
#undef SetupDiGetDeviceInstanceId
|
|
#undef SetupDiOpenDeviceInfo
|
|
#undef SetupDiCreateDeviceInfoList
|
|
#undef SetupDiOpenDevRegKey
|
|
|
|
#define SetupDiGetClassDevs \
|
|
g_setupapi._SetupDiGetClassDevs
|
|
|
|
#define SetupDiDestroyDeviceInfoList \
|
|
g_setupapi._SetupDiDestroyDeviceInfoList
|
|
|
|
#define SetupDiGetDeviceInterfaceDetail \
|
|
g_setupapi._SetupDiGetDeviceInterfaceDetail
|
|
|
|
#define SetupDiEnumDeviceInterfaces \
|
|
g_setupapi._SetupDiEnumDeviceInterfaces
|
|
|
|
#define SetupDiCreateDeviceInterfaceRegKey \
|
|
g_setupapi._SetupDiCreateDeviceInterfaceRegKey
|
|
|
|
#define SetupDiCallClassInstaller \
|
|
g_setupapi._SetupDiCallClassInstaller
|
|
|
|
#define SetupDiGetDeviceRegistryProperty \
|
|
g_setupapi._SetupDiGetDeviceRegistryProperty
|
|
|
|
#define SetupDiSetDeviceRegistryProperty \
|
|
g_setupapi._SetupDiSetDeviceRegistryProperty
|
|
|
|
#define SetupDiGetDeviceInstanceId \
|
|
g_setupapi._SetupDiGetDeviceInstanceId
|
|
|
|
#define SetupDiOpenDeviceInfo \
|
|
g_setupapi._SetupDiOpenDeviceInfo
|
|
|
|
#define SetupDiCreateDeviceInfoList \
|
|
g_setupapi._SetupDiCreateDeviceInfoList
|
|
|
|
#define SetupDiOpenDevRegKey \
|
|
g_setupapi._SetupDiOpenDevRegKey
|
|
|
|
#ifdef WINNT
|
|
#undef CM_Get_Child
|
|
#undef CM_Get_Sibling
|
|
#undef CM_Get_Parent
|
|
#undef CM_Get_DevNode_Registry_Property
|
|
#undef CM_Set_DevNode_Registry_Property
|
|
#undef CM_Get_Device_ID
|
|
|
|
#define CM_Get_Child \
|
|
g_setupapi._CM_Get_Child
|
|
|
|
#define CM_Get_Sibling \
|
|
g_setupapi._CM_Get_Sibling
|
|
|
|
#define CM_Get_Parent \
|
|
g_setupapi._CM_Get_Parent
|
|
|
|
#define CM_Get_DevNode_Registry_Property \
|
|
g_setupapi._CM_Get_DevNode_Registry_Property
|
|
|
|
#define CM_Set_DevNode_Registry_Property \
|
|
g_setupapi._CM_Set_DevNode_Registry_Property
|
|
|
|
#define CM_Get_Device_ID \
|
|
g_setupapi._CM_Get_Device_ID
|
|
#endif //#ifdef WINNT
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* HIDDLL
|
|
*
|
|
* Note that this must match the HID section in diextdll.c
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef union HIDDLL
|
|
{
|
|
|
|
MANUALIMPORT rgmi[21]; /* number of functions we import */
|
|
|
|
struct
|
|
{
|
|
void (__stdcall *_HidD_GetHidGuid)
|
|
(
|
|
OUT LPGUID HidGuid
|
|
);
|
|
|
|
BOOLEAN (__stdcall *_HidD_GetPreparsedData)
|
|
(
|
|
IN HANDLE HidDeviceObject,
|
|
OUT PHIDP_PREPARSED_DATA * PreparsedData
|
|
);
|
|
|
|
BOOLEAN (__stdcall *_HidD_FreePreparsedData)
|
|
(
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
BOOLEAN (__stdcall *_HidD_FlushQueue)
|
|
(
|
|
IN HANDLE HidDeviceObject
|
|
);
|
|
|
|
BOOLEAN (__stdcall *_HidD_GetAttributes)
|
|
(
|
|
IN HANDLE HidDeviceObject,
|
|
OUT PHIDD_ATTRIBUTES Attributes
|
|
);
|
|
|
|
BOOLEAN (__stdcall *_HidD_GetFeature)
|
|
(
|
|
IN HANDLE HidDeviceObject,
|
|
OUT PVOID ReportBuffer,
|
|
IN ULONG ReportBufferLength
|
|
);
|
|
|
|
BOOLEAN (__stdcall *_HidD_SetFeature)
|
|
(
|
|
IN HANDLE HidDeviceObject,
|
|
IN PVOID ReportBuffer,
|
|
IN ULONG ReportBufferLength
|
|
);
|
|
|
|
BOOLEAN (__stdcall *_HidD_GetProductString)
|
|
(
|
|
IN HANDLE HidDeviceObject,
|
|
OUT PVOID Buffer,
|
|
IN ULONG BufferLength
|
|
);
|
|
|
|
BOOLEAN (__stdcall *_HidD_GetInputReport)
|
|
(
|
|
IN HANDLE HidDeviceObject,
|
|
OUT PVOID ReportBuffer,
|
|
IN ULONG ReportBufferLength
|
|
);
|
|
|
|
NTSTATUS (__stdcall *_HidP_GetCaps)
|
|
(
|
|
IN PHIDP_PREPARSED_DATA PreparsedData,
|
|
OUT PHIDP_CAPS Capabilities
|
|
);
|
|
|
|
NTSTATUS (__stdcall *_HidP_GetButtonCaps)
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
OUT PHIDP_BUTTON_CAPS ButtonCaps,
|
|
IN OUT PUSHORT ButtonCapsLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
NTSTATUS (__stdcall *_HidP_GetValueCaps)
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
OUT PHIDP_VALUE_CAPS ValueCaps,
|
|
IN OUT PUSHORT ValueCapsLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
NTSTATUS (__stdcall *_HidP_GetLinkCollectionNodes)
|
|
(
|
|
OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
|
|
IN OUT PULONG LinkCollectionNodesLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
ULONG (__stdcall *_HidP_MaxDataListLength)
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
NTSTATUS (__stdcall *_HidP_GetUsagesEx)
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN USHORT LinkCollection,
|
|
OUT PUSAGE_AND_PAGE ButtonList,
|
|
IN OUT ULONG * UsageLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData,
|
|
IN PCHAR Report,
|
|
IN ULONG ReportLength
|
|
);
|
|
|
|
NTSTATUS (__stdcall *_HidP_GetScaledUsageValue)
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN USAGE UsagePage,
|
|
IN USHORT LinkCollection,
|
|
IN USAGE Usage,
|
|
OUT PLONG UsageValue,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData,
|
|
IN PCHAR Report,
|
|
IN ULONG ReportLength
|
|
);
|
|
|
|
NTSTATUS (__stdcall *_HidP_GetData)
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
OUT PHIDP_DATA DataList,
|
|
IN OUT PULONG DataLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData,
|
|
IN PCHAR Report,
|
|
IN ULONG ReportLength
|
|
);
|
|
|
|
NTSTATUS (__stdcall *_HidP_SetData)
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN PHIDP_DATA DataList,
|
|
IN OUT PULONG DataLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData,
|
|
IN OUT PCHAR Report,
|
|
IN ULONG ReportLength
|
|
);
|
|
|
|
NTSTATUS (__stdcall *_HidP_GetUsageValue)
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN USAGE UsagePage,
|
|
IN USHORT LinkCollection,
|
|
IN USAGE Usage,
|
|
OUT PULONG UsageValue,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData,
|
|
IN PCHAR Report,
|
|
IN ULONG ReportLength
|
|
);
|
|
|
|
ULONG (__stdcall *_HidP_MaxUsageListLength)
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN USAGE UsagePage,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
NTSTATUS (__stdcall *_HidP_GetSpecificButtonCaps)
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN USAGE UsagePage, // Optional (0 => ignore)
|
|
IN USHORT LinkCollection, // Optional (0 => ignore)
|
|
IN USAGE Usage, // Optional (0 => ignore)
|
|
OUT PHIDP_BUTTON_CAPS ButtonCaps,
|
|
IN OUT PUSHORT ButtonCapsLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
};
|
|
|
|
} HIDDLL, *PHIDDLL;
|
|
|
|
extern HIDDLL g_hiddll;
|
|
|
|
#undef HidD_GetHidGuid
|
|
#undef HidD_GetPreparsedData
|
|
#undef HidD_FreePreparsedData
|
|
#undef HidD_FlushQueue
|
|
#undef HidD_GetAttributes
|
|
#undef HidD_GetFeature
|
|
#undef HidD_SetFeature
|
|
#undef HidD_GetProductString
|
|
#undef HidD_GetInputReport
|
|
#undef HidP_GetCaps
|
|
#undef HidP_GetButtonCaps
|
|
#undef HidP_GetValueCaps
|
|
#undef HidP_GetLinkCollectionNodes
|
|
#undef HidP_MaxDataListLength
|
|
#undef HidP_GetUsagesEx
|
|
#undef HidP_GetScaledUsageValue
|
|
#undef HidP_GetData
|
|
#undef HidP_SetData
|
|
#undef HidP_GetUsageValue
|
|
#undef HidP_MaxUsageListLength
|
|
#undef HidP_GetSpecificButtonCaps
|
|
|
|
#define HidD_GetHidGuid \
|
|
g_hiddll._HidD_GetHidGuid
|
|
|
|
#define HidD_GetPreparsedData \
|
|
g_hiddll._HidD_GetPreparsedData
|
|
|
|
#define HidD_FreePreparsedData \
|
|
g_hiddll._HidD_FreePreparsedData
|
|
|
|
#define HidD_FlushQueue \
|
|
g_hiddll._HidD_FlushQueue
|
|
|
|
#define HidD_GetAttributes \
|
|
g_hiddll._HidD_GetAttributes \
|
|
|
|
#define HidD_GetFeature \
|
|
g_hiddll._HidD_GetFeature \
|
|
|
|
#define HidD_SetFeature \
|
|
g_hiddll._HidD_SetFeature \
|
|
|
|
#define HidD_GetProductString \
|
|
g_hiddll._HidD_GetProductString \
|
|
|
|
#define HidD_GetInputReport \
|
|
g_hiddll._HidD_GetInputReport \
|
|
|
|
#define HidP_GetCaps \
|
|
g_hiddll._HidP_GetCaps
|
|
|
|
#define HidP_GetButtonCaps \
|
|
g_hiddll._HidP_GetButtonCaps
|
|
|
|
#define HidP_GetValueCaps \
|
|
g_hiddll._HidP_GetValueCaps
|
|
|
|
#define HidP_GetLinkCollectionNodes \
|
|
g_hiddll._HidP_GetLinkCollectionNodes
|
|
|
|
#define HidP_MaxDataListLength \
|
|
g_hiddll._HidP_MaxDataListLength \
|
|
|
|
#define HidP_GetUsagesEx \
|
|
g_hiddll._HidP_GetUsagesEx \
|
|
|
|
#define HidP_GetScaledUsageValue \
|
|
g_hiddll._HidP_GetScaledUsageValue \
|
|
|
|
#define HidP_GetData \
|
|
g_hiddll._HidP_GetData \
|
|
|
|
#define HidP_SetData \
|
|
g_hiddll._HidP_SetData \
|
|
|
|
#define HidP_GetUsageValue \
|
|
g_hiddll._HidP_GetUsageValue \
|
|
|
|
#define HidP_MaxUsageListLength \
|
|
g_hiddll._HidP_MaxUsageListLength \
|
|
|
|
#define HidP_GetSpecificButtonCaps \
|
|
g_hiddll._HidP_GetSpecificButtonCaps \
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* WINMMDLL
|
|
*
|
|
* Note that this must match the WINMM section in diextdll.c
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef union WINMMDLL
|
|
{
|
|
|
|
MANUALIMPORT rgmi[4]; /* number of functions we import */
|
|
|
|
struct
|
|
{
|
|
MMRESULT ( WINAPI * _joyGetDevCaps)
|
|
(
|
|
IN UINT uJoyID,
|
|
OUT LPJOYCAPS pjc,
|
|
IN UINT cbjc
|
|
);
|
|
|
|
MMRESULT ( WINAPI * _joyGetPosEx)
|
|
(
|
|
IN UINT uJoyID,
|
|
OUT LPJOYINFOEX pji
|
|
);
|
|
|
|
MMRESULT ( WINAPI * _joyGetPos)
|
|
(
|
|
IN UINT uJoyID,
|
|
OUT LPJOYINFO pji
|
|
);
|
|
|
|
UINT ( WINAPI * _joyConfigChanged)
|
|
(
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
};
|
|
|
|
} WINMMDLL, *PWINMMDLL;
|
|
|
|
extern WINMMDLL g_winmmdll;
|
|
|
|
#undef joyGetDevCaps
|
|
#undef joyGetPosEx
|
|
#undef joyGetPos
|
|
#undef joyConfigChanged
|
|
|
|
#define joyGetDevCaps \
|
|
g_winmmdll._joyGetDevCaps
|
|
|
|
#define joyGetPosEx \
|
|
g_winmmdll._joyGetPosEx
|
|
|
|
#define joyGetPos \
|
|
g_winmmdll._joyGetPos
|
|
|
|
#define joyConfigChanged \
|
|
g_winmmdll._joyConfigChanged
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* USER32
|
|
*
|
|
* Note that this must match the USER32 section in diextdll.c
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#ifdef USE_WM_INPUT
|
|
|
|
typedef union USER32
|
|
{
|
|
|
|
MANUALIMPORT rgmi[2]; /* number of functions we import */
|
|
|
|
struct
|
|
{
|
|
BOOL ( WINAPI * _RegisterRawInputDevices)
|
|
(
|
|
PCRAWINPUTDEVICE pRawInputDevices,
|
|
UINT uiNumDevices,
|
|
UINT cbSize
|
|
);
|
|
|
|
UINT ( WINAPI * _GetRawInputData)
|
|
(
|
|
HRAWINPUT hRawInput,
|
|
UINT uiCommand,
|
|
LPVOID pData,
|
|
PUINT pcbSize,
|
|
UINT cbSizeHeader
|
|
);
|
|
};
|
|
|
|
} USER32, *PUSER32;
|
|
|
|
extern USER32 g_user32;
|
|
|
|
#undef RegisterRawInputDevices
|
|
#undef GetRawInputData
|
|
|
|
#define RegisterRawInputDevices \
|
|
g_user32._RegisterRawInputDevices
|
|
|
|
#define GetRawInputData \
|
|
g_user32._GetRawInputData
|
|
|
|
#endif
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Dummy functions
|
|
*
|
|
* These functions are used only when some DLLs can't be loaded.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
//cfgmgr32.dll
|
|
|
|
CONFIGRET WINAPI DIDummy_CM_Get_Child
|
|
(
|
|
OUT PDEVINST pdnDevInst,
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET WINAPI DIDummy_CM_Get_Sibling
|
|
(
|
|
OUT PDEVINST pdnDevInst,
|
|
IN DEVINST DevInst,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET WINAPI DIDummy_CM_Get_Parent
|
|
(
|
|
OUT PDEVINST pdnDevInst,
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET WINAPI DIDummy_CM_Get_DevNode_Registry_Property
|
|
(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulProperty,
|
|
OUT PULONG pulRegDataType, OPTIONAL
|
|
OUT PVOID Buffer, OPTIONAL
|
|
IN OUT PULONG pulLength,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET WINAPI DIDummy_CM_Set_DevNode_Registry_Property
|
|
(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulProperty,
|
|
IN PVOID Buffer, OPTIONAL
|
|
IN ULONG ulLength,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
CONFIGRET WINAPI DIDummy_CM_Get_Device_ID
|
|
(
|
|
IN DEVINST dnDevInst,
|
|
OUT PTCHAR Buffer,
|
|
IN ULONG BufferLen,
|
|
IN ULONG ulFlags
|
|
);
|
|
|
|
//Setupapi.dll
|
|
|
|
HDEVINFO WINAPI DIDummy_SetupDiGetClassDevs
|
|
(
|
|
IN LPGUID ClassGuid, OPTIONAL
|
|
IN LPCTSTR Enumerator, OPTIONAL
|
|
IN HWND hwndParent, OPTIONAL
|
|
IN DWORD Flags
|
|
);
|
|
|
|
BOOL WINAPI DIDummy_SetupDiDestroyDeviceInfoList
|
|
(
|
|
IN HDEVINFO DeviceInfoSet
|
|
);
|
|
|
|
BOOL WINAPI DIDummy_SetupDiGetDeviceInterfaceDetail
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN PSP_DEVICE_INTERFACE_DATA pdid,
|
|
OUT PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd, OPTIONAL
|
|
IN DWORD cbDidd,
|
|
OUT PDWORD RequiredSize, OPTIONAL
|
|
OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
|
|
);
|
|
|
|
BOOL WINAPI DIDummy_SetupDiEnumDeviceInterfaces
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL
|
|
IN LPGUID InterfaceClassGuid,
|
|
IN DWORD MemberIndex,
|
|
OUT PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
|
|
);
|
|
|
|
HKEY WINAPI DIDummy_SetupDiCreateDeviceInterfaceRegKey
|
|
(
|
|
IN HDEVINFO hdev,
|
|
IN PSP_DEVICE_INTERFACE_DATA pdid,
|
|
IN DWORD Reserved,
|
|
IN REGSAM samDesired,
|
|
IN HINF InfHandle, OPTIONAL
|
|
IN PCSTR InfSectionName OPTIONAL
|
|
);
|
|
|
|
BOOL WINAPI DIDummy_SetupDiCallClassInstaller
|
|
(
|
|
IN DI_FUNCTION InstallFunction,
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
|
|
);
|
|
|
|
BOOL WINAPI DIDummy_SetupDiGetDeviceRegistryProperty
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN PSP_DEVINFO_DATA DeviceInfoData,
|
|
IN DWORD Property,
|
|
OUT PDWORD PropertyRegDataType, OPTIONAL
|
|
OUT PBYTE PropertyBuffer,
|
|
IN DWORD PropertyBufferSize,
|
|
OUT PDWORD RequiredSize OPTIONAL
|
|
);
|
|
|
|
BOOL WINAPI DIDummy_SetupDiSetDeviceRegistryProperty
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN OUT PSP_DEVINFO_DATA DeviceInfoData,
|
|
IN DWORD Property,
|
|
IN CONST BYTE* PropertyBuffer,
|
|
IN DWORD PropertyBufferSize
|
|
);
|
|
|
|
BOOL WINAPI DIDummy_SetupDiGetDeviceInstanceId
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN PSP_DEVINFO_DATA DeviceInfoData,
|
|
OUT PTSTR DeviceInstanceId,
|
|
IN DWORD DeviceInstanceIdSize,
|
|
OUT PDWORD RequiredSize OPTIONAL
|
|
);
|
|
|
|
BOOL WINAPI DIDummy_SetupDiOpenDeviceInfo
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN LPCTSTR DeviceInstanceId,
|
|
IN HWND hwndParent, OPTIONAL
|
|
IN DWORD OpenFlags,
|
|
OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
|
|
);
|
|
|
|
HDEVINFO WINAPI DIDummy_SetupDiCreateDeviceInfoList
|
|
(
|
|
IN LPGUID ClassGuid, OPTIONAL
|
|
IN HWND hwndParent OPTIONAL
|
|
);
|
|
|
|
HKEY WINAPI DIDummy_SetupDiOpenDevRegKey
|
|
(
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN PSP_DEVINFO_DATA DeviceInfoData,
|
|
IN DWORD Scope,
|
|
IN DWORD HwProfile,
|
|
IN DWORD KeyType,
|
|
IN REGSAM samDesired
|
|
);
|
|
|
|
// hid.dll
|
|
|
|
void __stdcall DIDummy_HidD_GetHidGuid
|
|
(
|
|
OUT LPGUID HidGuid
|
|
);
|
|
|
|
BOOLEAN __stdcall DIDummy_HidD_GetPreparsedData
|
|
(
|
|
IN HANDLE HidDeviceObject,
|
|
OUT PHIDP_PREPARSED_DATA * PreparsedData
|
|
);
|
|
|
|
BOOLEAN __stdcall DIDummy_HidD_FreePreparsedData
|
|
(
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
BOOLEAN __stdcall DIDummy_HidD_FlushQueue
|
|
(
|
|
IN HANDLE HidDeviceObject
|
|
);
|
|
|
|
BOOLEAN __stdcall DIDummy_HidD_GetAttributes
|
|
(
|
|
IN HANDLE HidDeviceObject,
|
|
OUT PHIDD_ATTRIBUTES Attributes
|
|
);
|
|
|
|
BOOLEAN __stdcall DIDummy_HidD_GetFeature
|
|
(
|
|
IN HANDLE HidDeviceObject,
|
|
OUT PVOID ReportBuffer,
|
|
IN ULONG ReportBufferLength
|
|
);
|
|
|
|
BOOLEAN __stdcall DIDummy_HidD_SetFeature
|
|
(
|
|
IN HANDLE HidDeviceObject,
|
|
IN PVOID ReportBuffer,
|
|
IN ULONG ReportBufferLength
|
|
);
|
|
|
|
BOOLEAN __stdcall DIDummy_HidD_GetProductString
|
|
(
|
|
IN HANDLE HidDeviceObject,
|
|
OUT PVOID Buffer,
|
|
IN ULONG BufferLength
|
|
);
|
|
|
|
BOOLEAN __stdcall DIDummy_HidD_GetInputReport
|
|
(
|
|
IN HANDLE HidDeviceObject,
|
|
OUT PVOID ReportBuffer,
|
|
IN ULONG ReportBufferLength
|
|
);
|
|
|
|
NTSTATUS __stdcall DIDummy_HidP_GetCaps
|
|
(
|
|
IN PHIDP_PREPARSED_DATA PreparsedData,
|
|
OUT PHIDP_CAPS Capabilities
|
|
);
|
|
|
|
NTSTATUS __stdcall DIDummy_HidP_GetButtonCaps
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
OUT PHIDP_BUTTON_CAPS ButtonCaps,
|
|
IN OUT PUSHORT ButtonCapsLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
NTSTATUS __stdcall DIDummy_HidP_GetValueCaps
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
OUT PHIDP_VALUE_CAPS ValueCaps,
|
|
IN OUT PUSHORT ValueCapsLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
NTSTATUS __stdcall DIDummy_HidP_GetLinkCollectionNodes
|
|
(
|
|
OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
|
|
IN OUT PULONG LinkCollectionNodesLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
ULONG __stdcall DIDummy_HidP_MaxDataListLength
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
NTSTATUS __stdcall DIDummy_HidP_GetUsagesEx //unused
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN USHORT LinkCollection,
|
|
OUT PUSAGE_AND_PAGE ButtonList,
|
|
IN OUT ULONG * UsageLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData,
|
|
IN PCHAR Report,
|
|
IN ULONG ReportLength
|
|
);
|
|
|
|
NTSTATUS __stdcall DIDummy_HidP_GetScaledUsageValue //unused
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN USAGE UsagePage,
|
|
IN USHORT LinkCollection,
|
|
IN USAGE Usage,
|
|
OUT PLONG UsageValue,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData,
|
|
IN PCHAR Report,
|
|
IN ULONG ReportLength
|
|
);
|
|
|
|
NTSTATUS __stdcall DIDummy_HidP_GetData
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
OUT PHIDP_DATA DataList,
|
|
IN OUT PULONG DataLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData,
|
|
IN PCHAR Report,
|
|
IN ULONG ReportLength
|
|
);
|
|
|
|
NTSTATUS __stdcall DIDummy_HidP_SetData
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN PHIDP_DATA DataList,
|
|
IN OUT PULONG DataLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData,
|
|
IN OUT PCHAR Report,
|
|
IN ULONG ReportLength
|
|
);
|
|
|
|
NTSTATUS __stdcall DIDummy_HidP_GetUsageValue
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN USAGE UsagePage,
|
|
IN USHORT LinkCollection,
|
|
IN USAGE Usage,
|
|
OUT PULONG UsageValue,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData,
|
|
IN PCHAR Report,
|
|
IN ULONG ReportLength
|
|
);
|
|
|
|
ULONG __stdcall DIDummy_HidP_MaxUsageListLength
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN USAGE UsagePage,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
NTSTATUS __stdcall DIDummy_HidP_GetSpecificButtonCaps
|
|
(
|
|
IN HIDP_REPORT_TYPE ReportType,
|
|
IN USAGE UsagePage,
|
|
IN USHORT LinkCollection,
|
|
IN USAGE Usage,
|
|
OUT PHIDP_BUTTON_CAPS ButtonCaps,
|
|
IN OUT PUSHORT ButtonCapsLength,
|
|
IN PHIDP_PREPARSED_DATA PreparsedData
|
|
);
|
|
|
|
NTSTATUS __stdcall DIDummy_HidP_TranslateUsagesToI8042ScanCodes
|
|
(
|
|
IN PUSAGE ChangedUsageList, // Those usages that changed
|
|
IN ULONG UsageListLength,
|
|
IN HIDP_KEYBOARD_DIRECTION KeyAction,
|
|
IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
|
|
IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
|
|
IN PVOID InsertCodesContext
|
|
);
|
|
|
|
// winmm.dll
|
|
|
|
MMRESULT WINAPI DIDummy_joyGetDevCaps
|
|
(
|
|
IN UINT uJoyID,
|
|
OUT LPJOYCAPS pjc,
|
|
IN UINT cbjc
|
|
);
|
|
|
|
MMRESULT WINAPI DIDummy_joyGetPosEx
|
|
(
|
|
IN UINT uJoyID,
|
|
OUT LPJOYINFOEX pji
|
|
);
|
|
|
|
MMRESULT WINAPI DIDummy_joyGetPos
|
|
(
|
|
IN UINT uJoyID,
|
|
OUT LPJOYINFO pji
|
|
);
|
|
|
|
UINT WINAPI DIDummy_joyConfigChanged
|
|
(
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
MMRESULT WINAPI DIDummy_mmioClose
|
|
(
|
|
IN HMMIO hmmio,
|
|
IN UINT fuClose
|
|
);
|
|
|
|
HMMIO WINAPI DIDummy_mmioOpenA
|
|
(
|
|
IN OUT LPSTR pszFileName,
|
|
IN OUT LPMMIOINFO pmmioinfo,
|
|
IN DWORD fdwOpen
|
|
);
|
|
|
|
MMRESULT WINAPI DIDummy_mmioDescend
|
|
(
|
|
IN HMMIO hmmio,
|
|
IN OUT LPMMCKINFO pmmcki,
|
|
IN const MMCKINFO FAR* pmmckiParent,
|
|
IN UINT fuDescend
|
|
);
|
|
|
|
MMRESULT WINAPI DIDummy_mmioCreateChunk
|
|
(
|
|
IN HMMIO hmmio,
|
|
IN LPMMCKINFO pmmcki,
|
|
IN UINT fuCreate
|
|
);
|
|
|
|
LONG WINAPI DIDummy_mmioRead
|
|
(
|
|
IN HMMIO hmmio,
|
|
OUT HPSTR pch,
|
|
IN LONG cch
|
|
);
|
|
|
|
LONG WINAPI DIDummy_mmioWrite
|
|
(
|
|
IN HMMIO hmmio,
|
|
IN const char _huge* pch,
|
|
IN LONG cch
|
|
);
|
|
|
|
MMRESULT WINAPI DIDummy_mmioAscend
|
|
(
|
|
IN HMMIO hmmio,
|
|
IN LPMMCKINFO pmmcki,
|
|
IN UINT fuAscend
|
|
);
|
|
|
|
// user32.dll
|
|
|
|
#ifdef USE_WM_INPUT
|
|
|
|
BOOL WINAPI DIDummy_RegisterRawInputDevices
|
|
(
|
|
PCRAWINPUTDEVICE pRawInputDevices,
|
|
UINT uiNumDevices,
|
|
UINT cbSize
|
|
);
|
|
|
|
UINT WINAPI DIDummy_GetRawInputData
|
|
(
|
|
HRAWINPUT hRawInput,
|
|
UINT uiCommand,
|
|
LPVOID pData,
|
|
PUINT pcbSize,
|
|
UINT cbSizeHeader
|
|
);
|
|
|
|
#endif // #ifdef USE_WM_INPUT
|
|
|
|
#endif /* STATIC_DLLUSAGE */
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* dihidenm.c - HID enumeration functions.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
extern TCHAR g_tszIdLastRemoved[MAX_PATH]; //in dihidenm.c
|
|
extern DWORD g_tmLastRemoved; //in dihinenm.c
|
|
|
|
STDMETHODIMP hresFindHIDInstanceGUID(PCGUID pguid, CREATEDCB *pcdcb);
|
|
STDMETHODIMP hresFindHIDDeviceInterface(LPCTSTR ptszPath, LPGUID pguidOut);
|
|
|
|
PHIDDEVICEINFO EXTERNAL phdiFindHIDInstanceGUID(PCGUID pguid);
|
|
PHIDDEVICEINFO EXTERNAL phdiFindHIDDeviceInterface(LPCTSTR ptszPath);
|
|
|
|
void EXTERNAL DIHid_BuildHidList(BOOL fForce);
|
|
void EXTERNAL DIHid_EmptyHidList(void);
|
|
|
|
BOOL EXTERNAL
|
|
DIHid_GetDevicePath(HDEVINFO hdev,
|
|
PSP_DEVICE_INTERFACE_DATA pdid,
|
|
PSP_DEVICE_INTERFACE_DETAIL_DATA *ppdidd,
|
|
PSP_DEVINFO_DATA pdinf);
|
|
|
|
|
|
BOOL EXTERNAL
|
|
DIHid_GetDeviceInstanceId(HDEVINFO hdev,
|
|
PSP_DEVINFO_DATA pdinf,
|
|
LPTSTR *pptszId);
|
|
|
|
BOOL EXTERNAL
|
|
DIHid_GetInstanceGUID(HKEY hk, LPGUID pguid);
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* diguid.c - GUID generation
|
|
*
|
|
*****************************************************************************/
|
|
|
|
void EXTERNAL DICreateGuid(LPGUID pguid);
|
|
void EXTERNAL DICreateStaticGuid(LPGUID pguid, WORD pid, WORD vid);
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* dihid.c
|
|
*
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* We will just use the HID item index as our DirectInput
|
|
* internal ID number, which is in turn an index into the
|
|
* <t DIOBJECTDATAFORMAT> array.
|
|
*
|
|
* Keyboard support requires a translation table.
|
|
* Other devices also a translation table so that the external
|
|
* instance numbers can be made compatible with legacy ones and
|
|
* so that secondary aliases can be separated from primary ones.
|
|
*
|
|
* Since HID restarts the item index counter at zero for
|
|
* each of input, feature, and output, we need to do some
|
|
* adjustment so there aren't any collisions. So we
|
|
* shift the features to start after the inputs, and the
|
|
* outputs to start after the features.
|
|
*
|
|
* The <e CHid.rgdwBase> array contains the amount by which
|
|
* each group of HID item indexes has been shifted.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func BOOL | HidP_IsValidReportType |
|
|
*
|
|
* For debugging only. Check if a value is a valid
|
|
* <t HIDP_REPORT_TYPE>.
|
|
*
|
|
* Note that we also create a "fake" report type in which
|
|
* to record our collections.
|
|
*
|
|
* @field HIDP_REPORT_TYPE | type |
|
|
*
|
|
* One of the values
|
|
* <c HidP_Input>,
|
|
* <c HidP_Output>,
|
|
* or
|
|
* <c HidP_Feature>. Hopefully.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#define HidP_Max (HidP_Feature + 1)
|
|
#define HidP_Coll HidP_Max
|
|
#define HidP_MaxColl (HidP_Coll + 1)
|
|
|
|
BOOL INLINE
|
|
HidP_IsValidReportType(HIDP_REPORT_TYPE type)
|
|
{
|
|
CAssertF(HidP_Input == 0);
|
|
CAssertF(HidP_Output == 1);
|
|
CAssertF(HidP_Feature == 2);
|
|
return type < HidP_Max;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* There are three (overlapping) classes of HID reports.
|
|
*
|
|
* InputLike - HidP_Input and HidP_Feature
|
|
* OutputLike - HidP_Output and HidP_Feature
|
|
* NothingLike - HidP_Coll
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL INLINE
|
|
HidP_IsInputLike(HIDP_REPORT_TYPE type)
|
|
{
|
|
return type == HidP_Input || type == HidP_Feature;
|
|
}
|
|
|
|
BOOL INLINE
|
|
HidP_IsOutputLike(HIDP_REPORT_TYPE type)
|
|
{
|
|
return type == HidP_Output || type == HidP_Feature;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @struct LMINMAX |
|
|
*
|
|
* Min and max, that's all. These are kept in structures
|
|
* to make logical-to-physical and physical-to-logical
|
|
* translations less gross.
|
|
*
|
|
* @field LONG | Min |
|
|
*
|
|
* The minimum value.
|
|
*
|
|
* @field LONG | Max |
|
|
*
|
|
* The maximum value.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef struct LMINMAX
|
|
{
|
|
LONG Min;
|
|
LONG Max;
|
|
} LMINMAX, *PLMINMAX;
|
|
|
|
typedef const LMINMAX *PCLMINMAX;
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @struct HIDGROUPCAPS |
|
|
*
|
|
* This structure unifies the various HID caps structures
|
|
* <t HIDP_BUTTON_CAPS> and
|
|
* <t HIDP_VALUE_CAPS>.
|
|
*
|
|
* @field HIDP_REPORT_TYPE | type |
|
|
*
|
|
* One of the values
|
|
* <c HidP_Input>,
|
|
* <c HidP_Output>,
|
|
* or
|
|
* <c HidP_Feature>.
|
|
*
|
|
* @field UINT | cObj |
|
|
*
|
|
* Number of objects in this group.
|
|
*
|
|
* @field USAGE | UsagePage |
|
|
*
|
|
* Usage page for all usages in the group.
|
|
*
|
|
* @field USAGE | UsageMin |
|
|
*
|
|
* First usage described by this group. The remaining
|
|
* items are numbered consecutively starting from
|
|
* this value.
|
|
*
|
|
* @field USHORT | StringMin |
|
|
*
|
|
* String for first usage described by this group.
|
|
* The remaining strings are numbered consecutively
|
|
* starting from this value, unless the string maximum
|
|
* is reached, in which case all subsequent objects
|
|
* share that last string.
|
|
*
|
|
* @field USHORT | StringMax |
|
|
*
|
|
* Last string.
|
|
*
|
|
* @field USHORT | DesignatorMin |
|
|
*
|
|
* Designator for first usage described by this group.
|
|
* The remaining designators are numbered consecutively
|
|
* starting from this value, unless the designator maximum
|
|
* is reached, in which case all subsequent objects
|
|
* share that last designator.
|
|
*
|
|
* @field USHORT | DesignatorMax |
|
|
*
|
|
* Last designator.
|
|
*
|
|
* @field USHORT | DataIndexMin |
|
|
*
|
|
* Data index for the first usage described by this group.
|
|
* The remaining data index values are numbered consecutively
|
|
* starting from this value.
|
|
*
|
|
* @field USHORT | usGranularity |
|
|
*
|
|
* If object is a POV or wheel, then contains device granularity.
|
|
*
|
|
* @field LONG | lMask |
|
|
*
|
|
* Mask bits used for sign extension. For example, if the
|
|
* value is 8-bits, the mask will be 0xFFFFFF80, indicating
|
|
* that bit 7 (0x00000080) is extended to fill the remainder
|
|
* of the value.
|
|
*
|
|
* This field is used only by values.
|
|
*
|
|
* @field USHORT | BitSize |
|
|
*
|
|
* Number of bits devoted to this value, including the sign bit.
|
|
*
|
|
* ISSUE-2001/03/29-timgill structure field probably not used anywhere.
|
|
*
|
|
* @field USHORT | LinkCollection |
|
|
*
|
|
* HID link collection number.
|
|
*
|
|
* @field LMINMAX | Logical |
|
|
*
|
|
* Logical minimum and maximum values.
|
|
* These are the extremes of raw values
|
|
* that can validly be received from the device.
|
|
*
|
|
* This field is used only by values.
|
|
*
|
|
* @field LMINMAX | Physical |
|
|
*
|
|
* Physical minimum and maximum values.
|
|
* This is the "actual" value
|
|
* that the logical minimum and maximum value corresponds to.
|
|
*
|
|
* This field is used only by values, and is consulted
|
|
* only when converting between DirectInput calibration
|
|
* (which uses logical values) and VJOYD calibration
|
|
* (which uses physical values).
|
|
*
|
|
* @field LONG | Null |
|
|
*
|
|
* The null value to be used for output.
|
|
*
|
|
* This field is used only by values.
|
|
*
|
|
* @field ULONG | Units |
|
|
*
|
|
* The HID units descriptor, if any.
|
|
*
|
|
* @field WORD | Exponent |
|
|
*
|
|
* The HID unit exponent, if any.
|
|
*
|
|
* @field WORD | wReportId |
|
|
*
|
|
* HID report Id
|
|
*
|
|
* @field BOOL | IsAbsolute |
|
|
*
|
|
* Nonzero if the group describes absolute axes.
|
|
*
|
|
* This field is used only by values.
|
|
*
|
|
* @field BOOL | IsValue |
|
|
*
|
|
* Nonzero if the group describes a HID value.
|
|
*
|
|
* Note that an analog pushbutton is reported by
|
|
* DirectInput as a <c DIDFT_BUTTON>, but is
|
|
* handled internally as a HID value.
|
|
*
|
|
* @field BOOL | IsAlias |
|
|
*
|
|
* Nonzero if the group describes an alias.
|
|
*
|
|
* @field BOOL | IsSigned |
|
|
*
|
|
* The return data is signed.
|
|
*
|
|
* @field BOOL | IsPolledPOV |
|
|
*
|
|
* Nonzero if the axis is a polled POV.
|
|
*
|
|
* @devnote New for DX6.1a
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#define HIDGROUPCAPS_SIGNATURE 0x47444948 /* HIDG */
|
|
|
|
typedef struct HIDGROUPCAPS
|
|
{
|
|
|
|
D(DWORD dwSignature;)
|
|
HIDP_REPORT_TYPE type;
|
|
UINT cObj;
|
|
|
|
USAGE UsagePage;
|
|
USAGE UsageMin;
|
|
|
|
USHORT StringMin, StringMax;
|
|
USHORT DesignatorMin, DesignatorMax;
|
|
USHORT DataIndexMin;
|
|
|
|
USHORT usGranularity;
|
|
|
|
LONG lMask;
|
|
|
|
USHORT BitSize;
|
|
|
|
USHORT LinkCollection;
|
|
|
|
LMINMAX Logical;
|
|
LMINMAX Physical;
|
|
|
|
LONG Null;
|
|
|
|
ULONG Units;
|
|
WORD Exponent;
|
|
|
|
WORD wReportId;
|
|
BOOL fReportDisabled;
|
|
BOOL Reserved;
|
|
|
|
BOOL IsAbsolute;
|
|
BOOL IsValue;
|
|
BOOL IsAlias;
|
|
BOOL IsSigned;
|
|
|
|
#ifdef WINNT
|
|
BOOL IsPolledPOV;
|
|
#endif
|
|
|
|
} HIDGROUPCAPS, *PHIDGROUPCAPS;
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @struct HIDOBJCAPS |
|
|
*
|
|
* This structure contains various cached pointers for each
|
|
* object on the device, allowing us to get at things like
|
|
* the group caps and the calibration information.
|
|
*
|
|
* @field PHIDGROUPCAPS | pcaps |
|
|
*
|
|
* The <t PHIDGROUPCAPS> for the group the object belongs to.
|
|
*
|
|
* @field PJOYRANGECONVERT | pjrc |
|
|
*
|
|
* If non-NULL, then points to the range conversion information
|
|
* for the object.
|
|
*
|
|
* @field int | idata |
|
|
*
|
|
* Index into the <t HIDP_DATA> array for the corresponding
|
|
* output/feature report,
|
|
* or <c -1> if the item is not in the output/feature report.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef struct HIDOBJCAPS
|
|
{
|
|
PHIDGROUPCAPS pcaps;
|
|
PJOYRANGECONVERT pjrc;
|
|
int idata;
|
|
} HIDOBJCAPS, *PHIDOBJCAPS;
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @struct HIDREPORTINFO |
|
|
*
|
|
* This structure contains information that is used for
|
|
* parsing HID reports.
|
|
*
|
|
* @field PHIDP_DATA | rgdata |
|
|
*
|
|
* Array used when parsing reports via
|
|
* <f HidP_GetData> or <f HidP_SetData>. This MUST be aligned
|
|
* correctly on some architechtures.
|
|
*
|
|
* @field PV | pvReport |
|
|
*
|
|
* The report itself.
|
|
*
|
|
* @field int | cdataMax |
|
|
*
|
|
* Number of elements in the <e HIDREPORTINFO.rgdata> array.
|
|
*
|
|
* @field int | cdataUsed |
|
|
*
|
|
* Number of elements in the <e HIDREPORTINFO.rgdata> array
|
|
* that are actually in use.
|
|
*
|
|
* @field ULONG | cbReport |
|
|
*
|
|
* Number of bytes in the report.
|
|
*
|
|
* @field BOOL | fNeedClear |
|
|
*
|
|
* Nonzero if the report needs to be zero'd out because we
|
|
* deleted something (most likely a button) from it.
|
|
* The only way to delete an item from a report is to zero
|
|
* out the entire report and then re-add everything back in.
|
|
*
|
|
* @field BOOL | fChanged |
|
|
*
|
|
* Nonzero if an element in the report has changed.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef struct HIDREPORTINFO
|
|
{
|
|
PHIDP_DATA rgdata;
|
|
PV pvReport;
|
|
int cdataMax;
|
|
int cdataUsed;
|
|
ULONG cbReport;
|
|
BOOL fNeedClear;
|
|
BOOL fChanged;
|
|
} HIDREPORTINFO, *PHIDREPORTINFO;
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @struct CHid |
|
|
*
|
|
* The <i IDirectInputDeviceCallback> object for HID devices.
|
|
*
|
|
* @field IDirectInputDeviceCalllback | didc |
|
|
*
|
|
* The object (containing vtbl).
|
|
*
|
|
* @field PV | pvGroup2 |
|
|
*
|
|
* Pointer to group 2 memory. This field is a union with the
|
|
* pointer to the first chunk of memory in the second memory group.
|
|
*
|
|
* @field HIDREPORTINFO | hriIn |
|
|
*
|
|
* HID input report parsing and state.
|
|
*
|
|
* This memory is the first chunk of group 2.
|
|
*
|
|
* @field HIDREPORTINFO | hriOut |
|
|
*
|
|
* HID output report parsing and state.
|
|
*
|
|
* @field HIDREPORTINFO | hriFea |
|
|
*
|
|
* HID feature report parsing and state.
|
|
*
|
|
* @field PV | pvPhys |
|
|
*
|
|
* Pointer to physical device status information updated
|
|
* asynchronously by the data collection thread.
|
|
*
|
|
* @field PV | pvStage |
|
|
*
|
|
* Staging area used when the HID report is parsed.
|
|
*
|
|
* This memory is the last chunk of group 2.
|
|
*
|
|
* @field DWORD | cbPhys |
|
|
*
|
|
* Size of the physical device state.
|
|
*
|
|
* @field VXDINSTANCE * | pvi |
|
|
*
|
|
* The DirectInput instance handle.
|
|
*
|
|
* HID devices always run through ring 3, which is misleadingly
|
|
* called "emulation".
|
|
*
|
|
* @field DWORD | dwDevType |
|
|
*
|
|
* Device type code.
|
|
*
|
|
* @field LPTSTR | ptszId |
|
|
*
|
|
* Setupapi device instance ID. Used to obtain things
|
|
* like manufacturer name.
|
|
*
|
|
* @field LPTSTR | ptszPath |
|
|
*
|
|
* Path to the device, for <f CreateFile>.
|
|
*
|
|
* @field UINT | dwAxes |
|
|
*
|
|
* Number of axes on the device.
|
|
*
|
|
* @field UINT | dwButtons |
|
|
*
|
|
* Number of buttons on the device.
|
|
*
|
|
* @field UINT | dwPOVs |
|
|
*
|
|
* Number of POV controllers on the device.
|
|
*
|
|
* @field HANDLE | hdev |
|
|
*
|
|
* Handle to the device itself. This field is valid only
|
|
* while the device is acquired.
|
|
*
|
|
* @field HANDLE | hdevEm |
|
|
*
|
|
* <f DuplicateHandle> of the <e CHid.hdev> which is used
|
|
* by the worker thread. We need to keep this separate from
|
|
* the main copy to avoid race conditions between the main
|
|
* thread and the worker thread.
|
|
*
|
|
* @field HKEY | hkInstType |
|
|
*
|
|
* Per-instance registry key that contains additional configuration
|
|
* information, equivalent to the joystick Type key.
|
|
*
|
|
* @field DWORD | rgdwBase[HidP_MaxColl] |
|
|
*
|
|
* Array of base indices for the three HID usage classes:
|
|
* <c HidP_Input>, <c HidP_Output>, and <c HidP_Feature>.
|
|
* We hide the <c HidP_Collection> base index here, too.
|
|
*
|
|
* @field PHIDOBJCAPS | rghoc |
|
|
*
|
|
* Pointer to array of
|
|
* <t PHIDOBJCAPS>, one for each object on the device,
|
|
* each of which in turn contains info about a single object.
|
|
*
|
|
* This memory is allocated as part of the
|
|
* df.rgodf in the <t DIDATAFORMAT> structure
|
|
* hence should not be freed separately.
|
|
*
|
|
* @field DIDATAFORMAT | df |
|
|
*
|
|
* The dynamically-generated data format based on the
|
|
* usages on the HID device.
|
|
*
|
|
* @field DWORD | ibButtonData |
|
|
*
|
|
* The location of the button data inside the data format.
|
|
*
|
|
* @field DWORD | cbButtonData |
|
|
*
|
|
* The number of bytes of button data inside the data format.
|
|
*
|
|
* @field PBYTE * | rgpbButtonMasks |
|
|
*
|
|
* Pointer to a an array of pointers to byte strings to mask
|
|
* the buttons relevant to a report.
|
|
*
|
|
* @field PHIDP_PREPARSED_DATA | ppd |
|
|
*
|
|
* Preparsed data generated by the HID subsystem.
|
|
*
|
|
* @field PHIDGROUPCAPS | rgcaps |
|
|
*
|
|
* Array of <t HIDGROUPCAPS> structures used to keep
|
|
* track of the various buttons, groups, and collections.
|
|
*
|
|
* @field UINT | ccaps |
|
|
*
|
|
* Number of caps structures in the <e CHid.rgcaps> array.
|
|
*
|
|
* @field HIDP_CAPS | caps |
|
|
*
|
|
* Cached HID caps.
|
|
*
|
|
* @field OVERLAPPED | o |
|
|
*
|
|
* Overlapped I/O structure used by worker thread
|
|
* for reading.
|
|
*
|
|
* @field PJOYRANGECONVERT | pjrcNext |
|
|
*
|
|
* Pointer to the first <t JOYRANGECONVERT> structure
|
|
* (in a preallocated array) which has
|
|
* yet to be used.
|
|
* This structure is used for logical-to-physical
|
|
* range conversion (a.k.a. calibration).
|
|
*
|
|
* This memory is allocated as part of the
|
|
* df.rgodf in the <t DIDATAFORMAT> structure
|
|
* hence should not be freed separately.
|
|
*
|
|
* This field is used during device initialization to
|
|
* parcel out the <t JOYRANGECONVERT>s. Afterwards,
|
|
* the field is <c NULL> if we did not create any
|
|
* conversion structures (hence do not need to subclass
|
|
* the cooperative window to catch recalibrations).
|
|
*
|
|
* @field PINT | rgiobj |
|
|
*
|
|
* This points to an array which maps DirectInput instance
|
|
* values (DIDFT_GETINSTANCE) into object indices.
|
|
*
|
|
* @field PINT | rgipov |
|
|
*
|
|
* If we are not a keyboard, then this is the first element in
|
|
* the above array which maps povs.
|
|
*
|
|
* @field PINT | rgiaxis |
|
|
*
|
|
* If we are not a keyboard, then this is the first element in
|
|
* the above array which maps axes.
|
|
*
|
|
* @field PINT | rgicoll |
|
|
*
|
|
* If we are not a keyboard, then this is the first element in
|
|
* the above array which maps collections.
|
|
* //ISSUE-2001/03/29-timgill need to document keyboard case behaviour
|
|
*
|
|
* @field UINT | uiInstanceMax |
|
|
*
|
|
* The number of elements in the above
|
|
* <f rgiobj> array.
|
|
*
|
|
* @field int | idJoy |
|
|
*
|
|
* Joystick identifier for <f joyGetPosEx> and friends for
|
|
* legacy access.
|
|
*
|
|
* This value starts out as -1, to meant that
|
|
* the corresponding legacy joystick is unknown.
|
|
* If we do something that requires the matched legacy
|
|
* joystick to be found, we check if the current value
|
|
* is still valid. If not (either it is -1 or the cached
|
|
* value is stale), then we go hunt for the correct value.
|
|
*
|
|
* @field HKEY | hkType |
|
|
*
|
|
* The joystick type key opened with <c MAXIMUM_ALLOWED> access.
|
|
* This is not per-instance; multiple instances of the same
|
|
* hardware share this key.
|
|
*
|
|
* @field USHORT | VendorID |
|
|
*
|
|
* HID vendor ID for this device.
|
|
*
|
|
* @field USHORT | ProductID |
|
|
*
|
|
* HID product ID for this device.
|
|
*
|
|
* @field HWND | hwnd |
|
|
*
|
|
* The window which we have subclassed in order to watch
|
|
* for recalibration messages.
|
|
*
|
|
* @field BOOL | IsPolledInput |
|
|
*
|
|
* Nonzero if the device has to be polled for Input data.
|
|
*
|
|
* @field BOOL | fPIDdevice |
|
|
*
|
|
* Set to true if the device is found to support PID.
|
|
*
|
|
* @field WORD | wMaxReportId |
|
|
*
|
|
* The maximum (number) of ReportId used by the HID device.
|
|
*
|
|
* @field PUCHAR | pEnableReportId |
|
|
*
|
|
* Pointer to (wMaxReportId) bytes. If a reportID needs to be
|
|
* polled in order to get features / set Output, then that element
|
|
* of this array is set to 0x1.
|
|
*
|
|
* @field BOOL | fEnableInputReport |
|
|
*
|
|
* True if Input report should be enabled for this device.
|
|
*
|
|
* @field BOOL | fFlags2Checked |
|
|
*
|
|
* True after we check the registry for Flags2 for disabling
|
|
* input reports.
|
|
*
|
|
* @comm
|
|
*
|
|
* It is the caller's responsibility to serialize access as
|
|
* necessary.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef struct CHid
|
|
{
|
|
|
|
/* Supported interfaces */
|
|
IDirectInputDeviceCallback dcb;
|
|
|
|
union
|
|
{
|
|
PV pvGroup2;
|
|
HIDREPORTINFO hriIn;
|
|
};
|
|
|
|
HIDREPORTINFO hriOut;
|
|
HIDREPORTINFO hriFea;
|
|
|
|
PV pvPhys;
|
|
PV pvStage;
|
|
DWORD cbPhys;
|
|
|
|
VXDINSTANCE *pvi;
|
|
|
|
DWORD dwDevType;
|
|
|
|
UINT dwAxes;
|
|
UINT dwButtons;
|
|
UINT dwPOVs;
|
|
UINT dwCollections;
|
|
|
|
HANDLE hdev;
|
|
HANDLE hdevEm;
|
|
|
|
DWORD rgdwBase[HidP_MaxColl];
|
|
PHIDOBJCAPS rghoc;
|
|
DIDATAFORMAT df;
|
|
|
|
DWORD ibButtonData;
|
|
DWORD cbButtonData;
|
|
PBYTE *rgpbButtonMasks;
|
|
|
|
PHIDP_PREPARSED_DATA ppd;
|
|
PHIDGROUPCAPS rgcaps;
|
|
|
|
PJOYRANGECONVERT pjrcNext;
|
|
|
|
HIDP_CAPS caps;
|
|
|
|
ED ed;
|
|
OVERLAPPED o;
|
|
DWORD dwStartRead;
|
|
DWORD dwStopRead;
|
|
|
|
PINT rgiobj;
|
|
PINT rgipov;
|
|
PINT rgiaxis;
|
|
PINT rgicoll;
|
|
UINT uiInstanceMax;
|
|
|
|
LPTSTR ptszId;
|
|
LPTSTR ptszPath;
|
|
HKEY hkInstType;
|
|
UINT ccaps;
|
|
int idJoy;
|
|
|
|
HKEY hkType;
|
|
USHORT VendorID;
|
|
USHORT ProductID;
|
|
|
|
#define FAILED_POLL_THRESHOLD (0x4)
|
|
|
|
HWND hwnd;
|
|
|
|
BOOL IsPolledInput;
|
|
BOOL fPIDdevice;
|
|
WORD wMaxReportId[HidP_Max];
|
|
PUCHAR pEnableReportId[HidP_Max];
|
|
|
|
DWORD dwVersion;
|
|
|
|
#if (DIRECTINPUT_VERSION > 0x061A)
|
|
DIAPPHACKS diHacks;
|
|
#endif
|
|
|
|
BOOL fEnableInputReport;
|
|
BOOL fFlags2Checked;
|
|
|
|
} CHid, CHID, *PCHID;
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func PCHID | pchidFromPo |
|
|
*
|
|
* Given an interior pointer to an <t OVERLAPPED>, retrieve
|
|
* a pointer to the parent <t CHid>.
|
|
*
|
|
* @parm LPOVERLAPPED | po |
|
|
*
|
|
* The pointer to convert.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
PCHID INLINE
|
|
pchidFromPo(LPOVERLAPPED po)
|
|
{
|
|
return pvSubPvCb(po, FIELD_OFFSET(CHid, o));
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func PCHID | pchidFromPed |
|
|
*
|
|
* Given an interior pointer to a <t CEd>, retrieve
|
|
* a pointer to the parent <t CHid>.
|
|
*
|
|
* @parm PED | ped |
|
|
*
|
|
* The pointer to convert.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
PCHID INLINE
|
|
pchidFromPed(PED ped)
|
|
{
|
|
return pvSubPvCb(ped, FIELD_OFFSET(CHid, ed));
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func PCHID | pchidFromPem |
|
|
*
|
|
* Given a <t CEm>, wander back to the
|
|
* <t CHid> that spawned it.
|
|
*
|
|
* @parm PEM | pem |
|
|
*
|
|
* The pointer at which to start.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
PCHID INLINE
|
|
pchidFromPem(PEM pem)
|
|
{
|
|
PCHID pchid = pchidFromPed(pem->ped);
|
|
AssertF(pemFromPvi(pchid->pvi) == pem);
|
|
return pchid;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @method UINT | CHid | ObjFromType |
|
|
*
|
|
* Given a <p dwType>, extract the instance number
|
|
* and (if necessary) convert it to an object index.
|
|
* Note, the instance number will always be of the primary instance
|
|
* not an alias.
|
|
*
|
|
* @parm PCHID | this |
|
|
*
|
|
* HID device object.
|
|
*
|
|
* @parm DWORD | dwType |
|
|
*
|
|
* The type code to convert.
|
|
*
|
|
* @returns
|
|
*
|
|
* The object index, or an out-of-range value.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
UINT INLINE
|
|
CHid_ObjFromType(PCHID this, DWORD dwType)
|
|
{
|
|
UINT uiObj = DIDFT_GETINSTANCE(dwType);
|
|
|
|
// ISSUE-2001/03/29-timgill Range checks may be unnecessary
|
|
// MarcAnd can we ever get the out of range value?
|
|
// if so, can we really run with it?
|
|
// if not, can these range checks be converted into Asserts?
|
|
|
|
/*
|
|
* The range checking makes use of the fact that the translation
|
|
* tables are taken from a contiguous memory allocation and that
|
|
* aliased collections are not distinguished.
|
|
*/
|
|
if(this->rgiobj)
|
|
{
|
|
switch( DIDFT_GETTYPE(dwType) )
|
|
{
|
|
case DIDFT_RELAXIS:
|
|
case DIDFT_ABSAXIS:
|
|
if( &this->rgiaxis[uiObj] < this->rgicoll )
|
|
{
|
|
uiObj = this->rgiaxis[uiObj];
|
|
} else
|
|
{
|
|
uiObj = 0xFFFFFFFF;
|
|
}
|
|
break;
|
|
|
|
case DIDFT_PSHBUTTON:
|
|
case DIDFT_TGLBUTTON:
|
|
/*
|
|
* If it is keyboard, this->rgiobj == this->rgipov (see CHid_MungeKeyboard).
|
|
* So, we can't test &this->rgiobj[uiObj] < this->rgipov.
|
|
*/
|
|
if( (GET_DIDEVICE_TYPE(this->dwDevType) == DIDEVTYPE_KEYBOARD &&
|
|
uiObj < this->uiInstanceMax ) ||
|
|
&this->rgiobj[uiObj] < this->rgipov )
|
|
{
|
|
uiObj = this->rgiobj[uiObj];
|
|
} else
|
|
{
|
|
uiObj = 0xFFFFFFFF;
|
|
}
|
|
break;
|
|
|
|
case DIDFT_POV:
|
|
if( &this->rgipov[uiObj] < this->rgiaxis )
|
|
{
|
|
uiObj = this->rgipov[uiObj];
|
|
} else
|
|
{
|
|
uiObj = 0xFFFFFFFF;
|
|
}
|
|
break;
|
|
case (DIDFT_COLLECTION | DIDFT_NODATA):
|
|
if( &this->rgicoll[uiObj] <= &this->rgiobj[this->uiInstanceMax] )
|
|
{
|
|
uiObj = this->rgicoll[uiObj];
|
|
} else
|
|
{
|
|
uiObj = 0xFFFFFFFF;
|
|
}
|
|
break;
|
|
case DIDFT_NODATA:
|
|
/*
|
|
* So far, this TYPE only shows up on Keyboard (HID_USAGE_PAGE_LED).
|
|
*/
|
|
if( GET_DIDEVICE_TYPE(this->dwDevType) == DIDEVTYPE_KEYBOARD &&
|
|
uiObj < this->uiInstanceMax )
|
|
{
|
|
uiObj = this->rgiobj[uiObj];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/*
|
|
* Hopefully this is just a vendor defined object but squirt
|
|
* in debug as these may cause problems.
|
|
*/
|
|
SquirtSqflPtszV(sqflHidParse | sqflVerbose,
|
|
TEXT("CHid_ObjFromType: dwType 0x%08x not converted"),
|
|
dwType );
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SquirtSqflPtszV(sqflHidParse | sqflError,
|
|
TEXT("CHid_ObjFromType: Translation array missing") );
|
|
}
|
|
|
|
return uiObj;
|
|
}
|
|
|
|
LONG EXTERNAL
|
|
CHid_CoordinateTransform(PLMINMAX Dst, PLMINMAX Src, LONG lVal);
|
|
|
|
void EXTERNAL
|
|
CHid_UpdateVjoydCalibration(PCHID this, UINT iobj);
|
|
|
|
void EXTERNAL
|
|
CHid_UpdateCalibrationFromVjoyd(PCHID this, UINT iobj, LPDIOBJECTCALIBRATION pCal);
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* dihidini.c - Device callback initialization stuff
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#define INITBUTTONFLAG 0x10000000
|
|
|
|
HRESULT EXTERNAL CHid_InitParseData(PCHID this);
|
|
|
|
HRESULT EXTERNAL CHid_Init(PCHID this, REFGUID rguid);
|
|
|
|
HANDLE EXTERNAL CHid_OpenDevicePath(PCHID this, DWORD dwAttributes );
|
|
|
|
UINT EXTERNAL CHid_LoadCalibrations(PCHID this);
|
|
|
|
BOOL EXTERNAL CHid_IsPolledDevice( HANDLE hdev );
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* dihiddat.c - HID data parsing/management
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef HRESULT (FAR PASCAL * SENDHIDREPORT)(PCHID this, PHIDREPORTINFO phri);
|
|
|
|
void EXTERNAL CHid_ResetDeviceData(PCHID this, PHIDREPORTINFO phri,
|
|
HIDP_REPORT_TYPE type);
|
|
HRESULT EXTERNAL CHid_AddDeviceData(PCHID this, UINT uiObj, DWORD dwData);
|
|
STDMETHODIMP CHid_PrepareDeviceData(PCHID this, PHIDREPORTINFO phri);
|
|
STDMETHODIMP CHid_SendHIDReport(PCHID this, PHIDREPORTINFO phri,
|
|
HIDP_REPORT_TYPE type, SENDHIDREPORT SendHIDReport);
|
|
|
|
NTSTATUS EXTERNAL
|
|
CHid_ParseData(PCHID this, HIDP_REPORT_TYPE type, PHIDREPORTINFO phri);
|
|
|
|
|
|
HRESULT EXTERNAL
|
|
DIHid_GetRegistryProperty(LPTSTR ptszId, DWORD dwProperty, LPDIPROPHEADER pdiph);
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* diemh.c - HID "emulation"
|
|
*
|
|
*****************************************************************************/
|
|
|
|
void EXTERNAL CEm_HID_Sync(PLLTHREADSTATE plts, PEM pem);
|
|
|
|
BOOL EXTERNAL CEm_HID_IssueRead( PCHID pchid );
|
|
|
|
#else //No HID Support
|
|
|
|
#define DIHid_BuildHidList(fForce)
|
|
#define hresFindHIDDeviceInterface(ptszPath, pguidOut) ( E_FAIL )
|
|
|
|
#endif /* _DIHID_H */
|
|
#endif /* HID_SUPPORT */
|