Skip to content

Commit 3f46000

Browse files
committed
Manufacturer, product and serial number information to WinUSB and HID devices
1 parent 31ab4b1 commit 3f46000

4 files changed

Lines changed: 255 additions & 80 deletions

File tree

TabletDriverService/HIDDevice.cpp

Lines changed: 134 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,86 @@
44
#define LOG_MODULE "HIDDevice"
55
#include "Logger.h"
66

7-
HIDDevice::HIDDevice(USHORT VendorId, USHORT ProductId, USHORT UsagePage, USHORT Usage) : HIDDevice() {
7+
HIDDevice::HIDDevice(USHORT VendorId, USHORT ProductId, USHORT UsagePage, USHORT Usage, bool IsExclusive) {
88
this->vendorId = VendorId;
99
this->productId = ProductId;
1010
this->usagePage = UsagePage;
1111
this->usage = Usage;
12-
if(this->OpenDevice(&this->_deviceHandle, this->vendorId, this->productId, this->usagePage, this->usage)) {
12+
this->isExclusive = IsExclusive;
13+
if(this->OpenDevice(&this->_deviceHandle, this->vendorId, this->productId, this->usagePage, this->usage, this->isExclusive)) {
1314
isOpen = true;
1415
}
1516
isReading = false;
1617
}
1718

19+
HIDDevice::HIDDevice(USHORT VendorId, USHORT ProductId, USHORT UsagePage, USHORT Usage) : HIDDevice(VendorId, ProductId, UsagePage, Usage, false) {
20+
}
21+
1822
HIDDevice::HIDDevice() {
1923
isOpen = false;
2024
isReading = false;
25+
_manufacturerName = "";
26+
_productName = "";
27+
_serialNumber = "";
2128
_deviceHandle = NULL;
2229
}
2330

2431
HIDDevice::~HIDDevice() {
2532
CloseDevice();
2633
}
2734

28-
bool HIDDevice::OpenDevice(HANDLE *handle, USHORT vendorId, USHORT productId, USHORT usagePage, USHORT usage) {
35+
36+
bool GetHIDStrings(HANDLE deviceHandle, string *manufacturerName, string *productName, string *serialNumber) {
37+
BYTE buffer[1024];
38+
int i;
39+
40+
// HID manufacturer string
41+
if(HidD_GetManufacturerString(deviceHandle, &buffer, sizeof(buffer))) {
42+
for(i = 0; i < (int)sizeof(buffer); i += 2) {
43+
if(buffer[i]) manufacturerName->push_back(buffer[i]);
44+
else break;
45+
}
46+
}
47+
48+
// HID product string
49+
if(HidD_GetProductString(deviceHandle, &buffer, sizeof(buffer))) {
50+
for(i = 0; i < (int)sizeof(buffer); i += 2) {
51+
if(buffer[i]) productName->push_back(buffer[i]);
52+
else break;
53+
}
54+
}
55+
56+
// HID serial number
57+
if(HidD_GetSerialNumberString(deviceHandle, &buffer, sizeof(buffer))) {
58+
for(i = 0; i < (int)sizeof(buffer); i += 2) {
59+
if(buffer[i]) serialNumber->push_back(buffer[i]);
60+
else break;
61+
}
62+
}
63+
64+
return true;
65+
}
66+
67+
68+
//
69+
// Open device
70+
//
71+
bool HIDDevice::OpenDevice(HANDLE *handle, USHORT vendorId, USHORT productId, USHORT usagePage, USHORT usage, bool exclusive) {
2972
HDEVINFO deviceInfo;
3073
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
3174
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData;
3275
SP_DEVINFO_DATA deviceInfoData;
3376
DWORD dwSize, dwMemberIdx;
3477
GUID hidGuid;
35-
BYTE stringBytes[1024];
3678

3779
PHIDP_PREPARSED_DATA hidPreparsedData;
3880
HIDD_ATTRIBUTES hidAttributes;
3981
HIDP_CAPS hidCapabilities;
82+
string manufacturerName;
83+
string productName;
84+
string serialNumber;
4085

4186
HANDLE deviceHandle;
42-
4387
HANDLE resultHandle = 0;
4488

4589
HidD_GetHidGuid(&hidGuid);
@@ -68,15 +112,29 @@ bool HIDDevice::OpenDevice(HANDLE *handle, USHORT vendorId, USHORT productId, US
68112
// Get interface detail
69113
if(SetupDiGetDeviceInterfaceDetail(deviceInfo, &deviceInterfaceData, deviceInterfaceDetailData, dwSize, &dwSize, &deviceInfoData)) {
70114

71-
// Open HID
72-
deviceHandle = CreateFile(
73-
deviceInterfaceDetailData->DevicePath,
74-
GENERIC_READ | GENERIC_WRITE,
75-
FILE_SHARE_READ | FILE_SHARE_WRITE,
76-
NULL,
77-
OPEN_EXISTING,
78-
0,
79-
NULL);
115+
// Open HID in exclusive mode
116+
if(exclusive) {
117+
deviceHandle = CreateFile(
118+
deviceInterfaceDetailData->DevicePath,
119+
GENERIC_READ | GENERIC_WRITE,
120+
0, // No sharing
121+
NULL,
122+
OPEN_EXISTING,
123+
0,
124+
NULL);
125+
}
126+
127+
// Open HID in sharing mode
128+
else {
129+
deviceHandle = CreateFile(
130+
deviceInterfaceDetailData->DevicePath,
131+
GENERIC_READ | GENERIC_WRITE,
132+
FILE_SHARE_READ | FILE_SHARE_WRITE,
133+
NULL,
134+
OPEN_EXISTING,
135+
0,
136+
NULL);
137+
}
80138

81139
// HID handle valid?
82140
if(deviceHandle != INVALID_HANDLE_VALUE) {
@@ -93,34 +151,17 @@ bool HIDDevice::OpenDevice(HANDLE *handle, USHORT vendorId, USHORT productId, US
93151
// Debug logging
94152
if(this->debugEnabled) {
95153

96-
string manufacturerName = "";
97-
string productName = "";
98-
99-
// HID manufacturer string
100-
if(HidD_GetManufacturerString(deviceHandle, &stringBytes, sizeof(stringBytes))) {
101-
for(int i = 0; i < (int)sizeof(stringBytes); i += 2) {
102-
if(stringBytes[i]) {
103-
manufacturerName.push_back(stringBytes[i]);
104-
}
105-
else {
106-
break;
107-
}
108-
}
109-
}
110-
111-
// HID product string
112-
if(HidD_GetProductString(deviceHandle, &stringBytes, sizeof(stringBytes))) {
113-
for(int i = 0; i < (int)sizeof(stringBytes); i += 2) {
114-
if(stringBytes[i]) {
115-
productName.push_back(stringBytes[i]);
116-
}
117-
else {
118-
break;
119-
}
120-
}
121-
}
122-
123-
LOG_DEBUG("HID Device: Vendor: '%s' Product: '%s'\n", manufacturerName.c_str(), productName.c_str());
154+
manufacturerName = "";
155+
productName = "";
156+
serialNumber = "";
157+
158+
GetHIDStrings(deviceHandle, &manufacturerName, &productName, &serialNumber);
159+
160+
LOG_DEBUG("HID Device: Vendor: '%s' Product: '%s', Serial: '%s'\n",
161+
manufacturerName.c_str(),
162+
productName.c_str(),
163+
serialNumber.c_str()
164+
);
124165
LOG_DEBUG(" Vendor Id: 0x%04X, Product Id: 0x%04X\n",
125166
hidAttributes.VendorID,
126167
hidAttributes.ProductID
@@ -144,6 +185,8 @@ bool HIDDevice::OpenDevice(HANDLE *handle, USHORT vendorId, USHORT productId, US
144185
hidCapabilities.UsagePage == usagePage &&
145186
hidCapabilities.Usage == usage
146187
) {
188+
GetHIDStrings(deviceHandle, &_manufacturerName, &_productName, &_serialNumber);
189+
147190
resultHandle = deviceHandle;
148191
}
149192

@@ -176,6 +219,14 @@ bool HIDDevice::OpenDevice(HANDLE *handle, USHORT vendorId, USHORT productId, US
176219
return false;
177220
}
178221

222+
//
223+
// Open device
224+
//
225+
bool HIDDevice::OpenDevice(HANDLE * handle, USHORT vendorId, USHORT productId, USHORT usagePage, USHORT usage)
226+
{
227+
return OpenDevice(handle, vendorId, productId, usagePage, usage, false);
228+
}
229+
179230
// Read HID report
180231
int HIDDevice::Read(void *buffer, int length) {
181232
//return HidD_GetInputReport(_deviceHandle, buffer, length);
@@ -222,6 +273,47 @@ int HIDDevice::StringRequest(UCHAR stringId, UCHAR * buffer, int length)
222273
return 0;
223274
}
224275

276+
string HIDDevice::GetString(UCHAR stringId)
277+
{
278+
string resultString = "";
279+
UCHAR buffer[256];
280+
int bytesRead = 0;
281+
282+
if(isReading) {
283+
throw runtime_error("HID string request can't be sent when the device is in use!");
284+
}
285+
else {
286+
bytesRead = StringRequest(stringId, buffer, 256);
287+
}
288+
289+
// Reply received?
290+
if(bytesRead > 0) {
291+
for(int i = 0; i < bytesRead; i += 2) {
292+
resultString.push_back(buffer[i]);
293+
}
294+
}
295+
296+
return resultString;
297+
}
298+
299+
// Get HID manufacturer name
300+
string HIDDevice::GetManufacturerName()
301+
{
302+
return _manufacturerName;
303+
}
304+
305+
// Get HID product name
306+
string HIDDevice::GetProductName()
307+
{
308+
return _productName;
309+
}
310+
311+
// Get HID serial number
312+
string HIDDevice::GetSerialNumber()
313+
{
314+
return _serialNumber;
315+
}
316+
225317
// Close the device
226318
void HIDDevice::CloseDevice() {
227319
if(isOpen && _deviceHandle != NULL && _deviceHandle != INVALID_HANDLE_VALUE) {

TabletDriverService/HIDDevice.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ using namespace std;
1616
class HIDDevice {
1717
private:
1818
HANDLE _deviceHandle;
19+
string _manufacturerName;
20+
string _productName;
21+
string _serialNumber;
1922
public:
2023
bool isOpen;
2124
bool debugEnabled;
@@ -24,15 +27,23 @@ class HIDDevice {
2427
USHORT productId;
2528
USHORT usagePage;
2629
USHORT usage;
30+
bool isExclusive;
2731

32+
33+
HIDDevice(USHORT VendorId, USHORT ProductId, USHORT UsagePage, USHORT Usage, bool IsExclusive);
2834
HIDDevice(USHORT VendorId, USHORT ProductId, USHORT UsagePage, USHORT Usage);
2935
HIDDevice();
3036
~HIDDevice();
37+
bool OpenDevice(HANDLE *handle, USHORT vendorId, USHORT productId, USHORT usagePage, USHORT usage, bool exclusive);
3138
bool OpenDevice(HANDLE *handle, USHORT vendorId, USHORT productId, USHORT usagePage, USHORT usage);
3239
int Read(void *buffer, int length);
3340
int Write(void *buffer, int length);
3441
bool SetFeature(void *buffer, int length);
3542
bool GetFeature(void *buffer, int length);
3643
int StringRequest(UCHAR stringId, UCHAR *buffer, int length);
44+
string GetString(UCHAR stringId);
45+
string GetManufacturerName();
46+
string GetProductName();
47+
string GetSerialNumber();
3748
void CloseDevice();
3849
};

0 commit comments

Comments
 (0)