Author: mjmartin
Date: Tue Jun 2 16:10:17 2009
New Revision: 41254
URL:
http://svn.reactos.org/svn/reactos?rev=41254&view=rev
Log:
IopCreateObjectTypes: Add a DeleteProcedure for Device Objects.
IopUnloadDevice: After calling the drivers Unload routine, make the DriverObject temporary
and dereference it.
IopUnloadDriver: Check that the driver is not already unloading before trying to call
unload routine.
If any failure, dereference the DriverObject before returning STATUS code.
On an attempt to unload the driver, loop through each DeviceObject and set
DOE_UNLOAD_PENDING in device extensions flags.
Before calling the driver's unload routine set DRVO_UNLOAD_INVOKED in
DriverObject's flags.
Fixes Bugchecks when attempting to load driver a second time and when unloading a driver
that has upper level device attached.
Modified:
trunk/reactos/ntoskrnl/include/internal/io.h
trunk/reactos/ntoskrnl/io/iomgr/device.c
trunk/reactos/ntoskrnl/io/iomgr/driver.c
trunk/reactos/ntoskrnl/io/iomgr/iomgr.c
Modified: trunk/reactos/ntoskrnl/include/internal/io.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] Tue Jun 2 16:10:17 2009
@@ -938,6 +938,10 @@
//
// File Routines
//
+VOID
+NTAPI
+IopDeleteDevice(IN PVOID ObjectBody);
+
NTSTATUS
NTAPI
IopParseDevice(
Modified: trunk/reactos/ntoskrnl/io/iomgr/device.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/device.c…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/device.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/device.c [iso-8859-1] Tue Jun 2 16:10:17 2009
@@ -22,6 +22,21 @@
KSPIN_LOCK ShutdownListLock;
/* PRIVATE FUNCTIONS **********************************************************/
+
+VOID
+NTAPI
+IopDeleteDevice(IN PVOID ObjectBody)
+{
+ PDEVICE_OBJECT DeviceObject = ObjectBody;
+ PAGED_CODE();
+
+ /* TODO: Delete Device Node */
+
+ /* Dereference the driver object, referenced in IoCreateDevice */
+ if (DeviceObject->DriverObject);
+ ObDereferenceObject(DeviceObject->DriverObject);
+}
+
PDEVICE_OBJECT
NTAPI
@@ -356,6 +371,13 @@
/* Unload it */
if (DriverObject->DriverUnload) DriverObject->DriverUnload(DriverObject);
+
+ /* Make object temporary so it can be deleted */
+ ObMakeTemporaryObject(DriverObject);
+
+ /* Dereference once more, referenced at driver object creation */
+ ObDereferenceObject(DriverObject);
+
}
VOID
Modified: trunk/reactos/ntoskrnl/io/iomgr/driver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/driver.c…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/driver.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/driver.c [iso-8859-1] Tue Jun 2 16:10:17 2009
@@ -977,9 +977,12 @@
UNICODE_STRING ServiceName;
UNICODE_STRING ObjectName;
PDRIVER_OBJECT DriverObject;
+ PDEVICE_OBJECT DeviceObject;
+ PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
LOAD_UNLOAD_PARAMS LoadParams;
NTSTATUS Status;
LPWSTR Start;
+ BOOLEAN SafeToUnload = TRUE;
DPRINT("IopUnloadDriver('%wZ', %d)\n", DriverServiceName,
UnloadPnpDrivers);
@@ -1031,6 +1034,14 @@
return Status;
}
+ /* Check that driver is not already unloading */
+ if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
+ {
+ DPRINT1("Driver deletion pending\n");
+ ObDereferenceObject(DriverObject);
+ return STATUS_DELETE_PENDING;
+ }
+
/*
* Get path of service...
*/
@@ -1049,6 +1060,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
+ ObDereferenceObject(DriverObject);
return Status;
}
@@ -1061,6 +1073,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
+ ObDereferenceObject(DriverObject);
return Status;
}
@@ -1069,6 +1082,35 @@
*/
ExFreePool(ImagePath.Buffer);
+
+ /* Loop through each device object of the driver
+ and set DOE_UNLOAD_PENDING flag */
+ DeviceObject = DriverObject->DeviceObject;
+ while (DeviceObject)
+ {
+ /* Set the unload pending flag for the device */
+ DeviceExtension = IoGetDevObjExtension(DeviceObject);
+ DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
+
+ /* Make sure there are no attached devices or no reference counts */
+ if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
+ {
+ /* Not safe to unload */
+ DPRINT1("Drivers device object is referenced or has attached
devices\n");
+
+ SafeToUnload = FALSE;
+ }
+
+ DeviceObject = DeviceObject->NextDevice;
+ }
+
+ /* If not safe to unload, then return success */
+ if (!SafeToUnload)
+ {
+ ObDereferenceObject(DriverObject);
+ return STATUS_SUCCESS;
+ }
+
/*
* Unload the module and release the references to the device object
@@ -1077,6 +1119,9 @@
/* Call the load/unload routine, depending on current process */
if (DriverObject->DriverUnload && DriverObject->DriverSection)
{
+ /* Set the unload invoked flag */
+ DriverObject->Flags |= DRVO_UNLOAD_INVOKED;
+
if (PsGetCurrentProcess() == PsInitialSystemProcess)
{
/* Just call right away */
Modified: trunk/reactos/ntoskrnl/io/iomgr/iomgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/iomgr.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/iomgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/iomgr.c [iso-8859-1] Tue Jun 2 16:10:17 2009
@@ -265,9 +265,10 @@
NULL,
&IoControllerObjectType))) return FALSE;
- /* Do the Device Type. FIXME: Needs Delete Routine! */
+ /* Do the Device Type */
RtlInitUnicodeString(&Name, L"Device");
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DEVICE_OBJECT);
+ ObjectTypeInitializer.DeleteProcedure = IopDeleteDevice;
ObjectTypeInitializer.ParseProcedure = IopParseDevice;
ObjectTypeInitializer.SecurityProcedure = IopSecurityFile;
if (!NT_SUCCESS(ObCreateObjectType(&Name,