From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/tests/driver_bus.c | 53 +++++++++++++++++----------------- 1 file changed, 26 insertions(+), 27 deletions(-)
diff --git a/dlls/dinput/tests/driver_bus.c b/dlls/dinput/tests/driver_bus.c index 6a1994e509c..dc9b549e1d8 100644 --- a/dlls/dinput/tests/driver_bus.c +++ b/dlls/dinput/tests/driver_bus.c @@ -1244,40 +1244,29 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp ) return fdo_internal_ioctl( device, irp ); }
-static NTSTATUS WINAPI pdo_ioctl( DEVICE_OBJECT *device, IRP *irp ) +static NTSTATUS pdo_handle_ioctl( struct phys_device *impl, IRP *irp, ULONG code, void *in_buffer, ULONG in_size ) { - IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); - struct phys_device *impl = pdo_from_DEVICE_OBJECT( device ); - ULONG in_size = stack->Parameters.DeviceIoControl.InputBufferLength; - ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; - NTSTATUS status; KIRQL irql;
- if (winetest_debug > 1) trace( "%s: device %p, code %#lx %s\n", __func__, device, code, debugstr_ioctl(code) ); - switch (code) { case IOCTL_WINETEST_HID_SET_EXPECT: - expect_queue_reset( &impl->expect_queue, irp->AssociatedIrp.SystemBuffer, in_size ); - status = STATUS_SUCCESS; - break; + expect_queue_reset( &impl->expect_queue, in_buffer, in_size ); + return STATUS_SUCCESS; case IOCTL_WINETEST_HID_WAIT_EXPECT: { - struct wait_expect_params wait_params = *(struct wait_expect_params *)irp->AssociatedIrp.SystemBuffer; - if (!wait_params.wait_pending) status = expect_queue_wait( &impl->expect_queue, irp ); - else status = expect_queue_wait_pending( &impl->expect_queue, irp ); - break; + struct wait_expect_params wait_params = *(struct wait_expect_params *)in_buffer; + if (!wait_params.wait_pending) return expect_queue_wait( &impl->expect_queue, irp ); + else return expect_queue_wait_pending( &impl->expect_queue, irp ); } case IOCTL_WINETEST_HID_SEND_INPUT: - input_queue_reset( &impl->input_queue, irp->AssociatedIrp.SystemBuffer, in_size ); - status = STATUS_SUCCESS; - break; + input_queue_reset( &impl->input_queue, in_buffer, in_size ); + return STATUS_SUCCESS; case IOCTL_WINETEST_HID_SET_CONTEXT: KeAcquireSpinLock( &impl->expect_queue.lock, &irql ); - memcpy( impl->expect_queue.context, irp->AssociatedIrp.SystemBuffer, in_size ); + memcpy( impl->expect_queue.context, in_buffer, in_size ); KeReleaseSpinLock( &impl->expect_queue.lock, irql ); - status = STATUS_SUCCESS; - break; + return STATUS_SUCCESS; case IOCTL_WINETEST_REMOVE_DEVICE: KeAcquireSpinLock( &impl->base.lock, &irql ); impl->base.state = PNP_DEVICE_REMOVED; @@ -1285,17 +1274,27 @@ static NTSTATUS WINAPI pdo_ioctl( DEVICE_OBJECT *device, IRP *irp ) KeReleaseSpinLock( &impl->base.lock, irql ); impl->pending_remove = irp; IoMarkIrpPending( irp ); - status = STATUS_PENDING; - break; + return STATUS_PENDING; case IOCTL_WINETEST_CREATE_DEVICE: ok( 0, "unexpected call\n" ); - status = irp->IoStatus.Status; - break; + return irp->IoStatus.Status; default: ok( 0, "unexpected call\n" ); - status = irp->IoStatus.Status; - break; + return irp->IoStatus.Status; } +} + +static NTSTATUS WINAPI pdo_ioctl( DEVICE_OBJECT *device, IRP *irp ) +{ + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); + struct phys_device *impl = pdo_from_DEVICE_OBJECT( device ); + ULONG in_size = stack->Parameters.DeviceIoControl.InputBufferLength; + ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; + NTSTATUS status; + + if (winetest_debug > 1) trace( "%s: device %p, code %#lx %s\n", __func__, device, code, debugstr_ioctl(code) ); + + status = pdo_handle_ioctl( impl, irp, code, irp->AssociatedIrp.SystemBuffer, in_size );
if (status != STATUS_PENDING) {
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=115999
Your paranoid android.
=== w1064_tsign (64 bit report) ===
dinput: joystick8.c:1612: Test failed: 0x500: WaitForSingleObject failed joystick8.c:1616: Test failed: 0x500: GetDeviceState returned: 0x8007001e joystick8.c:1651: Test failed: 0x500: Unacquire returned: 0x1 joystick8.c:1835: Test failed: 0x500: state[0]: WaitForSingleObject succeeded
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/tests/driver_bus.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/dinput/tests/driver_bus.c b/dlls/dinput/tests/driver_bus.c index dc9b549e1d8..64ca33e7c89 100644 --- a/dlls/dinput/tests/driver_bus.c +++ b/dlls/dinput/tests/driver_bus.c @@ -1251,18 +1251,22 @@ static NTSTATUS pdo_handle_ioctl( struct phys_device *impl, IRP *irp, ULONG code switch (code) { case IOCTL_WINETEST_HID_SET_EXPECT: + if (in_size > EXPECT_QUEUE_BUFFER_SIZE) return STATUS_BUFFER_OVERFLOW; expect_queue_reset( &impl->expect_queue, in_buffer, in_size ); return STATUS_SUCCESS; case IOCTL_WINETEST_HID_WAIT_EXPECT: { - struct wait_expect_params wait_params = *(struct wait_expect_params *)in_buffer; - if (!wait_params.wait_pending) return expect_queue_wait( &impl->expect_queue, irp ); + struct wait_expect_params *wait_params = (struct wait_expect_params *)in_buffer; + if (in_size < sizeof(*wait_params)) return STATUS_BUFFER_TOO_SMALL; + if (!wait_params->wait_pending) return expect_queue_wait( &impl->expect_queue, irp ); else return expect_queue_wait_pending( &impl->expect_queue, irp ); } case IOCTL_WINETEST_HID_SEND_INPUT: + if (in_size > EXPECT_QUEUE_BUFFER_SIZE) return STATUS_BUFFER_OVERFLOW; input_queue_reset( &impl->input_queue, in_buffer, in_size ); return STATUS_SUCCESS; case IOCTL_WINETEST_HID_SET_CONTEXT: + if (in_size > sizeof(impl->expect_queue.context)) return STATUS_BUFFER_OVERFLOW; KeAcquireSpinLock( &impl->expect_queue.lock, &irql ); memcpy( impl->expect_queue.context, in_buffer, in_size ); KeReleaseSpinLock( &impl->expect_queue.lock, irql );
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/tests/dinput_test.h | 12 ++---------- dlls/dinput/tests/force_feedback.c | 6 +++--- dlls/dinput/tests/hid.c | 20 +++++++++++++++----- dlls/dinput/tests/hotplug.c | 4 ++-- dlls/dinput/tests/joystick8.c | 14 +++++++------- 5 files changed, 29 insertions(+), 27 deletions(-)
diff --git a/dlls/dinput/tests/dinput_test.h b/dlls/dinput/tests/dinput_test.h index c4ee42ca1c8..943dcd8034d 100644 --- a/dlls/dinput/tests/dinput_test.h +++ b/dlls/dinput/tests/dinput_test.h @@ -68,16 +68,8 @@ void dinput_test_exit(void); HRESULT dinput_test_create_device( DWORD version, DIDEVICEINSTANCEW *devinst, IDirectInputDevice8W **device ); DWORD WINAPI dinput_test_device_thread( void *stop_event );
-#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 fill_context( a, b ) fill_context_( __FILE__, __LINE__, a, b ) +void fill_context_( const char *file, int line, char *buffer, SIZE_T size );
#define check_member_( file, line, val, exp, fmt, member ) \ ok_(file, line)( (val).member == (exp).member, "got " #member " " fmt "\n", (val).member ) diff --git a/dlls/dinput/tests/force_feedback.c b/dlls/dinput/tests/force_feedback.c index c7498e45727..30d19cc04a0 100644 --- a/dlls/dinput/tests/force_feedback.c +++ b/dlls/dinput/tests/force_feedback.c @@ -2838,7 +2838,7 @@ static BOOL test_force_feedback_joystick( DWORD version )
desc.report_descriptor_len = sizeof(report_descriptor); memcpy( desc.report_descriptor_buf, report_descriptor, sizeof(report_descriptor) ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
if (!hid_device_start( &desc )) goto done; if (FAILED(hr = dinput_test_create_device( version, &devinst, &device ))) goto done; @@ -3959,7 +3959,7 @@ static void test_device_managed_effect(void) memcpy( desc.report_descriptor_buf, report_descriptor, sizeof(report_descriptor) ); desc.expect_size = sizeof(expect_pool); memcpy( desc.expect, expect_pool, sizeof(expect_pool) ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
if (!hid_device_start( &desc )) goto done; if (FAILED(hr = dinput_test_create_device( DIRECTINPUT_VERSION, &devinst, &device ))) goto done; @@ -5706,7 +5706,7 @@ static void test_windows_gaming_input(void) memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); desc.expect_size = sizeof(expect_init); memcpy( desc.expect, expect_init, sizeof(expect_init) ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
if (!hid_device_start( &desc )) goto done; WaitForSingleObject( controller_added.event, INFINITE ); diff --git a/dlls/dinput/tests/hid.c b/dlls/dinput/tests/hid.c index 00a3d65fe4d..98c1a350373 100644 --- a/dlls/dinput/tests/hid.c +++ b/dlls/dinput/tests/hid.c @@ -899,12 +899,22 @@ BOOL sync_ioctl_( const char *file, int line, HANDLE device, DWORD code, void *i return ret; }
+void fill_context_( const char *file, int line, char *buffer, SIZE_T size ) +{ + 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( buffer, size, "%s:%d", source_file, line ); +} + void set_hid_expect_( const char *file, int line, HANDLE device, struct hid_expect *expect, DWORD expect_size ) { char context[64]; BOOL ret;
- fill_context( line, context, ARRAY_SIZE(context) ); + fill_context_( file, line, context, ARRAY_SIZE(context) ); ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_SET_CONTEXT, context, ARRAY_SIZE(context), NULL, 0, INFINITE ); ok_(file, line)( ret, "IOCTL_WINETEST_HID_SET_CONTEXT failed, last error %lu\n", GetLastError() ); ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_SET_EXPECT, expect, expect_size, NULL, 0, INFINITE ); @@ -928,7 +938,7 @@ void send_hid_input_( const char *file, int line, HANDLE device, struct hid_expe char context[64]; BOOL ret;
- fill_context( line, context, ARRAY_SIZE(context) ); + fill_context_( file, line, context, ARRAY_SIZE(context) ); ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_SET_CONTEXT, context, ARRAY_SIZE(context), NULL, 0, INFINITE ); ok_(file, line)( ret, "IOCTL_WINETEST_HID_SET_CONTEXT failed, last error %lu\n", GetLastError() ); ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_SEND_INPUT, expect, expect_size, NULL, 0, INFINITE ); @@ -2894,7 +2904,7 @@ static void test_hid_driver( DWORD report_id, DWORD polled ) memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); desc.input_size = polled ? sizeof(expect_in) : 0; memcpy( desc.input, &expect_in, sizeof(expect_in) ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
if (hid_device_start( &desc )) test_hid_device( report_id, polled, &caps, desc.attributes.VendorID, desc.attributes.ProductID ); hid_device_stop( &desc ); @@ -3208,7 +3218,7 @@ static void test_hidp_kdr(void)
desc.report_descriptor_len = sizeof(report_desc); memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
if (!hid_device_start( &desc )) goto done;
@@ -3597,7 +3607,7 @@ DWORD WINAPI dinput_test_device_thread( void *stop_event )
desc.report_descriptor_len = sizeof(gamepad_desc); memcpy( desc.report_descriptor_buf, gamepad_desc, sizeof(gamepad_desc) ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
hid_device_start( &desc ); WaitForSingleObject( stop_event, INFINITE ); diff --git a/dlls/dinput/tests/hotplug.c b/dlls/dinput/tests/hotplug.c index 3f4aae3afac..885d0e036e0 100644 --- a/dlls/dinput/tests/hotplug.c +++ b/dlls/dinput/tests/hotplug.c @@ -167,7 +167,7 @@ static BOOL test_input_lost( DWORD version )
desc.report_descriptor_len = sizeof(report_desc); memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
if (!hid_device_start( &desc )) goto done; if (FAILED(hr = dinput_test_create_device( version, &devinst, &device ))) goto done; @@ -209,7 +209,7 @@ static BOOL test_input_lost( DWORD version ) hr = IDirectInputDevice8_Unacquire( device ); ok( hr == DI_NOEFFECT, "Unacquire returned: %#lx\n", hr );
- fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) ); hid_device_start( &desc );
hr = IDirectInputDevice8_Acquire( device ); diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index acf417a0068..070d9cc2361 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -802,7 +802,7 @@ static void test_simple_joystick( DWORD version )
desc.report_descriptor_len = sizeof(report_desc); memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
if (!hid_device_start( &desc )) goto done; if (FAILED(hr = dinput_test_create_device( version, &devinst, &device ))) goto done; @@ -2575,7 +2575,7 @@ static BOOL test_device_types( DWORD version ) desc.caps = device_desc[i].hid_caps; desc.report_descriptor_len = device_desc[i].report_desc_len; memcpy( desc.report_descriptor_buf, device_desc[i].report_desc_buf, device_desc[i].report_desc_len ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
if (!hid_device_start( &desc )) { @@ -3022,7 +3022,7 @@ static void test_many_axes_joystick(void)
desc.report_descriptor_len = sizeof(report_desc); memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
if (!hid_device_start( &desc )) goto done; if (FAILED(hr = dinput_test_create_device( DIRECTINPUT_VERSION, &devinst, &device ))) goto done; @@ -3364,7 +3364,7 @@ static void test_driving_wheel_axes(void)
desc.report_descriptor_len = sizeof(report_desc); memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
if (!hid_device_start( &desc )) goto done; if (FAILED(hr = dinput_test_create_device( DIRECTINPUT_VERSION, &devinst, &device ))) goto done; @@ -3600,7 +3600,7 @@ static BOOL test_winmm_joystick(void)
desc.report_descriptor_len = sizeof(report_desc); memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
if (!hid_device_start( &desc )) goto done;
@@ -4022,7 +4022,7 @@ static void test_windows_gaming_input(void)
desc.report_descriptor_len = sizeof(report_desc); memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
if (!hid_device_start( &desc )) goto done; WaitForSingleObject( controller_added.event, INFINITE ); @@ -4097,7 +4097,7 @@ static void test_windows_gaming_input(void)
desc.report_descriptor_len = sizeof(wheel_threepedals_desc); memcpy( desc.report_descriptor_buf, wheel_threepedals_desc, sizeof(wheel_threepedals_desc) ); - fill_context( __LINE__, desc.context, ARRAY_SIZE(desc.context) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) );
controller_added.event = CreateEventW( NULL, FALSE, FALSE, NULL ); ok( !!controller_added.event, "CreateEventW failed, error %lu\n", GetLastError() );
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/tests/dinput_test.h | 25 +++++++++------ dlls/dinput/tests/driver_bus.c | 30 ++++++++++++----- dlls/dinput/tests/driver_hid.h | 2 ++ dlls/dinput/tests/hid.c | 57 +++++++++++++++++++++++++-------- 4 files changed, 84 insertions(+), 30 deletions(-)
diff --git a/dlls/dinput/tests/dinput_test.h b/dlls/dinput/tests/dinput_test.h index 943dcd8034d..677f8c96361 100644 --- a/dlls/dinput/tests/dinput_test.h +++ b/dlls/dinput/tests/dinput_test.h @@ -92,14 +92,21 @@ void fill_context_( const char *file, int line, char *buffer, SIZE_T size ); BOOL sync_ioctl_( const char *file, int line, HANDLE device, DWORD code, void *in_buf, DWORD in_len, void *out_buf, DWORD *ret_len, DWORD timeout );
-#define set_hid_expect( a, b, c ) set_hid_expect_( __FILE__, __LINE__, a, b, c ) -void set_hid_expect_( const char *file, int line, HANDLE device, struct hid_expect *expect, DWORD expect_size ); - -#define wait_hid_expect( a, b ) wait_hid_expect_( __FILE__, __LINE__, a, b, FALSE, FALSE ) -#define wait_hid_pending( a, b ) wait_hid_expect_( __FILE__, __LINE__, a, b, TRUE, FALSE ) -void wait_hid_expect_( const char *file, int line, HANDLE device, DWORD timeout, BOOL wait_pending, BOOL todo ); - -#define send_hid_input( a, b, c ) send_hid_input_( __FILE__, __LINE__, a, b, c ) -void send_hid_input_( const char *file, int line, HANDLE device, struct hid_expect *expect, DWORD expect_size ); +#define set_hid_expect( a, b, c ) set_hid_expect_( __FILE__, __LINE__, a, NULL, b, c ) +#define bus_set_hid_expect( a, b, c, d ) set_hid_expect_( __FILE__, __LINE__, a, b, c, d ) +void set_hid_expect_( const char *file, int line, HANDLE device, struct hid_device_desc *desc, + struct hid_expect *expect, DWORD expect_size ); + +#define wait_hid_expect( a, b ) wait_hid_expect_( __FILE__, __LINE__, a, NULL, b, FALSE, FALSE ) +#define wait_hid_pending( a, b ) wait_hid_expect_( __FILE__, __LINE__, a, NULL, b, TRUE, FALSE ) +#define bus_wait_hid_expect( a, b, c ) wait_hid_expect_( __FILE__, __LINE__, a, b, c, FALSE, FALSE ) +#define bus_wait_hid_pending( a, b, c ) wait_hid_expect_( __FILE__, __LINE__, a, b, c, TRUE, FALSE ) +void wait_hid_expect_( const char *file, int line, HANDLE device, struct hid_device_desc *desc, + DWORD timeout, BOOL wait_pending, BOOL todo ); + +#define send_hid_input( a, b, c ) send_hid_input_( __FILE__, __LINE__, a, NULL, b, c ) +#define bus_send_hid_input( a, b, c, d ) send_hid_input_( __FILE__, __LINE__, a, b, c, d ) +void send_hid_input_( const char *file, int line, HANDLE device, struct hid_device_desc *desc, + struct hid_expect *expect, DWORD expect_size );
#endif /* __WINE_DINPUT_TEST_H */ diff --git a/dlls/dinput/tests/driver_bus.c b/dlls/dinput/tests/driver_bus.c index 64ca33e7c89..f200b7745d5 100644 --- a/dlls/dinput/tests/driver_bus.c +++ b/dlls/dinput/tests/driver_bus.c @@ -58,8 +58,6 @@ static void check_buffer_( int line, HID_XFER_PACKET *packet, struct hid_expect } }
-#define EXPECT_QUEUE_BUFFER_SIZE (64 * sizeof(struct hid_expect)) - struct expect_queue { KSPIN_LOCK lock; @@ -1293,12 +1291,13 @@ static NTSTATUS WINAPI pdo_ioctl( DEVICE_OBJECT *device, IRP *irp ) IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); struct phys_device *impl = pdo_from_DEVICE_OBJECT( device ); ULONG in_size = stack->Parameters.DeviceIoControl.InputBufferLength; + struct hid_device_desc *desc = irp->AssociatedIrp.SystemBuffer; ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; NTSTATUS status;
if (winetest_debug > 1) trace( "%s: device %p, code %#lx %s\n", __func__, device, code, debugstr_ioctl(code) );
- status = pdo_handle_ioctl( impl, irp, code, irp->AssociatedIrp.SystemBuffer, in_size ); + status = pdo_handle_ioctl( impl, irp, code, desc + 1, in_size - sizeof(*desc) );
if (status != STATUS_PENDING) { @@ -1312,8 +1311,10 @@ static NTSTATUS WINAPI fdo_ioctl( DEVICE_OBJECT *device, IRP *irp ) { IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); ULONG in_size = stack->Parameters.DeviceIoControl.InputBufferLength; + struct hid_device_desc *desc = irp->AssociatedIrp.SystemBuffer; ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; struct func_device *impl = fdo_from_DEVICE_OBJECT( device ); + struct phys_device *pdo; NTSTATUS status;
if (winetest_debug > 1) trace( "%s: device %p, code %#lx %s\n", __func__, device, code, debugstr_ioctl(code) ); @@ -1321,18 +1322,31 @@ static NTSTATUS WINAPI fdo_ioctl( DEVICE_OBJECT *device, IRP *irp ) switch (code) { case IOCTL_WINETEST_CREATE_DEVICE: - if (in_size < sizeof(struct hid_device_desc)) status = STATUS_INVALID_PARAMETER; - else status = create_child_pdo( device, irp->AssociatedIrp.SystemBuffer ); + if (in_size < sizeof(*desc)) status = STATUS_INVALID_PARAMETER; + else status = create_child_pdo( device, desc ); break; case IOCTL_WINETEST_REMOVE_DEVICE: - if ((device = find_child_device( impl, irp->AssociatedIrp.SystemBuffer )) && - !remove_child_device( impl, device )) + if (in_size < sizeof(*desc)) + status = STATUS_INVALID_PARAMETER; + else if (!(device = find_child_device( impl, desc )) || remove_child_device( impl, device )) + status = STATUS_NO_SUCH_DEVICE; + else { status = pdo_ioctl( device, irp ); IoInvalidateDeviceRelations( impl->pdo, BusRelations ); return status; } - status = STATUS_NO_SUCH_DEVICE; + break; + case IOCTL_WINETEST_HID_SET_EXPECT: + case IOCTL_WINETEST_HID_WAIT_EXPECT: + case IOCTL_WINETEST_HID_SEND_INPUT: + case IOCTL_WINETEST_HID_SET_CONTEXT: + if (in_size < sizeof(*desc)) + status = STATUS_INVALID_PARAMETER; + else if (!(device = find_child_device( impl, desc )) || !(pdo = pdo_from_DEVICE_OBJECT( device ))) + status = STATUS_NO_SUCH_DEVICE; + else + status = pdo_handle_ioctl( pdo, irp, code, desc + 1, in_size - sizeof(*desc) ); break; default: ok( 0, "unexpected call\n" ); diff --git a/dlls/dinput/tests/driver_hid.h b/dlls/dinput/tests/driver_hid.h index c5641097df3..3633cbdfd44 100644 --- a/dlls/dinput/tests/driver_hid.h +++ b/dlls/dinput/tests/driver_hid.h @@ -61,6 +61,8 @@ struct hid_expect BYTE report_buf[128]; };
+#define EXPECT_QUEUE_BUFFER_SIZE (64 * sizeof(struct hid_expect)) + struct wait_expect_params { BOOL wait_pending; diff --git a/dlls/dinput/tests/hid.c b/dlls/dinput/tests/hid.c index 98c1a350373..81bf8ed46f8 100644 --- a/dlls/dinput/tests/hid.c +++ b/dlls/dinput/tests/hid.c @@ -909,39 +909,70 @@ void fill_context_( const char *file, int line, char *buffer, SIZE_T size ) snprintf( buffer, size, "%s:%d", source_file, line ); }
-void set_hid_expect_( const char *file, int line, HANDLE device, struct hid_expect *expect, DWORD expect_size ) +void set_hid_expect_( const char *file, int line, HANDLE device, struct hid_device_desc *desc, + struct hid_expect *expect, DWORD expect_size ) { - char context[64]; + char buffer[sizeof(*desc) + EXPECT_QUEUE_BUFFER_SIZE]; + SIZE_T size; BOOL ret;
- fill_context_( file, line, context, ARRAY_SIZE(context) ); - ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_SET_CONTEXT, context, ARRAY_SIZE(context), NULL, 0, INFINITE ); + if (desc) memcpy( buffer, desc, sizeof(*desc) ); + else memset( buffer, 0, sizeof(*desc) ); + + fill_context_( file, line, buffer + sizeof(*desc), ARRAY_SIZE(buffer) - sizeof(*desc) ); + size = sizeof(*desc) + strlen( buffer + sizeof(*desc) ) + 1; + ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_SET_CONTEXT, buffer, size, NULL, 0, INFINITE ); ok_(file, line)( ret, "IOCTL_WINETEST_HID_SET_CONTEXT failed, last error %lu\n", GetLastError() ); - ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_SET_EXPECT, expect, expect_size, NULL, 0, INFINITE ); + + if (expect) memcpy( buffer + sizeof(*desc), expect, expect_size ); + else memset( buffer + sizeof(*desc), 0, expect_size ); + + size = sizeof(*desc) + expect_size; + ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_SET_EXPECT, buffer, size, NULL, 0, INFINITE ); ok_(file, line)( ret, "IOCTL_WINETEST_HID_SET_EXPECT failed, last error %lu\n", GetLastError() ); }
-void wait_hid_expect_( const char *file, int line, HANDLE device, DWORD timeout, BOOL wait_pending, BOOL todo ) +void wait_hid_expect_( const char *file, int line, HANDLE device, struct hid_device_desc *desc, + DWORD timeout, BOOL wait_pending, BOOL todo ) { struct wait_expect_params params = {.wait_pending = wait_pending}; + char buffer[sizeof(*desc) + sizeof(params)]; + SIZE_T size; + + if (desc) memcpy( buffer, desc, sizeof(*desc) ); + else memset( buffer, 0, sizeof(*desc) ); + + memcpy( buffer + sizeof(*desc), ¶ms, sizeof(params) ); + size = sizeof(*desc) + sizeof(params);
todo_wine_if(todo) { - BOOL ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_WAIT_EXPECT, ¶ms, sizeof(params), NULL, 0, timeout ); + BOOL ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_WAIT_EXPECT, buffer, size, NULL, 0, timeout ); ok_(file, line)( ret, "IOCTL_WINETEST_HID_WAIT_EXPECT failed, last error %lu\n", GetLastError() ); }
- set_hid_expect_( file, line, device, NULL, 0 ); + set_hid_expect_( file, line, device, desc, NULL, 0 ); }
-void send_hid_input_( const char *file, int line, HANDLE device, struct hid_expect *expect, DWORD expect_size ) +void send_hid_input_( const char *file, int line, HANDLE device, struct hid_device_desc *desc, + struct hid_expect *expect, DWORD expect_size ) { - char context[64]; + char buffer[sizeof(*desc) + EXPECT_QUEUE_BUFFER_SIZE]; + SIZE_T size; BOOL ret;
- fill_context_( file, line, context, ARRAY_SIZE(context) ); - ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_SET_CONTEXT, context, ARRAY_SIZE(context), NULL, 0, INFINITE ); + if (desc) memcpy( buffer, desc, sizeof(*desc) ); + else memset( buffer, 0, sizeof(*desc) ); + + fill_context_( file, line, buffer + sizeof(*desc), ARRAY_SIZE(buffer) - sizeof(*desc) ); + size = sizeof(*desc) + strlen( buffer + sizeof(*desc) ) + 1; + ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_SET_CONTEXT, buffer, size, NULL, 0, INFINITE ); ok_(file, line)( ret, "IOCTL_WINETEST_HID_SET_CONTEXT failed, last error %lu\n", GetLastError() ); - ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_SEND_INPUT, expect, expect_size, NULL, 0, INFINITE ); + + if (expect) memcpy( buffer + sizeof(*desc), expect, expect_size ); + else memset( buffer + sizeof(*desc), 0, expect_size ); + + size = sizeof(*desc) + expect_size; + ret = sync_ioctl_( file, line, device, IOCTL_WINETEST_HID_SEND_INPUT, buffer, size, NULL, 0, INFINITE ); ok_(file, line)( ret, "IOCTL_WINETEST_HID_SEND_INPUT failed, last error %lu\n", GetLastError() ); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=116002
Your paranoid android.
=== build (build log) ===
WineRunBuild.pl:error: The build timed out
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/tests/hid.c | 384 ++++++++++++++++++++++++++++++---------- 1 file changed, 292 insertions(+), 92 deletions(-)
diff --git a/dlls/dinput/tests/hid.c b/dlls/dinput/tests/hid.c index 81bf8ed46f8..2d7199fa3e5 100644 --- a/dlls/dinput/tests/hid.c +++ b/dlls/dinput/tests/hid.c @@ -3021,6 +3021,106 @@ struct hidp_kdr /* struct hidp_kdr_node nodes[1] */ };
+static void check_preparsed_data( HANDLE file, const struct hidp_kdr *expect_kdr, + UINT expect_caps_count, const struct hidp_kdr_caps *expect_caps, + UINT expect_nodes_count, const struct hidp_kdr_node *expect_nodes ) +{ + PHIDP_PREPARSED_DATA preparsed_data; + struct hidp_kdr *kdr; + BOOL ret; + UINT i; + + ret = HidD_GetPreparsedData( file, &preparsed_data ); + ok( ret, "HidD_GetPreparsedData failed with error %lu\n", GetLastError() ); + + kdr = (struct hidp_kdr *)preparsed_data; + ok( !strncmp( kdr->magic, expect_kdr->magic, 8 ), "got %s expected %s\n", + debugstr_an(kdr->magic, 8), debugstr_an(expect_kdr->magic, 8) ); + + if (!strncmp( kdr->magic, expect_kdr->magic, 8 )) + { + check_member( *kdr, *expect_kdr, "%04x", usage ); + check_member( *kdr, *expect_kdr, "%04x", usage_page ); + check_member( *kdr, *expect_kdr, "%#x", unknown[0] ); + check_member( *kdr, *expect_kdr, "%#x", unknown[1] ); + check_member( *kdr, *expect_kdr, "%d", input_caps_start ); + check_member( *kdr, *expect_kdr, "%d", input_caps_count ); + check_member( *kdr, *expect_kdr, "%d", input_caps_end ); + check_member( *kdr, *expect_kdr, "%d", input_report_byte_length ); + check_member( *kdr, *expect_kdr, "%d", output_caps_start ); + check_member( *kdr, *expect_kdr, "%d", output_caps_count ); + check_member( *kdr, *expect_kdr, "%d", output_caps_end ); + check_member( *kdr, *expect_kdr, "%d", output_report_byte_length ); + check_member( *kdr, *expect_kdr, "%d", feature_caps_start ); + todo_wine + check_member( *kdr, *expect_kdr, "%d", feature_caps_count ); + check_member( *kdr, *expect_kdr, "%d", feature_caps_end ); + check_member( *kdr, *expect_kdr, "%d", feature_report_byte_length ); + todo_wine + check_member( *kdr, *expect_kdr, "%d", caps_size ); + check_member( *kdr, *expect_kdr, "%d", number_link_collection_nodes ); + + for (i = 0; i < min( expect_caps_count, kdr->caps_size / sizeof(struct hidp_kdr_caps) ); ++i) + { + winetest_push_context( "caps[%u]", i ); + check_member( kdr->caps[i], expect_caps[i], "%04x", usage_page ); + check_member( kdr->caps[i], expect_caps[i], "%d", report_id ); + check_member( kdr->caps[i], expect_caps[i], "%d", start_bit ); + check_member( kdr->caps[i], expect_caps[i], "%d", bit_size ); + check_member( kdr->caps[i], expect_caps[i], "%d", report_count ); + check_member( kdr->caps[i], expect_caps[i], "%d", start_byte ); + check_member( kdr->caps[i], expect_caps[i], "%d", total_bits ); + check_member( kdr->caps[i], expect_caps[i], "%#lx", bit_field ); + check_member( kdr->caps[i], expect_caps[i], "%d", end_byte ); + check_member( kdr->caps[i], expect_caps[i], "%d", link_collection ); + check_member( kdr->caps[i], expect_caps[i], "%04x", link_usage_page ); + check_member( kdr->caps[i], expect_caps[i], "%04x", link_usage ); + check_member( kdr->caps[i], expect_caps[i], "%#lx", flags ); + check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[0] ); + check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[1] ); + check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[2] ); + check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[3] ); + check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[4] ); + check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[5] ); + check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[6] ); + check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[7] ); + check_member( kdr->caps[i], expect_caps[i], "%04x", usage_min ); + check_member( kdr->caps[i], expect_caps[i], "%04x", usage_max ); + check_member( kdr->caps[i], expect_caps[i], "%d", string_min ); + check_member( kdr->caps[i], expect_caps[i], "%d", string_max ); + check_member( kdr->caps[i], expect_caps[i], "%d", designator_min ); + check_member( kdr->caps[i], expect_caps[i], "%d", designator_max ); + check_member( kdr->caps[i], expect_caps[i], "%#x", data_index_min ); + check_member( kdr->caps[i], expect_caps[i], "%#x", data_index_max ); + check_member( kdr->caps[i], expect_caps[i], "%d", null_value ); + check_member( kdr->caps[i], expect_caps[i], "%d", unknown ); + check_member( kdr->caps[i], expect_caps[i], "%ld", logical_min ); + check_member( kdr->caps[i], expect_caps[i], "%ld", logical_max ); + check_member( kdr->caps[i], expect_caps[i], "%ld", physical_min ); + check_member( kdr->caps[i], expect_caps[i], "%ld", physical_max ); + check_member( kdr->caps[i], expect_caps[i], "%#lx", units ); + check_member( kdr->caps[i], expect_caps[i], "%#lx", units_exp ); + winetest_pop_context(); + } + + for (i = 0; i < expect_nodes_count; ++i) + { + struct hidp_kdr_node *nodes = (struct hidp_kdr_node *)((char *)kdr->caps + kdr->caps_size); + winetest_push_context( "nodes[%u]", i ); + check_member( nodes[i], expect_nodes[i], "%04x", usage ); + check_member( nodes[i], expect_nodes[i], "%04x", usage_page ); + check_member( nodes[i], expect_nodes[i], "%d", parent ); + check_member( nodes[i], expect_nodes[i], "%d", number_of_children ); + check_member( nodes[i], expect_nodes[i], "%d", next_sibling ); + check_member( nodes[i], expect_nodes[i], "%d", first_child ); + check_member( nodes[i], expect_nodes[i], "%#lx", collection_type ); + winetest_pop_context(); + } + } + + HidD_FreePreparsedData( preparsed_data ); +} + static void test_hidp_kdr(void) { #include "psh_hid_macros.h" @@ -3240,12 +3340,9 @@ static void test_hidp_kdr(void) }, };
- PHIDP_PREPARSED_DATA preparsed_data; WCHAR device_path[MAX_PATH]; - struct hidp_kdr *kdr; HANDLE file; BOOL ret; - DWORD i;
desc.report_descriptor_len = sizeof(report_desc); memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); @@ -3262,95 +3359,8 @@ static void test_hidp_kdr(void) FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); ok( file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError() );
- ret = HidD_GetPreparsedData( file, &preparsed_data ); - ok( ret, "HidD_GetPreparsedData failed with error %lu\n", GetLastError() ); - - kdr = (struct hidp_kdr *)preparsed_data; - ok( !strncmp( kdr->magic, expect_kdr.magic, 8 ), "got %s expected %s\n", - debugstr_an(kdr->magic, 8), debugstr_an(expect_kdr.magic, 8) ); - - if (!strncmp( kdr->magic, expect_kdr.magic, 8 )) - { - check_member( *kdr, expect_kdr, "%04x", usage ); - check_member( *kdr, expect_kdr, "%04x", usage_page ); - check_member( *kdr, expect_kdr, "%#x", unknown[0] ); - check_member( *kdr, expect_kdr, "%#x", unknown[1] ); - check_member( *kdr, expect_kdr, "%d", input_caps_start ); - check_member( *kdr, expect_kdr, "%d", input_caps_count ); - check_member( *kdr, expect_kdr, "%d", input_caps_end ); - check_member( *kdr, expect_kdr, "%d", input_report_byte_length ); - check_member( *kdr, expect_kdr, "%d", output_caps_start ); - check_member( *kdr, expect_kdr, "%d", output_caps_count ); - check_member( *kdr, expect_kdr, "%d", output_caps_end ); - check_member( *kdr, expect_kdr, "%d", output_report_byte_length ); - check_member( *kdr, expect_kdr, "%d", feature_caps_start ); - todo_wine - check_member( *kdr, expect_kdr, "%d", feature_caps_count ); - check_member( *kdr, expect_kdr, "%d", feature_caps_end ); - check_member( *kdr, expect_kdr, "%d", feature_report_byte_length ); - todo_wine - check_member( *kdr, expect_kdr, "%d", caps_size ); - check_member( *kdr, expect_kdr, "%d", number_link_collection_nodes ); - - for (i = 0; i < min( ARRAY_SIZE(expect_caps), kdr->caps_size / sizeof(struct hidp_kdr_caps) ); ++i) - { - winetest_push_context( "caps[%ld]", i ); - check_member( kdr->caps[i], expect_caps[i], "%04x", usage_page ); - check_member( kdr->caps[i], expect_caps[i], "%d", report_id ); - check_member( kdr->caps[i], expect_caps[i], "%d", start_bit ); - check_member( kdr->caps[i], expect_caps[i], "%d", bit_size ); - check_member( kdr->caps[i], expect_caps[i], "%d", report_count ); - check_member( kdr->caps[i], expect_caps[i], "%d", start_byte ); - check_member( kdr->caps[i], expect_caps[i], "%d", total_bits ); - check_member( kdr->caps[i], expect_caps[i], "%#lx", bit_field ); - check_member( kdr->caps[i], expect_caps[i], "%d", end_byte ); - check_member( kdr->caps[i], expect_caps[i], "%d", link_collection ); - check_member( kdr->caps[i], expect_caps[i], "%04x", link_usage_page ); - check_member( kdr->caps[i], expect_caps[i], "%04x", link_usage ); - check_member( kdr->caps[i], expect_caps[i], "%#lx", flags ); - check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[0] ); - check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[1] ); - check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[2] ); - check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[3] ); - check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[4] ); - check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[5] ); - check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[6] ); - check_member( kdr->caps[i], expect_caps[i], "%#lx", padding[7] ); - check_member( kdr->caps[i], expect_caps[i], "%04x", usage_min ); - check_member( kdr->caps[i], expect_caps[i], "%04x", usage_max ); - check_member( kdr->caps[i], expect_caps[i], "%d", string_min ); - check_member( kdr->caps[i], expect_caps[i], "%d", string_max ); - check_member( kdr->caps[i], expect_caps[i], "%d", designator_min ); - check_member( kdr->caps[i], expect_caps[i], "%d", designator_max ); - check_member( kdr->caps[i], expect_caps[i], "%#x", data_index_min ); - check_member( kdr->caps[i], expect_caps[i], "%#x", data_index_max ); - check_member( kdr->caps[i], expect_caps[i], "%d", null_value ); - check_member( kdr->caps[i], expect_caps[i], "%d", unknown ); - check_member( kdr->caps[i], expect_caps[i], "%ld", logical_min ); - check_member( kdr->caps[i], expect_caps[i], "%ld", logical_max ); - check_member( kdr->caps[i], expect_caps[i], "%ld", physical_min ); - check_member( kdr->caps[i], expect_caps[i], "%ld", physical_max ); - check_member( kdr->caps[i], expect_caps[i], "%#lx", units ); - check_member( kdr->caps[i], expect_caps[i], "%#lx", units_exp ); - winetest_pop_context(); - } - - for (i = 0; i < ARRAY_SIZE(expect_nodes); ++i) - { - struct hidp_kdr_node *nodes = (struct hidp_kdr_node *)((char *)kdr->caps + kdr->caps_size); - winetest_push_context( "nodes[%ld]", i ); - check_member( nodes[i], expect_nodes[i], "%04x", usage ); - check_member( nodes[i], expect_nodes[i], "%04x", usage_page ); - check_member( nodes[i], expect_nodes[i], "%d", parent ); - check_member( nodes[i], expect_nodes[i], "%d", number_of_children ); - check_member( nodes[i], expect_nodes[i], "%d", next_sibling ); - check_member( nodes[i], expect_nodes[i], "%d", first_child ); - check_member( nodes[i], expect_nodes[i], "%#lx", collection_type ); - winetest_pop_context(); - } - } - - HidD_FreePreparsedData( preparsed_data ); + check_preparsed_data( file, &expect_kdr, ARRAY_SIZE(expect_caps), expect_caps, + ARRAY_SIZE(expect_nodes), expect_nodes );
CloseHandle( file );
@@ -3730,6 +3740,195 @@ done: bus_device_stop(); }
+static void test_hid_multiple_tlc(void) +{ +#include "psh_hid_macros.h" + const unsigned char report_desc[] = + { + USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), + USAGE(1, HID_USAGE_GENERIC_JOYSTICK), + COLLECTION(1, Application), + USAGE(1, HID_USAGE_GENERIC_JOYSTICK), + COLLECTION(1, Physical), + REPORT_ID(1, 1), + + USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON), + USAGE_MINIMUM(1, 1), + USAGE_MAXIMUM(1, 2), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 1), + REPORT_SIZE(1, 1), + REPORT_COUNT(1, 8), + INPUT(1, Data|Var|Abs), + + USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), + USAGE(1, HID_USAGE_GENERIC_X), + USAGE(1, HID_USAGE_GENERIC_Y), + REPORT_SIZE(1, 16), + REPORT_COUNT(1, 2), + LOGICAL_MINIMUM(2, -10), + LOGICAL_MAXIMUM(2, +10), + INPUT(1, Data|Var|Rel), + END_COLLECTION, + END_COLLECTION, + + USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), + USAGE(1, HID_USAGE_GENERIC_GAMEPAD), + COLLECTION(1, Application), + USAGE(1, HID_USAGE_GENERIC_GAMEPAD), + COLLECTION(1, Physical), + REPORT_ID(1, 2), + + USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON), + USAGE_MINIMUM(1, 1), + USAGE_MAXIMUM(1, 40), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 1), + REPORT_SIZE(1, 1), + REPORT_COUNT(1, 40), + INPUT(1, Data|Var|Abs), + END_COLLECTION, + END_COLLECTION, + }; + C_ASSERT(sizeof(report_desc) < MAX_HID_DESCRIPTOR_LEN); +#include "pop_hid_macros.h" + + struct hid_device_desc desc = + { + .caps = { .InputReportByteLength = 7 }, + .attributes = default_attributes, + }; + + static const struct hidp_kdr expect_kdr_joystick = + { + .magic = "HidP KDR", + .usage = 0x04, + .usage_page = 0x01, + .input_caps_count = 3, + .input_caps_end = 3, + .input_report_byte_length = 6, + .output_caps_start = 3, + .output_caps_end = 3, + .feature_caps_start = 3, + .feature_caps_end = 3, + .caps_size = 312, + .number_link_collection_nodes = 2, + }; + static const struct hidp_kdr expect_kdr_gamepad = + { + .magic = "HidP KDR", + .usage = 0x05, + .usage_page = 0x01, + .input_caps_count = 1, + .input_caps_end = 1, + .input_report_byte_length = 6, + .output_caps_start = 1, + .output_caps_end = 1, + .feature_caps_start = 1, + .feature_caps_end = 1, + .caps_size = 104, + .number_link_collection_nodes = 2, + }; + static const struct hidp_kdr_caps expect_caps_joystick[] = + { + { + .usage_page = 9, .report_id = 1, .bit_size = 1, .report_count = 8, .start_byte = 1, .total_bits = 8, + .bit_field = 2, .end_byte = 2, .link_collection = 1, .link_usage_page = 0x01, .link_usage = 0x04, .flags = 0x1c, + .usage_min = 1, .usage_max = 2, .data_index_max = 1, + }, + { + .usage_page = 1, .report_id = 1, .bit_size = 16, .report_count = 1, .start_byte = 4, .total_bits = 16, + .bit_field = 6, .end_byte = 6, .link_collection = 1, .link_usage_page = 0x01, .link_usage = 0x04, + .usage_min = 0x31, .usage_max = 0x31, .data_index_min = 2, .data_index_max = 2, .logical_min = -10, .logical_max = +10, + }, + { + .usage_page = 1, .report_id = 1, .bit_size = 16, .report_count = 1, .start_byte = 2, .total_bits = 16, + .bit_field = 6, .end_byte = 4, .link_collection = 1, .link_usage_page = 0x01, .link_usage = 0x04, + .usage_min = 0x30, .usage_max = 0x30, .data_index_min = 3, .data_index_max = 3, .logical_min = -10, .logical_max = +10, + }, + }; + static const struct hidp_kdr_caps expect_caps_gamepad[] = + { + { + .usage_page = 9, .report_id = 2, .bit_size = 1, .report_count = 40, .start_byte = 1, .total_bits = 40, + .bit_field = 2, .end_byte = 6, .link_collection = 1, .link_usage_page = 0x01, .link_usage = 0x05, .flags = 0x1c, + .usage_min = 0x01, .usage_max = 0x28, .data_index_max = 0x27, + }, + }; + static const struct hidp_kdr_node expect_nodes_joystick[] = + { + { + .usage = 0x04, + .usage_page = 0x01, + .number_of_children = 1, + .first_child = 1, + .collection_type = 0x1, + }, + { + .usage = 0x04, + .usage_page = 0x01, + }, + }; + static const struct hidp_kdr_node expect_nodes_gamepad[] = + { + { + .usage = 0x05, + .usage_page = 0x01, + .number_of_children = 1, + .first_child = 1, + .collection_type = 1, + }, + { + .usage = 0x05, + .usage_page = 0x01, + }, + }; + + WCHAR device_path[MAX_PATH]; + HANDLE file; + BOOL ret; + + desc.report_descriptor_len = sizeof(report_desc); + memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) ); + + if (!hid_device_start( &desc )) goto done; + + swprintf( device_path, MAX_PATH, L"\\?\hid#vid_%04x&pid_%04x&col01", desc.attributes.VendorID, + desc.attributes.ProductID ); + ret = find_hid_device_path( device_path ); + todo_wine + ok( ret, "Failed to find HID device matching %s\n", debugstr_w( device_path ) ); + if (!ret) goto done; + + file = CreateFileW( device_path, FILE_READ_ACCESS | FILE_WRITE_ACCESS, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); + ok( file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError() ); + check_preparsed_data( file, &expect_kdr_joystick, ARRAY_SIZE(expect_caps_joystick), expect_caps_joystick, + ARRAY_SIZE(expect_nodes_joystick), expect_nodes_joystick ); + CloseHandle( file ); + + swprintf( device_path, MAX_PATH, L"\\?\hid#vid_%04x&pid_%04x&col02", desc.attributes.VendorID, + desc.attributes.ProductID ); + ret = find_hid_device_path( device_path ); + ok( ret, "Failed to find HID device matching %s\n", debugstr_w( device_path ) ); + + file = CreateFileW( device_path, FILE_READ_ACCESS | FILE_WRITE_ACCESS, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); + ok( file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError() ); + check_preparsed_data( file, &expect_kdr_gamepad, ARRAY_SIZE(expect_caps_gamepad), expect_caps_gamepad, + ARRAY_SIZE(expect_nodes_gamepad), expect_nodes_gamepad ); + CloseHandle( file ); + + swprintf( device_path, MAX_PATH, L"\\?\hid#vid_%04x&pid_%04x&col03", desc.attributes.VendorID, + desc.attributes.ProductID ); + ret = find_hid_device_path( device_path ); + ok( !ret, "Failed to find HID device matching %s\n", debugstr_w( device_path ) ); + +done: + hid_device_stop( &desc ); +} + START_TEST( hid ) { if (!dinput_test_init()) return; @@ -3742,6 +3941,7 @@ START_TEST( hid ) test_hid_driver( 1, FALSE ); test_hid_driver( 0, TRUE ); test_hid_driver( 1, TRUE ); + test_hid_multiple_tlc();
done: bus_device_stop();
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=116003
Your paranoid android.
=== build (build log) ===
WineRunBuild.pl:error: The build timed out