/*************************************************************************** * * 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 field contains the * device type code, used by * . * * If the device is a HID mouse, then the remaining fields * are commandeered as follows: * * The field is the number * of buttons on the mouse. * * The field is the number * of axes on the mouse. * * See 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 . * * @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 * points to the procedure name. If it has been resolved * successfully, then points to * the resolved address. If it has not been resolved * successfully, then 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 * 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 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 * . * * Note that we also create a "fake" report type in which * to record our collections. * * @field HIDP_REPORT_TYPE | type | * * One of the values * , * , * or * . 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 * and * . * * @field HIDP_REPORT_TYPE | type | * * One of the values * , * , * or * . * * @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 , 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 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 array for the corresponding * output/feature report, * or 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 * or . This MUST be aligned * correctly on some architechtures. * * @field PV | pvReport | * * The report itself. * * @field int | cdataMax | * * Number of elements in the array. * * @field int | cdataUsed | * * Number of elements in the 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 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 . * * @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 | * * of the 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: * , , and . * We hide the base index here, too. * * @field PHIDOBJCAPS | rghoc | * * Pointer to array of * , 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 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 structures used to keep * track of the various buttons, groups, and collections. * * @field UINT | ccaps | * * Number of caps structures in the 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 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 structure * hence should not be freed separately. * * This field is used during device initialization to * parcel out the s. Afterwards, * the field is 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 * array. * * @field int | idJoy | * * Joystick identifier for 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 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 , retrieve * a pointer to the parent . * * @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 , retrieve * a pointer to the parent . * * @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 , wander back to the * 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

, 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 */