From: Alexander Morozov amorozov@etersoft.ru
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57588 --- dlls/ntoskrnl.exe/pnp.c | 73 ++++++++++------------------ dlls/ntoskrnl.exe/tests/driver_pnp.c | 16 +++--- 2 files changed, 34 insertions(+), 55 deletions(-)
diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index e3825722ad6..f5954970b82 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -521,21 +521,18 @@ NTSTATUS WINAPI IoGetDevicePropertyData( DEVICE_OBJECT *device, const DEVPROPKEY LCID lcid, ULONG flags, ULONG size, void *data, ULONG *required_size, DEVPROPTYPE *property_type ) { + struct wine_device *wine_device = CONTAINING_RECORD(device, struct wine_device, device_obj); SP_DEVINFO_DATA sp_device = {sizeof(sp_device)}; - WCHAR device_instance_id[MAX_DEVICE_ID_LEN]; HDEVINFO set; - NTSTATUS status;
TRACE( "device %p, property_key %s, lcid %#lx, flags %#lx, size %lu, data %p, required_size %p, property_type %p\n", device, debugstr_propkey( property_key ), lcid, flags, size, data, required_size, property_type );
+ if (!wine_device->instance_id) return STATUS_INVALID_DEVICE_REQUEST; if (lcid == LOCALE_SYSTEM_DEFAULT || lcid == LOCALE_USER_DEFAULT) return STATUS_INVALID_PARAMETER; if (lcid != LOCALE_NEUTRAL) FIXME( "Only LOCALE_NEUTRAL is supported\n" );
- status = get_device_instance_id( device, device_instance_id ); - if (status != STATUS_SUCCESS) return status; - set = SetupDiCreateDeviceInfoList( &GUID_NULL, NULL ); if (set == INVALID_HANDLE_VALUE) { @@ -543,7 +540,7 @@ NTSTATUS WINAPI IoGetDevicePropertyData( DEVICE_OBJECT *device, const DEVPROPKEY return GetLastError(); }
- if (!SetupDiOpenDeviceInfoW( set, device_instance_id, NULL, 0, &sp_device )) + if (!SetupDiOpenDeviceInfoW( set, wine_device->instance_id, NULL, 0, &sp_device )) { ERR( "Failed to open device, error %#lx.\n", GetLastError() ); SetupDiDestroyDeviceInfoList( set ); @@ -569,38 +566,31 @@ NTSTATUS WINAPI IoGetDevicePropertyData( DEVICE_OBJECT *device, const DEVPROPKEY NTSTATUS WINAPI IoGetDeviceProperty( DEVICE_OBJECT *device, DEVICE_REGISTRY_PROPERTY property, ULONG length, void *buffer, ULONG *needed ) { + struct wine_device *wine_device = CONTAINING_RECORD(device, struct wine_device, device_obj); SP_DEVINFO_DATA sp_device = {sizeof(sp_device)}; - WCHAR device_instance_id[MAX_DEVICE_ID_LEN]; DWORD sp_property = -1; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; HDEVINFO set;
TRACE("device %p, property %u, length %lu, buffer %p, needed %p.\n", device, property, length, buffer, needed);
+ if (!wine_device->instance_id) return STATUS_INVALID_DEVICE_REQUEST; + switch (property) { case DevicePropertyEnumeratorName: { - WCHAR *id, *ptr; + const WCHAR *id = wine_device->instance_id; + const WCHAR *ptr = wcschr( id, '\' ); + size_t len = ptr ? ptr - id : wcslen(id);
- status = get_device_id( device, BusQueryDeviceID, &id ); - if (status != STATUS_SUCCESS) - { - ERR("Failed to get instance ID, status %#lx.\n", status); - break; - } - - ptr = wcschr( id, '\' ); - if (ptr) *ptr = 0; - - *needed = sizeof(WCHAR) * (lstrlenW(id) + 1); + *needed = sizeof(WCHAR) * (len + 1); if (length >= *needed) - memcpy( buffer, id, *needed ); + wcsncpy_s( buffer, len + 1, id, len ); else status = STATUS_BUFFER_TOO_SMALL;
- ExFreePool( id ); return status; } case DevicePropertyPhysicalDeviceObjectName: @@ -688,16 +678,13 @@ NTSTATUS WINAPI IoGetDeviceProperty( DEVICE_OBJECT *device, DEVICE_REGISTRY_PROP return STATUS_NOT_IMPLEMENTED; }
- if ((status = get_device_instance_id( device, device_instance_id ))) - return status; - if ((set = SetupDiCreateDeviceInfoList( &GUID_NULL, NULL )) == INVALID_HANDLE_VALUE) { ERR("Failed to create device list, error %#lx.\n", GetLastError()); return GetLastError(); }
- if (!SetupDiOpenDeviceInfoW( set, device_instance_id, NULL, 0, &sp_device)) + if (!SetupDiOpenDeviceInfoW( set, wine_device->instance_id, NULL, 0, &sp_device )) { ERR("Failed to open device, error %#lx.\n", GetLastError()); SetupDiDestroyDeviceInfoList( set ); @@ -886,9 +873,8 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( UNICODE_STRING *name, BOOLEAN enable NTSTATUS WINAPI IoSetDevicePropertyData( DEVICE_OBJECT *device, const DEVPROPKEY *property_key, LCID lcid, ULONG flags, DEVPROPTYPE type, ULONG size, void *data ) { + struct wine_device *wine_device = CONTAINING_RECORD(device, struct wine_device, device_obj); SP_DEVINFO_DATA sp_device = {sizeof(sp_device)}; - WCHAR device_instance_id[MAX_DEVICE_ID_LEN]; - NTSTATUS status; HDEVINFO set;
TRACE( "device %p, property_key %s, lcid %#lx, flags %#lx, type %#lx, size %lu, data %p.\n", @@ -896,17 +882,16 @@ NTSTATUS WINAPI IoSetDevicePropertyData( DEVICE_OBJECT *device, const DEVPROPKEY
/* flags is always treated as PLUGPLAY_PROPERTY_PERSISTENT starting with Win 8 / 2012 */
+ if (!wine_device->instance_id) return STATUS_INVALID_DEVICE_REQUEST; if (lcid != LOCALE_NEUTRAL) FIXME( "only LOCALE_NEUTRAL is supported\n" );
- if ((status = get_device_instance_id( device, device_instance_id ))) return status; - if ((set = SetupDiCreateDeviceInfoList( &GUID_NULL, NULL )) == INVALID_HANDLE_VALUE) { ERR( "Failed to create device list, error %#lx.\n", GetLastError() ); return GetLastError(); }
- if (!SetupDiOpenDeviceInfoW( set, device_instance_id, NULL, 0, &sp_device )) + if (!SetupDiOpenDeviceInfoW( set, wine_device->instance_id, NULL, 0, &sp_device )) { ERR( "Failed to open device, error %#lx.\n", GetLastError() ); SetupDiDestroyDeviceInfoList( set ); @@ -931,9 +916,9 @@ NTSTATUS WINAPI IoSetDevicePropertyData( DEVICE_OBJECT *device, const DEVPROPKEY NTSTATUS WINAPI IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *class_guid, UNICODE_STRING *refstr, UNICODE_STRING *symbolic_link) { + struct wine_device *wine_device = CONTAINING_RECORD(device, struct wine_device, device_obj); SP_DEVICE_INTERFACE_DATA sp_iface = {sizeof(sp_iface)}; SP_DEVINFO_DATA sp_device = {sizeof(sp_device)}; - WCHAR device_instance_id[MAX_DEVICE_ID_LEN]; NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING device_path; struct device_interface *iface; @@ -944,16 +929,15 @@ NTSTATUS WINAPI IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *cla TRACE("device %p, class_guid %s, refstr %s, symbolic_link %p.\n", device, debugstr_guid(class_guid), debugstr_us(refstr), symbolic_link);
- if ((status = get_device_instance_id( device, device_instance_id ))) - return status; + if (!wine_device->instance_id) return STATUS_INVALID_DEVICE_REQUEST;
set = SetupDiGetClassDevsW( class_guid, NULL, NULL, DIGCF_DEVICEINTERFACE ); if (set == INVALID_HANDLE_VALUE) return STATUS_UNSUCCESSFUL;
- if (!SetupDiCreateDeviceInfoW( set, device_instance_id, class_guid, NULL, NULL, 0, &sp_device ) - && !SetupDiOpenDeviceInfoW( set, device_instance_id, NULL, 0, &sp_device )) + if (!SetupDiCreateDeviceInfoW( set, wine_device->instance_id, class_guid, NULL, NULL, 0, &sp_device ) + && !SetupDiOpenDeviceInfoW( set, wine_device->instance_id, NULL, 0, &sp_device )) { - ERR("Failed to create device %s, error %#lx.\n", debugstr_w(device_instance_id), GetLastError()); + ERR("Failed to create device %s, error %#lx.\n", debugstr_w(wine_device->instance_id), GetLastError()); return GetLastError(); }
@@ -962,7 +946,7 @@ NTSTATUS WINAPI IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *cla
/* setupapi mangles the case; construct the interface path manually. */
- device_path.Length = (4 + wcslen( device_instance_id ) + 1 + 38) * sizeof(WCHAR); + device_path.Length = (4 + wcslen( wine_device->instance_id ) + 1 + 38) * sizeof(WCHAR); if (refstr) device_path.Length += sizeof(WCHAR) + refstr->Length; device_path.MaximumLength = device_path.Length + sizeof(WCHAR); @@ -970,7 +954,7 @@ NTSTATUS WINAPI IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *cla device_path.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, device_path.MaximumLength ); swprintf( device_path.Buffer, device_path.MaximumLength / sizeof(WCHAR), L"\??\%s#{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", - device_instance_id, class_guid->Data1, class_guid->Data2, class_guid->Data3, + wine_device->instance_id, class_guid->Data1, class_guid->Data2, class_guid->Data3, class_guid->Data4[0], class_guid->Data4[1], class_guid->Data4[2], class_guid->Data4[3], class_guid->Data4[4], class_guid->Data4[5], class_guid->Data4[6], class_guid->Data4[7] ); for (p = device_path.Buffer + 4; *p; p++) @@ -1071,22 +1055,17 @@ NTSTATUS WINAPI IoReportTargetDeviceChangeAsynchronous( DEVICE_OBJECT *device, v */ NTSTATUS WINAPI IoOpenDeviceRegistryKey( DEVICE_OBJECT *device, ULONG type, ACCESS_MASK access, HANDLE *key ) { + struct wine_device *wine_device = CONTAINING_RECORD(device, struct wine_device, device_obj); SP_DEVINFO_DATA sp_device = {sizeof(sp_device)}; - WCHAR device_instance_id[MAX_DEVICE_ID_LEN]; - NTSTATUS status; HDEVINFO set;
TRACE("device %p, type %#lx, access %#lx, key %p.\n", device, type, access, key);
- if ((status = get_device_instance_id( device, device_instance_id ))) - { - ERR("Failed to get device instance ID, error %#lx.\n", status); - return status; - } + if (!wine_device->instance_id) return STATUS_INVALID_PARAMETER;
set = SetupDiCreateDeviceInfoList( &GUID_NULL, NULL );
- SetupDiOpenDeviceInfoW( set, device_instance_id, NULL, 0, &sp_device ); + SetupDiOpenDeviceInfoW( set, wine_device->instance_id, NULL, 0, &sp_device );
*key = SetupDiOpenDevRegKey( set, &sp_device, DICS_FLAG_GLOBAL, 0, type, access ); SetupDiDestroyDeviceInfoList( set ); diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c index a5fb145c387..e364fecc49a 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -292,7 +292,7 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device_obj, IRP *irp)
query_id_count = 0; status = IoRegisterDeviceInterface(device_obj, &child_class, NULL, &device->child_symlink); - todo_wine ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); + ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); ok(!status, "Failed to register interface, status %#lx.\n", status); ok(device->child_symlink.Length == sizeof(expect_symlink) - sizeof(WCHAR), "Got length %u.\n", device->child_symlink.Length); @@ -710,12 +710,12 @@ static void test_child_device_properties(DEVICE_OBJECT *device)
query_id_count = 0; status = IoSetDevicePropertyData(device, key, LOCALE_NEUTRAL, 0, type, size, &value); - todo_wine ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); + ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); ok(status == STATUS_SUCCESS, "failed to set device property, status %#lx\n", status);
query_id_count = 0; status = IoGetDevicePropertyData(device, key, LOCALE_NEUTRAL, 0, size, &stored_value, &req_size, &stored_type); - todo_wine ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); + ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); ok(status == STATUS_SUCCESS, "failed to get device property, status %#lx\n", status); ok(req_size == size, "expected required size %lu, got %lu\n", req_size, size); ok(stored_type == type, "expected DEVPROPTYPE value %#lx, got %#lx\n", type, stored_type); @@ -723,7 +723,7 @@ static void test_child_device_properties(DEVICE_OBJECT *device)
query_id_count = 0; status = IoSetDevicePropertyData(device, key, LOCALE_NEUTRAL, 0, type, 0, NULL); - todo_wine ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); + ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); ok(status == STATUS_SUCCESS, "failed to delete device property, status %#lx\n", status); }
@@ -735,7 +735,7 @@ static void test_enumerator_name(void) NTSTATUS status;
status = IoGetDeviceProperty(bus_fdo, DevicePropertyEnumeratorName, sizeof(buffer), buffer, &req_size); - todo_wine ok(status == STATUS_INVALID_DEVICE_REQUEST, "got unexpected status %#lx\n", status); + ok(status == STATUS_INVALID_DEVICE_REQUEST, "got unexpected status %#lx\n", status);
req_size = 0; memset(buffer, 0, sizeof(buffer)); @@ -755,7 +755,7 @@ static void test_child_enumerator_name(DEVICE_OBJECT *device)
query_id_count = 0; status = IoGetDeviceProperty(device, DevicePropertyEnumeratorName, sizeof(buffer), buffer, &req_size); - todo_wine ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); + ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); ok(status == STATUS_SUCCESS, "IoGetDeviceProperty failed: %#lx\n", status); ok(req_size == sizeof(wine), "unexpected size %lu\n", req_size); if (status == STATUS_SUCCESS) @@ -774,7 +774,7 @@ static void test_device_registry_key(void) DWORD size;
status = IoOpenDeviceRegistryKey(bus_fdo, PLUGPLAY_REGKEY_DEVICE, KEY_ALL_ACCESS, &hkey); - todo_wine ok(status == STATUS_INVALID_PARAMETER, "got unexpected status %#lx\n", status); + ok(status == STATUS_INVALID_PARAMETER, "got unexpected status %#lx\n", status);
status = IoOpenDeviceRegistryKey(bus_pdo, PLUGPLAY_REGKEY_DEVICE, KEY_ALL_ACCESS, &hkey); ok(status == STATUS_SUCCESS, "IoOpenDeviceRegistryKey failed: %#lx\n", status); @@ -815,7 +815,7 @@ static void test_child_device_registry_key(DEVICE_OBJECT *device)
query_id_count = 0; status = IoOpenDeviceRegistryKey(device, PLUGPLAY_REGKEY_DEVICE, KEY_ALL_ACCESS, &hkey); - todo_wine ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); + ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); ok(status == STATUS_SUCCESS, "IoOpenDeviceRegistryKey failed: %#lx\n", status); if (status == STATUS_SUCCESS) {