diff --git a/hidtest/test.c b/hidtest/test.c index 4ac09a16..cb4a2ce0 100644 --- a/hidtest/test.c +++ b/hidtest/test.c @@ -198,6 +198,10 @@ int main(int argc, char* argv[]) return 1; } +#if defined(_WIN32) && HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0) + hid_winapi_set_write_timeout(handle, 5000); +#endif + // Read the Manufacturer String wstr[0] = 0x0000; res = hid_get_manufacturer_string(handle, wstr, MAX_STR); diff --git a/windows/hid.c b/windows/hid.c index bc676223..799c0e88 100644 --- a/windows/hid.c +++ b/windows/hid.c @@ -194,6 +194,7 @@ struct hid_device_ { OVERLAPPED ol; OVERLAPPED write_ol; struct hid_device_info* device_info; + DWORD write_timeout_ms; }; static hid_device *new_hid_device() @@ -219,6 +220,7 @@ static hid_device *new_hid_device() memset(&dev->write_ol, 0, sizeof(dev->write_ol)); dev->write_ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL); dev->device_info = NULL; + dev->write_timeout_ms = 1000; return dev; } @@ -1052,6 +1054,11 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path) return dev; } +void HID_API_EXPORT_CALL hid_winapi_set_write_timeout(hid_device *dev, unsigned long timeout) +{ + dev->write_timeout_ms = timeout; +} + int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length) { DWORD bytes_written = 0; @@ -1103,7 +1110,7 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char * if (overlapped) { /* Wait for the transaction to complete. This makes hid_write() synchronous. */ - res = WaitForSingleObject(dev->write_ol.hEvent, 1000); + res = WaitForSingleObject(dev->write_ol.hEvent, dev->write_timeout_ms); if (res != WAIT_OBJECT_0) { /* There was a Timeout. */ register_winapi_error(dev, L"hid_write/WaitForSingleObject"); diff --git a/windows/hidapi_winapi.h b/windows/hidapi_winapi.h index a9919923..e5a12428 100644 --- a/windows/hidapi_winapi.h +++ b/windows/hidapi_winapi.h @@ -67,6 +67,26 @@ extern "C" { */ int HID_API_EXPORT_CALL hid_winapi_descriptor_reconstruct_pp_data(void *hidp_preparsed_data, unsigned char *buf, size_t buf_size); + /** + * @brief Sets the timeout for hid_write operation. + * + * Since version 0.15.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0) + * + * The default timeout is 1sec for winapi backend. + * + * In case if 1sec is not enough, on in case of multi-platform development, + * the recommended value is 5sec, e.g. to match (unconfigurable) 5sec timeout + * set for hidraw (linux kernel) implementation. + * + * When the timeout is set to 0, hid_write function becomes non-blocking and would exit immediately. + * When the timeout is set to INFINITE ((DWORD)-1), the function will not exit, + * until the write operation is performed or an error occured. + * See dwMilliseconds parameter documentation of WaitForSingleObject function. + * + * @param timeout New timeout value in milliseconds. + */ + void HID_API_EXPORT_CALL hid_winapi_set_write_timeout(hid_device *dev, unsigned long timeout); + #ifdef __cplusplus } #endif