Rémi Bernon : dinput/tests: Queue IRP when the expect ret_status is STATUS_PENDING.
Alexandre Julliard
julliard at winehq.org
Thu Apr 21 15:21:39 CDT 2022
Module: wine
Branch: master
Commit: c6966b52948190fee25124aa3387e1ea4a0bb675
URL: https://source.winehq.org/git/wine.git/?a=commit;h=c6966b52948190fee25124aa3387e1ea4a0bb675
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Thu Apr 21 19:50:19 2022 +0200
dinput/tests: Queue IRP when the expect ret_status is STATUS_PENDING.
And complete it on the next IOCTL_WINETEST_HID_WAIT_EXPECT ioctl.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/dinput/tests/driver_bus.c | 71 ++++++++++++++++++++++++++++++++----------
1 file changed, 55 insertions(+), 16 deletions(-)
diff --git a/dlls/dinput/tests/driver_bus.c b/dlls/dinput/tests/driver_bus.c
index 6d7f86d0691..45a984b6c36 100644
--- a/dlls/dinput/tests/driver_bus.c
+++ b/dlls/dinput/tests/driver_bus.c
@@ -95,7 +95,6 @@ static void expect_queue_cleanup( struct expect_queue *queue )
if (irp)
{
- irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_DELETE_PENDING;
IoCompleteRequest( irp, IO_NO_INCREMENT );
}
@@ -162,29 +161,64 @@ static void WINAPI wait_cancel_routine( DEVICE_OBJECT *device, IRP *irp )
IoCompleteRequest( irp, IO_NO_INCREMENT );
}
-static NTSTATUS expect_queue_wait( struct expect_queue *queue, IRP *irp )
+static NTSTATUS expect_queue_add_pending_locked( struct expect_queue *queue, IRP *irp )
+{
+ if (queue->pending_wait) return STATUS_INVALID_PARAMETER;
+
+ IoSetCancelRoutine( irp, wait_cancel_routine );
+ if (irp->Cancel && !IoSetCancelRoutine( irp, NULL ))
+ return STATUS_CANCELLED;
+
+ irp->Tail.Overlay.DriverContext[0] = queue;
+ IoMarkIrpPending( irp );
+ queue->pending_wait = irp;
+
+ return STATUS_PENDING;
+}
+
+static NTSTATUS expect_queue_add_pending( struct expect_queue *queue, IRP *irp )
{
NTSTATUS status;
KIRQL irql;
KeAcquireSpinLock( &queue->lock, &irql );
- if (queue->pos == queue->end)
- status = STATUS_SUCCESS;
- else
+ status = expect_queue_add_pending_locked( queue, irp );
+ KeReleaseSpinLock( &queue->lock, irql );
+
+ return status;
+}
+
+static void expect_queue_clear_pending( struct expect_queue *queue )
+{
+ KIRQL irql;
+ IRP *irp;
+
+ KeAcquireSpinLock( &queue->lock, &irql );
+ if ((irp = queue->pending_wait))
{
- IoSetCancelRoutine( irp, wait_cancel_routine );
- if (irp->Cancel && !IoSetCancelRoutine( irp, NULL ))
- status = STATUS_CANCELLED;
- else
- {
- irp->Tail.Overlay.DriverContext[0] = queue;
- IoMarkIrpPending( irp );
- queue->pending_wait = irp;
- status = STATUS_PENDING;
- }
+ queue->pending_wait = NULL;
+ if (!IoSetCancelRoutine( irp, NULL )) irp = NULL;
}
KeReleaseSpinLock( &queue->lock, irql );
+ if (irp)
+ {
+ irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest( irp, IO_NO_INCREMENT );
+ }
+}
+
+static NTSTATUS expect_queue_wait( struct expect_queue *queue, IRP *irp )
+{
+ NTSTATUS status;
+ KIRQL irql;
+
+ irp->IoStatus.Information = 0;
+ KeAcquireSpinLock( &queue->lock, &irql );
+ if (queue->pos == queue->end) status = STATUS_SUCCESS;
+ else status = expect_queue_add_pending_locked( queue, irp );
+ KeReleaseSpinLock( &queue->lock, irql );
+
return status;
}
@@ -233,7 +267,6 @@ static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_
if (irp)
{
- irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest( irp, IO_NO_INCREMENT );
}
@@ -1055,6 +1088,7 @@ static NTSTATUS WINAPI pdo_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len;
status = expect.ret_status;
+ if (status == STATUS_PENDING) status = expect_queue_add_pending( &impl->expect_queue, irp );
break;
}
@@ -1078,6 +1112,7 @@ static NTSTATUS WINAPI pdo_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len;
memcpy( packet->reportBuffer, expect.report_buf, irp->IoStatus.Information );
status = expect.ret_status;
+ if (status == STATUS_PENDING) status = expect_queue_add_pending( &impl->expect_queue, irp );
break;
}
@@ -1101,6 +1136,7 @@ static NTSTATUS WINAPI pdo_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len;
status = expect.ret_status;
+ if (status == STATUS_PENDING) status = expect_queue_add_pending( &impl->expect_queue, irp );
break;
}
@@ -1124,6 +1160,7 @@ static NTSTATUS WINAPI pdo_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len;
memcpy( packet->reportBuffer, expect.report_buf, irp->IoStatus.Information );
status = expect.ret_status;
+ if (status == STATUS_PENDING) status = expect_queue_add_pending( &impl->expect_queue, irp );
break;
}
@@ -1147,6 +1184,7 @@ static NTSTATUS WINAPI pdo_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len;
status = expect.ret_status;
+ if (status == STATUS_PENDING) status = expect_queue_add_pending( &impl->expect_queue, irp );
break;
}
@@ -1215,6 +1253,7 @@ static NTSTATUS WINAPI pdo_ioctl( DEVICE_OBJECT *device, IRP *irp )
status = STATUS_SUCCESS;
break;
case IOCTL_WINETEST_HID_WAIT_EXPECT:
+ expect_queue_clear_pending( &impl->expect_queue );
status = expect_queue_wait( &impl->expect_queue, irp );
break;
case IOCTL_WINETEST_HID_SEND_INPUT:
More information about the wine-cvs
mailing list