From ccc358b878aa4e40f06f9214683bb5d36f9d410a Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 1 Apr 2010 18:17:25 +0000 Subject: [PATCH] [NTOSKRNL] - Store the device's assigned resources (raw and translated) in the RESOURCEMAP key - Implement IopUpdateResourceMap which is responsible for updating the key with new resource information and setting the DNF_RESOURCE_ASSIGNED flag - Fix IoGetDeviceProperty which was returning incorrect information for DevicePropertyPhysicalDeviceObjectName - Take a look at HKLM\Hardware\ResourceMap\PnP Manager\PnpManager and see the beautiful resource lists ;) - NOTE: Regedit has a bug so the "\Device\" prefix is hidden but you will see that it is there if you look with explorer's NT object viewer svn path=/trunk/; revision=46644 --- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 180 ++++++++++++++++++++++++- reactos/ntoskrnl/io/pnpmgr/pnpreport.c | 6 +- 2 files changed, 179 insertions(+), 7 deletions(-) diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index 4e820883b59..d8b6c675ab0 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -56,6 +56,10 @@ IopTranslateDeviceResources( IN PDEVICE_NODE DeviceNode, IN ULONG RequiredSize); +NTSTATUS +IopUpdateResourceMap( + IN PDEVICE_NODE DeviceNode); + PDEVICE_NODE FASTCALL IopGetDeviceNode(PDEVICE_OBJECT DeviceObject) @@ -159,7 +163,11 @@ IopStartDevice( Status = IopTranslateDeviceResources(DeviceNode, RequiredLength); if (NT_SUCCESS(Status)) { - IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED); + Status = IopUpdateResourceMap(DeviceNode); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopUpdateResourceMap() failed (Status 0x%08lx)\n", Status); + } } else { @@ -726,6 +734,128 @@ IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, return STATUS_UNSUCCESSFUL; } +NTSTATUS +IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode) +{ + NTSTATUS Status; + ULONG Disposition; + HANDLE PnpMgrLevel1, PnpMgrLevel2, ResourceMapKey; + UNICODE_STRING KeyName; + OBJECT_ATTRIBUTES ObjectAttributes; + + RtlInitUnicodeString(&KeyName, + L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE | OBJ_OPENIF, + 0, + NULL); + Status = ZwCreateKey(&ResourceMapKey, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + &Disposition); + if (!NT_SUCCESS(Status)) + return Status; + + RtlInitUnicodeString(&KeyName, L"PnP Manager"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE | OBJ_OPENIF, + ResourceMapKey, + NULL); + Status = ZwCreateKey(&PnpMgrLevel1, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + &Disposition); + ZwClose(ResourceMapKey); + if (!NT_SUCCESS(Status)) + return Status; + + RtlInitUnicodeString(&KeyName, L"PnpManager"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE | OBJ_OPENIF, + PnpMgrLevel1, + NULL); + Status = ZwCreateKey(&PnpMgrLevel2, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + &Disposition); + ZwClose(PnpMgrLevel1); + if (!NT_SUCCESS(Status)) + return Status; + + if (DeviceNode->ResourceList) + { + WCHAR NameBuff[256]; + UNICODE_STRING NameU; + UNICODE_STRING Suffix; + ULONG OldLength; + + ASSERT(DeviceNode->ResourceListTranslated); + + NameU.Buffer = NameBuff; + NameU.Length = 0; + NameU.MaximumLength = 256 * sizeof(WCHAR); + + Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject, + DevicePropertyPhysicalDeviceObjectName, + NameU.MaximumLength, + NameU.Buffer, + &OldLength); + ASSERT(Status == STATUS_SUCCESS); + + NameU.Length = (USHORT)OldLength; + + RtlInitUnicodeString(&Suffix, L".Raw"); + RtlAppendUnicodeStringToString(&NameU, &Suffix); + + Status = ZwSetValueKey(PnpMgrLevel2, + &NameU, + 0, + REG_RESOURCE_LIST, + DeviceNode->ResourceList, + CM_RESOURCE_LIST_SIZE(DeviceNode->ResourceList)); + if (!NT_SUCCESS(Status)) + { + ZwClose(PnpMgrLevel2); + return Status; + } + + /* "Remove" the suffix by setting the length back to what it used to be */ + NameU.Length = (USHORT)OldLength; + + RtlInitUnicodeString(&Suffix, L".Translated"); + RtlAppendUnicodeStringToString(&NameU, &Suffix); + + Status = ZwSetValueKey(PnpMgrLevel2, + &NameU, + 0, + REG_RESOURCE_LIST, + DeviceNode->ResourceListTranslated, + CM_RESOURCE_LIST_SIZE(DeviceNode->ResourceListTranslated)); + ZwClose(PnpMgrLevel2); + if (!NT_SUCCESS(Status)) + return Status; + } + else + { + ZwClose(PnpMgrLevel2); + } + + IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED); + + return STATUS_SUCCESS; +} NTSTATUS IopSetDeviceInstanceData(HANDLE InstanceKey, @@ -3069,7 +3199,7 @@ PpInitSystem(VOID) /* PUBLIC FUNCTIONS **********************************************************/ /* - * @unimplemented + * @implemented */ NTSTATUS NTAPI @@ -3085,6 +3215,8 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, PVOID Data = NULL; PWSTR Ptr; NTSTATUS Status; + POBJECT_NAME_INFORMATION ObjectNameInfo = NULL; + ULONG RequiredLength, ObjectNameInfoLength; DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty); @@ -3298,9 +3430,36 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, break; case DevicePropertyPhysicalDeviceObjectName: - /* InstancePath buffer is NULL terminated, so we can do this */ - Length = DeviceNode->InstancePath.MaximumLength; - Data = DeviceNode->InstancePath.Buffer; + Status = ObQueryNameString(DeviceNode->PhysicalDeviceObject, + NULL, + 0, + &RequiredLength); + if (Status == STATUS_SUCCESS) + { + Length = 0; + Data = L""; + } + else if (Status == STATUS_INFO_LENGTH_MISMATCH) + { + ObjectNameInfoLength = RequiredLength; + ObjectNameInfo = ExAllocatePool(PagedPool, ObjectNameInfoLength); + if (!ObjectNameInfo) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = ObQueryNameString(DeviceNode->PhysicalDeviceObject, + ObjectNameInfo, + ObjectNameInfoLength, + &RequiredLength); + if (NT_SUCCESS(Status)) + { + Length = ObjectNameInfo->Name.Length; + Data = ObjectNameInfo->Name.Buffer; + } + else + return Status; + } + else + return Status; break; default: @@ -3310,13 +3469,22 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, /* Prepare returned values */ *ResultLength = Length; if (BufferLength < Length) + { + if (ObjectNameInfo != NULL) + ExFreePool(ObjectNameInfo); + return STATUS_BUFFER_TOO_SMALL; + } RtlCopyMemory(PropertyBuffer, Data, Length); /* NULL terminate the string (if required) */ - if (DeviceProperty == DevicePropertyEnumeratorName) + if (DeviceProperty == DevicePropertyEnumeratorName || + DeviceProperty == DevicePropertyPhysicalDeviceObjectName) ((LPWSTR)PropertyBuffer)[Length / sizeof(WCHAR)] = UNICODE_NULL; + if (ObjectNameInfo != NULL) + ExFreePool(ObjectNameInfo); + return STATUS_SUCCESS; } diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpreport.c b/reactos/ntoskrnl/io/pnpmgr/pnpreport.c index 334a9ce26cb..69ccd6be43c 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpreport.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpreport.c @@ -35,6 +35,10 @@ NTSTATUS IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode, PVOID Context); +NTSTATUS +IopUpdateResourceMap( + IN PDEVICE_NODE DeviceNode); + /* PRIVATE FUNCTIONS *********************************************************/ PWCHAR @@ -268,7 +272,7 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, { Status = IopTranslateDeviceResources(DeviceNode, RequiredLength); if (NT_SUCCESS(Status)) - IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED); + Status = IopUpdateResourceMap(DeviceNode); } IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);