https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6f0e37b042414a5b4530b89f1bf2b719a6e9147f

commit 6f0e37b042414a5b4530b89f1bf2b719a6e9147f
Author:     Victor Perevertkin <[email protected]>
AuthorDate: Sun Nov 15 17:33:42 2020 +0300
Commit:     Victor Perevertkin <[email protected]>
CommitDate: Mon Jan 4 16:50:32 2021 +0300

    [NTOS:PNP][NTOS:IO] Do not create a device object + node on every driver 
load
    
    - Remove the usage of IopCreateDeviceNode and change it to
      PipAllocateDeviceNode where required
---
 ntoskrnl/include/internal/io.h | 13 ++-----
 ntoskrnl/io/iomgr/driver.c     | 85 +++++-------------------------------------
 ntoskrnl/io/pnpmgr/devaction.c | 16 ++++----
 ntoskrnl/io/pnpmgr/devnode.c   | 40 +++++++++++++++++---
 ntoskrnl/io/pnpmgr/pnpreport.c | 13 +++----
 5 files changed, 61 insertions(+), 106 deletions(-)

diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h
index 628929f1cff..4e81a6f1c83 100644
--- a/ntoskrnl/include/internal/io.h
+++ b/ntoskrnl/include/internal/io.h
@@ -615,18 +615,14 @@ IopGetSystemPowerDeviceObject(
 );
 
 PDEVICE_NODE
-NTAPI
 PipAllocateDeviceNode(
     IN PDEVICE_OBJECT PhysicalDeviceObject
 );
 
-NTSTATUS
-IopCreateDeviceNode(
-    IN PDEVICE_NODE ParentNode,
-    IN PDEVICE_OBJECT PhysicalDeviceObject,
-    IN PUNICODE_STRING ServiceName,
-    OUT PDEVICE_NODE *DeviceNode
-);
+VOID
+PiInsertDevNode(
+    _In_ PDEVICE_NODE DeviceNode,
+    _In_ PDEVICE_NODE ParentNode);
 
 NTSTATUS
 IopFreeDeviceNode(
@@ -1160,7 +1156,6 @@ IopLoadUnloadDriver(
 NTSTATUS
 FASTCALL
 IopInitializeDriverModule(
-    IN PDEVICE_NODE DeviceNode,
     IN PLDR_DATA_TABLE_ENTRY ModuleObject,
     IN PUNICODE_STRING ServiceName,
     IN BOOLEAN FileSystemDriver,
diff --git a/ntoskrnl/io/iomgr/driver.c b/ntoskrnl/io/iomgr/driver.c
index 3b033f9ab32..f3f4c5a79a8 100644
--- a/ntoskrnl/io/iomgr/driver.c
+++ b/ntoskrnl/io/iomgr/driver.c
@@ -464,10 +464,6 @@ MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY 
LdrEntry);
  *
  * Initialize a loaded driver.
  *
- * Parameters
- *    DeviceNode
- *       Pointer to device node.
- *
  *    ModuleObject
  *       Module object representing the driver. It can be retrieve by
  *       IopLoadServiceModule.
@@ -485,7 +481,6 @@ MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY 
LdrEntry);
 NTSTATUS
 FASTCALL
 IopInitializeDriverModule(
-    IN PDEVICE_NODE DeviceNode,
     IN PLDR_DATA_TABLE_ENTRY ModuleObject,
     IN PUNICODE_STRING ServiceName,
     IN BOOLEAN FileSystemDriver,
@@ -626,8 +621,7 @@ IopAttachFilterDriversCallback(
                 return Status;
             }
 
-            Status = IopInitializeDriverModule(DeviceNode,
-                                               ModuleObject,
+            Status = IopInitializeDriverModule(ModuleObject,
                                                &ServiceName,
                                                FALSE,
                                                &DriverObject);
@@ -827,7 +821,6 @@ NTSTATUS
 NTAPI
 IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
 {
-    PDEVICE_NODE DeviceNode;
     PDRIVER_OBJECT DriverObject;
     NTSTATUS Status;
     PWCHAR Buffer, FileNameWithoutPath;
@@ -885,21 +878,6 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY 
BootLdrEntry)
         FileExtension[0] = UNICODE_NULL;
     }
 
-    /*
-     * Determine the right device object
-     */
-    /* Use IopRootDeviceNode for now */
-    Status = IopCreateDeviceNode(IopRootDeviceNode,
-                                 NULL,
-                                 &ServiceName,
-                                 &DeviceNode);
-    RtlFreeUnicodeString(&ServiceName);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
-        return Status;
-    }
-
     /* Lookup the new Ldr entry in PsLoadedModuleList */
     NextEntry = PsLoadedModuleList.Flink;
     while (NextEntry != &PsLoadedModuleList)
@@ -919,23 +897,18 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY 
BootLdrEntry)
     /*
      * Initialize the driver
      */
