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+
1822HIDDevice::HIDDevice () {
1923 isOpen = false ;
2024 isReading = false ;
25+ _manufacturerName = " " ;
26+ _productName = " " ;
27+ _serialNumber = " " ;
2128 _deviceHandle = NULL ;
2229}
2330
2431HIDDevice::~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
180231int 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
226318void HIDDevice::CloseDevice () {
227319 if (isOpen && _deviceHandle != NULL && _deviceHandle != INVALID_HANDLE_VALUE ) {
0 commit comments