windows-nt/Source/XPSP1/NT/multimedia/directx/dinput/dx7/dll/dihid.h

2427 lines
66 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/***************************************************************************
*
* 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 */