From: Connor McAdams <cmcadams@codeweavers.com> Signed-off-by: Connor McAdams <cmcadams@codeweavers.com> --- dlls/dinput/tests/driver_bus.c | 18 +++++++++++++++--- dlls/dinput/tests/driver_hid.c | 33 +++++++++++++++++++++++++++++++-- dlls/dinput/tests/driver_hid.h | 1 + 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/dlls/dinput/tests/driver_bus.c b/dlls/dinput/tests/driver_bus.c index e8338e49711..780db34ab62 100644 --- a/dlls/dinput/tests/driver_bus.c +++ b/dlls/dinput/tests/driver_bus.c @@ -563,7 +563,8 @@ static NTSTATUS remove_child_device( struct func_device *impl, DEVICE_OBJECT *de for (i = 0; i < impl->devices->Count; ++i) if (impl->devices->Objects[i] == device) break; if (i == impl->devices->Count) status = STATUS_NOT_FOUND; - else impl->devices->Objects[i] = impl->devices->Objects[impl->devices->Count--]; + else impl->devices->Objects[i] = impl->devices->Objects[--impl->devices->Count]; + if (status != STATUS_NOT_FOUND) impl->devices->Objects[impl->devices->Count + 1] = NULL; KeReleaseSpinLock( &impl->base.lock, irql ); return status; @@ -587,8 +588,16 @@ static NTSTATUS append_child_device( struct func_device *impl, DEVICE_OBJECT *de return status; } +static BOOL check_device_match(struct phys_device *phys, const WCHAR *device_id, const WCHAR *instance_id) +{ + if (instance_id && wcscmp( phys->instance_id, instance_id )) + return FALSE; + return !wcscmp( phys->device_id, device_id ); +} + static DEVICE_OBJECT *find_child_device( struct func_device *impl, struct hid_device_desc *desc ) { + const WCHAR *instance_id = desc->instance_id[0] ? desc->instance_id : NULL; DEVICE_OBJECT *device = NULL, **devices; WCHAR device_id[MAX_PATH]; KIRQL irql; @@ -603,7 +612,7 @@ static DEVICE_OBJECT *find_child_device( struct func_device *impl, struct hid_de for (i = 0; i < impl->devices->Count; ++i) { struct phys_device *phys = pdo_from_DEVICE_OBJECT( (device = devices[i]) ); - if (!wcscmp( phys->device_id, device_id )) break; + if (check_device_match(phys, device_id, instance_id)) break; else device = NULL; } KeReleaseSpinLock( &impl->base.lock, irql ); @@ -907,7 +916,10 @@ static NTSTATUS create_child_pdo( DEVICE_OBJECT *device, struct hid_device_desc desc->attributes.ProductID ); /* use a different device ID so that driver cache select the polled driver */ if (desc->is_polled) wcscat( impl->device_id, L"&POLL" ); - swprintf( impl->instance_id, MAX_PATH, L"0&0000&0" ); + if (desc->instance_id[0]) + swprintf( impl->instance_id, MAX_PATH, L"%s", desc->instance_id ); + else + swprintf( impl->instance_id, MAX_PATH, L"0&0000&0" ); impl->base.is_phys = TRUE; impl->fdo = fdo; diff --git a/dlls/dinput/tests/driver_hid.c b/dlls/dinput/tests/driver_hid.c index 7b20af07493..f98ec2edb7b 100644 --- a/dlls/dinput/tests/driver_hid.c +++ b/dlls/dinput/tests/driver_hid.c @@ -42,8 +42,12 @@ static DRIVER_OBJECT *expect_driver; +static KSPIN_LOCK driver_data_lock; +static struct list device_list = LIST_INIT(device_list); + struct hid_device { + struct list entry; DEVICE_OBJECT *expect_bus_pdo; DEVICE_OBJECT *expect_hid_fdo; struct hid_device *expect_hid_ext; @@ -54,11 +58,27 @@ static void check_device( DEVICE_OBJECT *device ) { HID_DEVICE_EXTENSION *ext = device->DeviceExtension; struct hid_device *impl = ext->MiniDeviceExtension; + KIRQL irql; ok( device == impl->expect_hid_fdo, "got device %p\n", device ); ok( device->DriverObject == expect_driver, "got DriverObject %p\n", device->DriverObject ); - if (!device->NextDevice) ok( device == impl->expect_hid_fdo, "got device %p\n", device ); - else ok( device->NextDevice == impl->expect_hid_fdo, "got NextDevice %p\n", device->NextDevice ); + + KeAcquireSpinLock( &driver_data_lock, &irql ); + if (!device->NextDevice) + { + struct hid_device *impl_tail = LIST_ENTRY( list_tail(&device_list), struct hid_device, entry ); + + ok( device == impl_tail->expect_hid_fdo, "got device %p\n", device ); + } + else + { + struct hid_device *next_impl = LIST_ENTRY( list_next(&device_list, &impl->entry), struct hid_device, entry ); + HID_DEVICE_EXTENSION *next_ext = device->NextDevice->DeviceExtension; + struct hid_device *next_ext_impl = next_ext->MiniDeviceExtension; + + ok( next_impl == next_ext_impl, "got NextDevice %p.\n", device->NextDevice ); + } + KeReleaseSpinLock( &driver_data_lock, irql ); ok( !device->AttachedDevice, "got AttachedDevice %p\n", device->AttachedDevice ); ok( ext->MiniDeviceExtension == impl->expect_hid_ext, "got MiniDeviceExtension %p\n", ext->MiniDeviceExtension ); @@ -113,6 +133,7 @@ static NTSTATUS WINAPI driver_pnp( DEVICE_OBJECT *device, IRP *irp ) HID_DEVICE_EXTENSION *ext = device->DeviceExtension; struct hid_device *impl = ext->MiniDeviceExtension; ULONG code = stack->MinorFunction; + KIRQL irql; if (winetest_debug > 1) trace( "%s: device %p, code %#lx %s\n", __func__, device, code, debugstr_pnp(code) ); @@ -126,6 +147,9 @@ static NTSTATUS WINAPI driver_pnp( DEVICE_OBJECT *device, IRP *irp ) IoSetDeviceInterfaceState( &impl->control_symlink, FALSE ); RtlFreeUnicodeString( &impl->control_symlink ); irp->IoStatus.Status = STATUS_SUCCESS; + KeAcquireSpinLock( &driver_data_lock, &irql ); + list_remove( &impl->entry ); + KeReleaseSpinLock( &driver_data_lock, irql ); break; case IRP_MN_STOP_DEVICE: case IRP_MN_SURPRISE_REMOVAL: @@ -229,12 +253,16 @@ static NTSTATUS WINAPI driver_add_device( DRIVER_OBJECT *driver, DEVICE_OBJECT * struct hid_device *impl = ext->MiniDeviceExtension; DEVICE_OBJECT *bus_pdo = ext->PhysicalDeviceObject; NTSTATUS status; + KIRQL irql; if (winetest_debug > 1) trace( "%s: driver %p, device %p\n", __func__, driver, device ); impl->expect_hid_fdo = device; impl->expect_bus_pdo = ext->PhysicalDeviceObject; impl->expect_hid_ext = ext->MiniDeviceExtension; + KeAcquireSpinLock( &driver_data_lock, &irql ); + list_add_head( &device_list, &impl->entry ); + KeReleaseSpinLock( &driver_data_lock, irql ); todo_wine ok( impl->expect_bus_pdo->AttachedDevice == device, "got AttachedDevice %p\n", bus_pdo->AttachedDevice ); @@ -286,6 +314,7 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *registry ) NTSTATUS status; expect_driver = driver; + KeInitializeSpinLock( &driver_data_lock ); if ((status = winetest_init())) return status; if (winetest_debug > 1) trace( "%s: driver %p\n", __func__, driver ); diff --git a/dlls/dinput/tests/driver_hid.h b/dlls/dinput/tests/driver_hid.h index 8ba01d14b1e..e4f8f00a07a 100644 --- a/dlls/dinput/tests/driver_hid.h +++ b/dlls/dinput/tests/driver_hid.h @@ -92,6 +92,7 @@ struct hid_device_desc struct hid_expect expect[64]; ULONG context_size; char context[64]; + WCHAR instance_id[MAX_PATH]; }; /* kernel/user shared data */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10364