static int IOWritePerSetOutputReport(HANDLE& dev_handle, const u8* buf, size_t len, DWORD* written) { BOOLEAN result = pHidD_SetOutputReport(dev_handle, const_cast<u8*>(buf) + 1, (ULONG)(len - 1)); if (!result) { DWORD err = GetLastError(); if (err == 121) { // Semaphore timeout NOTICE_LOG(WIIMOTE, "IOWrite[WWM_SET_OUTPUT_REPORT]: Unable to send data to the Wiimote"); } else if (err != 0x1F) // Some third-party adapters (DolphinBar) use this // error code to signal the absence of a Wiimote // linked to the HID device. { WARN_LOG(WIIMOTE, "IOWrite[WWM_SET_OUTPUT_REPORT]: Error: %08x", err); } } if (written) { *written = (result ? (DWORD)len : 0); } return result; }
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len, DWORD* written) { switch (stack) { case MSBT_STACK_UNKNOWN: { // Try to auto-detect the stack type stack = MSBT_STACK_BLUESOLEIL; if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len, written)) return 1; stack = MSBT_STACK_MS; if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len, written)) return 1; stack = MSBT_STACK_UNKNOWN; break; } case MSBT_STACK_MS: { auto result = pHidD_SetOutputReport(dev_handle, const_cast<u8*>(buf) + 1, (ULONG)(len - 1)); //FlushFileBuffers(dev_handle); if (!result) { auto err = GetLastError(); if (err == 121) { // Semaphore timeout NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to the Wiimote"); } else if (err != 0x1F) // Some third-party adapters (DolphinBar) use this // error code to signal the absence of a Wiimote // linked to the HID device. { WARN_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err); } } if (written) *written = (result ? (DWORD)len : 0); return result; } case MSBT_STACK_BLUESOLEIL: { u8 big_buf[MAX_PAYLOAD]; if (len < MAX_PAYLOAD) { std::copy(buf, buf + len, big_buf); std::fill(big_buf + len, big_buf + MAX_PAYLOAD, 0); buf = big_buf; } ResetEvent(hid_overlap_write.hEvent); DWORD bytes = 0; if (WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_write)) { // If the number of written bytes is requested, block until we can provide // this information to the called. if (written) { auto const wait_result = WaitForSingleObject(hid_overlap_write.hEvent, WIIMOTE_DEFAULT_TIMEOUT); if (WAIT_TIMEOUT == wait_result) { WARN_LOG(WIIMOTE, "_IOWrite: A timeout occurred on writing to Wiimote."); CancelIo(dev_handle); *written = 0; } else if (WAIT_FAILED == wait_result) { WARN_LOG(WIIMOTE, "_IOWrite: A wait error occurred on writing to Wiimote."); CancelIo(dev_handle); *written = 0; } else if (!GetOverlappedResult(dev_handle, &hid_overlap_write, written, TRUE)) *written = 0; } return 1; } else { auto const err = GetLastError(); if (ERROR_IO_PENDING == err) { CancelIo(dev_handle); } return 0; } } } return 0; }