[PATCH 1/2] xinput1_3: Destroy controllers when ReadFile fails and I/O is not pending.
Rémi Bernon
rbernon at codeweavers.com
Thu Oct 7 04:14:10 CDT 2021
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
These should help with some inconsistent hotplugging behavior in xinput,
PATCH 2 is adapted from a Proton patch.
dlls/xinput1_3/main.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/dlls/xinput1_3/main.c b/dlls/xinput1_3/main.c
index 81d11e5d38f..f3ad7d1d360 100644
--- a/dlls/xinput1_3/main.c
+++ b/dlls/xinput1_3/main.c
@@ -331,9 +331,14 @@ static DWORD HID_set_state(struct xinput_controller *controller, XINPUT_VIBRATIO
return ERROR_SUCCESS;
}
+static void controller_destroy(struct xinput_controller *controller);
+
static void controller_enable(struct xinput_controller *controller)
{
+ ULONG report_len = controller->hid.caps.InputReportByteLength;
+ char *report_buf = controller->hid.input_report_buf;
XINPUT_VIBRATION state = controller->vibration;
+ BOOL ret;
if (controller->enabled) return;
if (controller->caps.Flags & XINPUT_CAPS_FFB_SUPPORTED) HID_set_state(controller, &state);
@@ -341,8 +346,9 @@ static void controller_enable(struct xinput_controller *controller)
memset(&controller->hid.read_ovl, 0, sizeof(controller->hid.read_ovl));
controller->hid.read_ovl.hEvent = controller->hid.read_event;
- ReadFile(controller->device, controller->hid.input_report_buf, controller->hid.caps.InputReportByteLength, NULL, &controller->hid.read_ovl);
- SetEvent(update_event);
+ ret = ReadFile(controller->device, report_buf, report_len, NULL, &controller->hid.read_ovl);
+ if (!ret && GetLastError() != ERROR_IO_PENDING) controller_destroy(controller);
+ else SetEvent(update_event);
}
static void controller_disable(struct xinput_controller *controller)
@@ -554,6 +560,7 @@ static void read_controller_state(struct xinput_controller *controller)
NTSTATUS status;
USAGE buttons[11];
ULONG i, button_length, value;
+ BOOL ret;
if (!GetOverlappedResult(controller->device, &controller->hid.read_ovl, &read_len, TRUE))
{
@@ -635,7 +642,8 @@ static void read_controller_state(struct xinput_controller *controller)
controller->state = state;
memset(&controller->hid.read_ovl, 0, sizeof(controller->hid.read_ovl));
controller->hid.read_ovl.hEvent = controller->hid.read_event;
- ReadFile(controller->device, controller->hid.input_report_buf, controller->hid.caps.InputReportByteLength, NULL, &controller->hid.read_ovl);
+ ret = ReadFile(controller->device, report_buf, report_len, NULL, &controller->hid.read_ovl);
+ if (!ret && GetLastError() != ERROR_IO_PENDING) controller_destroy(controller);
}
LeaveCriticalSection(&controller->crit);
}
--
2.33.0
More information about the wine-devel
mailing list