Skip to content

Commit 2cfd63a

Browse files
authored
windows: Add Windows-specific API to get device container ID (signal11#379)
1 parent e08ddce commit 2cfd63a

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

windows/hid.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,44 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int
10481048
return 0;
10491049
}
10501050

1051+
int HID_API_EXPORT_CALL hid_winapi_get_container_id(hid_device *dev, GUID *container_id)
1052+
{
1053+
wchar_t *interface_path = NULL, *device_id = NULL;
1054+
CONFIGRET cr = CR_FAILURE;
1055+
DEVINST dev_node;
1056+
DEVPROPTYPE property_type;
1057+
ULONG len;
1058+
1059+
if (!container_id)
1060+
return -1;
1061+
1062+
interface_path = hid_internal_UTF8toUTF16(dev->device_info->path);
1063+
if (!interface_path)
1064+
goto end;
1065+
1066+
/* Get the device id from interface path */
1067+
device_id = hid_internal_get_device_interface_property(interface_path, &DEVPKEY_Device_InstanceId, DEVPROP_TYPE_STRING);
1068+
if (!device_id)
1069+
goto end;
1070+
1071+
/* Open devnode from device id */
1072+
cr = CM_Locate_DevNodeW(&dev_node, (DEVINSTID_W)device_id, CM_LOCATE_DEVNODE_NORMAL);
1073+
if (cr != CR_SUCCESS)
1074+
goto end;
1075+
1076+
/* Get the container id from devnode */
1077+
len = sizeof(*container_id);
1078+
cr = CM_Get_DevNode_PropertyW(dev_node, &DEVPKEY_Device_ContainerId, &property_type, (PBYTE)container_id, &len, 0);
1079+
if (cr == CR_SUCCESS && property_type != DEVPROP_TYPE_GUID)
1080+
cr = CR_FAILURE;
1081+
1082+
end:
1083+
free(interface_path);
1084+
free(device_id);
1085+
1086+
return cr == CR_SUCCESS ? 0 : -1;
1087+
}
1088+
10511089

10521090
HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
10531091
{

windows/hidapi_cfgmgr32.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ typedef WCHAR* DEVNODEID_W, * DEVINSTID_W;
4040

4141
#define CR_SUCCESS (0x00000000)
4242
#define CR_BUFFER_SMALL (0x0000001A)
43+
#define CR_FAILURE (0x00000013)
4344

4445
#define CM_LOCATE_DEVNODE_NORMAL 0x00000000
4546

@@ -57,6 +58,7 @@ static DEVPROPKEY DEVPKEY_NAME = { { 0xb725f130, 0x47ef, 0x101a, 0xa5, 0xf1, 0x0
5758
static DEVPROPKEY DEVPKEY_Device_InstanceId = { { 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57 }, 256 }; // DEVPROP_TYPE_STRING
5859
static DEVPROPKEY DEVPKEY_Device_HardwareIds = { { 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0}, 3 }; // DEVPROP_TYPE_STRING_LIST
5960
static DEVPROPKEY DEVPKEY_Device_CompatibleIds = { { 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0}, 4 }; // DEVPROP_TYPE_STRING_LIST
61+
static DEVPROPKEY DEVPKEY_Device_ContainerId = { { 0x8c7ed206, 0x3f8a, 0x4827, 0xb3, 0xab, 0xae, 0x9e, 0x1f, 0xae, 0xfc, 0x6c}, 2 }; // DEVPROP_TYPE_GUID
6062

6163
// from propkey.h
6264
static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_DeviceAddress = { { 0x2bd67d8b, 0x8beb, 0x48d5, 0x87, 0xe0, 0x6c, 0xda, 0x34, 0x28, 0x04, 0x0a }, 1 }; // DEVPROP_TYPE_STRING

windows/hidapi_winapi.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*******************************************************
2+
HIDAPI - Multi-Platform library for
3+
communication with HID devices.
4+
5+
libusb/hidapi Team
6+
7+
Copyright 2022, All Rights Reserved.
8+
9+
At the discretion of the user of this library,
10+
this software may be licensed under the terms of the
11+
GNU General Public License v3, a BSD-Style license, or the
12+
original HIDAPI license as outlined in the LICENSE.txt,
13+
LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
14+
files located at the root of the source distribution.
15+
These files may also be found in the public source
16+
code repository located at:
17+
https://github.com/libusb/hidapi .
18+
********************************************************/
19+
20+
/** @file
21+
* @defgroup API hidapi API
22+
*/
23+
24+
#ifndef HIDAPI_WINAPI_H__
25+
#define HIDAPI_WINAPI_H__
26+
27+
#include <guiddef.h>
28+
29+
#include "hidapi.h"
30+
31+
#ifdef __cplusplus
32+
extern "C" {
33+
#endif
34+
35+
/** @brief Get the container ID for a HID device.
36+
37+
This function returns the `DEVPKEY_Device_ContainerId` property of
38+
the given device. This can be used to correlate different
39+
interfaces/ports on the same hardware device.
40+
41+
@ingroup API
42+
@param dev A device handle returned from hid_open().
43+
@param guid The device's container ID on return.
44+
45+
@returns
46+
This function returns 0 on success and -1 on error.
47+
*/
48+
int HID_API_EXPORT_CALL hid_winapi_get_container_id(hid_device *dev, GUID *container_id);
49+
50+
#ifdef __cplusplus
51+
}
52+
#endif
53+
54+
#endif

0 commit comments

Comments
 (0)