Esempio n. 1
0
int CheckDeviceType_Write(HANDLE &dev_handle, const u8* buf, size_t size, int attempts)
{
	OVERLAPPED hid_overlap_write = OVERLAPPED();
	hid_overlap_write.hEvent = CreateEvent(nullptr, true, false, nullptr);
	enum win_bt_stack_t stack = MSBT_STACK_UNKNOWN;

	DWORD written = 0;

	for (; attempts>0; --attempts)
	{
		if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, size, &written))
			break;
	}

	CloseHandle(hid_overlap_write.hEvent);

	return written;
}
Esempio n. 2
0
int WiimoteWindows::IOWrite(const u8* buf, size_t len)
{
	return _IOWrite(m_dev_handle, m_hid_overlap_write, m_stack, buf, len, nullptr);
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
int Wiimote::IOWrite(const u8* buf, size_t len)
{
	return _IOWrite(dev_handle, hid_overlap_write, stack, buf, len, nullptr);
}