If device instance id is not unique, prepend information from parent bus device Modified: trunk/reactos/ntoskrnl/io/pnpmgr.c _____
Modified: trunk/reactos/ntoskrnl/io/pnpmgr.c --- trunk/reactos/ntoskrnl/io/pnpmgr.c 2005-09-24 11:43:23 UTC (rev 18024) +++ trunk/reactos/ntoskrnl/io/pnpmgr.c 2005-09-24 13:19:25 UTC (rev 18025) @@ -1294,6 +1294,7 @@
HANDLE InstanceKey = NULL; UNICODE_STRING ValueName; DEVICE_CAPABILITIES DeviceCapabilities; + PKEY_VALUE_PARTIAL_INFORMATION ParentPrefixIdInformation = NULL;
DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context); DPRINT("PDO 0x%p\n", DeviceNode->PhysicalDeviceObject); @@ -1351,6 +1352,69 @@ DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); }
+ DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack\n"); + + Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCapabilities); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopInitiatePnpIrp() failed (Status 0x%08lx)\n", Status); + } + + DeviceNode->CapabilityFlags = *(PULONG)((ULONG_PTR)&DeviceCapabilities + 4); + + if (!DeviceCapabilities.UniqueID) + { + /* Device has not a unique ID. We need to prepend parent bus unique identifier */ + DPRINT("Instance ID is not unique\n"); + if (DeviceNode->Parent->InstancePath.Length > 0) + { + /* Parent device node exists */ + HANDLE hKey; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + ULONG KeyNameBufferLength; + PWSTR KeyNameBuffer = NULL; + + KeyNameBufferLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]) + MAX_PATH * sizeof(WCHAR); + ParentPrefixIdInformation = ExAllocatePool(PagedPool, KeyNameBufferLength + sizeof(WCHAR)); + KeyNameBuffer = ExAllocatePool(PagedPool, (49 * sizeof(WCHAR)) + DeviceNode->Parent->InstancePath.Length); + if (ParentPrefixIdInformation && KeyNameBuffer) + { + /* Memory is allocated, let's try to read registry settings */ + wcscpy(KeyNameBuffer, L"\Registry\Machine\System\CurrentControlSet\Enum\"); + wcscat(KeyNameBuffer, DeviceNode->Parent->InstancePath.Buffer); + RtlInitUnicodeString(&KeyName, KeyNameBuffer); + InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); + Status = ZwOpenKey(&hKey, KEY_READ, &ObjectAttributes); + if (NT_SUCCESS(Status)) + { + RtlInitUnicodeString(&ValueName, L"ParentIdPrefix"); + Status = ZwQueryValueKey( + hKey, &ValueName, + KeyValuePartialInformation, ParentPrefixIdInformation, + KeyNameBufferLength, &KeyNameBufferLength); + if (NT_SUCCESS(Status)) + { + /* NULL-terminate the string, as we have allocated enough place for it */ + ((PWSTR)ParentPrefixIdInformation->Data)[ParentPrefixIdInformation->Data Length / sizeof(WCHAR)] = 0; + } + else + { + ExFreePool(ParentPrefixIdInformation); + ParentPrefixIdInformation = NULL; + } + ZwClose(hKey); + } + else + { + ExFreePool(ParentPrefixIdInformation); + ParentPrefixIdInformation = NULL; + } + } + ExFreePool(KeyNameBuffer); + } + } + DPRINT("Sending IRP_MN_QUERY_ID.BusQueryInstanceID to device stack\n");
Stack.Parameters.QueryId.IdType = BusQueryInstanceID; @@ -1363,6 +1427,13 @@ { /* Append the instance id string */ wcscat(InstancePath, L"\"); + if (ParentPrefixIdInformation && ParentPrefixIdInformation->Type == REG_SZ) + { + /* Add information from parent bus device to InstancePath */ + wcscat(InstancePath, (PWSTR)ParentPrefixIdInformation->Data); + if (*(PWSTR)IoStatusBlock.Information) + wcscat(InstancePath, L"&"); + } wcscat(InstancePath, (PWSTR)IoStatusBlock.Information);
/* @@ -1374,21 +1445,8 @@ { DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); } + ExFreePool(ParentPrefixIdInformation);
- Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCapabilities); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopInitiatePnpIrp() failed (Status 0x%08lx)\n", Status); - } - - DeviceNode->CapabilityFlags = *(PULONG)((ULONG_PTR)&DeviceCapabilities + 4); - - if (!DeviceCapabilities.UniqueID) - { - DPRINT("Instance ID is not unique\n"); - /* FIXME: Add information from parent bus driver to InstancePath */ - } - if (!RtlCreateUnicodeString(&DeviceNode->InstancePath, InstancePath)) { DPRINT("No resources\n");