-    Status = IopInitializeDriverModule(DeviceNode,
-                                       LdrEntry,
-                                       &DeviceNode->ServiceName,
+    Status = IopInitializeDriverModule(LdrEntry,
+                                       &ServiceName,
                                        FALSE,
                                        &DriverObject);
+    RtlFreeUnicodeString(&ServiceName);
 
     if (!NT_SUCCESS(Status))
     {
+        DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
         return Status;
     }
 
-    Status = IopInitializeDevice(DeviceNode, DriverObject);
-    if (NT_SUCCESS(Status))
-    {
-        Status = IopStartDevice(DeviceNode);
-    }
-
     /* Remove extra reference from IopInitializeDriverModule */
     ObDereferenceObject(DriverObject);
 
@@ -960,7 +933,6 @@ IopInitializeBootDrivers(VOID)
 {
     PLIST_ENTRY ListHead, NextEntry, NextEntry2;
     PLDR_DATA_TABLE_ENTRY LdrEntry;
-    PDEVICE_NODE DeviceNode;
     PDRIVER_OBJECT DriverObject;
     LDR_DATA_TABLE_ENTRY ModuleObject;
     NTSTATUS Status;
@@ -971,10 +943,6 @@ IopInitializeBootDrivers(VOID)
     PBOOT_DRIVER_LIST_ENTRY BootEntry;
     DPRINT("IopInitializeBootDrivers()\n");
 
-    /* Use IopRootDeviceNode for now */
-    Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, NULL, &DeviceNode);
-    if (!NT_SUCCESS(Status)) return;
-
     /* Setup the module object for the RAW FS Driver */
     ModuleObject.DllBase = NULL;
     ModuleObject.SizeOfImage = 0;
@@ -982,8 +950,7 @@ IopInitializeBootDrivers(VOID)
     RtlInitUnicodeString(&DriverName, L"RAW");
 
     /* Initialize it */
-    Status = IopInitializeDriverModule(DeviceNode,
-                                       &ModuleObject,
+    Status = IopInitializeDriverModule(&ModuleObject,
                                        &DriverName,
                                        TRUE,
                                        &DriverObject);
@@ -993,24 +960,6 @@ IopInitializeBootDrivers(VOID)
         return;
     }
 
-    /* Now initialize the associated device */
-    Status = IopInitializeDevice(DeviceNode, DriverObject);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Fail */
-        ObDereferenceObject(DriverObject);
-        return;
-    }
-
-    /* Start it up */
-    Status = IopStartDevice(DeviceNode);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Fail */
-        ObDereferenceObject(DriverObject);
-        return;
-    }
-
     /* Get highest group order index */
     IopGroupIndex = PpInitGetGroupOrderIndex(NULL);
     if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
@@ -1943,7 +1892,6 @@ IopLoadUnloadDriver(
     UNICODE_STRING ServiceName;
     NTSTATUS Status;
     ULONG Type;
-    PDEVICE_NODE DeviceNode;
     PLDR_DATA_TABLE_ENTRY ModuleObject;
     PVOID BaseAddress;
     WCHAR *cur;
@@ -2069,21 +2017,10 @@ IopLoadUnloadDriver(
         /*
          * Initialize the driver module if it's loaded for the first time
          */
-        Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, 
&DeviceNode);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
-            ExReleaseResourceLite(&IopDriverLoadResource);
-            KeLeaveCriticalRegion();
-            MmUnloadSystemImage(ModuleObject);
-            return Status;
-        }
+        IopDisplayLoadingMessage(&ServiceName);
 
