mirror of
https://github.com/reactos/reactos.git
synced 2025-06-06 09:50:43 +00:00
[NTOS:PNP] When traversing the device tree, keep a reference to the current device. CORE-15874
This commit is contained in:
parent
08110c11d6
commit
934484ea3e
1 changed files with 18 additions and 1 deletions
|
@ -1518,33 +1518,50 @@ IopTraverseDeviceTreeNode(PDEVICETREE_TRAVERSE_CONTEXT Context)
|
||||||
{
|
{
|
||||||
PDEVICE_NODE ParentDeviceNode;
|
PDEVICE_NODE ParentDeviceNode;
|
||||||
PDEVICE_NODE ChildDeviceNode;
|
PDEVICE_NODE ChildDeviceNode;
|
||||||
|
PDEVICE_NODE NextDeviceNode;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Copy context data so we don't overwrite it in subsequent calls to this function */
|
/* Copy context data so we don't overwrite it in subsequent calls to this function */
|
||||||
ParentDeviceNode = Context->DeviceNode;
|
ParentDeviceNode = Context->DeviceNode;
|
||||||
|
|
||||||
|
/* HACK: Keep a reference to the PDO so we can keep traversing the tree
|
||||||
|
* if the device is deleted. In a perfect world, children would have to be
|
||||||
|
* deleted before their parents, and we'd restart the traversal after
|
||||||
|
* deleting a device node. */
|
||||||
|
ObReferenceObject(ParentDeviceNode->PhysicalDeviceObject);
|
||||||
|
|
||||||
/* Call the action routine */
|
/* Call the action routine */
|
||||||
Status = (Context->Action)(ParentDeviceNode, Context->Context);
|
Status = (Context->Action)(ParentDeviceNode, Context->Context);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
ObDereferenceObject(ParentDeviceNode->PhysicalDeviceObject);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Traversal of all children nodes */
|
/* Traversal of all children nodes */
|
||||||
for (ChildDeviceNode = ParentDeviceNode->Child;
|
for (ChildDeviceNode = ParentDeviceNode->Child;
|
||||||
ChildDeviceNode != NULL;
|
ChildDeviceNode != NULL;
|
||||||
ChildDeviceNode = ChildDeviceNode->Sibling)
|
ChildDeviceNode = NextDeviceNode)
|
||||||
{
|
{
|
||||||
|
/* HACK: We need this reference to ensure we can get Sibling below. */
|
||||||
|
ObReferenceObject(ChildDeviceNode->PhysicalDeviceObject);
|
||||||
|
|
||||||
/* Pass the current device node to the action routine */
|
/* Pass the current device node to the action routine */
|
||||||
Context->DeviceNode = ChildDeviceNode;
|
Context->DeviceNode = ChildDeviceNode;
|
||||||
|
|
||||||
Status = IopTraverseDeviceTreeNode(Context);
|
Status = IopTraverseDeviceTreeNode(Context);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
ObDereferenceObject(ChildDeviceNode->PhysicalDeviceObject);
|
||||||
|
ObDereferenceObject(ParentDeviceNode->PhysicalDeviceObject);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NextDeviceNode = ChildDeviceNode->Sibling;
|
||||||
|
ObDereferenceObject(ChildDeviceNode->PhysicalDeviceObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(ParentDeviceNode->PhysicalDeviceObject);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue