mirror of
https://github.com/reactos/reactos.git
synced 2024-10-04 16:36:11 +00:00
[NTOSKRNL]
- Reenable some dereferences of the driver object - Fix return values in NtLoadDriver - Split unloading into code for legacy drivers and non-legacy drivers svn path=/trunk/; revision=56184
This commit is contained in:
parent
295501f398
commit
326be77908
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue