From ff611584662e9955047294a0b7d2b9fe1f8a4354 Mon Sep 17 00:00:00 2001
From: Pierre Bourdon <delroth@gmail.com>
Date: Wed, 23 Jul 2014 03:32:15 +0200
Subject: [PATCH 1/2] IOWin: Make error 0x1F less noisy.

This error code is used by third-party WiiMote adapters to signal the
absence of a WiiMote connected to their virtual HID port. Ignoring it
removes some log spamming and doesn't change anything in terms of
behavior.
---
 Source/Core/Core/HW/WiimoteReal/IOWin.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Source/Core/Core/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/HW/WiimoteReal/IOWin.cpp
index ec72599286..8460294da0 100644
--- a/Source/Core/Core/HW/WiimoteReal/IOWin.cpp
+++ b/Source/Core/Core/HW/WiimoteReal/IOWin.cpp
@@ -673,7 +673,9 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac
 					// Semaphore timeout
 					NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]:  Unable to send data to the Wiimote");
 				}
-				else
+				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);
 				}

From e51c459406f003d9dd38f5f9d255363f3b571879 Mon Sep 17 00:00:00 2001
From: Pierre Bourdon <delroth@gmail.com>
Date: Wed, 23 Jul 2014 03:33:44 +0200
Subject: [PATCH 2/2] IOWin: rework _IOWrite OVERLAPPED/bytes written handling.

CheckDeviceType_Write uses an OVERLAPPED structure to make sure some bytes
were written to the device for a given _IOWrite operation. However, the
OVERLAPPED structure is only used for the BlueSoleil stack, not the MS stack
(which goes through an alternate HID path instead of WriteFile, and does not
have an equivalent async operation).

Make _IOWrite return the number of written bytes instead, since it knows
about the Bluetooth stack being used.
---
 Source/Core/Core/HW/WiimoteReal/IOWin.cpp | 58 ++++++++++++-----------
 1 file changed, 31 insertions(+), 27 deletions(-)

diff --git a/Source/Core/Core/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/HW/WiimoteReal/IOWin.cpp
index 8460294da0..1413ed76bc 100644
--- a/Source/Core/Core/HW/WiimoteReal/IOWin.cpp
+++ b/Source/Core/Core/HW/WiimoteReal/IOWin.cpp
@@ -140,7 +140,7 @@ namespace WiimoteReal
 {
 
 
-int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len);
+int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len, DWORD* written);
 int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index);
 void _IOWakeup(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read);
 
@@ -257,26 +257,8 @@ int CheckDeviceType_Write(HANDLE &dev_handle, const u8* buf, size_t size, int at
 
 	for (; attempts>0; --attempts)
 	{
-		if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, size))
-		{
-			auto const wait_result = WaitForSingleObject(hid_overlap_write.hEvent, WIIMOTE_DEFAULT_TIMEOUT);
-			if (WAIT_TIMEOUT == wait_result)
-			{
-				WARN_LOG(WIIMOTE, "CheckDeviceType_Write: A timeout occurred on writing to Wiimote.");
-				CancelIo(dev_handle);
-				continue;
-			}
-			else if (WAIT_FAILED == wait_result)
-			{
-				WARN_LOG(WIIMOTE, "CheckDeviceType_Write: A wait error occurred on writing to Wiimote.");
-				CancelIo(dev_handle);
-				continue;
-			}
-			if (GetOverlappedResult(dev_handle, &hid_overlap_write, &written, TRUE))
-			{
-				break;
-			}
-		}
+		if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, size, &written))
+			break;
 	}
 
 	CloseHandle(hid_overlap_write.hEvent);
@@ -640,7 +622,7 @@ int Wiimote::IORead(u8* buf)
 }
 
 
-int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len)
+int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len, DWORD* written)
 {
 	WiimoteEmu::Spy(nullptr, buf, len);
 
@@ -650,11 +632,11 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac
 		{
 			// Try to auto-detect the stack type
 			stack = MSBT_STACK_BLUESOLEIL;
-			if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len))
+			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))
+			if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len, written))
 				return 1;
 
 			stack = MSBT_STACK_UNKNOWN;
@@ -681,6 +663,9 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac
 				}
 			}
 
+			if (written)
+				*written = (result ? (DWORD)len : 0);
+
 			return result;
 		}
 		case MSBT_STACK_BLUESOLEIL:
@@ -697,7 +682,26 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac
 			DWORD bytes = 0;
 			if (WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_write))
 			{
-				// WriteFile always returns true with bluesoleil.
+				// 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
@@ -707,8 +711,8 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac
 				{
 					CancelIo(dev_handle);
 				}
+				return 0;
 			}
-			break;
 		}
 	}
 
@@ -717,7 +721,7 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac
 
 int Wiimote::IOWrite(const u8* buf, size_t len)
 {
-	return _IOWrite(dev_handle, hid_overlap_write, stack, buf, len);
+	return _IOWrite(dev_handle, hid_overlap_write, stack, buf, len, nullptr);
 }
 
 // invokes callback for each found wiimote bluetooth device