[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
This commit is contained in:
Cameron Gutman 2010-04-01 18:17:25 +00:00
parent d66a0171a1
commit ccc358b878
2 changed files with 179 additions and 7 deletions

View file

@ -56,6 +56,10 @@ IopTranslateDeviceResources(
IN PDEVICE_NODE DeviceNode, IN PDEVICE_NODE DeviceNode,
IN ULONG RequiredSize); IN ULONG RequiredSize);
NTSTATUS
IopUpdateResourceMap(
IN PDEVICE_NODE DeviceNode);
PDEVICE_NODE PDEVICE_NODE
FASTCALL FASTCALL
IopGetDeviceNode(PDEVICE_OBJECT DeviceObject) IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
@ -159,7 +163,11 @@ IopStartDevice(
Status = IopTranslateDeviceResources(DeviceNode, RequiredLength); Status = IopTranslateDeviceResources(DeviceNode, RequiredLength);
if (NT_SUCCESS(Status)) 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 else
{ {
@ -726,6 +734,128 @@ IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath,
return STATUS_UNSUCCESSFUL; 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 NTSTATUS
IopSetDeviceInstanceData(HANDLE InstanceKey, IopSetDeviceInstanceData(HANDLE InstanceKey,
@ -3069,7 +3199,7 @@ PpInitSystem(VOID)
/* PUBLIC FUNCTIONS **********************************************************/ /* PUBLIC FUNCTIONS **********************************************************/
/* /*
* @unimplemented * @implemented
*/ */
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -3085,6 +3215,8 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
PVOID Data = NULL; PVOID Data = NULL;
PWSTR Ptr; PWSTR Ptr;
NTSTATUS Status; NTSTATUS Status;
POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
ULONG RequiredLength, ObjectNameInfoLength;
DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty); DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
@ -3298,9 +3430,36 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
break; break;
case DevicePropertyPhysicalDeviceObjectName: case DevicePropertyPhysicalDeviceObjectName:
/* InstancePath buffer is NULL terminated, so we can do this */ Status = ObQueryNameString(DeviceNode->PhysicalDeviceObject,
Length = DeviceNode->InstancePath.MaximumLength; NULL,
Data = DeviceNode->InstancePath.Buffer; 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; break;
default: default:
@ -3310,13 +3469,22 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
/* Prepare returned values */ /* Prepare returned values */
*ResultLength = Length; *ResultLength = Length;
if (BufferLength < Length) if (BufferLength < Length)
{
if (ObjectNameInfo != NULL)
ExFreePool(ObjectNameInfo);
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
}
RtlCopyMemory(PropertyBuffer, Data, Length); RtlCopyMemory(PropertyBuffer, Data, Length);
/* NULL terminate the string (if required) */ /* NULL terminate the string (if required) */
if (DeviceProperty == DevicePropertyEnumeratorName) if (DeviceProperty == DevicePropertyEnumeratorName ||
DeviceProperty == DevicePropertyPhysicalDeviceObjectName)
((LPWSTR)PropertyBuffer)[Length / sizeof(WCHAR)] = UNICODE_NULL; ((LPWSTR)PropertyBuffer)[Length / sizeof(WCHAR)] = UNICODE_NULL;
if (ObjectNameInfo != NULL)
ExFreePool(ObjectNameInfo);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -35,6 +35,10 @@ NTSTATUS
IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode, IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
PVOID Context); PVOID Context);
NTSTATUS
IopUpdateResourceMap(
IN PDEVICE_NODE DeviceNode);
/* PRIVATE FUNCTIONS *********************************************************/ /* PRIVATE FUNCTIONS *********************************************************/
PWCHAR PWCHAR
@ -268,7 +272,7 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
{ {
Status = IopTranslateDeviceResources(DeviceNode, RequiredLength); Status = IopTranslateDeviceResources(DeviceNode, RequiredLength);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED); Status = IopUpdateResourceMap(DeviceNode);
} }
IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);