mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[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:
parent
d66a0171a1
commit
ccc358b878
2 changed files with 179 additions and 7 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue