diff --git a/windows/hid.c b/windows/hid.c index 17a1a2d..b0cbc76 100755 --- a/windows/hid.c +++ b/windows/hid.c @@ -132,6 +132,7 @@ struct hid_device_ { BOOL read_pending; char *read_buf; OVERLAPPED ol; + OVERLAPPED write_ol; }; static hid_device *new_hid_device() @@ -147,6 +148,8 @@ static hid_device *new_hid_device() dev->read_buf = NULL; memset(&dev->ol, 0, sizeof(dev->ol)); dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*inital state f=nonsignaled*/, NULL); + memset(&dev->write_ol, 0, sizeof(dev->write_ol)); + dev->write_ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*inital state f=nonsignaled*/, NULL); return dev; } @@ -590,10 +593,9 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char * { DWORD bytes_written; BOOL res; + BOOL overlapped = FALSE; - OVERLAPPED ol; unsigned char *buf; - memset(&ol, 0, sizeof(ol)); /* Make sure the right number of bytes are passed to WriteFile. Windows expects the number of bytes which are in the _longest_ report (plus @@ -613,7 +615,7 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char * length = dev->output_report_length; } - res = WriteFile(dev->device_handle, buf, length, NULL, &ol); + res = WriteFile(dev->device_handle, buf, length, NULL, &dev->write_ol); if (!res) { if (GetLastError() != ERROR_IO_PENDING) { @@ -622,16 +624,28 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char * bytes_written = -1; goto end_of_function; } + overlapped = TRUE; } - /* Wait here until the write is done. This makes - hid_write() synchronous. */ - res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE/*wait*/); - if (!res) { - /* The Write operation failed. */ - register_error(dev, "WriteFile"); - bytes_written = -1; - goto end_of_function; + if (overlapped) { + /* Wait for the transaction to complete */ + res = WaitForSingleObject(dev->write_ol.hEvent, 1000); + if (res != WAIT_OBJECT_0) { + // There was a Timeout. + bytes_written = -1; + register_error(dev, "WriteFile/WaitForSingleObject Timeout"); + goto end_of_function; + } + + /* Wait here until the write is done. This makes + hid_write() synchronous. */ + res = GetOverlappedResult(dev->device_handle, &dev->write_ol, &bytes_written, FALSE/*F=don't_wait*/); + if (!res) { + /* The Write operation failed. */ + register_error(dev, "WriteFile"); + bytes_written = -1; + goto end_of_function; + } } end_of_function: @@ -783,6 +797,7 @@ void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev) if (!dev) return; CancelIo(dev->device_handle); + CloseHandle(dev->write_ol.hEvent); CloseHandle(dev->ol.hEvent); CloseHandle(dev->device_handle); LocalFree(dev->last_error_str);