diff --git a/reactos/ntoskrnl/ex/sysinfo.c b/reactos/ntoskrnl/ex/sysinfo.c index 5f5450659a0..c0637d5e0c0 100644 --- a/reactos/ntoskrnl/ex/sysinfo.c +++ b/reactos/ntoskrnl/ex/sysinfo.c @@ -139,17 +139,6 @@ ExpQueryModuleInformation(IN PLIST_ENTRY KernelModeList, /* FUNCTIONS *****************************************************************/ -/* - * @implemented - */ -#undef ExGetPreviousMode -KPROCESSOR_MODE -NTAPI -ExGetPreviousMode (VOID) -{ - return KeGetPreviousMode(); -} - /* * @implemented */ @@ -1006,12 +995,23 @@ QSI_DEF(SystemCallTimeInformation) /* Class 11 - Module Information */ QSI_DEF(SystemModuleInformation) { - extern LIST_ENTRY PsLoadedModuleList; - return ExpQueryModuleInformation(&PsLoadedModuleList, - NULL, - (PRTL_PROCESS_MODULES)Buffer, - Size, - ReqSize); + NTSTATUS Status; + + /* Acquire system module list lock */ + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&PsLoadedModuleResource, TRUE); + + /* Call the generic handler with the system module list */ + Status = ExpQueryModuleInformation(&PsLoadedModuleList, + &MmLoadedUserImageList, + (PRTL_PROCESS_MODULES)Buffer, + Size, + ReqSize); + + /* Release list lock and return status */ + ExReleaseResourceLite(&PsLoadedModuleResource); + KeLeaveCriticalRegion(); + return Status; } /* Class 12 - Locks Information */ @@ -1322,10 +1322,9 @@ QSI_DEF(SystemFullMemoryInformation) SSI_DEF(SystemLoadGdiDriverInformation) { PSYSTEM_GDI_DRIVER_INFORMATION DriverInfo = (PVOID)Buffer; - KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); UNICODE_STRING ImageName; PVOID ImageBase; - PLDR_DATA_TABLE_ENTRY ModuleObject; + PVOID SectionPointer; ULONG_PTR EntryPoint; NTSTATUS Status; ULONG DirSize; @@ -1338,8 +1337,8 @@ SSI_DEF(SystemLoadGdiDriverInformation) return STATUS_INFO_LENGTH_MISMATCH; } - /* Only kernel-mode can call this function */ - if (PreviousMode != KernelMode) return STATUS_PRIVILEGE_NOT_HELD; + /* Only kernel mode can call this function */ + if (ExGetPreviousMode() != KernelMode) return STATUS_PRIVILEGE_NOT_HELD; /* Load the driver */ ImageName = DriverInfo->DriverName; @@ -1347,7 +1346,7 @@ SSI_DEF(SystemLoadGdiDriverInformation) NULL, NULL, 0, - (PVOID)&ModuleObject, + &SectionPointer, &ImageBase); if (!NT_SUCCESS(Status)) return Status; @@ -1365,7 +1364,7 @@ SSI_DEF(SystemLoadGdiDriverInformation) /* Save other data */ DriverInfo->ImageAddress = ImageBase; - DriverInfo->SectionPointer = NULL; + DriverInfo->SectionPointer = SectionPointer; DriverInfo->EntryPoint = (PVOID)EntryPoint; DriverInfo->ImageLength = NtHeader->OptionalHeader.SizeOfImage; @@ -1376,44 +1375,21 @@ SSI_DEF(SystemLoadGdiDriverInformation) /* Class 27 - Unload Image */ SSI_DEF(SystemUnloadGdiDriverInformation) { - PLDR_DATA_TABLE_ENTRY LdrEntry; - PLIST_ENTRY NextEntry; - PVOID BaseAddr = *((PVOID*)Buffer); + PVOID SectionPointer = Buffer; - if(Size != sizeof(PVOID)) + /* Validate size */ + if (Size != sizeof(PVOID)) + { + /* Incorrect length, fail */ return STATUS_INFO_LENGTH_MISMATCH; - - if(KeGetPreviousMode() != KernelMode) - return STATUS_PRIVILEGE_NOT_HELD; - - // Scan the module list - NextEntry = PsLoadedModuleList.Flink; - while(NextEntry != &PsLoadedModuleList) - { - LdrEntry = CONTAINING_RECORD(NextEntry, - LDR_DATA_TABLE_ENTRY, - InLoadOrderLinks); - - if (LdrEntry->DllBase == BaseAddr) - { - // Found it. - break; - } - - NextEntry = NextEntry->Flink; } - // Check if we found the image - if(NextEntry != &PsLoadedModuleList) - { - return MmUnloadSystemImage(LdrEntry); - } - else - { - DPRINT1("Image 0x%x not found.\n", BaseAddr); - return STATUS_DLL_NOT_FOUND; - } + /* Only kernel mode can call this function */ + if (ExGetPreviousMode() != KernelMode) return STATUS_PRIVILEGE_NOT_HELD; + /* Unload the image */ + MmUnloadSystemImage(SectionPointer); + return STATUS_SUCCESS; } /* Class 28 - Time Adjustment Information */ @@ -1986,7 +1962,6 @@ NtSetSystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, return STATUS_INVALID_INFO_CLASS; } - NTSTATUS NTAPI NtFlushInstructionCache(IN HANDLE ProcessHandle, @@ -2018,4 +1993,13 @@ NtGetCurrentProcessorNumber(VOID) return KeGetCurrentProcessorNumber(); } -/* EOF */ +/* + * @implemented + */ +#undef ExGetPreviousMode +KPROCESSOR_MODE +NTAPI +ExGetPreviousMode (VOID) +{ + return KeGetPreviousMode(); +} diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index d7dc087d826..79adab4672b 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -28,6 +28,8 @@ extern MEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorOrg; extern LIST_ENTRY MmLoadedUserImageList; +extern KMUTANT MmSystemLoadLock; + extern ULONG MmNumberOfPagingFiles; extern PVOID MmUnloadedDrivers; diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index 50f32626f47..1d55e3068ff 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -434,6 +434,8 @@ extern POBJECT_TYPE PsJobType; extern LARGE_INTEGER ShortPsLockDelay; extern UNICODE_STRING PsNtDllPathName; extern LIST_ENTRY PsLoadedModuleList; +extern KSPIN_LOCK PsLoadedModuleSpinLock; +extern ERESOURCE PsLoadedModuleResource; extern ULONG_PTR PsNtosImageBase; // diff --git a/reactos/ntoskrnl/io/iomgr/driver.c b/reactos/ntoskrnl/io/iomgr/driver.c index c162bdb08dd..4dc022fb93f 100644 --- a/reactos/ntoskrnl/io/iomgr/driver.c +++ b/reactos/ntoskrnl/io/iomgr/driver.c @@ -692,8 +692,6 @@ MiResolveImageReferences(IN PVOID ImageBase, OUT PWCHAR *MissingDriver, OUT PLOAD_IMPORTS *LoadImports); -extern KSPIN_LOCK PsLoadedModuleSpinLock; - // // Used for images already loaded (boot drivers) // diff --git a/reactos/ntoskrnl/mm/ARM3/drvmgmt.c b/reactos/ntoskrnl/mm/ARM3/drvmgmt.c index 11ecbc1822d..4811a441dd4 100644 --- a/reactos/ntoskrnl/mm/ARM3/drvmgmt.c +++ b/reactos/ntoskrnl/mm/ARM3/drvmgmt.c @@ -21,8 +21,6 @@ MM_DRIVER_VERIFIER_DATA MmVerifierData; LIST_ENTRY MiVerifierDriverAddedThunkListHead; ULONG MiActiveVerifierThunks; -extern KMUTANT MmSystemLoadLock; -extern LIST_ENTRY PsLoadedModuleList; /* PRIVATE FUNCTIONS *********************************************************/ diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index d964c22388b..c9a837dd678 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -56,7 +56,6 @@ ULONG MmReadClusterSize; UCHAR MmDisablePagingExecutive = 1; // Forced to off PMMPTE MmSharedUserDataPte; PMMSUPPORT MmKernelAddressSpace; -extern KMUTANT MmSystemLoadLock; BOOLEAN MiDbgEnableMdDump = #ifdef _ARM_ TRUE; diff --git a/reactos/ntoskrnl/mm/sysldr.c b/reactos/ntoskrnl/mm/sysldr.c index f6177e4479f..26f36f8ee20 100644 --- a/reactos/ntoskrnl/mm/sysldr.c +++ b/reactos/ntoskrnl/mm/sysldr.c @@ -30,6 +30,7 @@ sprintf_nt(IN PCHAR Buffer, LIST_ENTRY PsLoadedModuleList; LIST_ENTRY MmLoadedUserImageList; KSPIN_LOCK PsLoadedModuleSpinLock; +ERESOURCE PsLoadedModuleResource; ULONG_PTR PsNtosImageBase; KMUTANT MmSystemLoadLock; @@ -438,15 +439,21 @@ MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry, { KIRQL OldIrql; - /* Acquire the lock */ - KeAcquireSpinLock(&PsLoadedModuleSpinLock, &OldIrql); + /* Acquire module list lock */ + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&PsLoadedModuleResource, TRUE); + + /* Acquire the spinlock too as we will insert or remove the entry */ + OldIrql = KeAcquireSpinLockRaiseToSynch(&PsLoadedModuleSpinLock); /* Insert or remove from the list */ Insert ? InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks) : RemoveEntryList(&LdrEntry->InLoadOrderLinks); - /* Release the lock */ + /* Release locks */ KeReleaseSpinLock(&PsLoadedModuleSpinLock, OldIrql); + ExReleaseResourceLite(&PsLoadedModuleResource); + KeLeaveCriticalRegion(); } VOID @@ -1332,7 +1339,8 @@ MiInitializeLoadedModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock) PLIST_ENTRY ListHead, NextEntry; ULONG EntrySize; - /* Setup the loaded module list and lock */ + /* Setup the loaded module list and locks */ + ExInitializeResourceLite(&PsLoadedModuleResource); KeInitializeSpinLock(&PsLoadedModuleSpinLock); InitializeListHead(&PsLoadedModuleList); @@ -2005,6 +2013,7 @@ MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName) /* Lock the list */ KeEnterCriticalRegion(); + ExAcquireResourceSharedLite(&PsLoadedModuleResource, TRUE); /* Loop the loaded module list */ NextEntry = PsLoadedModuleList.Flink; @@ -2046,6 +2055,7 @@ MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName) } /* Release the lock */ + ExReleaseResourceLite(&PsLoadedModuleResource); KeLeaveCriticalRegion(); /* Free the string and return */ diff --git a/reactos/subsystems/win32/win32k/ldr/loader.c b/reactos/subsystems/win32/win32k/ldr/loader.c index 945b0f4422d..838483efafe 100644 --- a/reactos/subsystems/win32/win32k/ldr/loader.c +++ b/reactos/subsystems/win32/win32k/ldr/loader.c @@ -29,12 +29,13 @@ typedef struct _DRIVERS { LIST_ENTRY ListEntry; - HANDLE ImageHandle; + PVOID SectionPointer; UNICODE_STRING DriverName; }DRIVERS, *PDRIVERS; extern LIST_ENTRY GlobalDriverListHead; + /* * Blatantly stolen from ldr/utils.c in ntdll. I can't link ntdll from * here, though. @@ -199,8 +200,8 @@ HANDLE APIENTRY EngLoadImage (LPWSTR DriverName) { - HANDLE hImageHandle = NULL; SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo; + PDRIVERS DriverInfo = NULL; NTSTATUS Status; RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName); @@ -213,14 +214,14 @@ EngLoadImage (LPWSTR DriverName) { Current = CONTAINING_RECORD(CurrentEntry, DRIVERS, ListEntry); if( Current && (0 == RtlCompareUnicodeString(&GdiDriverInfo.DriverName, &Current->DriverName, FALSE)) ) { - hImageHandle = Current->ImageHandle; + DriverInfo = Current; break; } CurrentEntry = CurrentEntry->Flink; }; } - if( !hImageHandle ) + if( !DriverInfo ) { /* the driver was not loaded before, so let's do that */ Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION)); @@ -228,19 +229,17 @@ EngLoadImage (LPWSTR DriverName) DPRINT1("ZwSetSystemInformation failed with Status 0x%lx\n", Status); } else { - PDRIVERS DriverInfo; - hImageHandle = (HANDLE)GdiDriverInfo.ImageAddress; DriverInfo = ExAllocatePool(PagedPool, sizeof(DRIVERS)); DriverInfo->DriverName.MaximumLength = GdiDriverInfo.DriverName.MaximumLength; DriverInfo->DriverName.Length = GdiDriverInfo.DriverName.Length; DriverInfo->DriverName.Buffer = ExAllocatePool(PagedPool, GdiDriverInfo.DriverName.MaximumLength); RtlCopyUnicodeString(&DriverInfo->DriverName, &GdiDriverInfo.DriverName); - DriverInfo->ImageHandle = hImageHandle; + DriverInfo->SectionPointer = GdiDriverInfo.SectionPointer; InsertHeadList(&GlobalDriverListHead, &DriverInfo->ListEntry); } } - return hImageHandle; + return DriverInfo; } VOID @@ -248,11 +247,12 @@ APIENTRY EngUnloadImage ( IN HANDLE hModule ) { NTSTATUS Status; + PDRIVERS DriverInfo = (PDRIVERS)hModule; DPRINT("hModule 0x%x\n", hModule); Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation, - &hModule, sizeof(HANDLE)); + DriverInfo->SectionPointer, sizeof(PVOID)); if(!NT_SUCCESS(Status)) { @@ -261,27 +261,9 @@ EngUnloadImage ( IN HANDLE hModule ) } else { - /* remove from the list */ - if( !IsListEmpty(&GlobalDriverListHead) ) - { - PLIST_ENTRY CurrentEntry = GlobalDriverListHead.Flink; - PDRIVERS Current; - /* probably the driver was already loaded, let's try to find it out */ - while( CurrentEntry != &GlobalDriverListHead ) - { - Current = CONTAINING_RECORD(CurrentEntry, DRIVERS, ListEntry); - - if( Current ) { - if(Current->ImageHandle == hModule) { - ExFreePool(Current->DriverName.Buffer); - RemoveEntryList(&Current->ListEntry); - ExFreePool(Current); - break; - } - } - CurrentEntry = CurrentEntry->Flink; - }; - } + ExFreePool(DriverInfo->DriverName.Buffer); + RemoveEntryList(&DriverInfo->ListEntry); + ExFreePool(DriverInfo); } }