mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-19 16:21:44 +00:00
Get the name, manufacturer and serial number for Bluetooth devices on Windows
Adapted from upstream hidapi code
This commit is contained in:
@@ -67,14 +67,10 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#include <setupapi.h>
|
#include <setupapi.h>
|
||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
#ifdef HIDAPI_USE_DDK
|
#include <devpropdef.h>
|
||||||
#include <hidsdi.h>
|
#include "hidapi_cfgmgr32.h"
|
||||||
#endif
|
#include "hidapi_hidclass.h"
|
||||||
|
#include "hidapi_hidsdi.h"
|
||||||
/* Copied from inc/ddk/hidclass.h, part of the Windows DDK. */
|
|
||||||
#define HID_OUT_CTL_CODE(id) \
|
|
||||||
CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
|
|
||||||
#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
@@ -96,8 +92,11 @@ extern "C" {
|
|||||||
#define strlen SDL_strlen
|
#define strlen SDL_strlen
|
||||||
#define strstr SDL_strstr
|
#define strstr SDL_strstr
|
||||||
#define strtol SDL_strtol
|
#define strtol SDL_strtol
|
||||||
|
#define towupper SDL_toupper
|
||||||
#define wcscmp SDL_wcscmp
|
#define wcscmp SDL_wcscmp
|
||||||
|
#define wcslen SDL_wcslen
|
||||||
#define _wcsdup SDL_wcsdup
|
#define _wcsdup SDL_wcsdup
|
||||||
|
#define wcsstr SDL_wcsstr
|
||||||
|
|
||||||
|
|
||||||
#undef MIN
|
#undef MIN
|
||||||
@@ -112,49 +111,21 @@ extern "C" {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef HIDAPI_USE_DDK
|
#ifndef HIDAPI_USE_DDK
|
||||||
/* Since we're not building with the DDK, and the HID header
|
/* Since we're not building with the DDK, and the HID header
|
||||||
files aren't part of the SDK, we have to define all this
|
files aren't part of the Windows SDK, we define what we need ourselves.
|
||||||
stuff here. In lookup_functions(), the function pointers
|
In lookup_functions(), the function pointers
|
||||||
defined below are set. */
|
defined below are set. */
|
||||||
typedef struct _HIDD_ATTRIBUTES{
|
|
||||||
ULONG Size;
|
|
||||||
USHORT VendorID;
|
|
||||||
USHORT ProductID;
|
|
||||||
USHORT VersionNumber;
|
|
||||||
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
|
|
||||||
|
|
||||||
typedef USHORT USAGE;
|
static HidD_GetHidGuid_ HidD_GetHidGuid;
|
||||||
typedef struct _HIDP_CAPS {
|
|
||||||
USAGE Usage;
|
|
||||||
USAGE UsagePage;
|
|
||||||
USHORT InputReportByteLength;
|
|
||||||
USHORT OutputReportByteLength;
|
|
||||||
USHORT FeatureReportByteLength;
|
|
||||||
USHORT Reserved[17];
|
|
||||||
USHORT fields_not_used_by_hidapi[10];
|
|
||||||
} HIDP_CAPS, *PHIDP_CAPS;
|
|
||||||
typedef void* PHIDP_PREPARSED_DATA;
|
|
||||||
#define HIDP_STATUS_SUCCESS 0x110000
|
|
||||||
|
|
||||||
typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib);
|
|
||||||
typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len);
|
|
||||||
typedef BOOLEAN (__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
|
|
||||||
typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
|
|
||||||
typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length);
|
|
||||||
typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length);
|
|
||||||
typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len);
|
|
||||||
typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data);
|
|
||||||
typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data);
|
|
||||||
typedef NTSTATUS (__stdcall *HidP_GetCaps_)(PHIDP_PREPARSED_DATA preparsed_data, HIDP_CAPS *caps);
|
|
||||||
typedef BOOLEAN (__stdcall *HidD_SetNumInputBuffers_)(HANDLE handle, ULONG number_buffers);
|
|
||||||
typedef BOOLEAN(__stdcall *HidD_SetOutputReport_ )(HANDLE handle, PVOID buffer, ULONG buffer_len);
|
|
||||||
static HidD_GetAttributes_ HidD_GetAttributes;
|
static HidD_GetAttributes_ HidD_GetAttributes;
|
||||||
static HidD_GetSerialNumberString_ HidD_GetSerialNumberString;
|
static HidD_GetSerialNumberString_ HidD_GetSerialNumberString;
|
||||||
static HidD_GetManufacturerString_ HidD_GetManufacturerString;
|
static HidD_GetManufacturerString_ HidD_GetManufacturerString;
|
||||||
static HidD_GetProductString_ HidD_GetProductString;
|
static HidD_GetProductString_ HidD_GetProductString;
|
||||||
static HidD_SetFeature_ HidD_SetFeature;
|
static HidD_SetFeature_ HidD_SetFeature;
|
||||||
static HidD_GetFeature_ HidD_GetFeature;
|
static HidD_GetFeature_ HidD_GetFeature;
|
||||||
|
static HidD_GetInputReport_ HidD_GetInputReport;
|
||||||
static HidD_GetIndexedString_ HidD_GetIndexedString;
|
static HidD_GetIndexedString_ HidD_GetIndexedString;
|
||||||
static HidD_GetPreparsedData_ HidD_GetPreparsedData;
|
static HidD_GetPreparsedData_ HidD_GetPreparsedData;
|
||||||
static HidD_FreePreparsedData_ HidD_FreePreparsedData;
|
static HidD_FreePreparsedData_ HidD_FreePreparsedData;
|
||||||
@@ -162,8 +133,79 @@ extern "C" {
|
|||||||
static HidD_SetNumInputBuffers_ HidD_SetNumInputBuffers;
|
static HidD_SetNumInputBuffers_ HidD_SetNumInputBuffers;
|
||||||
static HidD_SetOutputReport_ HidD_SetOutputReport;
|
static HidD_SetOutputReport_ HidD_SetOutputReport;
|
||||||
|
|
||||||
static HMODULE lib_handle = NULL;
|
static CM_Locate_DevNodeW_ CM_Locate_DevNodeW = NULL;
|
||||||
static BOOLEAN initialized = FALSE;
|
static CM_Get_Parent_ CM_Get_Parent = NULL;
|
||||||
|
static CM_Get_DevNode_PropertyW_ CM_Get_DevNode_PropertyW = NULL;
|
||||||
|
static CM_Get_Device_Interface_PropertyW_ CM_Get_Device_Interface_PropertyW = NULL;
|
||||||
|
static CM_Get_Device_Interface_List_SizeW_ CM_Get_Device_Interface_List_SizeW = NULL;
|
||||||
|
static CM_Get_Device_Interface_ListW_ CM_Get_Device_Interface_ListW = NULL;
|
||||||
|
|
||||||
|
static HMODULE hid_lib_handle = NULL;
|
||||||
|
static HMODULE cfgmgr32_lib_handle = NULL;
|
||||||
|
static BOOLEAN hidapi_initialized = FALSE;
|
||||||
|
|
||||||
|
static void free_library_handles()
|
||||||
|
{
|
||||||
|
if (hid_lib_handle)
|
||||||
|
FreeLibrary(hid_lib_handle);
|
||||||
|
hid_lib_handle = NULL;
|
||||||
|
if (cfgmgr32_lib_handle)
|
||||||
|
FreeLibrary(cfgmgr32_lib_handle);
|
||||||
|
cfgmgr32_lib_handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lookup_functions()
|
||||||
|
{
|
||||||
|
hid_lib_handle = LoadLibraryW(L"hid.dll");
|
||||||
|
if (hid_lib_handle == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfgmgr32_lib_handle = LoadLibraryW(L"cfgmgr32.dll");
|
||||||
|
if (cfgmgr32_lib_handle == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
# pragma GCC diagnostic push
|
||||||
|
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||||
|
#endif
|
||||||
|
#define RESOLVE(lib_handle, x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) goto err;
|
||||||
|
|
||||||
|
RESOLVE(hid_lib_handle, HidD_GetHidGuid);
|
||||||
|
RESOLVE(hid_lib_handle, HidD_GetAttributes);
|
||||||
|
RESOLVE(hid_lib_handle, HidD_GetSerialNumberString);
|
||||||
|
RESOLVE(hid_lib_handle, HidD_GetManufacturerString);
|
||||||
|
RESOLVE(hid_lib_handle, HidD_GetProductString);
|
||||||
|
RESOLVE(hid_lib_handle, HidD_SetFeature);
|
||||||
|
RESOLVE(hid_lib_handle, HidD_GetFeature);
|
||||||
|
RESOLVE(hid_lib_handle, HidD_GetInputReport);
|
||||||
|
RESOLVE(hid_lib_handle, HidD_GetIndexedString);
|
||||||
|
RESOLVE(hid_lib_handle, HidD_GetPreparsedData);
|
||||||
|
RESOLVE(hid_lib_handle, HidD_FreePreparsedData);
|
||||||
|
RESOLVE(hid_lib_handle, HidP_GetCaps);
|
||||||
|
RESOLVE(hid_lib_handle, HidD_SetNumInputBuffers);
|
||||||
|
RESOLVE(hid_lib_handle, HidD_SetOutputReport);
|
||||||
|
|
||||||
|
RESOLVE(cfgmgr32_lib_handle, CM_Locate_DevNodeW);
|
||||||
|
RESOLVE(cfgmgr32_lib_handle, CM_Get_Parent);
|
||||||
|
RESOLVE(cfgmgr32_lib_handle, CM_Get_DevNode_PropertyW);
|
||||||
|
RESOLVE(cfgmgr32_lib_handle, CM_Get_Device_Interface_PropertyW);
|
||||||
|
RESOLVE(cfgmgr32_lib_handle, CM_Get_Device_Interface_List_SizeW);
|
||||||
|
RESOLVE(cfgmgr32_lib_handle, CM_Get_Device_Interface_ListW);
|
||||||
|
|
||||||
|
#undef RESOLVE
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
# pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
free_library_handles();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* HIDAPI_USE_DDK */
|
#endif /* HIDAPI_USE_DDK */
|
||||||
|
|
||||||
struct hid_device_ {
|
struct hid_device_ {
|
||||||
@@ -261,33 +303,6 @@ static void register_error(hid_device *device, const char *op)
|
|||||||
device->last_error_str = msg;
|
device->last_error_str = msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HIDAPI_USE_DDK
|
|
||||||
static int lookup_functions()
|
|
||||||
{
|
|
||||||
lib_handle = LoadLibrary(TEXT("hid.dll"));
|
|
||||||
if (lib_handle) {
|
|
||||||
#define RESOLVE(x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) return -1;
|
|
||||||
RESOLVE(HidD_GetAttributes);
|
|
||||||
RESOLVE(HidD_GetSerialNumberString);
|
|
||||||
RESOLVE(HidD_GetManufacturerString);
|
|
||||||
RESOLVE(HidD_GetProductString);
|
|
||||||
RESOLVE(HidD_SetFeature);
|
|
||||||
RESOLVE(HidD_GetFeature);
|
|
||||||
RESOLVE(HidD_GetIndexedString);
|
|
||||||
RESOLVE(HidD_GetPreparsedData);
|
|
||||||
RESOLVE(HidD_FreePreparsedData);
|
|
||||||
RESOLVE(HidP_GetCaps);
|
|
||||||
RESOLVE(HidD_SetNumInputBuffers);
|
|
||||||
RESOLVE(HidD_SetOutputReport);
|
|
||||||
#undef RESOLVE
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static HANDLE open_device(const char *path, BOOL enumerate, BOOL bExclusive )
|
static HANDLE open_device(const char *path, BOOL enumerate, BOOL bExclusive )
|
||||||
{
|
{
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
@@ -312,12 +327,11 @@ static HANDLE open_device(const char *path, BOOL enumerate, BOOL bExclusive )
|
|||||||
int HID_API_EXPORT hid_init(void)
|
int HID_API_EXPORT hid_init(void)
|
||||||
{
|
{
|
||||||
#ifndef HIDAPI_USE_DDK
|
#ifndef HIDAPI_USE_DDK
|
||||||
if (!initialized) {
|
if (!hidapi_initialized) {
|
||||||
if (lookup_functions() < 0) {
|
if (lookup_functions() < 0) {
|
||||||
hid_exit();
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
initialized = TRUE;
|
hidapi_initialized = TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
@@ -326,15 +340,317 @@ int HID_API_EXPORT hid_init(void)
|
|||||||
int HID_API_EXPORT hid_exit(void)
|
int HID_API_EXPORT hid_exit(void)
|
||||||
{
|
{
|
||||||
#ifndef HIDAPI_USE_DDK
|
#ifndef HIDAPI_USE_DDK
|
||||||
if (lib_handle)
|
free_library_handles();
|
||||||
FreeLibrary(lib_handle);
|
hidapi_initialized = FALSE;
|
||||||
lib_handle = NULL;
|
|
||||||
initialized = FALSE;
|
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hid_blacklist(unsigned short vendor_id, unsigned short product_id)
|
static void* hid_internal_get_devnode_property(DEVINST dev_node, const DEVPROPKEY* property_key, DEVPROPTYPE expected_property_type)
|
||||||
|
{
|
||||||
|
ULONG len = 0;
|
||||||
|
CONFIGRET cr;
|
||||||
|
DEVPROPTYPE property_type;
|
||||||
|
PBYTE property_value = NULL;
|
||||||
|
|
||||||
|
cr = CM_Get_DevNode_PropertyW(dev_node, property_key, &property_type, NULL, &len, 0);
|
||||||
|
if (cr != CR_BUFFER_SMALL || property_type != expected_property_type)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
property_value = (PBYTE)calloc(len, sizeof(BYTE));
|
||||||
|
cr = CM_Get_DevNode_PropertyW(dev_node, property_key, &property_type, property_value, &len, 0);
|
||||||
|
if (cr != CR_SUCCESS) {
|
||||||
|
free(property_value);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return property_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* hid_internal_get_device_interface_property(const wchar_t* interface_path, const DEVPROPKEY* property_key, DEVPROPTYPE expected_property_type)
|
||||||
|
{
|
||||||
|
ULONG len = 0;
|
||||||
|
CONFIGRET cr;
|
||||||
|
DEVPROPTYPE property_type;
|
||||||
|
PBYTE property_value = NULL;
|
||||||
|
|
||||||
|
cr = CM_Get_Device_Interface_PropertyW(interface_path, property_key, &property_type, NULL, &len, 0);
|
||||||
|
if (cr != CR_BUFFER_SMALL || property_type != expected_property_type)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
property_value = (PBYTE)calloc(len, sizeof(BYTE));
|
||||||
|
cr = CM_Get_Device_Interface_PropertyW(interface_path, property_key, &property_type, property_value, &len, 0);
|
||||||
|
if (cr != CR_SUCCESS) {
|
||||||
|
free(property_value);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return property_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hid_internal_get_ble_info(struct hid_device_info* dev, DEVINST dev_node)
|
||||||
|
{
|
||||||
|
wchar_t *manufacturer_string, *serial_number, *product_string;
|
||||||
|
/* Manufacturer String */
|
||||||
|
manufacturer_string = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_Manufacturer, DEVPROP_TYPE_STRING);
|
||||||
|
if (manufacturer_string) {
|
||||||
|
free(dev->manufacturer_string);
|
||||||
|
dev->manufacturer_string = manufacturer_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Serial Number String (MAC Address) */
|
||||||
|
serial_number = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_DeviceAddress, DEVPROP_TYPE_STRING);
|
||||||
|
if (serial_number) {
|
||||||
|
free(dev->serial_number);
|
||||||
|
dev->serial_number = serial_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get devnode grandparent to reach out Bluetooth LE device node */
|
||||||
|
if (CM_Get_Parent(&dev_node, dev_node, 0) != CR_SUCCESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Product String */
|
||||||
|
product_string = hid_internal_get_devnode_property(dev_node, &DEVPKEY_NAME, DEVPROP_TYPE_STRING);
|
||||||
|
if (product_string) {
|
||||||
|
free(dev->product_string);
|
||||||
|
dev->product_string = product_string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* USB Device Interface Number.
|
||||||
|
It can be parsed out of the Hardware ID if a USB device is has multiple interfaces (composite device).
|
||||||
|
See https://docs.microsoft.com/windows-hardware/drivers/hid/hidclass-hardware-ids-for-top-level-collections
|
||||||
|
and https://docs.microsoft.com/windows-hardware/drivers/install/standard-usb-identifiers
|
||||||
|
|
||||||
|
hardware_id is always expected to be uppercase.
|
||||||
|
*/
|
||||||
|
static int hid_internal_get_interface_number(const wchar_t* hardware_id)
|
||||||
|
{
|
||||||
|
int interface_number;
|
||||||
|
wchar_t *startptr, *endptr;
|
||||||
|
const wchar_t *interface_token = L"&MI_";
|
||||||
|
|
||||||
|
startptr = wcsstr(hardware_id, interface_token);
|
||||||
|
if (!startptr)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
startptr += wcslen(interface_token);
|
||||||
|
interface_number = wcstol(startptr, &endptr, 16);
|
||||||
|
if (endptr == startptr)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return interface_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hid_internal_get_info(const wchar_t* interface_path, struct hid_device_info* dev)
|
||||||
|
{
|
||||||
|
wchar_t *device_id = NULL, *compatible_ids = NULL, *hardware_ids = NULL;
|
||||||
|
CONFIGRET cr;
|
||||||
|
DEVINST dev_node;
|
||||||
|
|
||||||
|
/* Get the device id from interface path */
|
||||||
|
device_id = hid_internal_get_device_interface_property(interface_path, &DEVPKEY_Device_InstanceId, DEVPROP_TYPE_STRING);
|
||||||
|
if (!device_id)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Open devnode from device id */
|
||||||
|
cr = CM_Locate_DevNodeW(&dev_node, (DEVINSTID_W)device_id, CM_LOCATE_DEVNODE_NORMAL);
|
||||||
|
if (cr != CR_SUCCESS)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Get the hardware ids from devnode */
|
||||||
|
hardware_ids = hid_internal_get_devnode_property(dev_node, &DEVPKEY_Device_HardwareIds, DEVPROP_TYPE_STRING_LIST);
|
||||||
|
if (!hardware_ids)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Search for interface number in hardware ids */
|
||||||
|
for (wchar_t* hardware_id = hardware_ids; *hardware_id; hardware_id += wcslen(hardware_id) + 1) {
|
||||||
|
/* Normalize to upper case */
|
||||||
|
for (wchar_t* p = hardware_id; *p; ++p) *p = towupper(*p);
|
||||||
|
|
||||||
|
dev->interface_number = hid_internal_get_interface_number(hardware_id);
|
||||||
|
|
||||||
|
if (dev->interface_number != -1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get devnode parent */
|
||||||
|
cr = CM_Get_Parent(&dev_node, dev_node, 0);
|
||||||
|
if (cr != CR_SUCCESS)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Get the compatible ids from parent devnode */
|
||||||
|
compatible_ids = hid_internal_get_devnode_property(dev_node, &DEVPKEY_Device_CompatibleIds, DEVPROP_TYPE_STRING_LIST);
|
||||||
|
if (!compatible_ids)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Now we can parse parent's compatible IDs to find out the device bus type */
|
||||||
|
for (wchar_t* compatible_id = compatible_ids; *compatible_id; compatible_id += wcslen(compatible_id) + 1) {
|
||||||
|
/* Normalize to upper case */
|
||||||
|
for (wchar_t* p = compatible_id; *p; ++p) *p = towupper(*p);
|
||||||
|
|
||||||
|
/* USB devices
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-support
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/install/standard-usb-identifiers */
|
||||||
|
if (wcsstr(compatible_id, L"USB") != NULL) {
|
||||||
|
dev->bus_type = HID_API_BUS_USB;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bluetooth devices
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/bluetooth/installing-a-bluetooth-device */
|
||||||
|
if (wcsstr(compatible_id, L"BTHENUM") != NULL) {
|
||||||
|
dev->bus_type = HID_API_BUS_BLUETOOTH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bluetooth LE devices */
|
||||||
|
if (wcsstr(compatible_id, L"BTHLEDEVICE") != NULL) {
|
||||||
|
/* HidD_GetProductString/HidD_GetManufacturerString/HidD_GetSerialNumberString is not working for BLE HID devices
|
||||||
|
Request this info via dev node properties instead.
|
||||||
|
https://docs.microsoft.com/answers/questions/401236/hidd-getproductstring-with-ble-hid-device.html */
|
||||||
|
hid_internal_get_ble_info(dev, dev_node);
|
||||||
|
|
||||||
|
dev->bus_type = HID_API_BUS_BLUETOOTH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* I2C devices
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-support-and-power-management */
|
||||||
|
if (wcsstr(compatible_id, L"PNP0C50") != NULL) {
|
||||||
|
dev->bus_type = HID_API_BUS_I2C;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SPI devices
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-for-spi */
|
||||||
|
if (wcsstr(compatible_id, L"PNP0C51") != NULL) {
|
||||||
|
dev->bus_type = HID_API_BUS_SPI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
free(device_id);
|
||||||
|
free(hardware_ids);
|
||||||
|
free(compatible_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *hid_internal_UTF16toUTF8(const wchar_t *src)
|
||||||
|
{
|
||||||
|
char *dst = NULL;
|
||||||
|
int len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, NULL, 0, NULL, NULL);
|
||||||
|
if (len) {
|
||||||
|
dst = (char*)calloc(len, sizeof(char));
|
||||||
|
if (dst == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, dst, len, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
#endif /* 0 */
|
||||||
|
|
||||||
|
static wchar_t *hid_internal_UTF8toUTF16(const char *src)
|
||||||
|
{
|
||||||
|
wchar_t *dst = NULL;
|
||||||
|
int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, NULL, 0);
|
||||||
|
if (len) {
|
||||||
|
dst = (wchar_t*)calloc(len, sizeof(wchar_t));
|
||||||
|
if (dst == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, dst, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hid_get_bluetooth_info(const char *path, struct hid_device_info* dev)
|
||||||
|
{
|
||||||
|
wchar_t *interface_path = NULL, *device_id = NULL, *compatible_ids = NULL;
|
||||||
|
CONFIGRET cr;
|
||||||
|
DEVINST dev_node;
|
||||||
|
int is_bluetooth = 0;
|
||||||
|
|
||||||
|
/* Get the device id from interface path */
|
||||||
|
interface_path = hid_internal_UTF8toUTF16(path);
|
||||||
|
device_id = hid_internal_get_device_interface_property(interface_path, &DEVPKEY_Device_InstanceId, DEVPROP_TYPE_STRING);
|
||||||
|
if (!device_id)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Open devnode from device id */
|
||||||
|
cr = CM_Locate_DevNodeW(&dev_node, (DEVINSTID_W)device_id, CM_LOCATE_DEVNODE_NORMAL);
|
||||||
|
if (cr != CR_SUCCESS)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Get devnode parent */
|
||||||
|
cr = CM_Get_Parent(&dev_node, dev_node, 0);
|
||||||
|
if (cr != CR_SUCCESS)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Get the compatible ids from parent devnode */
|
||||||
|
compatible_ids = hid_internal_get_devnode_property(dev_node, &DEVPKEY_Device_CompatibleIds, DEVPROP_TYPE_STRING_LIST);
|
||||||
|
if (!compatible_ids)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Now we can parse parent's compatible IDs to find out the device bus type */
|
||||||
|
for (wchar_t* compatible_id = compatible_ids; *compatible_id; compatible_id += wcslen(compatible_id) + 1) {
|
||||||
|
/* Normalize to upper case */
|
||||||
|
for (wchar_t* p = compatible_id; *p; ++p) *p = towupper(*p);
|
||||||
|
|
||||||
|
/* USB devices
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-support
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/install/standard-usb-identifiers */
|
||||||
|
if (wcsstr(compatible_id, L"USB") != NULL) {
|
||||||
|
/*dev->bus_type = HID_API_BUS_USB;*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bluetooth devices
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/bluetooth/installing-a-bluetooth-device */
|
||||||
|
if (wcsstr(compatible_id, L"BTHENUM") != NULL) {
|
||||||
|
/*dev->bus_type = HID_API_BUS_BLUETOOTH;*/
|
||||||
|
is_bluetooth = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bluetooth LE devices */
|
||||||
|
if (wcsstr(compatible_id, L"BTHLEDEVICE") != NULL) {
|
||||||
|
/* HidD_GetProductString/HidD_GetManufacturerString/HidD_GetSerialNumberString is not working for BLE HID devices
|
||||||
|
Request this info via dev node properties instead.
|
||||||
|
https://docs.microsoft.com/answers/questions/401236/hidd-getproductstring-with-ble-hid-device.html */
|
||||||
|
if (dev)
|
||||||
|
hid_internal_get_ble_info(dev, dev_node);
|
||||||
|
|
||||||
|
/*dev->bus_type = HID_API_BUS_BLUETOOTH;*/
|
||||||
|
is_bluetooth = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* I2C devices
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-support-and-power-management */
|
||||||
|
if (wcsstr(compatible_id, L"PNP0C50") != NULL) {
|
||||||
|
/*dev->bus_type = HID_API_BUS_I2C;*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SPI devices
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-for-spi */
|
||||||
|
if (wcsstr(compatible_id, L"PNP0C51") != NULL) {
|
||||||
|
/*dev->bus_type = HID_API_BUS_SPI;*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
free(interface_path);
|
||||||
|
free(device_id);
|
||||||
|
free(compatible_ids);
|
||||||
|
return is_bluetooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hid_blacklist(unsigned short vendor_id, unsigned short product_id)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
static const struct { unsigned short vid; unsigned short pid; } known_bad[] = {
|
static const struct { unsigned short vid; unsigned short pid; } known_bad[] = {
|
||||||
@@ -609,6 +925,9 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the Bluetooth device info */
|
||||||
|
hid_get_bluetooth_info(cur_dev->path, cur_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
cont_close:
|
cont_close:
|
||||||
|
77
src/hidapi/windows/hidapi_cfgmgr32.h
Normal file
77
src/hidapi/windows/hidapi_cfgmgr32.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/*******************************************************
|
||||||
|
HIDAPI - Multi-Platform library for
|
||||||
|
communication with HID devices.
|
||||||
|
|
||||||
|
libusb/hidapi Team
|
||||||
|
|
||||||
|
Copyright 2022, All Rights Reserved.
|
||||||
|
|
||||||
|
At the discretion of the user of this library,
|
||||||
|
this software may be licensed under the terms of the
|
||||||
|
GNU General Public License v3, a BSD-Style license, or the
|
||||||
|
original HIDAPI license as outlined in the LICENSE.txt,
|
||||||
|
LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
|
||||||
|
files located at the root of the source distribution.
|
||||||
|
These files may also be found in the public source
|
||||||
|
code repository located at:
|
||||||
|
https://github.com/libusb/hidapi .
|
||||||
|
********************************************************/
|
||||||
|
|
||||||
|
#ifndef HIDAPI_CFGMGR32_H
|
||||||
|
#define HIDAPI_CFGMGR32_H
|
||||||
|
|
||||||
|
#ifdef HIDAPI_USE_DDK
|
||||||
|
|
||||||
|
#include <cfgmgr32.h>
|
||||||
|
#include <initguid.h>
|
||||||
|
#include <devpkey.h>
|
||||||
|
#include <propkey.h>
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifndef PROPERTYKEY_DEFINED
|
||||||
|
#define PROPERTYKEY_DEFINED
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GUID fmtid;
|
||||||
|
DWORD pid;
|
||||||
|
} PROPERTYKEY;
|
||||||
|
#endif /* PROPERTYKEY_DEFINED */
|
||||||
|
|
||||||
|
/* This part of the header mimics cfgmgr32.h,
|
||||||
|
but only what is used by HIDAPI */
|
||||||
|
|
||||||
|
typedef DWORD RETURN_TYPE;
|
||||||
|
typedef RETURN_TYPE CONFIGRET;
|
||||||
|
typedef DWORD DEVNODE, DEVINST;
|
||||||
|
typedef DEVNODE* PDEVNODE, * PDEVINST;
|
||||||
|
typedef WCHAR* DEVNODEID_W, * DEVINSTID_W;
|
||||||
|
|
||||||
|
#define CR_SUCCESS (0x00000000)
|
||||||
|
#define CR_BUFFER_SMALL (0x0000001A)
|
||||||
|
#define CR_FAILURE (0x00000013)
|
||||||
|
|
||||||
|
#define CM_LOCATE_DEVNODE_NORMAL 0x00000000
|
||||||
|
|
||||||
|
#define CM_GET_DEVICE_INTERFACE_LIST_PRESENT (0x00000000)
|
||||||
|
|
||||||
|
typedef CONFIGRET(__stdcall* CM_Locate_DevNodeW_)(PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags);
|
||||||
|
typedef CONFIGRET(__stdcall* CM_Get_Parent_)(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags);
|
||||||
|
typedef CONFIGRET(__stdcall* CM_Get_DevNode_PropertyW_)(DEVINST dnDevInst, CONST DEVPROPKEY* PropertyKey, DEVPROPTYPE* PropertyType, PBYTE PropertyBuffer, PULONG PropertyBufferSize, ULONG ulFlags);
|
||||||
|
typedef CONFIGRET(__stdcall* CM_Get_Device_Interface_PropertyW_)(LPCWSTR pszDeviceInterface, CONST DEVPROPKEY* PropertyKey, DEVPROPTYPE* PropertyType, PBYTE PropertyBuffer, PULONG PropertyBufferSize, ULONG ulFlags);
|
||||||
|
typedef CONFIGRET(__stdcall* CM_Get_Device_Interface_List_SizeW_)(PULONG pulLen, LPGUID InterfaceClassGuid, DEVINSTID_W pDeviceID, ULONG ulFlags);
|
||||||
|
typedef CONFIGRET(__stdcall* CM_Get_Device_Interface_ListW_)(LPGUID InterfaceClassGuid, DEVINSTID_W pDeviceID, PZZWSTR Buffer, ULONG BufferLen, ULONG ulFlags);
|
||||||
|
|
||||||
|
// from devpkey.h
|
||||||
|
static DEVPROPKEY DEVPKEY_NAME = { { 0xb725f130, 0x47ef, 0x101a, {0xa5, 0xf1, 0x02, 0x60, 0x8c, 0x9e, 0xeb, 0xac} }, 10 }; // DEVPROP_TYPE_STRING
|
||||||
|
static DEVPROPKEY DEVPKEY_Device_InstanceId = { { 0x78c34fc8, 0x104a, 0x4aca, {0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57} }, 256 }; // DEVPROP_TYPE_STRING
|
||||||
|
static DEVPROPKEY DEVPKEY_Device_HardwareIds = { { 0xa45c254e, 0xdf1c, 0x4efd, {0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0} }, 3 }; // DEVPROP_TYPE_STRING_LIST
|
||||||
|
static DEVPROPKEY DEVPKEY_Device_CompatibleIds = { { 0xa45c254e, 0xdf1c, 0x4efd, {0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0} }, 4 }; // DEVPROP_TYPE_STRING_LIST
|
||||||
|
static DEVPROPKEY DEVPKEY_Device_ContainerId = { { 0x8c7ed206, 0x3f8a, 0x4827, {0xb3, 0xab, 0xae, 0x9e, 0x1f, 0xae, 0xfc, 0x6c} }, 2 }; // DEVPROP_TYPE_GUID
|
||||||
|
|
||||||
|
// from propkey.h
|
||||||
|
static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_DeviceAddress = { { 0x2bd67d8b, 0x8beb, 0x48d5, {0x87, 0xe0, 0x6c, 0xda, 0x34, 0x28, 0x04, 0x0a} }, 1 }; // DEVPROP_TYPE_STRING
|
||||||
|
static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_Manufacturer = { { 0x2bd67d8b, 0x8beb, 0x48d5, {0x87, 0xe0, 0x6c, 0xda, 0x34, 0x28, 0x04, 0x0a} }, 4 }; // DEVPROP_TYPE_STRING
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HIDAPI_CFGMGR32_H */
|
38
src/hidapi/windows/hidapi_hidclass.h
Normal file
38
src/hidapi/windows/hidapi_hidclass.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/*******************************************************
|
||||||
|
HIDAPI - Multi-Platform library for
|
||||||
|
communication with HID devices.
|
||||||
|
|
||||||
|
libusb/hidapi Team
|
||||||
|
|
||||||
|
Copyright 2022, All Rights Reserved.
|
||||||
|
|
||||||
|
At the discretion of the user of this library,
|
||||||
|
this software may be licensed under the terms of the
|
||||||
|
GNU General Public License v3, a BSD-Style license, or the
|
||||||
|
original HIDAPI license as outlined in the LICENSE.txt,
|
||||||
|
LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
|
||||||
|
files located at the root of the source distribution.
|
||||||
|
These files may also be found in the public source
|
||||||
|
code repository located at:
|
||||||
|
https://github.com/libusb/hidapi .
|
||||||
|
********************************************************/
|
||||||
|
|
||||||
|
#ifndef HIDAPI_HIDCLASS_H
|
||||||
|
#define HIDAPI_HIDCLASS_H
|
||||||
|
|
||||||
|
#ifdef HIDAPI_USE_DDK
|
||||||
|
|
||||||
|
#include <hidclass.h>
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* This part of the header mimics hidclass.h,
|
||||||
|
but only what is used by HIDAPI */
|
||||||
|
|
||||||
|
#define HID_OUT_CTL_CODE(id) CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
|
||||||
|
#define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HIDAPI_HIDCLASS_H */
|
65
src/hidapi/windows/hidapi_hidpi.h
Normal file
65
src/hidapi/windows/hidapi_hidpi.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*******************************************************
|
||||||
|
HIDAPI - Multi-Platform library for
|
||||||
|
communication with HID devices.
|
||||||
|
|
||||||
|
libusb/hidapi Team
|
||||||
|
|
||||||
|
Copyright 2022, All Rights Reserved.
|
||||||
|
|
||||||
|
At the discretion of the user of this library,
|
||||||
|
this software may be licensed under the terms of the
|
||||||
|
GNU General Public License v3, a BSD-Style license, or the
|
||||||
|
original HIDAPI license as outlined in the LICENSE.txt,
|
||||||
|
LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
|
||||||
|
files located at the root of the source distribution.
|
||||||
|
These files may also be found in the public source
|
||||||
|
code repository located at:
|
||||||
|
https://github.com/libusb/hidapi .
|
||||||
|
********************************************************/
|
||||||
|
|
||||||
|
#ifndef HIDAPI_HIDPI_H
|
||||||
|
#define HIDAPI_HIDPI_H
|
||||||
|
|
||||||
|
#ifdef HIDAPI_USE_DDK
|
||||||
|
|
||||||
|
#include <hidpi.h>
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* This part of the header mimics hidpi.h,
|
||||||
|
but only what is used by HIDAPI */
|
||||||
|
|
||||||
|
typedef struct _HIDP_PREPARSED_DATA * PHIDP_PREPARSED_DATA;
|
||||||
|
|
||||||
|
typedef struct _HIDP_CAPS
|
||||||
|
{
|
||||||
|
USAGE Usage;
|
||||||
|
USAGE UsagePage;
|
||||||
|
USHORT InputReportByteLength;
|
||||||
|
USHORT OutputReportByteLength;
|
||||||
|
USHORT FeatureReportByteLength;
|
||||||
|
USHORT Reserved[17];
|
||||||
|
|
||||||
|
USHORT NumberLinkCollectionNodes;
|
||||||
|
|
||||||
|
USHORT NumberInputButtonCaps;
|
||||||
|
USHORT NumberInputValueCaps;
|
||||||
|
USHORT NumberInputDataIndices;
|
||||||
|
|
||||||
|
USHORT NumberOutputButtonCaps;
|
||||||
|
USHORT NumberOutputValueCaps;
|
||||||
|
USHORT NumberOutputDataIndices;
|
||||||
|
|
||||||
|
USHORT NumberFeatureButtonCaps;
|
||||||
|
USHORT NumberFeatureValueCaps;
|
||||||
|
USHORT NumberFeatureDataIndices;
|
||||||
|
} HIDP_CAPS, *PHIDP_CAPS;
|
||||||
|
|
||||||
|
#define HIDP_STATUS_SUCCESS 0x00110000
|
||||||
|
#define HIDP_STATUS_INVALID_PREPARSED_DATA 0xc0110001
|
||||||
|
|
||||||
|
typedef NTSTATUS (__stdcall *HidP_GetCaps_)(PHIDP_PREPARSED_DATA preparsed_data, PHIDP_CAPS caps);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HIDAPI_HIDPI_H */
|
62
src/hidapi/windows/hidapi_hidsdi.h
Normal file
62
src/hidapi/windows/hidapi_hidsdi.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*******************************************************
|
||||||
|
HIDAPI - Multi-Platform library for
|
||||||
|
communication with HID devices.
|
||||||
|
|
||||||
|
libusb/hidapi Team
|
||||||
|
|
||||||
|
Copyright 2022, All Rights Reserved.
|
||||||
|
|
||||||
|
At the discretion of the user of this library,
|
||||||
|
this software may be licensed under the terms of the
|
||||||
|
GNU General Public License v3, a BSD-Style license, or the
|
||||||
|
original HIDAPI license as outlined in the LICENSE.txt,
|
||||||
|
LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
|
||||||
|
files located at the root of the source distribution.
|
||||||
|
These files may also be found in the public source
|
||||||
|
code repository located at:
|
||||||
|
https://github.com/libusb/hidapi .
|
||||||
|
********************************************************/
|
||||||
|
|
||||||
|
#ifndef HIDAPI_HIDSDI_H
|
||||||
|
#define HIDAPI_HIDSDI_H
|
||||||
|
|
||||||
|
#ifdef HIDAPI_USE_DDK
|
||||||
|
|
||||||
|
#include <hidsdi.h>
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* This part of the header mimics hidsdi.h,
|
||||||
|
but only what is used by HIDAPI */
|
||||||
|
|
||||||
|
typedef USHORT USAGE;
|
||||||
|
|
||||||
|
#include "hidapi_hidpi.h"
|
||||||
|
|
||||||
|
typedef struct _HIDD_ATTRIBUTES{
|
||||||
|
ULONG Size;
|
||||||
|
USHORT VendorID;
|
||||||
|
USHORT ProductID;
|
||||||
|
USHORT VersionNumber;
|
||||||
|
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
|
||||||
|
|
||||||
|
typedef struct _HIDP_PREPARSED_DATA * PHIDP_PREPARSED_DATA;
|
||||||
|
|
||||||
|
typedef void (__stdcall *HidD_GetHidGuid_)(LPGUID hid_guid);
|
||||||
|
typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib);
|
||||||
|
typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len);
|
||||||
|
typedef BOOLEAN (__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
|
||||||
|
typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
|
||||||
|
typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length);
|
||||||
|
typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length);
|
||||||
|
typedef BOOLEAN (__stdcall *HidD_GetInputReport_)(HANDLE handle, PVOID data, ULONG length);
|
||||||
|
typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len);
|
||||||
|
typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data);
|
||||||
|
typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data);
|
||||||
|
typedef BOOLEAN (__stdcall *HidD_SetNumInputBuffers_)(HANDLE handle, ULONG number_buffers);
|
||||||
|
typedef BOOLEAN (__stdcall *HidD_SetOutputReport_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HIDAPI_HIDSDI_H */
|
Reference in New Issue
Block a user