| 643 | |
| 644 | |
| 645 | int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) |
| 646 | { |
| 647 | DWORD bytes_read = 0; |
| 648 | BOOL res; |
| 649 | |
| 650 | /* Copy the handle for convenience. */ |
| 651 | HANDLE ev = dev->ol.hEvent; |
| 652 | |
| 653 | if (!dev->read_pending) { |
| 654 | /* Start an Overlapped I/O read. */ |
| 655 | dev->read_pending = TRUE; |
| 656 | memset(dev->read_buf, 0, dev->input_report_length); |
| 657 | ResetEvent(ev); |
| 658 | res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->ol); |
| 659 | |
| 660 | if (!res) { |
| 661 | if (GetLastError() != ERROR_IO_PENDING) { |
| 662 | /* ReadFile() has failed. |
| 663 | Clean up and return error. */ |
| 664 | CancelIo(dev->device_handle); |
| 665 | dev->read_pending = FALSE; |
| 666 | goto end_of_function; |
| 667 | } |
| 668 | } |
| 669 | } |
| 670 | |
| 671 | if (milliseconds >= 0) { |
| 672 | /* See if there is any data yet. */ |
| 673 | res = WaitForSingleObject(ev, milliseconds); |
| 674 | if (res != WAIT_OBJECT_0) { |
| 675 | /* There was no data this time. Return zero bytes available, |
| 676 | but leave the Overlapped I/O running. */ |
| 677 | return 0; |
| 678 | } |
| 679 | } |
| 680 | |
| 681 | /* Either WaitForSingleObject() told us that ReadFile has completed, or |
| 682 | we are in non-blocking mode. Get the number of bytes read. The actual |
| 683 | data has been copied to the data[] array which was passed to ReadFile(). */ |
| 684 | res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/); |
| 685 | |
| 686 | /* Set pending back to false, even if GetOverlappedResult() returned error. */ |
| 687 | dev->read_pending = FALSE; |
| 688 | |
| 689 | if (res && bytes_read > 0) { |
| 690 | if (dev->read_buf[0] == 0x0) { |
| 691 | /* If report numbers aren't being used, but Windows sticks a report |
| 692 | number (0x0) on the beginning of the report anyway. To make this |
| 693 | work like the other platforms, and to make it work more like the |
| 694 | HID spec, we'll skip over this byte. */ |
| 695 | size_t copy_len; |
| 696 | bytes_read--; |
| 697 | copy_len = length > bytes_read ? bytes_read : length; |
| 698 | memcpy(data, dev->read_buf+1, copy_len); |
| 699 | } |
| 700 | else { |
| 701 | /* Copy the whole buffer, report number and all. */ |
| 702 | size_t copy_len = length > bytes_read ? bytes_read : length; |
no test coverage detected