From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ntoskrnl.exe/pnp.c | 40 ++++++++++++++++------------ dlls/ntoskrnl.exe/tests/driver_pnp.c | 2 +- 2 files changed, 24 insertions(+), 18 deletions(-)
diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index 25a52d7d219..e1c34ab57c3 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -883,13 +883,12 @@ NTSTATUS WINAPI IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *cla 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]; - SP_DEVICE_INTERFACE_DETAIL_DATA_W *data; NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING device_path; struct device_interface *iface; struct wine_rb_entry *entry; - DWORD required; HDEVINFO set; + WCHAR *p;
TRACE("device %p, class_guid %s, refstr %s, symbolic_link %p.\n", device, debugstr_guid(class_guid), debugstr_us(refstr), symbolic_link); @@ -910,22 +909,31 @@ NTSTATUS WINAPI IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *cla if (!SetupDiCreateDeviceInterfaceW( set, &sp_device, class_guid, refstr ? refstr->Buffer : NULL, 0, &sp_iface )) return STATUS_UNSUCCESSFUL;
- required = 0; - SetupDiGetDeviceInterfaceDetailW( set, &sp_iface, NULL, 0, &required, NULL ); - if (required == 0) return STATUS_UNSUCCESSFUL; + /* setupapi mangles the case; construct the interface path manually. */
- data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, required ); - data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W); + device_path.Length = (4 + wcslen( device_instance_id ) + 1 + 38) * sizeof(WCHAR); + if (refstr) + device_path.Length += sizeof(WCHAR) + refstr->Length; + device_path.MaximumLength = device_path.Length + sizeof(WCHAR);
- if (!SetupDiGetDeviceInterfaceDetailW( set, &sp_iface, data, required, NULL, NULL )) + 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, + 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++) { - HeapFree( GetProcessHeap(), 0, data ); - return STATUS_UNSUCCESSFUL; + if (*p == '\') + *p = '#'; + } + if (refstr) + { + *p++ = '\'; + wcscpy( p, refstr->Buffer ); }
- data->DevicePath[1] = '?'; - TRACE("Returning path %s.\n", debugstr_w(data->DevicePath)); - RtlCreateUnicodeString( &device_path, data->DevicePath); + TRACE("Returning path %s.\n", debugstr_us(&device_path));
entry = wine_rb_get( &device_interfaces, &device_path ); if (entry) @@ -937,7 +945,7 @@ NTSTATUS WINAPI IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *cla else { iface = heap_alloc_zero( sizeof(struct device_interface) ); - RtlCreateUnicodeString(&iface->symbolic_link, data->DevicePath); + RtlDuplicateUnicodeString( 1, &device_path, &iface->symbolic_link ); if (wine_rb_put( &device_interfaces, &iface->symbolic_link, &iface->entry )) ERR("Failed to insert interface %s into tree.\n", debugstr_us(&iface->symbolic_link)); } @@ -945,9 +953,7 @@ NTSTATUS WINAPI IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *cla iface->device = device; iface->interface_class = *class_guid; if (symbolic_link) - RtlCreateUnicodeString( symbolic_link, data->DevicePath); - - HeapFree( GetProcessHeap(), 0, data ); + RtlDuplicateUnicodeString( 1, &device_path, symbolic_link );
RtlFreeUnicodeString( &device_path );
diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c index 50b3ce29d58..b8876dd60d1 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -285,7 +285,7 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device_obj, IRP *irp) "Got length %u.\n", device->child_symlink.Length); ok(device->child_symlink.MaximumLength == sizeof(expect_symlink), "Got maximum length %u.\n", device->child_symlink.MaximumLength); - todo_wine ok(!kmemcmp(device->child_symlink.Buffer, expect_symlink, device->child_symlink.MaximumLength), + ok(!kmemcmp(device->child_symlink.Buffer, expect_symlink, device->child_symlink.MaximumLength), "Got symlink "%ls".\n", device->child_symlink.Buffer);
IoSetDeviceInterfaceState(&device->child_symlink, TRUE);