| 688 | } |
| 689 | |
| 690 | static int hid_write_timeout(hid_device *dev, const unsigned char *data, size_t length, int milliseconds) |
| 691 | { |
| 692 | DWORD bytes_written; |
| 693 | BOOL res; |
| 694 | size_t stashed_length = length; |
| 695 | unsigned char *buf; |
| 696 | |
| 697 | /* Make sure the right number of bytes are passed to WriteFile. Windows |
| 698 | expects the number of bytes which are in the _longest_ report (plus |
| 699 | one for the report number) bytes even if the data is a report |
| 700 | which is shorter than that. Windows gives us this value in |
| 701 | caps.OutputReportByteLength. If a user passes in fewer bytes than this, |
| 702 | create a temporary buffer which is the proper size. */ |
| 703 | if (length >= dev->output_report_length) { |
| 704 | /* The user passed the right number of bytes. Use the buffer as-is. */ |
| 705 | buf = (unsigned char *) data; |
| 706 | } else { |
| 707 | /* Create a temporary buffer and copy the user's data |
| 708 | into it, padding the rest with zeros. */ |
| 709 | buf = (unsigned char *) malloc(dev->output_report_length); |
| 710 | memcpy(buf, data, length); |
| 711 | memset(buf + length, 0, dev->output_report_length - length); |
| 712 | length = dev->output_report_length; |
| 713 | } |
| 714 | if (length > 512) |
| 715 | { |
| 716 | return hid_write_output_report( dev, data, stashed_length ); |
| 717 | } |
| 718 | else |
| 719 | { |
| 720 | res = WriteFile( dev->device_handle, buf, ( DWORD ) length, NULL, &dev->write_ol ); |
| 721 | if (!res) { |
| 722 | if (GetLastError() != ERROR_IO_PENDING) { |
| 723 | /* WriteFile() failed. Return error. */ |
| 724 | register_error(dev, "WriteFile"); |
| 725 | bytes_written = (DWORD) -1; |
| 726 | goto end_of_function; |
| 727 | } |
| 728 | } |
| 729 | |
| 730 | /* Wait here until the write is done. This makes |
| 731 | hid_write() synchronous. */ |
| 732 | res = WaitForSingleObject(dev->write_ol.hEvent, milliseconds); |
| 733 | if (res != WAIT_OBJECT_0) |
| 734 | { |
| 735 | // There was a Timeout. |
| 736 | bytes_written = (DWORD) -1; |
| 737 | register_error(dev, "WriteFile/WaitForSingleObject Timeout"); |
| 738 | goto end_of_function; |
| 739 | } |
| 740 | |
| 741 | res = GetOverlappedResult(dev->device_handle, &dev->write_ol, &bytes_written, FALSE/*F=don't_wait*/); |
| 742 | if (!res) { |
| 743 | /* The Write operation failed. */ |
| 744 | register_error(dev, "WriteFile"); |
| 745 | bytes_written = (DWORD) -1; |
| 746 | goto end_of_function; |
| 747 | } |
no test coverage detected