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/…
==============================================================================
--- 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 */