mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
- Use IopLoanUnloadDriver() for calling unload routine too, in the context of system process, when needed.
svn path=/trunk/; revision=29373
This commit is contained in:
parent
d0ae8b7806
commit
a68ed2f38a
2 changed files with 48 additions and 1 deletions
|
@ -358,6 +358,7 @@ typedef struct _LOAD_UNLOAD_PARAMS
|
|||
PUNICODE_STRING ServiceName;
|
||||
WORK_QUEUE_ITEM WorkItem;
|
||||
KEVENT Event;
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
} LOAD_UNLOAD_PARAMS, *PLOAD_UNLOAD_PARAMS;
|
||||
|
||||
//
|
||||
|
@ -842,6 +843,12 @@ IopLoadServiceModule(
|
|||
OUT PLDR_DATA_TABLE_ENTRY *ModuleObject
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
IopLoadUnloadDriver(
|
||||
IN OUT PLOAD_UNLOAD_PARAMS LoadParams
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
FASTCALL
|
||||
IopInitializeDriverModule(
|
||||
|
|
|
@ -927,6 +927,7 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
|
|||
UNICODE_STRING ServiceName;
|
||||
UNICODE_STRING ObjectName;
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
LOAD_UNLOAD_PARAMS LoadParams;
|
||||
NTSTATUS Status;
|
||||
LPWSTR Start;
|
||||
|
||||
|
@ -1019,8 +1020,35 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
|
|||
* Unload the module and release the references to the device object
|
||||
*/
|
||||
|
||||
/* Call the load/unload routine, depending on current process */
|
||||
if (DriverObject->DriverUnload)
|
||||
(*DriverObject->DriverUnload)(DriverObject);
|
||||
{
|
||||
if (PsGetCurrentProcess() == PsInitialSystemProcess)
|
||||
{
|
||||
/* Just call right away */
|
||||
(*DriverObject->DriverUnload)(DriverObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Load/Unload must be called from system process */
|
||||
|
||||
/* Prepare parameters block */
|
||||
LoadParams.DriverObject = DriverObject;
|
||||
KeInitializeEvent(&LoadParams.Event, NotificationEvent, FALSE);
|
||||
|
||||
ExInitializeWorkItem(&LoadParams.WorkItem,
|
||||
(PWORKER_THREAD_ROUTINE)IopLoadUnloadDriver,
|
||||
(PVOID)&LoadParams);
|
||||
|
||||
/* Queue it */
|
||||
ExQueueWorkItem(&LoadParams.WorkItem, DelayedWorkQueue);
|
||||
|
||||
/* And wait when it completes */
|
||||
KeWaitForSingleObject(&LoadParams.Event, UserRequest, KernelMode,
|
||||
FALSE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ObDereferenceObject(DriverObject);
|
||||
ObDereferenceObject(DriverObject);
|
||||
MmUnloadSystemImage(DriverObject->DriverSection);
|
||||
|
@ -1478,6 +1506,17 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
|
|||
PDRIVER_OBJECT DriverObject;
|
||||
WCHAR *cur;
|
||||
|
||||
/* Check if it's an unload request */
|
||||
if (LoadParams->DriverObject)
|
||||
{
|
||||
(*DriverObject->DriverUnload)(DriverObject);
|
||||
|
||||
/* Return success and signal the event */
|
||||
LoadParams->Status = STATUS_SUCCESS;
|
||||
(VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&ImagePath, NULL);
|
||||
|
||||
/*
|
||||
|
@ -1675,6 +1714,7 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
|
|||
DPRINT("NtLoadDriver('%wZ')\n", &CapturedDriverServiceName);
|
||||
|
||||
LoadParams.ServiceName = &CapturedDriverServiceName;
|
||||
LoadParams.DriverObject = NULL;
|
||||
KeInitializeEvent(&LoadParams.Event, NotificationEvent, FALSE);
|
||||
|
||||
/* Call the load/unload routine, depending on current process */
|
||||
|
|
Loading…
Reference in a new issue