https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b5815efe83ba99eac8126…
commit b5815efe83ba99eac81269aa28e271bf935ec4fa
Author: Victor Perevertkin <victor.perevertkin(a)reactos.org>
AuthorDate: Fri Jun 19 23:55:40 2020 +0300
Commit: Victor Perevertkin <victor.perevertkin(a)reactos.org>
CommitDate: Sun Jun 21 09:39:13 2020 +0300
[NTOS:IO] Move device node functions from pnpmgr/pnpmgr.c to pnpmgr/devnode.c
Add SAL2 annotations to functions while moving
Convert IopCreateDeviceNode description to a Doxygen format
---
ntoskrnl/include/internal/io.h | 9 +-
ntoskrnl/io/pnpmgr/devnode.c | 400 +++++++++++++++++++++++++++++++++++++++++
ntoskrnl/io/pnpmgr/pnpmgr.c | 384 +--------------------------------------
ntoskrnl/io/pnpmgr/pnpreport.c | 6 -
ntoskrnl/ntos.cmake | 1 +
5 files changed, 410 insertions(+), 390 deletions(-)
diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h
index d518e2e6ba9..3f801a0f647 100644
--- a/ntoskrnl/include/internal/io.h
+++ b/ntoskrnl/include/internal/io.h
@@ -762,6 +762,13 @@ NTSTATUS
IopTraverseDeviceTree(
PDEVICETREE_TRAVERSE_CONTEXT Context);
+NTSTATUS
+NTAPI
+IopCreateDeviceKeyPath(
+ IN PCUNICODE_STRING RegistryPath,
+ IN ULONG CreateOptions,
+ OUT PHANDLE Handle);
+
//
// PnP Routines
//
@@ -1391,7 +1398,7 @@ IoSetIoCompletion(
IN PVOID ApcContext,
IN NTSTATUS IoStatus,
IN ULONG_PTR IoStatusInformation,
- IN BOOLEAN Quota
+ IN BOOLEAN Quota
);
//
diff --git a/ntoskrnl/io/pnpmgr/devnode.c b/ntoskrnl/io/pnpmgr/devnode.c
new file mode 100644
index 00000000000..6f5e029ceff
--- /dev/null
+++ b/ntoskrnl/io/pnpmgr/devnode.c
@@ -0,0 +1,400 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: PnP manager device tree functions
+ * COPYRIGHT: Casper S. Hornstrup (chorns(a)users.sourceforge.net)
+ * 2007 Hervé Poussineau (hpoussin(a)reactos.org)
+ * 2010-2012 Cameron Gutman (cameron.gutman(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS *******************************************************************/
+
+PDEVICE_NODE IopRootDeviceNode;
+KSPIN_LOCK IopDeviceTreeLock;
+
+LONG IopNumberDeviceNodes;
+
+/* FUNCTIONS *****************************************************************/
+
+PDEVICE_NODE
+FASTCALL
+IopGetDeviceNode(
+ _In_ PDEVICE_OBJECT DeviceObject)
+{
+ return
((PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension)->DeviceNode;
+}
+
+PDEVICE_NODE
+NTAPI
+PipAllocateDeviceNode(
+ _In_opt_ PDEVICE_OBJECT PhysicalDeviceObject)
+{
+ PDEVICE_NODE DeviceNode;
+ PAGED_CODE();
+
+ /* Allocate it */
+ DeviceNode = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE),
TAG_IO_DEVNODE);
+ if (!DeviceNode) return DeviceNode;
+
+ /* Statistics */
+ InterlockedIncrement(&IopNumberDeviceNodes);
+
+ /* Set it up */
+ RtlZeroMemory(DeviceNode, sizeof(DEVICE_NODE));
+ DeviceNode->InterfaceType = InterfaceTypeUndefined;
+ DeviceNode->BusNumber = -1;
+ DeviceNode->ChildInterfaceType = InterfaceTypeUndefined;
+ DeviceNode->ChildBusNumber = -1;
+ DeviceNode->ChildBusTypeIndex = -1;
+// KeInitializeEvent(&DeviceNode->EnumerationMutex, SynchronizationEvent,
TRUE);
+ InitializeListHead(&DeviceNode->DeviceArbiterList);
+ InitializeListHead(&DeviceNode->DeviceTranslatorList);
+ InitializeListHead(&DeviceNode->TargetDeviceNotify);
+ InitializeListHead(&DeviceNode->DockInfo.ListEntry);
+ InitializeListHead(&DeviceNode->PendedSetInterfaceState);
+
+ /* Check if there is a PDO */
+ if (PhysicalDeviceObject)
+ {
+ /* Link it and remove the init flag */
+ DeviceNode->PhysicalDeviceObject = PhysicalDeviceObject;
+
((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode
= DeviceNode;
+ PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+ }
+
+ /* Return the node */
+ return DeviceNode;
+}
+
+/**
+ * @brief Creates a device node
+ *
+ * @param[in] ParentNode Pointer to parent device node
+ * @param[in] PhysicalDeviceObject Pointer to PDO for device object. Pass NULL to have
+ * the root device node create one (eg. for legacy
drivers)
+ * @param[in] ServiceName The service (driver) name for a node. Pass NULL
+ * to set UNKNOWN as a service
+ * @param[out] DeviceNode Pointer to storage for created device node
+ *
+ * @return Status, indicating the result of an operation
+ */
+
+NTSTATUS
+IopCreateDeviceNode(
+ _In_ PDEVICE_NODE ParentNode,
+ _In_opt_ PDEVICE_OBJECT PhysicalDeviceObject,
+ _In_opt_ PUNICODE_STRING ServiceName,
+ _Out_ PDEVICE_NODE *DeviceNode)
+{
+ PDEVICE_NODE Node;
+ NTSTATUS Status;
+ KIRQL OldIrql;
+ UNICODE_STRING FullServiceName;
+ UNICODE_STRING LegacyPrefix = RTL_CONSTANT_STRING(L"LEGACY_");
+ UNICODE_STRING UnknownDeviceName = RTL_CONSTANT_STRING(L"UNKNOWN");
+ UNICODE_STRING KeyName, ClassName;
+ PUNICODE_STRING ServiceName1;
+ ULONG LegacyValue;
+ UNICODE_STRING ClassGUID;
+ HANDLE InstanceHandle;
+
+ DPRINT("ParentNode 0x%p PhysicalDeviceObject 0x%p ServiceName %wZ\n",
+ ParentNode, PhysicalDeviceObject, ServiceName);
+
+ Node = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE), TAG_IO_DEVNODE);
+ if (!Node)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlZeroMemory(Node, sizeof(DEVICE_NODE));
+
+ if (!ServiceName)
+ ServiceName1 = &UnknownDeviceName;
+ else
+ ServiceName1 = ServiceName;
+
+ if (!PhysicalDeviceObject)
+ {
+ FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName1->Length +
sizeof(UNICODE_NULL);
+ FullServiceName.Length = 0;
+ FullServiceName.Buffer = ExAllocatePool(PagedPool,
FullServiceName.MaximumLength);
+ if (!FullServiceName.Buffer)
+ {
+ ExFreePoolWithTag(Node, TAG_IO_DEVNODE);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix);
+ RtlAppendUnicodeStringToString(&FullServiceName, ServiceName1);
+ RtlUpcaseUnicodeString(&FullServiceName, &FullServiceName, FALSE);
+
+ Status = PnpRootCreateDevice(&FullServiceName, NULL,
&PhysicalDeviceObject, &Node->InstancePath);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("PnpRootCreateDevice() failed with status 0x%08X\n",
Status);
+ ExFreePool(FullServiceName.Buffer);
+ ExFreePoolWithTag(Node, TAG_IO_DEVNODE);
+ return Status;
+ }
+
+ /* Create the device key for legacy drivers */
+ Status = IopCreateDeviceKeyPath(&Node->InstancePath, REG_OPTION_VOLATILE,
&InstanceHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(FullServiceName.Buffer);
+ ExFreePoolWithTag(Node, TAG_IO_DEVNODE);
+ return Status;
+ }
+
+ Node->ServiceName.MaximumLength = ServiceName1->Length +
sizeof(UNICODE_NULL);
+ Node->ServiceName.Length = 0;
+ Node->ServiceName.Buffer = ExAllocatePool(PagedPool,
Node->ServiceName.MaximumLength);
+ if (!Node->ServiceName.Buffer)
+ {
+ ZwClose(InstanceHandle);
+ ExFreePool(FullServiceName.Buffer);
+ ExFreePoolWithTag(Node, TAG_IO_DEVNODE);
+ return Status;
+ }
+
+ RtlCopyUnicodeString(&Node->ServiceName, ServiceName1);
+
+ if (ServiceName)
+ {
+ RtlInitUnicodeString(&KeyName, L"Service");
+ Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ,
ServiceName->Buffer, ServiceName->Length + sizeof(UNICODE_NULL));
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ RtlInitUnicodeString(&KeyName, L"Legacy");
+ LegacyValue = 1;
+ Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD,
&LegacyValue, sizeof(LegacyValue));
+
+ RtlInitUnicodeString(&KeyName, L"ConfigFlags");
+ LegacyValue = 0;
+ ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue,
sizeof(LegacyValue));
+
+ if (NT_SUCCESS(Status))
+ {
+ RtlInitUnicodeString(&KeyName, L"Class");
+ RtlInitUnicodeString(&ClassName, L"LegacyDriver");
+ Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ,
ClassName.Buffer, ClassName.Length + sizeof(UNICODE_NULL));
+ if (NT_SUCCESS(Status))
+ {
+ RtlInitUnicodeString(&KeyName, L"ClassGUID");
+ RtlInitUnicodeString(&ClassGUID,
L"{8ECC055D-047F-11D1-A537-0000F8753ED1}");
+ Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ,
ClassGUID.Buffer, ClassGUID.Length + sizeof(UNICODE_NULL));
+ if (NT_SUCCESS(Status))
+ {
+ // FIXME: Retrieve the real "description" by looking at
the "DisplayName" string
+ // of the corresponding CurrentControlSet\Services\xxx entry for
this driver.
+ RtlInitUnicodeString(&KeyName, L"DeviceDesc");
+ Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ,
ServiceName1->Buffer, ServiceName1->Length + sizeof(UNICODE_NULL));
+ }
+ }
+ }
+ }
+
+ ZwClose(InstanceHandle);
+ ExFreePool(FullServiceName.Buffer);
+
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(Node->ServiceName.Buffer);
+ ExFreePoolWithTag(Node, TAG_IO_DEVNODE);
+ return Status;
+ }
+
+ IopDeviceNodeSetFlag(Node, DNF_LEGACY_DRIVER);
+ IopDeviceNodeSetFlag(Node, DNF_PROCESSED);
+ IopDeviceNodeSetFlag(Node, DNF_ADDED);
+ IopDeviceNodeSetFlag(Node, DNF_STARTED);
+ }
+
+ Node->PhysicalDeviceObject = PhysicalDeviceObject;
+
+
((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode
= Node;
+
+ if (ParentNode)
+ {
+ KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
+ Node->Parent = ParentNode;
+ Node->Sibling = NULL;
+ if (ParentNode->LastChild == NULL)
+ {
+ ParentNode->Child = Node;
+ ParentNode->LastChild = Node;
+ }
+ else
+ {
+ ParentNode->LastChild->Sibling = Node;
+ ParentNode->LastChild = Node;
+ }
+ KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
+ Node->Level = ParentNode->Level + 1;
+ }
+
+ PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ *DeviceNode = Node;
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+IopFreeDeviceNode(
+ _In_ PDEVICE_NODE DeviceNode)
+{
+ KIRQL OldIrql;
+ PDEVICE_NODE PrevSibling = NULL;
+
+ /* All children must be deleted before a parent is deleted */
+ ASSERT(!DeviceNode->Child);
+ ASSERT(DeviceNode->PhysicalDeviceObject);
+
+ KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
+
+ /* Get previous sibling */
+ if (DeviceNode->Parent && DeviceNode->Parent->Child != DeviceNode)
+ {
+ PrevSibling = DeviceNode->Parent->Child;
+ while (PrevSibling->Sibling != DeviceNode)
+ PrevSibling = PrevSibling->Sibling;
+ }
+
+ /* Unlink from parent if it exists */
+ if (DeviceNode->Parent)
+ {
+ if (DeviceNode->Parent->LastChild == DeviceNode)
+ {
+ DeviceNode->Parent->LastChild = PrevSibling;
+ if (PrevSibling)
+ PrevSibling->Sibling = NULL;
+ }
+ if (DeviceNode->Parent->Child == DeviceNode)
+ DeviceNode->Parent->Child = DeviceNode->Sibling;
+ }
+
+ /* Unlink from sibling list */
+ if (PrevSibling)
+ PrevSibling->Sibling = DeviceNode->Sibling;
+
+ KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
+
+ RtlFreeUnicodeString(&DeviceNode->InstancePath);
+
+ RtlFreeUnicodeString(&DeviceNode->ServiceName);
+
+ if (DeviceNode->ResourceList)
+ {
+ ExFreePool(DeviceNode->ResourceList);
+ }
+
+ if (DeviceNode->ResourceListTranslated)
+ {
+ ExFreePool(DeviceNode->ResourceListTranslated);
+ }
+
+ if (DeviceNode->ResourceRequirements)
+ {
+ ExFreePool(DeviceNode->ResourceRequirements);
+ }
+
+ if (DeviceNode->BootResources)
+ {
+ ExFreePool(DeviceNode->BootResources);
+ }
+
+
((PEXTENDED_DEVOBJ_EXTENSION)DeviceNode->PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode
= NULL;
+ ExFreePoolWithTag(DeviceNode, TAG_IO_DEVNODE);
+
+ return STATUS_SUCCESS;
+}
+
+static
+NTSTATUS
+IopTraverseDeviceTreeNode(
+ _In_ 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;
+
+ /* 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 */
+ 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 = 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 */
+ 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;
+}
+
+NTSTATUS
+IopTraverseDeviceTree(
+ _In_ PDEVICETREE_TRAVERSE_CONTEXT Context)
+{
+ NTSTATUS Status;
+
+ DPRINT("Context 0x%p\n", Context);
+
+ DPRINT("IopTraverseDeviceTree(DeviceNode 0x%p FirstDeviceNode 0x%p Action %p
Context 0x%p)\n",
+ Context->DeviceNode, Context->FirstDeviceNode, Context->Action,
Context->Context);
+
+ /* Start from the specified device node */
+ Context->DeviceNode = Context->FirstDeviceNode;
+
+ /* Recursively traverse the device tree */
+ Status = IopTraverseDeviceTreeNode(Context);
+ if (Status == STATUS_UNSUCCESSFUL)
+ {
+ /* The action routine just wanted to terminate the traversal with status
+ code STATUS_SUCCESS */
+ Status = STATUS_SUCCESS;
+ }
+
+ return Status;
+}
diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c
index 48890364bf9..436e1376f9a 100644
--- a/ntoskrnl/io/pnpmgr/pnpmgr.c
+++ b/ntoskrnl/io/pnpmgr/pnpmgr.c
@@ -15,8 +15,6 @@
/* GLOBALS *******************************************************************/
-PDEVICE_NODE IopRootDeviceNode;
-KSPIN_LOCK IopDeviceTreeLock;
ERESOURCE PpRegistryDeviceResource;
KGUARDED_MUTEX PpDeviceReferenceTableLock;
RTL_AVL_TABLE PpDeviceReferenceTable;
@@ -24,6 +22,7 @@ RTL_AVL_TABLE PpDeviceReferenceTable;
extern ERESOURCE IopDriverLoadResource;
extern ULONG ExpInitializationPhase;
extern BOOLEAN PnpSystemInit;
+extern PDEVICE_NODE IopRootDeviceNode;
#define MAX_DEVICE_ID_LEN 200
#define MAX_SEPARATORS_INSTANCEID 0
@@ -40,12 +39,6 @@ KSPIN_LOCK IopDeviceActionLock;
/* FUNCTIONS *****************************************************************/
-NTSTATUS
-NTAPI
-IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath,
- IN ULONG CreateOptions,
- OUT PHANDLE Handle);
-
VOID
IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject);
@@ -55,13 +48,6 @@ IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN
Force);
PDEVICE_OBJECT
IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance);
-PDEVICE_NODE
-FASTCALL
-IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
-{
- return
((PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension)->DeviceNode;
-}
-
VOID
IopFixupDeviceId(PWCHAR String)
{
@@ -1239,252 +1225,6 @@ Quickie:
return FoundIndex;
}
-/*
- * DESCRIPTION
- * Creates a device node
- *
- * ARGUMENTS
- * ParentNode = Pointer to parent device node
- * PhysicalDeviceObject = Pointer to PDO for device object. Pass NULL
- * to have the root device node create one
- * (eg. for legacy drivers)
- * DeviceNode = Pointer to storage for created device node
- *
- * RETURN VALUE
- * Status
- */
-NTSTATUS
-IopCreateDeviceNode(PDEVICE_NODE ParentNode,
- PDEVICE_OBJECT PhysicalDeviceObject,
- PUNICODE_STRING ServiceName,
- PDEVICE_NODE *DeviceNode)
-{
- PDEVICE_NODE Node;
- NTSTATUS Status;
- KIRQL OldIrql;
- UNICODE_STRING FullServiceName;
- UNICODE_STRING LegacyPrefix = RTL_CONSTANT_STRING(L"LEGACY_");
- UNICODE_STRING UnknownDeviceName = RTL_CONSTANT_STRING(L"UNKNOWN");
- UNICODE_STRING KeyName, ClassName;
- PUNICODE_STRING ServiceName1;
- ULONG LegacyValue;
- UNICODE_STRING ClassGUID;
- HANDLE InstanceHandle;
-
- DPRINT("ParentNode 0x%p PhysicalDeviceObject 0x%p ServiceName %wZ\n",
- ParentNode, PhysicalDeviceObject, ServiceName);
-
- Node = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE), TAG_IO_DEVNODE);
- if (!Node)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- RtlZeroMemory(Node, sizeof(DEVICE_NODE));
-
- if (!ServiceName)
- ServiceName1 = &UnknownDeviceName;
- else
- ServiceName1 = ServiceName;
-
- if (!PhysicalDeviceObject)
- {
- FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName1->Length +
sizeof(UNICODE_NULL);
- FullServiceName.Length = 0;
- FullServiceName.Buffer = ExAllocatePool(PagedPool,
FullServiceName.MaximumLength);
- if (!FullServiceName.Buffer)
- {
- ExFreePoolWithTag(Node, TAG_IO_DEVNODE);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix);
- RtlAppendUnicodeStringToString(&FullServiceName, ServiceName1);
- RtlUpcaseUnicodeString(&FullServiceName, &FullServiceName, FALSE);
-
- Status = PnpRootCreateDevice(&FullServiceName, NULL,
&PhysicalDeviceObject, &Node->InstancePath);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("PnpRootCreateDevice() failed with status 0x%08X\n",
Status);
- ExFreePool(FullServiceName.Buffer);
- ExFreePoolWithTag(Node, TAG_IO_DEVNODE);
- return Status;
- }
-
- /* Create the device key for legacy drivers */
- Status = IopCreateDeviceKeyPath(&Node->InstancePath, REG_OPTION_VOLATILE,
&InstanceHandle);
- if (!NT_SUCCESS(Status))
- {
- ExFreePool(FullServiceName.Buffer);
- ExFreePoolWithTag(Node, TAG_IO_DEVNODE);
- return Status;
- }
-
- Node->ServiceName.MaximumLength = ServiceName1->Length +
sizeof(UNICODE_NULL);
- Node->ServiceName.Length = 0;
- Node->ServiceName.Buffer = ExAllocatePool(PagedPool,
Node->ServiceName.MaximumLength);
- if (!Node->ServiceName.Buffer)
- {
- ZwClose(InstanceHandle);
- ExFreePool(FullServiceName.Buffer);
- ExFreePoolWithTag(Node, TAG_IO_DEVNODE);
- return Status;
- }
-
- RtlCopyUnicodeString(&Node->ServiceName, ServiceName1);
-
- if (ServiceName)
- {
- RtlInitUnicodeString(&KeyName, L"Service");
- Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ,
ServiceName->Buffer, ServiceName->Length + sizeof(UNICODE_NULL));
- }
-
- if (NT_SUCCESS(Status))
- {
- RtlInitUnicodeString(&KeyName, L"Legacy");
- LegacyValue = 1;
- Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD,
&LegacyValue, sizeof(LegacyValue));
-
- RtlInitUnicodeString(&KeyName, L"ConfigFlags");
- LegacyValue = 0;
- ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue,
sizeof(LegacyValue));
-
- if (NT_SUCCESS(Status))
- {
- RtlInitUnicodeString(&KeyName, L"Class");
- RtlInitUnicodeString(&ClassName, L"LegacyDriver");
- Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ,
ClassName.Buffer, ClassName.Length + sizeof(UNICODE_NULL));
- if (NT_SUCCESS(Status))
- {
- RtlInitUnicodeString(&KeyName, L"ClassGUID");
- RtlInitUnicodeString(&ClassGUID,
L"{8ECC055D-047F-11D1-A537-0000F8753ED1}");
- Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ,
ClassGUID.Buffer, ClassGUID.Length + sizeof(UNICODE_NULL));
- if (NT_SUCCESS(Status))
- {
- // FIXME: Retrieve the real "description" by looking at
the "DisplayName" string
- // of the corresponding CurrentControlSet\Services\xxx entry for
this driver.
- RtlInitUnicodeString(&KeyName, L"DeviceDesc");
- Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ,
ServiceName1->Buffer, ServiceName1->Length + sizeof(UNICODE_NULL));
- }
- }
- }
- }
-
- ZwClose(InstanceHandle);
- ExFreePool(FullServiceName.Buffer);
-
- if (!NT_SUCCESS(Status))
- {
- ExFreePool(Node->ServiceName.Buffer);
- ExFreePoolWithTag(Node, TAG_IO_DEVNODE);
- return Status;
- }
-
- IopDeviceNodeSetFlag(Node, DNF_LEGACY_DRIVER);
- IopDeviceNodeSetFlag(Node, DNF_PROCESSED);
- IopDeviceNodeSetFlag(Node, DNF_ADDED);
- IopDeviceNodeSetFlag(Node, DNF_STARTED);
- }
-
- Node->PhysicalDeviceObject = PhysicalDeviceObject;
-
-
((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode
= Node;
-
- if (ParentNode)
- {
- KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
- Node->Parent = ParentNode;
- Node->Sibling = NULL;
- if (ParentNode->LastChild == NULL)
- {
- ParentNode->Child = Node;
- ParentNode->LastChild = Node;
- }
- else
- {
- ParentNode->LastChild->Sibling = Node;
- ParentNode->LastChild = Node;
- }
- KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
- Node->Level = ParentNode->Level + 1;
- }
-
- PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-
- *DeviceNode = Node;
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-IopFreeDeviceNode(PDEVICE_NODE DeviceNode)
-{
- KIRQL OldIrql;
- PDEVICE_NODE PrevSibling = NULL;
-
- /* All children must be deleted before a parent is deleted */
- ASSERT(!DeviceNode->Child);
- ASSERT(DeviceNode->PhysicalDeviceObject);
-
- KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
-
- /* Get previous sibling */
- if (DeviceNode->Parent && DeviceNode->Parent->Child != DeviceNode)
- {
- PrevSibling = DeviceNode->Parent->Child;
- while (PrevSibling->Sibling != DeviceNode)
- PrevSibling = PrevSibling->Sibling;
- }
-
- /* Unlink from parent if it exists */
- if (DeviceNode->Parent)
- {
- if (DeviceNode->Parent->LastChild == DeviceNode)
- {
- DeviceNode->Parent->LastChild = PrevSibling;
- if (PrevSibling)
- PrevSibling->Sibling = NULL;
- }
- if (DeviceNode->Parent->Child == DeviceNode)
- DeviceNode->Parent->Child = DeviceNode->Sibling;
- }
-
- /* Unlink from sibling list */
- if (PrevSibling)
- PrevSibling->Sibling = DeviceNode->Sibling;
-
- KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
-
- RtlFreeUnicodeString(&DeviceNode->InstancePath);
-
- RtlFreeUnicodeString(&DeviceNode->ServiceName);
-
- if (DeviceNode->ResourceList)
- {
- ExFreePool(DeviceNode->ResourceList);
- }
-
- if (DeviceNode->ResourceListTranslated)
- {
- ExFreePool(DeviceNode->ResourceListTranslated);
- }
-
- if (DeviceNode->ResourceRequirements)
- {
- ExFreePool(DeviceNode->ResourceRequirements);
- }
-
- if (DeviceNode->BootResources)
- {
- ExFreePool(DeviceNode->BootResources);
- }
-
-
((PEXTENDED_DEVOBJ_EXTENSION)DeviceNode->PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode
= NULL;
- ExFreePoolWithTag(DeviceNode, TAG_IO_DEVNODE);
-
- return STATUS_SUCCESS;
-}
-
NTSTATUS
NTAPI
IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject,
@@ -1583,85 +1323,6 @@ IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject,
return IoStatusBlock->Status;
}
-NTSTATUS
-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;
-
- /* 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 */
- 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 = 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 */
- 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;
-}
-
-
-NTSTATUS
-IopTraverseDeviceTree(PDEVICETREE_TRAVERSE_CONTEXT Context)
-{
- NTSTATUS Status;
-
- DPRINT("Context 0x%p\n", Context);
-
- DPRINT("IopTraverseDeviceTree(DeviceNode 0x%p FirstDeviceNode 0x%p Action %p
Context 0x%p)\n",
- Context->DeviceNode, Context->FirstDeviceNode, Context->Action,
Context->Context);
-
- /* Start from the specified device node */
- Context->DeviceNode = Context->FirstDeviceNode;
-
- /* Recursively traverse the device tree */
- Status = IopTraverseDeviceTreeNode(Context);
- if (Status == STATUS_UNSUCCESSFUL)
- {
- /* The action routine just wanted to terminate the traversal with status
- code STATUS_SUCCESS */
- Status = STATUS_SUCCESS;
- }
-
- return Status;
-}
-
-
/*
* IopCreateDeviceKeyPath
*
@@ -4038,49 +3699,6 @@ PpInitSystem(VOID)
}
}
-LONG IopNumberDeviceNodes;
-
-PDEVICE_NODE
-NTAPI
-PipAllocateDeviceNode(IN PDEVICE_OBJECT PhysicalDeviceObject)
-{
- PDEVICE_NODE DeviceNode;
- PAGED_CODE();
-
- /* Allocate it */
- DeviceNode = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE),
TAG_IO_DEVNODE);
- if (!DeviceNode) return DeviceNode;
-
- /* Statistics */
- InterlockedIncrement(&IopNumberDeviceNodes);
-
- /* Set it up */
- RtlZeroMemory(DeviceNode, sizeof(DEVICE_NODE));
- DeviceNode->InterfaceType = InterfaceTypeUndefined;
- DeviceNode->BusNumber = -1;
- DeviceNode->ChildInterfaceType = InterfaceTypeUndefined;
- DeviceNode->ChildBusNumber = -1;
- DeviceNode->ChildBusTypeIndex = -1;
-// KeInitializeEvent(&DeviceNode->EnumerationMutex, SynchronizationEvent,
TRUE);
- InitializeListHead(&DeviceNode->DeviceArbiterList);
- InitializeListHead(&DeviceNode->DeviceTranslatorList);
- InitializeListHead(&DeviceNode->TargetDeviceNotify);
- InitializeListHead(&DeviceNode->DockInfo.ListEntry);
- InitializeListHead(&DeviceNode->PendedSetInterfaceState);
-
- /* Check if there is a PDO */
- if (PhysicalDeviceObject)
- {
- /* Link it and remove the init flag */
- DeviceNode->PhysicalDeviceObject = PhysicalDeviceObject;
-
((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode
= DeviceNode;
- PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
- }
-
- /* Return the node */
- return DeviceNode;
-}
-
/* PUBLIC FUNCTIONS **********************************************************/
NTSTATUS
diff --git a/ntoskrnl/io/pnpmgr/pnpreport.c b/ntoskrnl/io/pnpmgr/pnpreport.c
index a9a9b3fab68..b16f70afdc4 100644
--- a/ntoskrnl/io/pnpmgr/pnpreport.c
+++ b/ntoskrnl/io/pnpmgr/pnpreport.c
@@ -24,12 +24,6 @@ typedef struct _INTERNAL_WORK_QUEUE_ITEM
PTARGET_DEVICE_CUSTOM_NOTIFICATION NotificationStructure;
} INTERNAL_WORK_QUEUE_ITEM, *PINTERNAL_WORK_QUEUE_ITEM;
-NTSTATUS
-NTAPI
-IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath,
- IN ULONG CreateOptions,
- OUT PHANDLE Handle);
-
NTSTATUS
IopSetDeviceInstanceData(HANDLE InstanceKey,
PDEVICE_NODE DeviceNode);
diff --git a/ntoskrnl/ntos.cmake b/ntoskrnl/ntos.cmake
index b2224bed4c7..a938a42b783 100644
--- a/ntoskrnl/ntos.cmake
+++ b/ntoskrnl/ntos.cmake
@@ -152,6 +152,7 @@ list(APPEND SOURCE
${REACTOS_SOURCE_DIR}/ntoskrnl/io/iomgr/util.c
${REACTOS_SOURCE_DIR}/ntoskrnl/io/iomgr/volume.c
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/arbs.c
+ ${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/devnode.c
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/plugplay.c
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpdma.c
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpinit.c