From fa08cadc26d2b57f9c6fb12965135cea08dd2d82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Wed, 1 Dec 2021 12:44:52 +0100 Subject: [PATCH] dinput8/tests: Provide an explicit test context to the driver. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RĂ©mi Bernon Signed-off-by: Alexandre Julliard --- dlls/dinput8/tests/driver_hid.c | 51 ++++++++++++++++------- dlls/dinput8/tests/driver_hid.h | 2 +- dlls/dinput8/tests/hid.c | 73 +++++++++++++++++++-------------- 3 files changed, 80 insertions(+), 46 deletions(-) diff --git a/dlls/dinput8/tests/driver_hid.c b/dlls/dinput8/tests/driver_hid.c index db7b3185906..9a58b1c7d44 100644 --- a/dlls/dinput8/tests/driver_hid.c +++ b/dlls/dinput8/tests/driver_hid.c @@ -56,6 +56,7 @@ struct expect_queue struct hid_expect spurious; struct hid_expect *buffer; IRP *pending_wait; + char context[64]; }; static void expect_queue_init( struct expect_queue *queue ) @@ -93,6 +94,7 @@ static void expect_queue_cleanup( struct expect_queue *queue ) static void expect_queue_reset( struct expect_queue *queue, void *buffer, unsigned int size ) { struct hid_expect *missing, *missing_end, *tmp; + char context[64]; KIRQL irql; missing = ExAllocatePool( PagedPool, EXPECT_QUEUE_BUFFER_SIZE ); @@ -108,12 +110,13 @@ static void expect_queue_reset( struct expect_queue *queue, void *buffer, unsign if (size) memcpy( queue->end, buffer, size ); queue->end = queue->end + size / sizeof(struct hid_expect); + memcpy( context, queue->context, sizeof(context) ); KeReleaseSpinLock( &queue->lock, irql ); tmp = missing; while (tmp != missing_end) { - winetest_push_context( "%s expect[%d]", tmp->context, tmp - missing ); + winetest_push_context( "%s expect[%d]", context, tmp - missing ); if (tmp->broken) { todo_wine_if( tmp->todo ) @@ -180,7 +183,8 @@ static NTSTATUS expect_queue_wait( struct expect_queue *queue, IRP *irp ) } static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_PACKET *packet, - LONG *index, struct hid_expect *expect, BOOL compare_buf ) + LONG *index, struct hid_expect *expect, BOOL compare_buf, + char *context, ULONG context_size ) { struct hid_expect *missing, *missing_end, *tmp; ULONG len = packet->reportBufferLen; @@ -219,6 +223,7 @@ static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_ queue->pending_wait = NULL; if (!IoSetCancelRoutine( irp, NULL )) irp = NULL; } + memcpy( context, queue->context, context_size ); KeReleaseSpinLock( &queue->lock, irql ); if (irp) @@ -228,9 +233,9 @@ static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_ IoCompleteRequest( irp, IO_NO_INCREMENT ); } - ok( tmp != &queue->spurious, "got spurious packet\n" ); + ok( tmp != &queue->spurious, "%s got spurious packet\n", context ); - winetest_push_context( "%s expect[%d]", tmp->context, tmp - queue->buffer ); + winetest_push_context( "%s expect[%d]", context, tmp - queue->buffer ); todo_wine_if( tmp->todo ) ok( !tmp->wine_only, "found code %#x id %u len %u\n", tmp->code, tmp->report_id, tmp->report_len ); winetest_pop_context(); @@ -238,7 +243,7 @@ static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_ tmp = missing; while (tmp != missing_end) { - winetest_push_context( "%s expect[%d]", tmp->context, tmp - missing ); + winetest_push_context( "%s expect[%d]", context, tmp - missing ); if (tmp->broken) { todo_wine_if( tmp->todo ) @@ -471,6 +476,7 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp ) ULONG out_size = stack->Parameters.DeviceIoControl.OutputBufferLength; const ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; struct hid_expect expect = {0}; + char context[64]; NTSTATUS ret; BOOL removed; KIRQL irql; @@ -563,8 +569,8 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp ) ok( !out_size, "got output size %u\n", out_size ); ok( packet->reportBufferLen >= expected_size, "got report size %u\n", packet->reportBufferLen ); - expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE ); - winetest_push_context( "%s expect[%d]", expect.context, index ); + expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE, context, sizeof(context) ); + winetest_push_context( "%s expect[%d]", context, index ); ok( code == expect.code, "got %#x, expected %#x\n", code, expect.code ); ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId ); ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen ); @@ -587,8 +593,8 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp ) ok( packet->reportBufferLen >= expected_size, "got len %u\n", packet->reportBufferLen ); ok( !!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer ); - expect_queue_next( &expect_queue, code, packet, &index, &expect, FALSE ); - winetest_push_context( "%s expect[%d]", expect.context, index ); + expect_queue_next( &expect_queue, code, packet, &index, &expect, FALSE, context, sizeof(context) ); + winetest_push_context( "%s expect[%d]", context, index ); ok( code == expect.code, "got %#x, expected %#x\n", code, expect.code ); ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId ); ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen ); @@ -610,8 +616,8 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp ) ok( packet->reportBufferLen >= expected_size, "got len %u\n", packet->reportBufferLen ); ok( !!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer ); - expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE ); - winetest_push_context( "%s expect[%d]", expect.context, index ); + expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE, context, sizeof(context) ); + winetest_push_context( "%s expect[%d]", context, index ); ok( code == expect.code, "got %#x, expected %#x\n", code, expect.code ); ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId ); ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen ); @@ -634,8 +640,8 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp ) ok( packet->reportBufferLen >= expected_size, "got len %u\n", packet->reportBufferLen ); ok( !!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer ); - expect_queue_next( &expect_queue, code, packet, &index, &expect, FALSE ); - winetest_push_context( "%s expect[%d]", expect.context, index ); + expect_queue_next( &expect_queue, code, packet, &index, &expect, FALSE, context, sizeof(context) ); + winetest_push_context( "%s expect[%d]", context, index ); ok( code == expect.code, "got %#x, expected %#x\n", code, expect.code ); ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId ); ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen ); @@ -657,8 +663,8 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp ) ok( packet->reportBufferLen >= expected_size, "got len %u\n", packet->reportBufferLen ); ok( !!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer ); - expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE ); - winetest_push_context( "%s expect[%d]", expect.context, index ); + expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE, context, sizeof(context) ); + winetest_push_context( "%s expect[%d]", context, index ); ok( code == expect.code, "got %#x, expected %#x\n", code, expect.code ); ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId ); ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen ); @@ -702,6 +708,7 @@ static NTSTATUS WINAPI driver_ioctl( DEVICE_OBJECT *device, IRP *irp ) IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); ULONG in_size = stack->Parameters.DeviceIoControl.InputBufferLength; ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; + KIRQL irql; switch (code) { @@ -714,6 +721,14 @@ static NTSTATUS WINAPI driver_ioctl( DEVICE_OBJECT *device, IRP *irp ) return expect_queue_wait( &expect_queue, irp ); case IOCTL_WINETEST_HID_SEND_INPUT: input_queue_reset( &input_queue, irp->AssociatedIrp.SystemBuffer, in_size ); + irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest( irp, IO_NO_INCREMENT ); + return STATUS_SUCCESS; + case IOCTL_WINETEST_HID_SET_CONTEXT: + KeAcquireSpinLock( &expect_queue.lock, &irql ); + memcpy( expect_queue.context, irp->AssociatedIrp.SystemBuffer, in_size ); + KeReleaseSpinLock( &expect_queue.lock, irql ); + irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest( irp, IO_NO_INCREMENT ); return STATUS_SUCCESS; @@ -837,6 +852,12 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *registry ) ok( !ret, "ZwQueryValueKey returned %#x\n", ret ); input_queue_reset( &input_queue, buffer + info_size, size - info_size ); + RtlInitUnicodeString( &name_str, L"Context" ); + size = info_size + sizeof(expect_queue.context); + ret = ZwQueryValueKey( hkey, &name_str, KeyValuePartialInformation, buffer, size, &size ); + ok( !ret, "ZwQueryValueKey returned %#x\n", ret ); + memcpy( expect_queue.context, buffer + info_size, size - info_size ); + driver->DriverExtension->AddDevice = driver_add_device; driver->DriverUnload = driver_unload; driver->MajorFunction[IRP_MJ_PNP] = driver_pnp; diff --git a/dlls/dinput8/tests/driver_hid.h b/dlls/dinput8/tests/driver_hid.h index 191c0c7bae2..3d31b4ee824 100644 --- a/dlls/dinput8/tests/driver_hid.h +++ b/dlls/dinput8/tests/driver_hid.h @@ -42,6 +42,7 @@ DEFINE_GUID(control_class,0xdeadbeef,0x29ef,0x4538,0xa5,0xfd,0xb6,0x95,0x73,0xa3 #define IOCTL_WINETEST_HID_SET_EXPECT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x800, METHOD_IN_DIRECT, FILE_ANY_ACCESS) #define IOCTL_WINETEST_HID_WAIT_EXPECT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x801, METHOD_NEITHER, FILE_ANY_ACCESS) #define IOCTL_WINETEST_HID_SEND_INPUT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x802, METHOD_IN_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_WINETEST_HID_SET_CONTEXT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x803, METHOD_IN_DIRECT, FILE_ANY_ACCESS) struct hid_expect { @@ -54,7 +55,6 @@ struct hid_expect BYTE report_id; BYTE report_len; BYTE report_buf[128]; - char context[64]; }; /* kernel/user shared data */ diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index a8ea8eaea9f..c0bfc8e8b30 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -765,21 +765,25 @@ static BOOL sync_ioctl_( int line, HANDLE file, DWORD code, void *in_buf, DWORD return ret; } +#define fill_context( line, a, b ) \ + do { \ + const char *source_file; \ + source_file = strrchr( __FILE__, '/' ); \ + if (!source_file) source_file = strrchr( __FILE__, '\\' ); \ + if (!source_file) source_file = __FILE__; \ + else source_file++; \ + snprintf( a, b, "%s:%d", source_file, line ); \ + } while (0) + #define set_hid_expect( a, b, c ) set_hid_expect_( __LINE__, a, b, c ) static void set_hid_expect_( int line, HANDLE file, struct hid_expect *expect, DWORD expect_size ) { - const char *source_file; + char context[64]; BOOL ret; - int i; - - source_file = strrchr( __FILE__, '/' ); - if (!source_file) source_file = strrchr( __FILE__, '\\' ); - if (!source_file) source_file = __FILE__; - else source_file++; - - for (i = 0; i < expect_size / sizeof(struct hid_expect); ++i) - snprintf( expect[i].context, ARRAY_SIZE(expect[i].context), "%s:%d", source_file, line ); + fill_context( line, context, ARRAY_SIZE(context) ); + ret = sync_ioctl_( line, file, IOCTL_WINETEST_HID_SET_CONTEXT, context, ARRAY_SIZE(context), NULL, 0, INFINITE ); + ok_(__FILE__, line)( ret, "IOCTL_WINETEST_HID_SET_CONTEXT failed, last error %u\n", GetLastError() ); ret = sync_ioctl_( line, file, IOCTL_WINETEST_HID_SET_EXPECT, expect, expect_size, NULL, 0, INFINITE ); ok_(__FILE__, line)( ret, "IOCTL_WINETEST_HID_SET_EXPECT failed, last error %u\n", GetLastError() ); } @@ -796,18 +800,12 @@ static void wait_hid_expect_( int line, HANDLE file, DWORD timeout ) #define send_hid_input( a, b, c ) send_hid_input_( __LINE__, a, b, c ) static void send_hid_input_( int line, HANDLE file, struct hid_expect *expect, DWORD expect_size ) { - const char *source_file; + char context[64]; BOOL ret; - int i; - - source_file = strrchr( __FILE__, '/' ); - if (!source_file) source_file = strrchr( __FILE__, '\\' ); - if (!source_file) source_file = __FILE__; - else source_file++; - - for (i = 0; i < expect_size / sizeof(struct hid_expect); ++i) - snprintf( expect[i].context, ARRAY_SIZE(expect[i].context), "%s:%d", source_file, line ); + fill_context( line, context, ARRAY_SIZE(context) ); + ret = sync_ioctl_( line, file, IOCTL_WINETEST_HID_SET_CONTEXT, context, ARRAY_SIZE(context), NULL, 0, INFINITE ); + ok_(__FILE__, line)( ret, "IOCTL_WINETEST_HID_SET_CONTEXT failed, last error %u\n", GetLastError() ); ret = sync_ioctl( file, IOCTL_WINETEST_HID_SEND_INPUT, expect, expect_size, NULL, 0, INFINITE ); ok( ret, "IOCTL_WINETEST_HID_SEND_INPUT failed, last error %u\n", GetLastError() ); } @@ -2750,6 +2748,7 @@ static void test_hid_driver( DWORD report_id, DWORD polled ) }; WCHAR cwd[MAX_PATH], tempdir[MAX_PATH]; + char context[64]; LSTATUS status; HKEY hkey; @@ -2782,6 +2781,10 @@ static void test_hid_driver( DWORD report_id, DWORD polled ) status = RegSetValueExW( hkey, L"Input", 0, REG_BINARY, (void *)&expect_in, polled ? sizeof(expect_in) : 0 ); ok( !status, "RegSetValueExW returned %#x\n", status ); + fill_context( __LINE__, context, ARRAY_SIZE(context) ); + status = RegSetValueExW( hkey, L"Context", 0, REG_BINARY, (void *)context, sizeof(context) ); + ok( !status, "RegSetValueExW returned %#x\n", status ); + if (pnp_driver_start( L"driver_hid.dll" )) test_hid_device( report_id, polled, &caps ); pnp_driver_stop(); @@ -3102,6 +3105,7 @@ static void test_hidp_kdr(void) PHIDP_PREPARSED_DATA preparsed_data; DWORD i, report_id = 0, polled = 0; struct hidp_kdr *kdr; + char context[64]; LSTATUS status; HDEVINFO set; HANDLE file; @@ -3137,6 +3141,10 @@ static void test_hidp_kdr(void) status = RegSetValueExW( hkey, L"Input", 0, REG_BINARY, NULL, 0 ); ok( !status, "RegSetValueExW returned %#x\n", status ); + fill_context( __LINE__, context, ARRAY_SIZE(context) ); + status = RegSetValueExW( hkey, L"Context", 0, REG_BINARY, (void *)context, sizeof(context) ); + ok( !status, "RegSetValueExW returned %#x\n", status ); + if (!pnp_driver_start( L"driver_hid.dll" )) goto done; set = SetupDiGetClassDevsW( &GUID_DEVINTERFACE_HID, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT ); @@ -3291,8 +3299,9 @@ static void cleanup_registry_keys(void) RegCloseKey( root_key ); } -static BOOL dinput_driver_start( const BYTE *desc_buf, ULONG desc_len, const HIDP_CAPS *caps, - struct hid_expect *expect, ULONG expect_size ) +#define dinput_driver_start( a, b, c, d, e ) dinput_driver_start_( __LINE__, a, b, c, d, e ) +static BOOL dinput_driver_start_( int line, const BYTE *desc_buf, ULONG desc_len, const HIDP_CAPS *caps, + struct hid_expect *expect, ULONG expect_size ) { static const HID_DEVICE_ATTRIBUTES attributes = { @@ -3303,26 +3312,30 @@ static BOOL dinput_driver_start( const BYTE *desc_buf, ULONG desc_len, const HID }; DWORD report_id = 1; DWORD polled = 0; + char context[64]; LSTATUS status; HKEY hkey; status = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services\\winetest", 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ); - ok( !status, "RegCreateKeyExW returned %#x\n", status ); + ok_(__FILE__, line)( !status, "RegCreateKeyExW returned %#x\n", status ); status = RegSetValueExW( hkey, L"ReportID", 0, REG_DWORD, (void *)&report_id, sizeof(report_id) ); - ok( !status, "RegSetValueExW returned %#x\n", status ); + ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status ); status = RegSetValueExW( hkey, L"PolledMode", 0, REG_DWORD, (void *)&polled, sizeof(polled) ); - ok( !status, "RegSetValueExW returned %#x\n", status ); + ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status ); status = RegSetValueExW( hkey, L"Descriptor", 0, REG_BINARY, (void *)desc_buf, desc_len ); - ok( !status, "RegSetValueExW returned %#x\n", status ); + ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status ); status = RegSetValueExW( hkey, L"Attributes", 0, REG_BINARY, (void *)&attributes, sizeof(attributes) ); - ok( !status, "RegSetValueExW returned %#x\n", status ); + ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status ); status = RegSetValueExW( hkey, L"Caps", 0, REG_BINARY, (void *)caps, sizeof(*caps) ); - ok( !status, "RegSetValueExW returned %#x\n", status ); + ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status ); status = RegSetValueExW( hkey, L"Expect", 0, REG_BINARY, (void *)expect, expect_size ); - ok( !status, "RegSetValueExW returned %#x\n", status ); + ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status ); status = RegSetValueExW( hkey, L"Input", 0, REG_BINARY, NULL, 0 ); - ok( !status, "RegSetValueExW returned %#x\n", status ); + ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status ); + fill_context( line, context, ARRAY_SIZE(context) ); + status = RegSetValueExW( hkey, L"Context", 0, REG_BINARY, (void *)context, sizeof(context) ); + ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status ); return pnp_driver_start( L"driver_hid.dll" ); }