+static void close_device(void) {
+ CancelIo(device_handle);
+
+ /* According to MSDN, CancelIo() does not necessarily wait for the operation to complete.
+ To prevent race conditions, make sure the operation is complete
+ before we close the event it's referencing. */
+
+ DWORD len;
+
+ if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s read to cancel: %s", device_info, device, winerror(GetLastError()));
+ }
+
+ if(device_write_packet.len > 0 && !GetOverlappedResult(device_handle, &device_write_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s write to cancel: %s", device_info, device, winerror(GetLastError()));
+ }
+
+ device_write_packet.len = 0;
+
+ CloseHandle(device_read_overlapped.hEvent);
+ CloseHandle(device_write_overlapped.hEvent);