@@ -56,22 +56,32 @@ size_t MultiSzWcsLen(PCWSTR MultiSzString)
5656 return len;
5757}
5858
59- BOOL DeviceIoControlInSync (HANDLE Handle, DWORD Ioctl, LPCVOID InBuffer, DWORD InBufferSize)
59+ BOOL DeviceIoControlInSync (HANDLE Handle, HANDLE OverlappedEvent, DWORD Ioctl, LPCVOID InBuffer, DWORD InBufferSize)
6060{
6161 OVERLAPPED overlapped = {};
62+ Wrappers::Event privateEvent;
6263 DWORD bytesRead;
6364 BOOL ret;
6465
65- Wrappers::Event overlappedEvent{ CreateEventW (NULL , FALSE , FALSE , NULL ) };
66- if (!overlappedEvent.IsValid ()) {
67- return FALSE ;
66+ //
67+ // Use the caller's event if provided, otherwise create one for this operation
68+ //
69+ if (OverlappedEvent) {
70+ ResetEvent (OverlappedEvent);
71+ overlapped.hEvent = OverlappedEvent;
6872 }
73+ else {
74+ privateEvent.Attach (CreateEventW (NULL , TRUE , FALSE , NULL ));
75+ if (!privateEvent.IsValid ()) {
76+ return FALSE ;
77+ }
6978
70- overlapped.hEvent = overlappedEvent.Get ();
79+ overlapped.hEvent = privateEvent.Get ();
80+ }
7181
7282 ret = DeviceIoControl (Handle, Ioctl, const_cast <LPVOID>(InBuffer), InBufferSize, NULL , 0 , &bytesRead, &overlapped);
7383 if (!ret && GetLastError () == ERROR_IO_PENDING) {
74- ret = GetOverlappedResult (Handle, &overlapped, &bytesRead, TRUE );
84+ ret = GetOverlappedResultEx (Handle, &overlapped, &bytesRead, INFINITE, FALSE );
7585 }
7686
7787 return ret;
@@ -115,6 +125,11 @@ WINUHID_API PWINUHID_DEVICE WinUHidCreateDevice(PCWINUHID_DEVICE_CONFIG Config)
115125 return NULL ;
116126 }
117127
128+ Wrappers::Event overlappedEvent{ CreateEventW (NULL , TRUE , FALSE , NULL ) };
129+ if (!overlappedEvent.IsValid ()) {
130+ return NULL ;
131+ }
132+
118133 device = (PWINUHID_DEVICE)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof (*device));
119134 if (!device) {
120135 SetLastError (ERROR_OUTOFMEMORY);
@@ -145,22 +160,22 @@ WINUHID_API PWINUHID_DEVICE WinUHidCreateDevice(PCWINUHID_DEVICE_CONFIG Config)
145160 devInfo.ProductID = Config->ProductID ;
146161 devInfo.VersionNumber = Config->VersionNumber ;
147162 devInfo.ContainerId = Config->ContainerId ;
148- if (!DeviceIoControlInSync (device->Handle , IOCTL_WINUHID_SET_DEVICE_INFO, &devInfo, sizeof (devInfo))) {
163+ if (!DeviceIoControlInSync (device->Handle , overlappedEvent. Get (), IOCTL_WINUHID_SET_DEVICE_INFO, &devInfo, sizeof (devInfo))) {
149164 goto Fail;
150165 }
151166
152167 //
153168 // Set the required report descriptor
154169 //
155- if (!DeviceIoControlInSync (device->Handle , IOCTL_WINUHID_SET_REPORT_DESCRIPTOR, Config->ReportDescriptor , Config->ReportDescriptorLength )) {
170+ if (!DeviceIoControlInSync (device->Handle , overlappedEvent. Get (), IOCTL_WINUHID_SET_REPORT_DESCRIPTOR, Config->ReportDescriptor , Config->ReportDescriptorLength )) {
156171 goto Fail;
157172 }
158173
159174 //
160175 // Set the instance ID if one was provided
161176 //
162177 if (Config->InstanceID != NULL ) {
163- if (!DeviceIoControlInSync (device->Handle , IOCTL_WINUHID_SET_INSTANCE_ID, (LPVOID)Config->InstanceID , (DWORD)(wcslen (Config->InstanceID ) + 1 ) * sizeof (WCHAR))) {
178+ if (!DeviceIoControlInSync (device->Handle , overlappedEvent. Get (), IOCTL_WINUHID_SET_INSTANCE_ID, (LPVOID)Config->InstanceID , (DWORD)(wcslen (Config->InstanceID ) + 1 ) * sizeof (WCHAR))) {
164179 goto Fail;
165180 }
166181 }
@@ -169,15 +184,15 @@ WINUHID_API PWINUHID_DEVICE WinUHidCreateDevice(PCWINUHID_DEVICE_CONFIG Config)
169184 // Set additional hardware IDs if provided
170185 //
171186 if (Config->HardwareIDs != NULL ) {
172- if (!DeviceIoControlInSync (device->Handle , IOCTL_WINUHID_SET_HARDWARE_IDS, (LPVOID)Config->HardwareIDs , (DWORD)(MultiSzWcsLen (Config->HardwareIDs ) + 1 ) * sizeof (WCHAR))) {
187+ if (!DeviceIoControlInSync (device->Handle , overlappedEvent. Get (), IOCTL_WINUHID_SET_HARDWARE_IDS, (LPVOID)Config->HardwareIDs , (DWORD)(MultiSzWcsLen (Config->HardwareIDs ) + 1 ) * sizeof (WCHAR))) {
173188 goto Fail;
174189 }
175190 }
176191
177192 //
178193 // Finally, create the device
179194 //
180- if (!DeviceIoControlInSync (device->Handle , IOCTL_WINUHID_CREATE_DEVICE, NULL , 0 )) {
195+ if (!DeviceIoControlInSync (device->Handle , overlappedEvent. Get (), IOCTL_WINUHID_CREATE_DEVICE, NULL , 0 )) {
181196 goto Fail;
182197 }
183198
@@ -199,7 +214,7 @@ WINUHID_API BOOL WinUHidSubmitInputReport(PWINUHID_DEVICE Device, LPCVOID Report
199214 return FALSE ;
200215 }
201216
202- Wrappers::Event overlappedEvent{ CreateEventW (NULL , FALSE , FALSE , NULL ) };
217+ Wrappers::Event overlappedEvent{ CreateEventW (NULL , TRUE , FALSE , NULL ) };
203218 if (!overlappedEvent.IsValid ()) {
204219 return FALSE ;
205220 }
@@ -208,7 +223,7 @@ WINUHID_API BOOL WinUHidSubmitInputReport(PWINUHID_DEVICE Device, LPCVOID Report
208223
209224 ret = WriteFile (Device->Handle , Report, ReportSize, &bytesWritten, &overlapped);
210225 if (!ret && GetLastError () == ERROR_IO_PENDING) {
211- ret = GetOverlappedResult (Device->Handle , &overlapped, &bytesWritten, TRUE );
226+ ret = GetOverlappedResultEx (Device->Handle , &overlapped, &bytesWritten, INFINITE, FALSE );
212227 }
213228
214229 return ret;
@@ -260,7 +275,7 @@ WINUHID_API BOOL WinUHidStartDevice(PWINUHID_DEVICE Device, PWINUHID_EVENT_CALLB
260275 }
261276 }
262277
263- if (!DeviceIoControlInSync (Device->Handle , IOCTL_WINUHID_START_DEVICE, NULL , 0 )) {
278+ if (!DeviceIoControlInSync (Device->Handle , NULL , IOCTL_WINUHID_START_DEVICE, NULL , 0 )) {
264279 //
265280 // Unwinding the event thread creation is relatively simple. We are not yet
266281 // in the Started state and we hold the device lock exclusively, so the
@@ -290,21 +305,18 @@ WINUHID_API BOOL WinUHidStartDevice(PWINUHID_DEVICE Device, PWINUHID_EVENT_CALLB
290305WINUHID_API PCWINUHID_EVENT WinUHidPollEvent (PWINUHID_DEVICE Device, DWORD TimeoutMillis)
291306{
292307 PWINUHID_EVENT event;
293- OVERLAPPED overlapped = {};
294308 DWORD bufferSize;
295309
296310 if (Device == NULL ) {
297311 SetLastError (ERROR_INVALID_PARAMETER);
298312 return NULL ;
299313 }
300314
301- Wrappers::Event overlappedEvent{ CreateEventW (NULL , FALSE , FALSE , NULL ) };
315+ Wrappers::Event overlappedEvent{ CreateEventW (NULL , TRUE , FALSE , NULL ) };
302316 if (!overlappedEvent.IsValid ()) {
303317 return NULL ;
304318 }
305319
306- overlapped.hEvent = overlappedEvent.Get ();
307-
308320 //
309321 // Acquire the device lock in shared mode to protect the state and event buffer size hints
310322 //
@@ -320,6 +332,7 @@ WINUHID_API PCWINUHID_EVENT WinUHidPollEvent(PWINUHID_DEVICE Device, DWORD Timeo
320332 BOOL ret;
321333 DWORD bytesWritten;
322334 PWINUHID_EVENT newEvent;
335+ OVERLAPPED overlapped;
323336
324337 //
325338 // If the device has been stopped, abort now
@@ -333,14 +346,18 @@ WINUHID_API PCWINUHID_EVENT WinUHidPollEvent(PWINUHID_DEVICE Device, DWORD Timeo
333346 //
334347 // Issue the asynchronous IOCTL
335348 //
349+ RtlZeroMemory (&overlapped, sizeof (overlapped));
350+ overlapped.hEvent = overlappedEvent.Get ();
351+ ResetEvent (overlapped.hEvent );
336352 ret = DeviceIoControl (Device->Handle , IOCTL_WINUHID_GET_NEXT_EVENT, NULL , 0 , event, bufferSize, &bytesWritten, &overlapped);
337353 ReleaseSRWLockShared (&Device->Lock );
338354
339355 if (!ret && GetLastError () == ERROR_IO_PENDING) {
340356 //
341357 // Wait for the IOCTL to complete or the timeout to expire
342358 //
343- if (WaitForSingleObject (overlapped.hEvent , TimeoutMillis) != WAIT_OBJECT_0) {
359+ ret = GetOverlappedResultEx (Device->Handle , &overlapped, &bytesWritten, TimeoutMillis, FALSE );
360+ if (!ret && GetLastError () == WAIT_TIMEOUT) {
344361 //
345362 // If the timeout expired, we need to cancel the pending I/O and wait for completion.
346363 //
@@ -354,19 +371,12 @@ WINUHID_API PCWINUHID_EVENT WinUHidPollEvent(PWINUHID_DEVICE Device, DWORD Timeo
354371 // processing the request as if it didn't time out.
355372 //
356373 CancelIoEx (Device->Handle , &overlapped);
357- WaitForSingleObject (overlapped.hEvent , INFINITE);
358- ret = GetOverlappedResult (Device->Handle , &overlapped, &bytesWritten, FALSE );
374+ ret = GetOverlappedResultEx (Device->Handle , &overlapped, &bytesWritten, INFINITE, FALSE );
359375 if (!ret) {
360376 SetLastError (ERROR_TIMEOUT);
361377 goto Fail;
362378 }
363379 }
364- else {
365- //
366- // Get the results of the asynchronous operation
367- //
368- ret = GetOverlappedResult (Device->Handle , &overlapped, &bytesWritten, FALSE );
369- }
370380 }
371381
372382 if (!ret && GetLastError () == ERROR_INSUFFICIENT_BUFFER) {
@@ -425,7 +435,7 @@ WINUHID_API PCWINUHID_EVENT WinUHidPollEvent(PWINUHID_DEVICE Device, DWORD Timeo
425435 readComplete.RequestId = event->RequestId ;
426436 readComplete.Status = STATUS_NO_MEMORY;
427437 readComplete.DataLength = 0 ;
428- DeviceIoControlInSync (Device->Handle , IOCTL_WINUHID_COMPLETE_READ_EVENT, &readComplete, sizeof (readComplete));
438+ DeviceIoControlInSync (Device->Handle , overlappedEvent. Get (), IOCTL_WINUHID_COMPLETE_READ_EVENT, &readComplete, sizeof (readComplete));
429439
430440 SetLastError (ERROR_OUTOFMEMORY);
431441 goto Fail;
@@ -450,7 +460,7 @@ WINUHID_API VOID WinUHidCompleteWriteEvent(PWINUHID_DEVICE Device, PCWINUHID_EVE
450460
451461 eventComplete.RequestId = Event->RequestId ;
452462 eventComplete.Status = Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
453- DeviceIoControlInSync (Device->Handle , IOCTL_WINUHID_COMPLETE_WRITE_EVENT, &eventComplete, sizeof (eventComplete));
463+ DeviceIoControlInSync (Device->Handle , NULL , IOCTL_WINUHID_COMPLETE_WRITE_EVENT, &eventComplete, sizeof (eventComplete));
454464
455465 HeapFree (GetProcessHeap (), 0 , const_cast <PWINUHID_EVENT>(Event));
456466}
@@ -487,7 +497,7 @@ WINUHID_API VOID WinUHidCompleteReadEvent(PWINUHID_DEVICE Device, PCWINUHID_EVEN
487497 eventComplete->DataLength = 0 ;
488498 }
489499
490- DeviceIoControlInSync (Device->Handle , IOCTL_WINUHID_COMPLETE_READ_EVENT, eventComplete, FIELD_OFFSET (WINUHID_READ_EVENT_COMPLETE, Data) + eventComplete->DataLength );
500+ DeviceIoControlInSync (Device->Handle , NULL , IOCTL_WINUHID_COMPLETE_READ_EVENT, eventComplete, FIELD_OFFSET (WINUHID_READ_EVENT_COMPLETE, Data) + eventComplete->DataLength );
491501
492502 HeapFree (GetProcessHeap (), 0 , const_cast <PWINUHID_EVENT>(Event));
493503}
0 commit comments