Author: fireball Date: Wed Oct 3 15:54:31 2007 New Revision: 29373
URL: http://svn.reactos.org/svn/reactos?rev=29373&view=rev Log: - Use IopLoanUnloadDriver() for calling unload routine too, in the context of system process, when needed.
Modified: trunk/reactos/ntoskrnl/include/internal/io.h trunk/reactos/ntoskrnl/io/iomgr/driver.c
Modified: trunk/reactos/ntoskrnl/include/internal/io.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/io.h (original) +++ trunk/reactos/ntoskrnl/include/internal/io.h Wed Oct 3 15:54:31 2007 @@ -358,6 +358,7 @@ PUNICODE_STRING ServiceName; WORK_QUEUE_ITEM WorkItem; KEVENT Event; + PDRIVER_OBJECT DriverObject; } LOAD_UNLOAD_PARAMS, *PLOAD_UNLOAD_PARAMS;
// @@ -840,6 +841,12 @@ IopLoadServiceModule( IN PUNICODE_STRING ServiceName, OUT PLDR_DATA_TABLE_ENTRY *ModuleObject +); + +VOID +NTAPI +IopLoadUnloadDriver( + IN OUT PLOAD_UNLOAD_PARAMS LoadParams );
NTSTATUS
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 (original) +++ trunk/reactos/ntoskrnl/io/iomgr/driver.c Wed Oct 3 15:54:31 2007 @@ -927,6 +927,7 @@ UNICODE_STRING ServiceName; UNICODE_STRING ObjectName; PDRIVER_OBJECT DriverObject; + LOAD_UNLOAD_PARAMS LoadParams; NTSTATUS Status; LPWSTR Start;
@@ -1019,8 +1020,35 @@ * 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); @@ -1477,6 +1505,17 @@ PLDR_DATA_TABLE_ENTRY ModuleObject; 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 @@ 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 */