From d2241f8ec437bf7873ae25a7a7bbc193d2495a35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 20 Sep 2006 18:16:24 +0000 Subject: [PATCH] If boot resources are provided, use them instead of using resource requirements. In all cases, translate the resource list before calling the driver svn path=/trunk/; revision=24217 --- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 506 +++++++++++++++++++--------- 1 file changed, 340 insertions(+), 166 deletions(-) diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index c0047ae1cca..9d664858a5b 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -132,12 +132,6 @@ IopStartDevice( Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList; Stack.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->ResourceListTranslated; - /* FIXME: Not sure of this! */ - if (!Stack.Parameters.StartDevice.AllocatedResources) - Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->BootResources; - if (!Stack.Parameters.StartDevice.AllocatedResourcesTranslated) - Stack.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->BootResources; - Status = IopInitiatePnpIrp( Fdo, &IoStatusBlock, @@ -1229,30 +1223,70 @@ IopSetDeviceInstanceData(HANDLE InstanceKey, } -NTSTATUS -IopAssignDeviceResources(PDEVICE_NODE DeviceNode) +static NTSTATUS +IopAssignDeviceResources( + IN PDEVICE_NODE DeviceNode, + OUT ULONG *pRequiredSize) { PIO_RESOURCE_LIST ResourceList; PIO_RESOURCE_DESCRIPTOR ResourceDescriptor; - PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw, DescriptorTranslated; + PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw; + PCM_PARTIAL_RESOURCE_LIST pPartialResourceList; ULONG NumberOfResources = 0; - ULONG i; + ULONG Size; + ULONG i, j; NTSTATUS Status; - /* Fill DeviceNode->ResourceList and DeviceNode->ResourceListTranslated; - * by using DeviceNode->ResourceRequirements */ - - if (!DeviceNode->ResourceRequirements - || DeviceNode->ResourceRequirements->AlternativeLists == 0) + if (!DeviceNode->BootResources && !DeviceNode->ResourceRequirements) { - DeviceNode->ResourceList = DeviceNode->ResourceListTranslated = NULL; + /* No resource needed for this device */ + DeviceNode->ResourceList = NULL; return STATUS_SUCCESS; } + /* Fill DeviceNode->ResourceList + * FIXME: the PnP arbiter should go there! + * Actually, use the BootResources if provided, else the resource list #0 + */ + + IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); + + if (DeviceNode->BootResources) + { + /* Browse the boot resources to know if we have some custom structures */ + Size = FIELD_OFFSET(CM_RESOURCE_LIST, List); + for (i = 0; i < DeviceNode->BootResources->Count; i++) + { + pPartialResourceList = &DeviceNode->BootResources->List[i].PartialResourceList; + if (pPartialResourceList->Version != 1 || pPartialResourceList->Revision != 1) + { + Status = STATUS_REVISION_MISMATCH; + goto ByeBye; + } + Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors) + + pPartialResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + for (j = 0; j < pPartialResourceList->Count; j++) + { + if (pPartialResourceList->PartialDescriptors[j].Type == CmResourceTypeDeviceSpecific) + Size += pPartialResourceList->PartialDescriptors[j].u.DeviceSpecificData.DataSize; + } + } + + DeviceNode->ResourceList = ExAllocatePool(PagedPool, Size); + if (!DeviceNode->ResourceList) + { + Status = STATUS_NO_MEMORY; + goto ByeBye; + } + RtlCopyMemory(DeviceNode->ResourceList, DeviceNode->BootResources, Size); + + *pRequiredSize = Size; + return STATUS_SUCCESS; + } + + /* Ok, here, we have to use the device requirement list */ IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); - /* FIXME: that's here that PnP arbiter should go */ - /* Actually, simply use resource list #0 as assigned resource list */ ResourceList = &DeviceNode->ResourceRequirements->List[0]; if (ResourceList->Version != 1 || ResourceList->Revision != 1) { @@ -1260,19 +1294,12 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode) goto ByeBye; } - DeviceNode->ResourceList = ExAllocatePool(PagedPool, - sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); + Size = sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + *pRequiredSize = Size; + DeviceNode->ResourceList = ExAllocatePool(PagedPool, Size); if (!DeviceNode->ResourceList) { - Status = STATUS_INSUFFICIENT_RESOURCES; - goto ByeBye; - } - - DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, - sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); - if (!DeviceNode->ResourceListTranslated) - { - Status = STATUS_INSUFFICIENT_RESOURCES; + Status = STATUS_NO_MEMORY; goto ByeBye; } @@ -1282,12 +1309,6 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode) DeviceNode->ResourceList->List[0].PartialResourceList.Version = 1; DeviceNode->ResourceList->List[0].PartialResourceList.Revision = 1; - DeviceNode->ResourceListTranslated->Count = 1; - DeviceNode->ResourceListTranslated->List[0].InterfaceType = DeviceNode->ResourceRequirements->InterfaceType; - DeviceNode->ResourceListTranslated->List[0].BusNumber = DeviceNode->ResourceRequirements->BusNumber; - DeviceNode->ResourceListTranslated->List[0].PartialResourceList.Version = 1; - DeviceNode->ResourceListTranslated->List[0].PartialResourceList.Revision = 1; - for (i = 0; i < ResourceList->Count; i++) { ResourceDescriptor = &ResourceList->Descriptors[i]; @@ -1295,31 +1316,18 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode) if (ResourceDescriptor->Option == 0 || ResourceDescriptor->Option == IO_RESOURCE_PREFERRED) { DescriptorRaw = &DeviceNode->ResourceList->List[0].PartialResourceList.PartialDescriptors[NumberOfResources]; - DescriptorTranslated = &DeviceNode->ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[NumberOfResources]; NumberOfResources++; /* Copy ResourceDescriptor to DescriptorRaw and DescriptorTranslated */ - DescriptorRaw->Type = DescriptorTranslated->Type = ResourceDescriptor->Type; - DescriptorRaw->ShareDisposition = DescriptorTranslated->ShareDisposition = ResourceDescriptor->ShareDisposition; - DescriptorRaw->Flags = DescriptorTranslated->Flags = ResourceDescriptor->Flags; + DescriptorRaw->Type = ResourceDescriptor->Type; + DescriptorRaw->ShareDisposition = ResourceDescriptor->ShareDisposition; + DescriptorRaw->Flags = ResourceDescriptor->Flags; switch (ResourceDescriptor->Type) { case CmResourceTypePort: { - ULONG AddressSpace = 0; /* IO space */ DescriptorRaw->u.Port.Start = ResourceDescriptor->u.Port.MinimumAddress; - DescriptorRaw->u.Port.Length = DescriptorTranslated->u.Port.Length - = ResourceDescriptor->u.Port.Length; - if (!HalTranslateBusAddress( - DeviceNode->ResourceRequirements->InterfaceType, - DeviceNode->ResourceRequirements->BusNumber, - DescriptorRaw->u.Port.Start, - &AddressSpace, - &DescriptorTranslated->u.Port.Start)) - { - Status = STATUS_UNSUCCESSFUL; - goto ByeBye; - } + DescriptorRaw->u.Port.Length = ResourceDescriptor->u.Port.Length; break; } case CmResourceTypeInterrupt: @@ -1379,54 +1387,26 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode) } } } - - DescriptorTranslated->u.Interrupt.Level = 0; - DescriptorTranslated->u.Interrupt.Vector = HalGetInterruptVector( - DeviceNode->ResourceRequirements->InterfaceType, - DeviceNode->ResourceRequirements->BusNumber, - DescriptorRaw->u.Interrupt.Level, - DescriptorRaw->u.Interrupt.Vector, - (PKIRQL)&DescriptorTranslated->u.Interrupt.Level, - &DescriptorRaw->u.Interrupt.Affinity); - DescriptorTranslated->u.Interrupt.Affinity = DescriptorRaw->u.Interrupt.Affinity; break; } case CmResourceTypeMemory: { - ULONG AddressSpace = 1; /* Memory space */ DescriptorRaw->u.Memory.Start = ResourceDescriptor->u.Memory.MinimumAddress; - DescriptorRaw->u.Memory.Length = DescriptorTranslated->u.Memory.Length - = ResourceDescriptor->u.Memory.Length; - if (!HalTranslateBusAddress( - DeviceNode->ResourceRequirements->InterfaceType, - DeviceNode->ResourceRequirements->BusNumber, - DescriptorRaw->u.Memory.Start, - &AddressSpace, - &DescriptorTranslated->u.Memory.Start)) - { - Status = STATUS_UNSUCCESSFUL; - goto ByeBye; - } + DescriptorRaw->u.Memory.Length = ResourceDescriptor->u.Memory.Length; break; } case CmResourceTypeDma: { - DescriptorRaw->u.Dma.Channel = DescriptorTranslated->u.Dma.Channel - = ResourceDescriptor->u.Dma.MinimumChannel; - DescriptorRaw->u.Dma.Port = DescriptorTranslated->u.Dma.Port - = 0; /* FIXME */ - DescriptorRaw->u.Dma.Reserved1 = DescriptorTranslated->u.Dma.Reserved1 - = 0; + DescriptorRaw->u.Dma.Channel = ResourceDescriptor->u.Dma.MinimumChannel; + DescriptorRaw->u.Dma.Port = 0; /* FIXME */ + DescriptorRaw->u.Dma.Reserved1 = 0; break; } case CmResourceTypeBusNumber: { - DescriptorRaw->u.BusNumber.Start = DescriptorTranslated->u.BusNumber.Start - = ResourceDescriptor->u.BusNumber.MinBusNumber; - DescriptorRaw->u.BusNumber.Length = DescriptorTranslated->u.BusNumber.Length - = ResourceDescriptor->u.BusNumber.Length; - DescriptorRaw->u.BusNumber.Reserved = DescriptorTranslated->u.BusNumber.Reserved - = ResourceDescriptor->u.BusNumber.Reserved; + DescriptorRaw->u.BusNumber.Start = ResourceDescriptor->u.BusNumber.MinBusNumber; + DescriptorRaw->u.BusNumber.Length = ResourceDescriptor->u.BusNumber.Length; + DescriptorRaw->u.BusNumber.Reserved = ResourceDescriptor->u.BusNumber.Reserved; break; } /*CmResourceTypeDevicePrivate: @@ -1452,10 +1432,7 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode) } DeviceNode->ResourceList->List[0].PartialResourceList.Count = NumberOfResources; - DeviceNode->ResourceListTranslated->List[0].PartialResourceList.Count = NumberOfResources; - IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); - IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED); return STATUS_SUCCESS; ByeBye: @@ -1464,13 +1441,111 @@ ByeBye: ExFreePool(DeviceNode->ResourceList); DeviceNode->ResourceList = NULL; } + return Status; +} + + +static NTSTATUS +IopTranslateDeviceResources( + IN PDEVICE_NODE DeviceNode, + IN ULONG RequiredSize) +{ + PCM_PARTIAL_RESOURCE_LIST pPartialResourceList; + PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw, DescriptorTranslated; + ULONG i, j; + NTSTATUS Status; + + if (!DeviceNode->ResourceList) + { + DeviceNode->ResourceListTranslated = NULL; + return STATUS_SUCCESS; + } + + /* That's easy to translate a resource list. Just copy the + * untranslated one and change few fields in the copy + */ + DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, RequiredSize); + if (!DeviceNode->ResourceListTranslated) + { + Status =STATUS_NO_MEMORY; + goto cleanup; + } + RtlCopyMemory(DeviceNode->ResourceListTranslated, DeviceNode->ResourceList, RequiredSize); + + for (i = 0; i < DeviceNode->ResourceList->Count; i++) + { + pPartialResourceList = &DeviceNode->ResourceList->List[i].PartialResourceList; + for (j = 0; j < pPartialResourceList->Count; j++) + { + DescriptorRaw = &pPartialResourceList->PartialDescriptors[j]; + DescriptorTranslated = &DeviceNode->ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j]; + switch (DescriptorRaw->Type) + { + case CmResourceTypePort: + { + ULONG AddressSpace = 0; /* IO space */ + if (!HalTranslateBusAddress( + DeviceNode->ResourceList->List[i].InterfaceType, + DeviceNode->ResourceList->List[i].BusNumber, + DescriptorRaw->u.Port.Start, + &AddressSpace, + &DescriptorTranslated->u.Port.Start)) + { + Status = STATUS_UNSUCCESSFUL; + goto cleanup; + } + break; + } + case CmResourceTypeInterrupt: + { + DescriptorTranslated->u.Interrupt.Vector = HalGetInterruptVector( + DeviceNode->ResourceList->List[i].InterfaceType, + DeviceNode->ResourceList->List[i].BusNumber, + DescriptorRaw->u.Interrupt.Level, + DescriptorRaw->u.Interrupt.Vector, + (PKIRQL)&DescriptorTranslated->u.Interrupt.Level, + &DescriptorRaw->u.Interrupt.Affinity); + break; + } + case CmResourceTypeMemory: + { + ULONG AddressSpace = 1; /* Memory space */ + if (!HalTranslateBusAddress( + DeviceNode->ResourceList->List[i].InterfaceType, + DeviceNode->ResourceList->List[i].BusNumber, + DescriptorRaw->u.Memory.Start, + &AddressSpace, + &DescriptorTranslated->u.Memory.Start)) + { + Status = STATUS_UNSUCCESSFUL; + goto cleanup; + } + } + + case CmResourceTypeDma: + case CmResourceTypeBusNumber: + case CmResourceTypeDeviceSpecific: + /* Nothing to do */ + break; + default: + DPRINT1("Unknown resource descriptor type 0x%x\n", DescriptorRaw->Type); + Status = STATUS_NOT_IMPLEMENTED; + goto cleanup; + } + } + } + return STATUS_SUCCESS; + +cleanup: + /* Yes! Also delete ResourceList because ResourceList and + * ResourceListTranslated should be a pair! */ + ExFreePool(DeviceNode->ResourceList); + DeviceNode->ResourceList = NULL; if (DeviceNode->ResourceListTranslated) { ExFreePool(DeviceNode->ResourceListTranslated); - DeviceNode->ResourceListTranslated = NULL; + DeviceNode->ResourceList = NULL; } - - IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); return Status; } @@ -2030,11 +2105,25 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode, ZwClose(InstanceKey); - Status = IopAssignDeviceResources(DeviceNode); - if (!NT_SUCCESS(Status)) + IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); + Status = IopAssignDeviceResources(DeviceNode, &RequiredLength); + if (NT_SUCCESS(Status)) { - DPRINT("IopAssignDeviceResources() failed (Status %x)\n", Status); + Status = IopTranslateDeviceResources(DeviceNode, RequiredLength); + if (NT_SUCCESS(Status)) + { + IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED); + } + else + { + DPRINT("IopTranslateDeviceResources() failed (Status 0x08lx)\n", Status); + } } + else + { + DPRINT("IopAssignDeviceResources() failed (Status 0x08lx)\n", Status); + } + IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); DeviceNode->Flags |= DNF_PROCESSED; @@ -2596,7 +2685,9 @@ IopEnumerateDetectedDevices( IN HANDLE hBaseKey, IN PUNICODE_STRING RelativePath, IN HANDLE hRootKey, - IN BOOLEAN EnumerateSubKeys) + IN BOOLEAN EnumerateSubKeys, + IN PCM_FULL_RESOURCE_DESCRIPTOR ParentBootResources, + IN ULONG ParentBootResourcesLength) { UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier"); UNICODE_STRING DeviceDescU = RTL_CONSTANT_STRING(L"DeviceDesc"); @@ -2618,6 +2709,8 @@ IopEnumerateDetectedDevices( ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR); UNICODE_STRING DeviceName, ValueName; ULONG RequiredSize; + PCM_FULL_RESOURCE_DESCRIPTOR BootResources = NULL; + ULONG BootResourcesLength; NTSTATUS Status; const UNICODE_STRING IdentifierPci = RTL_CONSTANT_STRING(L"PCI BIOS"); @@ -2701,6 +2794,87 @@ IopEnumerateDetectedDevices( goto cleanup; } + /* Read boot resources, and add then to parent ones */ + Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + if (Status == STATUS_BUFFER_OVERFLOW) + { + ExFreePool(pValueInformation); + ValueInfoLength = RequiredSize; + pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); + if (!pValueInformation) + { + DPRINT("ExAllocatePool() failed\n"); + ZwDeleteKey(hLevel2Key); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + } + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + BootResources = ParentBootResources; + BootResourcesLength = ParentBootResourcesLength; + } + else if (!NT_SUCCESS(Status)) + { + DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); + goto nextdevice; + } + else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR) + { + DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR); + goto nextdevice; + } + else if (((PCM_FULL_RESOURCE_DESCRIPTOR)pValueInformation->Data)->PartialResourceList.Count == 0) + { + BootResources = ParentBootResources; + BootResourcesLength = ParentBootResourcesLength; + } + else + { + static const ULONG Header = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors); + + /* Concatenate current resources and parent ones */ + if (ParentBootResourcesLength == 0) + BootResourcesLength = pValueInformation->DataLength; + else + BootResourcesLength = ParentBootResourcesLength + + pValueInformation->DataLength + - Header; + BootResources = ExAllocatePool(PagedPool, BootResourcesLength); + if (!BootResources) + { + DPRINT("ExAllocatePool() failed\n"); + goto nextdevice; + } + if (ParentBootResourcesLength == 0) + { + RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength); + } + else if (ParentBootResources->PartialResourceList.PartialDescriptors[ParentBootResources->PartialResourceList.Count - 1].Type == CmResourceTypeDeviceSpecific) + { + RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength); + RtlCopyMemory( + (PVOID)((ULONG_PTR)BootResources + pValueInformation->DataLength), + (PVOID)((ULONG_PTR)ParentBootResources + Header), + ParentBootResourcesLength - Header); + BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count; + } + else + { + RtlCopyMemory(BootResources, pValueInformation->Data, Header); + RtlCopyMemory( + (PVOID)((ULONG_PTR)BootResources + Header), + (PVOID)((ULONG_PTR)ParentBootResources + Header), + ParentBootResourcesLength - Header); + RtlCopyMemory( + (PVOID)((ULONG_PTR)BootResources + ParentBootResourcesLength), + pValueInformation->Data + Header, + pValueInformation->DataLength - Header); + BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count; + } + } + if (EnumerateSubKeys) { IndexSubKey = 0; @@ -2731,7 +2905,13 @@ IopEnumerateDetectedDevices( DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength; DeviceName.Buffer = pDeviceInformation->Name; - Status = IopEnumerateDetectedDevices(hDeviceKey, &DeviceName, hRootKey, TRUE); + Status = IopEnumerateDetectedDevices( + hDeviceKey, + &DeviceName, + hRootKey, + TRUE, + BootResources, + BootResourcesLength); if (!NT_SUCCESS(Status)) goto cleanup; } @@ -2754,31 +2934,27 @@ IopEnumerateDetectedDevices( } if (!NT_SUCCESS(Status)) { - DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); - goto nextdevice; + if (Status != STATUS_OBJECT_NAME_NOT_FOUND) + { + DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); + goto nextdevice; + } } else if (pValueInformation->Type != REG_SZ) { DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ); goto nextdevice; } - - /* Assign hardware id to this device */ - ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength; - ValueName.Buffer = (PWCHAR)pValueInformation->Data; - if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) - ValueName.Length -= sizeof(WCHAR); - if (RtlCompareUnicodeString(&ValueName, &IdentifierPci, FALSE) == 0) + else { - pHardwareId = &HardwareIdPci; - DeviceIndex = DeviceIndexPci++; + /* Assign hardware id to this device */ + ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength; + ValueName.Buffer = (PWCHAR)pValueInformation->Data; + if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) + ValueName.Length -= sizeof(WCHAR); } - /*else if (RtlCompareUnicodeString(&ValueName, &IdentifierAcpi, FALSE) == 0) - { - pHardwareId = &HardwareIdAcpi; - DeviceIndex = DeviceIndexAcpi++; - }*/ - else if (RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0) + + if (RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0) { pHardwareId = &HardwareIdSerial; DeviceIndex = DeviceIndexSerial++; @@ -2793,10 +2969,30 @@ IopEnumerateDetectedDevices( pHardwareId = &HardwareIdMouse; DeviceIndex = DeviceIndexMouse++; } + else if (NT_SUCCESS(Status)) + { + /* Try to also match the device identifier */ + if (RtlCompareUnicodeString(&ValueName, &IdentifierPci, FALSE) == 0) + { + pHardwareId = &HardwareIdPci; + DeviceIndex = DeviceIndexPci++; + } + /*else if (RtlCompareUnicodeString(&ValueName, &IdentifierAcpi, FALSE) == 0) + { + pHardwareId = &HardwareIdAcpi; + DeviceIndex = DeviceIndexAcpi++; + }*/ + else + { + /* Unknown device */ + DPRINT("Unknown device '%wZ'\n", &ValueName); + goto nextdevice; + } + } else { - /* Unknown device */ - DPRINT("Unknown device %wZ in %wZ\n", &ValueName, RelativePath); + /* Unknown key path */ + DPRINT("Unknown key path %wZ\n", RelativePath); goto nextdevice; } @@ -2847,61 +3043,37 @@ IopEnumerateDetectedDevices( ZwDeleteKey(hLevel2Key); goto nextdevice; } - /* Copy 'Configuration Data' to 'LogConf\BootConfig' */ - Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); - if (Status == STATUS_BUFFER_OVERFLOW) + if (BootResourcesLength > 0) { - ExFreePool(pValueInformation); - ValueInfoLength = RequiredSize; - pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); - if (!pValueInformation) + /* Save boot resources to 'LogConf\BootConfig' */ + InitializeObjectAttributes(&ObjectAttributes, &LogConfU, OBJ_KERNEL_HANDLE, hLevel2Key, NULL); + Status = ZwCreateKey( + &hLogConf, + KEY_SET_VALUE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL); + if (!NT_SUCCESS(Status)) { - DPRINT("ExAllocatePool() failed\n"); + DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); ZwDeleteKey(hLevel2Key); - Status = STATUS_NO_MEMORY; - goto cleanup; + goto nextdevice; + } + Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_FULL_RESOURCE_DESCRIPTOR, BootResources, BootResourcesLength); + ZwClose(hLogConf); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); + ZwDeleteKey(hLevel2Key); + goto nextdevice; } - Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); - } - if (Status == STATUS_OBJECT_NAME_NOT_FOUND) - goto nextdevice; - else if (!NT_SUCCESS(Status)) - { - DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); - ZwDeleteKey(hLevel2Key); - goto nextdevice; - } - else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR) - { - DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR); - ZwDeleteKey(hLevel2Key); - goto nextdevice; - } - InitializeObjectAttributes(&ObjectAttributes, &LogConfU, OBJ_KERNEL_HANDLE, hLevel2Key, NULL); - Status = ZwCreateKey( - &hLogConf, - KEY_SET_VALUE, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_VOLATILE, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); - ZwDeleteKey(hLevel2Key); - goto nextdevice; - } - Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, pValueInformation->Type, pValueInformation->Data, pValueInformation->DataLength); - ZwClose(hLogConf); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); - ZwDeleteKey(hLevel2Key); - goto nextdevice; } nextdevice: + if (BootResources && BootResources != ParentBootResources) + ExFreePool(BootResources); if (hLevel2Key) { ZwClose(hLevel2Key); @@ -3119,7 +3291,9 @@ IopUpdateRootKey(VOID) NULL, &MultiKeyPathU, hRoot, - TRUE); + TRUE, + NULL, + 0); ZwClose(hRoot); return Status; }