mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 05:52:56 +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
2 changed files with 59 additions and 93 deletions
|
@ -364,22 +364,8 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IopUnloadDevice(IN PDEVICE_OBJECT DeviceObject)
|
IopUnloadDevice(IN PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject;
|
PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject;
|
||||||
PEXTENDED_DEVOBJ_EXTENSION ThisExtension = IoGetDevObjExtension(DeviceObject);
|
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 */
|
/* Check if deletion is pending */
|
||||||
if (ThisExtension->ExtensionFlags & DOE_DELETE_PENDING)
|
if (ThisExtension->ExtensionFlags & DOE_DELETE_PENDING)
|
||||||
|
@ -410,45 +396,28 @@ IopUnloadDevice(IN PDEVICE_OBJECT DeviceObject)
|
||||||
ObDereferenceObject(DeviceObject);
|
ObDereferenceObject(DeviceObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop all the device objects */
|
/* We can't unload a non-PnP driver here */
|
||||||
DeviceObject = DriverObject->DeviceObject;
|
if (DriverObject->Flags & DRVO_LEGACY_DRIVER)
|
||||||
while (DeviceObject)
|
|
||||||
{
|
{
|
||||||
/*
|
DPRINT("Not a PnP driver! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
|
||||||
* Make sure we're not attached, having a reference count
|
return;
|
||||||
* 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 */
|
/* Return if we've already called unload (maybe we're in it?) */
|
||||||
DeviceObject = DriverObject->DeviceObject;
|
if (DriverObject->Flags & DRVO_UNLOAD_INVOKED) return;
|
||||||
while (DeviceObject)
|
|
||||||
{
|
|
||||||
/* Set the unload pending flag */
|
|
||||||
IoGetDevObjExtension(DeviceObject)->ExtensionFlags |= DOE_UNLOAD_PENDING;
|
|
||||||
|
|
||||||
/* Go to the next device */
|
/* We can't unload unless there's an unload handler */
|
||||||
DeviceObject = DeviceObject->NextDevice;
|
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);
|
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 */
|
/* Make object temporary so it can be deleted */
|
||||||
ObMakeTemporaryObject(DriverObject);
|
ObMakeTemporaryObject(DriverObject);
|
||||||
|
|
||||||
/* Dereference once more, referenced at driver object creation */
|
|
||||||
ObDereferenceObject(DriverObject);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -589,7 +589,7 @@ IopAttachFilterDriversCallback(
|
||||||
Status = IopInitializeDevice(DeviceNode, DriverObject);
|
Status = IopInitializeDevice(DeviceNode, DriverObject);
|
||||||
|
|
||||||
/* Remove extra reference */
|
/* Remove extra reference */
|
||||||
//ObDereferenceObject(DriverObject);
|
ObDereferenceObject(DriverObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -885,7 +885,7 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove extra reference from IopInitializeDriverModule */
|
/* Remove extra reference from IopInitializeDriverModule */
|
||||||
//ObDereferenceObject(DriverObject);
|
ObDereferenceObject(DriverObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -948,6 +948,7 @@ IopInitializeBootDrivers(VOID)
|
||||||
{
|
{
|
||||||
/* Fail */
|
/* Fail */
|
||||||
IopFreeDeviceNode(DeviceNode);
|
IopFreeDeviceNode(DeviceNode);
|
||||||
|
ObDereferenceObject(DriverObject);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -957,6 +958,7 @@ IopInitializeBootDrivers(VOID)
|
||||||
{
|
{
|
||||||
/* Fail */
|
/* Fail */
|
||||||
IopFreeDeviceNode(DeviceNode);
|
IopFreeDeviceNode(DeviceNode);
|
||||||
|
ObDereferenceObject(DriverObject);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1268,7 +1270,8 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Call the load/unload routine, depending on current process */
|
/* 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
|
/* Loop through each device object of the driver
|
||||||
and set DOE_UNLOAD_PENDING flag */
|
and set DOE_UNLOAD_PENDING flag */
|
||||||
|
@ -1484,7 +1487,7 @@ try_again:
|
||||||
RtlZeroMemory(DriverObject, ObjectSize);
|
RtlZeroMemory(DriverObject, ObjectSize);
|
||||||
DriverObject->Type = IO_TYPE_DRIVER;
|
DriverObject->Type = IO_TYPE_DRIVER;
|
||||||
DriverObject->Size = sizeof(DRIVER_OBJECT);
|
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 = (PDRIVER_EXTENSION)(DriverObject + 1);
|
||||||
DriverObject->DriverExtension->DriverObject = DriverObject;
|
DriverObject->DriverExtension->DriverObject = DriverObject;
|
||||||
DriverObject->DriverInit = InitializationFunction;
|
DriverObject->DriverInit = InitializationFunction;
|
||||||
|
@ -1585,6 +1588,10 @@ try_again:
|
||||||
*pDriverObject = DriverObject;
|
*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 */
|
/* Loop all Major Functions */
|
||||||
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
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);
|
DPRINT("Loading module from %wZ\n", &ImagePath);
|
||||||
Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
|
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);
|
DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
|
||||||
LoadParams->Status = 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
|
* 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);
|
DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
|
||||||
|
MmUnloadSystemImage(ModuleObject);
|
||||||
if (!NT_SUCCESS(Status))
|
LoadParams->Status = Status;
|
||||||
{
|
(VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
|
||||||
DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
|
return;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue