diff --git a/reactos/ntoskrnl/io/iomgr/device.c b/reactos/ntoskrnl/io/iomgr/device.c index 029c4c2cb41..b4336907699 100644 --- a/reactos/ntoskrnl/io/iomgr/device.c +++ b/reactos/ntoskrnl/io/iomgr/device.c @@ -364,22 +364,8 @@ VOID NTAPI IopUnloadDevice(IN PDEVICE_OBJECT DeviceObject) { -#if 0 PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject; PEXTENDED_DEVOBJ_EXTENSION ThisExtension = IoGetDevObjExtension(DeviceObject); - PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject); - - /* Return if we've already called unload (maybe we're in it?) */ - if (DriverObject->Flags & DRVO_UNLOAD_INVOKED) return; - - /* 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); - - return; - } /* Check if deletion is pending */ if (ThisExtension->ExtensionFlags & DOE_DELETE_PENDING) @@ -410,45 +396,28 @@ IopUnloadDevice(IN PDEVICE_OBJECT DeviceObject) ObDereferenceObject(DeviceObject); } - /* Loop all the device objects */ - DeviceObject = DriverObject->DeviceObject; - while (DeviceObject) + /* We can't unload a non-PnP driver here */ + if (DriverObject->Flags & DRVO_LEGACY_DRIVER) { - /* - * 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; + DPRINT("Not a PnP driver! '%wZ' will not be unloaded!\n", &DriverObject->DriverName); + return; } - /* Loop all the device objects */ - DeviceObject = DriverObject->DeviceObject; - while (DeviceObject) - { - /* Set the unload pending flag */ - IoGetDevObjExtension(DeviceObject)->ExtensionFlags |= DOE_UNLOAD_PENDING; + /* Return if we've already called unload (maybe we're in it?) */ + if (DriverObject->Flags & DRVO_UNLOAD_INVOKED) return; - /* Go to the next device */ - DeviceObject = DeviceObject->NextDevice; + /* We can't unload unless there's an unload handler */ + if (!DriverObject->DriverUnload) + { + DPRINT1("No DriverUnload function on PnP driver! '%wZ' will not be unloaded!\n", &DriverObject->DriverName); + return; + } + + /* 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 @@ IopUnloadDevice(IN PDEVICE_OBJECT DeviceObject) /* Make object temporary so it can be deleted */ ObMakeTemporaryObject(DriverObject); - - /* Dereference once more, referenced at driver object creation */ - ObDereferenceObject(DriverObject); -#endif } VOID diff --git a/reactos/ntoskrnl/io/iomgr/driver.c b/reactos/ntoskrnl/io/iomgr/driver.c index 7f146a7f84a..75acb515987 100644 --- a/reactos/ntoskrnl/io/iomgr/driver.c +++ b/reactos/ntoskrnl/io/iomgr/driver.c @@ -589,7 +589,7 @@ IopAttachFilterDriversCallback( Status = IopInitializeDevice(DeviceNode, DriverObject); /* Remove extra reference */ - //ObDereferenceObject(DriverObject); + ObDereferenceObject(DriverObject); } return STATUS_SUCCESS; @@ -885,7 +885,7 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry) } /* Remove extra reference from IopInitializeDriverModule */ - //ObDereferenceObject(DriverObject); + ObDereferenceObject(DriverObject); return Status; } @@ -948,6 +948,7 @@ IopInitializeBootDrivers(VOID) { /* Fail */ IopFreeDeviceNode(DeviceNode); + ObDereferenceObject(DriverObject); return; } @@ -957,6 +958,7 @@ IopInitializeBootDrivers(VOID) { /* Fail */ IopFreeDeviceNode(DeviceNode); + ObDereferenceObject(DriverObject); return; } @@ -1268,7 +1270,8 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers) */ /* 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 @@ try_again: 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; @@ -1585,6 +1588,10 @@ try_again: *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 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) 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 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) /* * 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 {