From 2cfd63ac412500a6e2f79636ef9865ed191e42b8 Mon Sep 17 00:00:00 2001 From: Frederik Seiffert Date: Fri, 25 Feb 2022 09:53:00 +0100 Subject: [PATCH] windows: Add Windows-specific API to get device container ID (#379) --- windows/hid.c | 38 +++++++++++++++++++++++++++ windows/hidapi_cfgmgr32.h | 2 ++ windows/hidapi_winapi.h | 54 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 windows/hidapi_winapi.h diff --git a/windows/hid.c b/windows/hid.c index fb227a614..efa61969c 100644 --- a/windows/hid.c +++ b/windows/hid.c @@ -1048,6 +1048,44 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int return 0; } +int HID_API_EXPORT_CALL hid_winapi_get_container_id(hid_device *dev, GUID *container_id) +{ + wchar_t *interface_path = NULL, *device_id = NULL; + CONFIGRET cr = CR_FAILURE; + DEVINST dev_node; + DEVPROPTYPE property_type; + ULONG len; + + if (!container_id) + return -1; + + interface_path = hid_internal_UTF8toUTF16(dev->device_info->path); + if (!interface_path) + goto end; + + /* 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 container id from devnode */ + len = sizeof(*container_id); + cr = CM_Get_DevNode_PropertyW(dev_node, &DEVPKEY_Device_ContainerId, &property_type, (PBYTE)container_id, &len, 0); + if (cr == CR_SUCCESS && property_type != DEVPROP_TYPE_GUID) + cr = CR_FAILURE; + +end: + free(interface_path); + free(device_id); + + return cr == CR_SUCCESS ? 0 : -1; +} + HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) { diff --git a/windows/hidapi_cfgmgr32.h b/windows/hidapi_cfgmgr32.h index 90a902471..b9e705b03 100644 --- a/windows/hidapi_cfgmgr32.h +++ b/windows/hidapi_cfgmgr32.h @@ -40,6 +40,7 @@ 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 @@ -57,6 +58,7 @@ static DEVPROPKEY DEVPKEY_NAME = { { 0xb725f130, 0x47ef, 0x101a, 0xa5, 0xf1, 0x0 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 diff --git a/windows/hidapi_winapi.h b/windows/hidapi_winapi.h new file mode 100644 index 000000000..43156a6b9 --- /dev/null +++ b/windows/hidapi_winapi.h @@ -0,0 +1,54 @@ +/******************************************************* + 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 . +********************************************************/ + +/** @file + * @defgroup API hidapi API + */ + +#ifndef HIDAPI_WINAPI_H__ +#define HIDAPI_WINAPI_H__ + +#include + +#include "hidapi.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /** @brief Get the container ID for a HID device. + + This function returns the `DEVPKEY_Device_ContainerId` property of + the given device. This can be used to correlate different + interfaces/ports on the same hardware device. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param guid The device's container ID on return. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_winapi_get_container_id(hid_device *dev, GUID *container_id); + +#ifdef __cplusplus +} +#endif + +#endif