[ros-diffs] [cgutman] 56184: [NTOSKRNL] - Reenable some dereferences of the driver object - Fix return values in NtLoadDriver - Split unloading into code for legacy drivers and non-legacy drivers

cgutman at svn.reactos.org cgutman at svn.reactos.org
Sun Mar 18 22:11:47 UTC 2012


Author: cgutman
Date: Sun Mar 18 22:11:46 2012
New Revision: 56184

URL: http://svn.reactos.org/svn/reactos?rev=56184&view=rev
Log:
[NTOSKRNL]
- Reenable some dereferences of the driver object
- Fix return values in NtLoadDriver
- Split unloading into code for legacy drivers and non-legacy drivers

Modified:
    trunk/reactos/ntoskrnl/io/iomgr/device.c
    trunk/reactos/ntoskrnl/io/iomgr/driver.c

Modified: trunk/reactos/ntoskrnl/io/iomgr/device.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/device.c?rev=56184&r1=56183&r2=56184&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/device.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/device.c [iso-8859-1] Sun Mar 18 22:11:46 2012
@@ -364,10 +364,44 @@
 NTAPI
 IopUnloadDevice(IN PDEVICE_OBJECT DeviceObject)
 {
-#if 0
     PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject;
     PEXTENDED_DEVOBJ_EXTENSION ThisExtension = IoGetDevObjExtension(DeviceObject);
-    PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
+
+    /* Check if deletion is pending */
+    if (ThisExtension->ExtensionFlags & DOE_DELETE_PENDING)
+    {
+        if (DeviceObject->AttachedDevice)
+        {
+            DPRINT("Device object is in the middle of a device stack\n");
+            return;
+        }
+
+        if (DeviceObject->ReferenceCount)
+        {
+            DPRINT("Device object still has %d references\n", DeviceObject->ReferenceCount);
+            return;
+        }
+
+        /* Check if we have a Security Descriptor */
+        if (DeviceObject->SecurityDescriptor)
+        {
+            /* Free it */
+            ExFreePoolWithTag(DeviceObject->SecurityDescriptor, TAG_SD);
+        }
+
+        /* Remove the device from the list */
+        IopEditDeviceList(DeviceObject->DriverObject, DeviceObject, IopRemove);
+
+        /* Dereference the keep-alive */
+        ObDereferenceObject(DeviceObject);
+    }
+
+    /* We can't unload a non-PnP driver here */
+    if (DriverObject->Flags & DRVO_LEGACY_DRIVER)
+    {
+        DPRINT("Not a PnP driver! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
+        return;
+    }
 
     /* Return if we've already called unload (maybe we're in it?) */
     if (DriverObject->Flags & DRVO_UNLOAD_INVOKED) return;
@@ -375,80 +409,15 @@
     /* We can't unload unless there's an unload handler */
     if (!DriverObject->DriverUnload)
     {
-        if (DeviceNode && !(DeviceNode->Flags & DNF_LEGACY_DRIVER))
-            DPRINT1("No DriverUnload function on PnP driver! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
-
+        DPRINT1("No DriverUnload function on PnP driver! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
         return;
     }
 
-    /* Check if deletion is pending */
-    if (ThisExtension->ExtensionFlags & DOE_DELETE_PENDING)
-    {
-        if (DeviceObject->AttachedDevice)
-        {
-            DPRINT("Device object is in the middle of a device stack\n");
-            return;
-        }
-
-        if (DeviceObject->ReferenceCount)
-        {
-            DPRINT("Device object still has %d references\n", DeviceObject->ReferenceCount);
-            return;
-        }
-
-        /* Check if we have a Security Descriptor */
-        if (DeviceObject->SecurityDescriptor)
-        {
-            /* Free it */
-            ExFreePoolWithTag(DeviceObject->SecurityDescriptor, TAG_SD);
-        }
-
-        /* Remove the device from the list */
-        IopEditDeviceList(DeviceObject->DriverObject, DeviceObject, IopRemove);
-
-        /* Dereference the keep-alive */
-        ObDereferenceObject(DeviceObject);
-    }
-
-    /* Loop all the device objects */
-    DeviceObject = DriverObject->DeviceObject;
-    while (DeviceObject)
-    {
-        /*
-         * Make sure we're not attached, having a reference count
-         * or already deleting
-         */
-        if (DeviceObject->ReferenceCount)
-        {
-            DPRINT("Device object still has %d references\n", DeviceObject->ReferenceCount);
-            return;
-        }
-
-        if (DeviceObject->AttachedDevice)
-        {
-            DPRINT("Device object is in the middle of a device stack\n");
-            return;
-        }
-
-        if (IoGetDevObjExtension(DeviceObject)->ExtensionFlags & (DOE_DELETE_PENDING | DOE_REMOVE_PENDING))
-        {
-            DPRINT("Device object has a pending destructive operation\n");
-            return;
-        }
-
-        /* Check the next device */
-        DeviceObject = DeviceObject->NextDevice;
-    }
-
-    /* Loop all the device objects */
-    DeviceObject = DriverObject->DeviceObject;
-    while (DeviceObject)
-    {
-        /* Set the unload pending flag */
-        IoGetDevObjExtension(DeviceObject)->ExtensionFlags |= DOE_UNLOAD_PENDING;
-
-        /* Go to the next device */
-        DeviceObject = DeviceObject->NextDevice;
+    /* Bail if there are still devices present */
+    if (DriverObject->DeviceObject)
+    {
+        DPRINT("Devices still present! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
+        return;
     }
 
     DPRINT1("Unloading driver '%wZ' (automatic)\n", &DriverObject->DriverName);
@@ -461,10 +430,6 @@
 
     /* Make object temporary so it can be deleted */
     ObMakeTemporaryObject(DriverObject);
-
-    /* Dereference once more, referenced at driver object creation */
-    ObDereferenceObject(DriverObject);
-#endif
 }
 
 VOID

Modified: trunk/reactos/ntoskrnl/io/iomgr/driver.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/driver.c?rev=56184&r1=56183&r2=56184&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/driver.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/driver.c [iso-8859-1] Sun Mar 18 22:11:46 2012
@@ -589,7 +589,7 @@
        Status = IopInitializeDevice(DeviceNode, DriverObject);
 
        /* Remove extra reference */
-       //ObDereferenceObject(DriverObject);
+       ObDereferenceObject(DriverObject);
    }
 
    return STATUS_SUCCESS;
@@ -885,7 +885,7 @@
    }
 
    /* Remove extra reference from IopInitializeDriverModule */
-   //ObDereferenceObject(DriverObject);
+   ObDereferenceObject(DriverObject);
 
    return Status;
 }
@@ -948,6 +948,7 @@
     {
         /* Fail */
         IopFreeDeviceNode(DeviceNode);
+        ObDereferenceObject(DriverObject);
         return;
     }
 
@@ -957,6 +958,7 @@
     {
         /* Fail */
         IopFreeDeviceNode(DeviceNode);
+        ObDereferenceObject(DriverObject);
         return;
     }
 
@@ -1268,7 +1270,8 @@
     */
 
     /* Call the load/unload routine, depending on current process */
-   if (DriverObject->DriverUnload && DriverObject->DriverSection)
+   if (DriverObject->DriverUnload && DriverObject->DriverSection &&
+       (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
    {
       /* Loop through each device object of the driver
          and set DOE_UNLOAD_PENDING flag */
@@ -1484,7 +1487,7 @@
     RtlZeroMemory(DriverObject, ObjectSize);
     DriverObject->Type = IO_TYPE_DRIVER;
     DriverObject->Size = sizeof(DRIVER_OBJECT);
-    DriverObject->Flags = DRVO_LEGACY_DRIVER;//DRVO_BUILTIN_DRIVER;
+    DriverObject->Flags = DRVO_LEGACY_DRIVER;
     DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
     DriverObject->DriverExtension->DriverObject = DriverObject;
     DriverObject->DriverInit = InitializationFunction;
@@ -1584,6 +1587,10 @@
         /* Returns to caller the object */
         *pDriverObject = DriverObject;
     }
+
+    /* We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
+     * Other parts of the I/O manager depend on this behavior */
+    if (!DriverObject->DeviceObject) DriverObject->Flags &= ~DRVO_LEGACY_DRIVER;
 
     /* Loop all Major Functions */
     for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
@@ -1920,7 +1927,7 @@
        DPRINT("Loading module from %wZ\n", &ImagePath);
        Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
 
-       if (!NT_SUCCESS(Status) && Status != STATUS_IMAGE_ALREADY_LOADED)
+       if (!NT_SUCCESS(Status))
        {
            DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
            LoadParams->Status = Status;
@@ -1931,43 +1938,37 @@
        /*
         * Initialize the driver module if it's loaded for the first time
         */
-       if (Status != STATUS_IMAGE_ALREADY_LOADED)
+       Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
+       if (!NT_SUCCESS(Status))
        {
-           Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
-
-           if (!NT_SUCCESS(Status))
-           {
-               DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
-               MmUnloadSystemImage(ModuleObject);
-               LoadParams->Status = Status;
-               (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
-               return;
-           }
-
-           IopDisplayLoadingMessage(&DeviceNode->ServiceName);
-
-           Status = IopInitializeDriverModule(
-               DeviceNode,
-               ModuleObject,
-               &DeviceNode->ServiceName,
-               (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
-               Type == 8 /* SERVICE_RECOGNIZER_DRIVER */),
-               &DriverObject);
-
-           if (!NT_SUCCESS(Status))
-           {
-               DPRINT1("IopInitializeDriver() failed (Status %lx)\n", Status);
-               MmUnloadSystemImage(ModuleObject);
-               IopFreeDeviceNode(DeviceNode);
-               LoadParams->Status = Status;
-               (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
-               return;
-           }
-
-           /* Initialize and start device */
-           IopInitializeDevice(DeviceNode, DriverObject);
-           Status = IopStartDevice(DeviceNode);
+           DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
+           MmUnloadSystemImage(ModuleObject);
+           LoadParams->Status = Status;
+           (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
+           return;
        }
+
+       IopDisplayLoadingMessage(&DeviceNode->ServiceName);
+
+       Status = IopInitializeDriverModule(DeviceNode,
+                                          ModuleObject,
+                                          &DeviceNode->ServiceName,
+                                          (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
+                                           Type == 8 /* SERVICE_RECOGNIZER_DRIVER */),
+                                          &DriverObject);
+       if (!NT_SUCCESS(Status))
+       {
+           DPRINT1("IopInitializeDriver() failed (Status %lx)\n", Status);
+           MmUnloadSystemImage(ModuleObject);
+           IopFreeDeviceNode(DeviceNode);
+           LoadParams->Status = Status;
+           (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
+           return;
+       }
+
+       /* Initialize and start device */
+       IopInitializeDevice(DeviceNode, DriverObject);
+       Status = IopStartDevice(DeviceNode);
    }
    else
    {




More information about the Ros-diffs mailing list