mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 00:45:24 +00:00
[0.4.12][NTOS:PNP] Workaround a BSOD with HDAUDIO during boot PR#1560 CORE-15874
Thanks to Thomas Faber, author of the patch.
I depend on external testers here for confirmation of effectiveness.
We think the problem was unhidden by 0.4.12-dev-757-g
789cfd3ddc
and surrounding works.
When traversing the device tree, keep a reference to the current device.
Devices can be deleted during the traversal, so in order to keep
the tree walk intact without use-after-free situations,
this just keeps the PDO around until we no longer need the device node.
It could be argued that this is a hack, however implementing it the "correct way"
(I haven't actually researched how Windows does this) is unlikely to be possible
with our current PNP manager -- so this should keep us going for a while.
This commit is contained in:
parent
9513c9bf12
commit
78b5bc9de7
1 changed files with 12 additions and 1 deletions
|
@ -1517,33 +1517,44 @@ IopTraverseDeviceTreeNode(PDEVICETREE_TRAVERSE_CONTEXT Context)
|
|||
{
|
||||
PDEVICE_NODE ParentDeviceNode;
|
||||
PDEVICE_NODE ChildDeviceNode;
|
||||
PDEVICE_NODE NextDeviceNode;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Copy context data so we don't overwrite it in subsequent calls to this function */
|
||||
ParentDeviceNode = Context->DeviceNode;
|
||||
|
||||
ObReferenceObject(ParentDeviceNode->PhysicalDeviceObject);
|
||||
|
||||
/* Call the action routine */
|
||||
Status = (Context->Action)(ParentDeviceNode, Context->Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(ParentDeviceNode->PhysicalDeviceObject);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Traversal of all children nodes */
|
||||
for (ChildDeviceNode = ParentDeviceNode->Child;
|
||||
ChildDeviceNode != NULL;
|
||||
ChildDeviceNode = ChildDeviceNode->Sibling)
|
||||
ChildDeviceNode = NextDeviceNode)
|
||||
{
|
||||
ObReferenceObject(ChildDeviceNode->PhysicalDeviceObject);
|
||||
/* Pass the current device node to the action routine */
|
||||
Context->DeviceNode = ChildDeviceNode;
|
||||
|
||||
Status = IopTraverseDeviceTreeNode(Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(ChildDeviceNode->PhysicalDeviceObject);
|
||||
ObDereferenceObject(ParentDeviceNode->PhysicalDeviceObject);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NextDeviceNode = ChildDeviceNode->Sibling;
|
||||
ObDereferenceObject(ChildDeviceNode->PhysicalDeviceObject);
|
||||
}
|
||||
|
||||
ObDereferenceObject(ParentDeviceNode->PhysicalDeviceObject);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue