| 1004 | } |
| 1005 | |
| 1006 | int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length) |
| 1007 | { |
| 1008 | DWORD bytes_written = 0; |
| 1009 | int function_result = -1; |
| 1010 | BOOL res; |
| 1011 | BOOL overlapped = FALSE; |
| 1012 | |
| 1013 | unsigned char *buf; |
| 1014 | |
| 1015 | if (!data || !length) { |
| 1016 | register_string_error(dev, L"Zero buffer/length"); |
| 1017 | return function_result; |
| 1018 | } |
| 1019 | |
| 1020 | register_string_error(dev, NULL); |
| 1021 | |
| 1022 | /* Make sure the right number of bytes are passed to WriteFile. Windows |
| 1023 | expects the number of bytes which are in the _longest_ report (plus |
| 1024 | one for the report number) bytes even if the data is a report |
| 1025 | which is shorter than that. Windows gives us this value in |
| 1026 | caps.OutputReportByteLength. If a user passes in fewer bytes than this, |
| 1027 | use cached temporary buffer which is the proper size. */ |
| 1028 | if (length >= dev->output_report_length) { |
| 1029 | /* The user passed the right number of bytes. Use the buffer as-is. */ |
| 1030 | buf = (unsigned char *) data; |
| 1031 | } else { |
| 1032 | if (dev->write_buf == NULL) |
| 1033 | dev->write_buf = (unsigned char *) malloc(dev->output_report_length); |
| 1034 | buf = dev->write_buf; |
| 1035 | memcpy(buf, data, length); |
| 1036 | memset(buf + length, 0, dev->output_report_length - length); |
| 1037 | length = dev->output_report_length; |
| 1038 | } |
| 1039 | |
| 1040 | res = WriteFile(dev->device_handle, buf, (DWORD) length, NULL, &dev->write_ol); |
| 1041 | |
| 1042 | if (!res) { |
| 1043 | if (GetLastError() != ERROR_IO_PENDING) { |
| 1044 | /* WriteFile() failed. Return error. */ |
| 1045 | register_winapi_error(dev, L"WriteFile"); |
| 1046 | goto end_of_function; |
| 1047 | } |
| 1048 | overlapped = TRUE; |
| 1049 | } |
| 1050 | |
| 1051 | if (overlapped) { |
| 1052 | /* Wait for the transaction to complete. This makes |
| 1053 | hid_write() synchronous. */ |
| 1054 | res = WaitForSingleObject(dev->write_ol.hEvent, 1000); |
| 1055 | if (res != WAIT_OBJECT_0) { |
| 1056 | /* There was a Timeout. */ |
| 1057 | register_winapi_error(dev, L"hid_write/WaitForSingleObject"); |
| 1058 | goto end_of_function; |
| 1059 | } |
| 1060 | |
| 1061 | /* Get the result. */ |
| 1062 | res = GetOverlappedResult(dev->device_handle, &dev->write_ol, &bytes_written, FALSE/*wait*/); |
| 1063 | if (res) { |
nothing calls this directly
no test coverage detected