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 {