예제 #1
0
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;
}
예제 #2
0
파일: IOWin.cpp 프로젝트: Ahriman/dolphin
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;
}