-        IopDisplayLoadingMessage(&DeviceNode->ServiceName);
-
-        Status = IopInitializeDriverModule(DeviceNode,
-                                           ModuleObject,
-                                           &DeviceNode->ServiceName,
+        Status = IopInitializeDriverModule(ModuleObject,
+                                           &ServiceName,
                                            (Type == SERVICE_FILE_SYSTEM_DRIVER 
||
                                             Type == SERVICE_RECOGNIZER_DRIVER),
                                            DriverObject);
@@ -2098,10 +2035,6 @@ IopLoadUnloadDriver(
 
         ExReleaseResourceLite(&IopDriverLoadResource);
         KeLeaveCriticalRegion();
-
-        /* Initialize and start device */
-        IopInitializeDevice(DeviceNode, *DriverObject);
-        Status = IopStartDevice(DeviceNode);
     }
     else
     {
diff --git a/ntoskrnl/io/pnpmgr/devaction.c b/ntoskrnl/io/pnpmgr/devaction.c
index 34d71e18a2e..99e4e2b944d 100644
--- a/ntoskrnl/io/pnpmgr/devaction.c
+++ b/ntoskrnl/io/pnpmgr/devaction.c
@@ -1079,8 +1079,10 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode,
             if (NT_SUCCESS(Status) || Status == STATUS_IMAGE_ALREADY_LOADED)
             {
                 /* Initialize the driver */
-                Status = IopInitializeDriverModule(DeviceNode, ModuleObject,
-                    &DeviceNode->ServiceName, FALSE, &DriverObject);
+                Status = IopInitializeDriverModule(ModuleObject,
+                                                   &DeviceNode->ServiceName,
+                                                   FALSE,
+                                                   &DriverObject);
                 if (!NT_SUCCESS(Status))
                     DeviceNode->Problem = CM_PROB_FAILED_DRIVER_ENTRY;
             }
@@ -2183,13 +2185,11 @@ PipEnumerateDevice(
         if (!ChildDeviceNode)
         {
             /* One doesn't exist, create it */
-            Status = IopCreateDeviceNode(
-                DeviceNode,
-                ChildDeviceObject,
-                NULL,
-                &ChildDeviceNode);
-            if (NT_SUCCESS(Status))
+            ChildDeviceNode = PipAllocateDeviceNode(ChildDeviceObject);
+            if (ChildDeviceNode)
             {
+                PiInsertDevNode(ChildDeviceNode, DeviceNode);
+
                 /* Mark the node as enumerated */
                 ChildDeviceNode->Flags |= DNF_ENUMERATED;
 
diff --git a/ntoskrnl/io/pnpmgr/devnode.c b/ntoskrnl/io/pnpmgr/devnode.c
index 230fcce100b..0442e1765c2 100644
--- a/ntoskrnl/io/pnpmgr/devnode.c
+++ b/ntoskrnl/io/pnpmgr/devnode.c
@@ -31,7 +31,6 @@ IopGetDeviceNode(
 }
 
 PDEVICE_NODE
-NTAPI
 PipAllocateDeviceNode(
     _In_opt_ PDEVICE_OBJECT PhysicalDeviceObject)
 {
@@ -39,19 +38,22 @@ PipAllocateDeviceNode(
     PAGED_CODE();
 
     /* Allocate it */
-    DeviceNode = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE), 
TAG_IO_DEVNODE);
-    if (!DeviceNode) return DeviceNode;
+    DeviceNode = ExAllocatePoolZero(NonPagedPool, sizeof(DEVICE_NODE), 
TAG_IO_DEVNODE);
+    if (!DeviceNode)
+    {
+        return NULL;
+    }
 
     /* 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;
+    DeviceNode->State = DeviceNodeUninitialized;
 //    KeInitializeEvent(&DeviceNode->EnumerationMutex, SynchronizationEvent, 
TRUE);
     InitializeListHead(&DeviceNode->DeviceArbiterList);
     InitializeListHead(&DeviceNode->DeviceTranslatorList);
@@ -72,6 +74,32 @@ PipAllocateDeviceNode(
     return DeviceNode;
 }
 
+VOID
+PiInsertDevNode(
+    _In_ PDEVICE_NODE DeviceNode,
+    _In_ PDEVICE_NODE ParentNode)
+{
+    KIRQL oldIrql;
+
+    ASSERT(DeviceNode->Parent == NULL);
+
+    KeAcquireSpinLock(&IopDeviceTreeLock, &oldIrql);
+    DeviceNode->Parent = ParentNode;
+    DeviceNode->Sibling = NULL;
+    if (ParentNode->LastChild == NULL)
+    {
+        ParentNode->Child = DeviceNode;
+        ParentNode->LastChild = DeviceNode;
+    }
+    else
+    {
+        ParentNode->LastChild->Sibling = DeviceNode;
+        ParentNode->LastChild = DeviceNode;
+    }
+    KeReleaseSpinLock(&IopDeviceTreeLock, oldIrql);
+    DeviceNode->Level = ParentNode->Level + 1;
+}
+
 /**
  * @brief      Creates a device node
  *
@@ -84,7 +112,7 @@ PipAllocateDeviceNode(
  *
  * @return     Status, indicating the result of an operation
  */
-
+#if 0
 NTSTATUS
 IopCreateDeviceNode(
     _In_ PDEVICE_NODE ParentNode,
@@ -94,7 +122,6 @@ IopCreateDeviceNode(
 {
     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");
@@ -249,6 +276,7 @@ IopCreateDeviceNode(
 
     return STATUS_SUCCESS;
 }
+#endif
 
 NTSTATUS
 IopFreeDeviceNode(
diff --git a/ntoskrnl/io/pnpmgr/pnpreport.c b/ntoskrnl/io/pnpmgr/pnpreport.c
index ae0ac9566d3..4c5e36cb147 100644
--- a/ntoskrnl/io/pnpmgr/pnpreport.c
+++ b/ntoskrnl/io/pnpmgr/pnpreport.c
@@ -242,16 +242,15 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
     }
 
     /* Create the device node for the new PDO */
-    Status = IopCreateDeviceNode(IopRootDeviceNode,
-                                 Pdo,
-                                 NULL,
-                                 &DeviceNode);
-    if (!NT_SUCCESS(Status))
+    DeviceNode = PipAllocateDeviceNode(Pdo);
+    if (!DeviceNode)
     {
-        DPRINT("IopCreateDeviceNode() failed (Status 0x%08lx)\n", Status);
-        return Status;
+        DPRINT("PipAllocateDeviceNode() failed\n");
+        return STATUS_INSUFFICIENT_RESOURCES;
     }
 
+    PiInsertDevNode(DeviceNode, IopRootDeviceNode);
+
     /* We're enumerated already */
     IopDeviceNodeSetFlag(DeviceNode, DNF_ENUMERATED);
 

Reply via email to