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…
==============================================================================
--- 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…
==============================================================================
--- 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
{