@@ -438,6 +438,7 @@ NTSTATUS InitializeLockHeld() {
438438 status = STATUS_NOT_SUPPORTED;
439439 }
440440 else {
441+ ++MmpGlobalDataPtr->ReferenceCount ;
441442 status = STATUS_SUCCESS;
442443 }
443444 }
@@ -448,6 +449,7 @@ NTSTATUS InitializeLockHeld() {
448449 MmpGlobalDataPtr->MajorVersion = MEMORY_MODULE_MAJOR_VERSION;
449450 MmpGlobalDataPtr->MinorVersion = MEMORY_MODULE_MINOR_VERSION;
450451 MmpGlobalDataPtr->BaseAddress = MmpGlobalDataPtr;
452+ MmpGlobalDataPtr->ReferenceCount = 1 ;
451453
452454 GetSystemInfo (&MmpGlobalDataPtr->SystemInfo );
453455
@@ -504,16 +506,74 @@ NTSTATUS InitializeLockHeld() {
504506 return status;
505507}
506508
507- NTSTATUS NTAPI Initialize () {
509+ NTSTATUS NTAPI MmInitialize () {
508510 NTSTATUS status;
509511
510- RtlAcquirePebLock ();
511- status = InitializeLockHeld ();
512- RtlReleasePebLock ();
512+ PVOID cookie;
513+ LdrLockLoaderLock (LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, nullptr , &cookie);
514+
515+ __try {
516+ status = InitializeLockHeld ();
517+ }
518+ __finally {
519+ LdrUnlockLoaderLock (LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, cookie);
520+ }
513521
514522 return status;
515523}
516524
525+ NTSTATUS CleanupLockHeld () {
526+
527+ PLIST_ENTRY ListHead = &NtCurrentPeb ()->Ldr ->InLoadOrderModuleList , ListEntry = ListHead->Flink ;
528+ PLDR_DATA_TABLE_ENTRY CurEntry;
529+
530+ while (ListEntry != ListHead) {
531+ CurEntry = CONTAINING_RECORD (ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
532+ ListEntry = ListEntry->Flink ;
533+
534+ if (IsValidMemoryModuleHandle ((HMEMORYMODULE)CurEntry->DllBase )) {
535+
536+ //
537+ // Make sure all memory module is unloaded.
538+ //
539+
540+ return STATUS_NOT_SUPPORTED;
541+ }
542+ }
543+
544+ if (--MmpGlobalDataPtr->ReferenceCount > 0 ) {
545+ return STATUS_SUCCESS;
546+ }
547+
548+ MmpTlsCleanup ();
549+ MmpCleanupDotNetHooks ();
550+
551+ NtUnmapViewOfSection (NtCurrentProcess (), MmpGlobalDataPtr->BaseAddress );
552+ MmpGlobalDataPtr = nullptr ;
553+ return STATUS_SUCCESS;
554+ }
555+
556+ NTSTATUS NTAPI MmCleanup () {
557+ NTSTATUS status;
558+ PVOID cookie;
559+ LdrLockLoaderLock (LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, nullptr , &cookie);
560+
561+ __try {
562+
563+ if (MmpGlobalDataPtr == nullptr ) {
564+ status = STATUS_ACCESS_VIOLATION;
565+ __leave;
566+ }
567+
568+ status = CleanupLockHeld ();
569+ }
570+ __finally {
571+ LdrUnlockLoaderLock (LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, cookie);
572+ }
573+
574+ return status;
575+ }
576+
517577#ifdef _USRDLL
518578extern " C" __declspec(dllexport) BOOL WINAPI ReflectiveMapDll (HMODULE hModule) {
519579 PIMAGE_NT_HEADERS headers = RtlImageNtHeader (hModule);
@@ -542,7 +602,8 @@ extern "C" __declspec(dllexport) BOOL WINAPI ReflectiveMapDll(HMODULE hModule) {
542602
543603BOOL APIENTRY DllMain (HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
544604 if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
545- if (NT_SUCCESS (Initialize ())) {
605+ #ifdef _HAS_AUTO_INITIALIZE
606+ if (NT_SUCCESS (MmInitialize ())) {
546607 if (lpReserved == (PVOID)-1 ) {
547608 if (!ReflectiveMapDll (hModule)) {
548609 RtlRaiseStatus (STATUS_NOT_SUPPORTED);
@@ -553,10 +614,13 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser
553614 }
554615
555616 return FALSE ;
617+ #endif
556618 }
557619
558620 return TRUE ;
559621}
560622#else
561- const NTSTATUS Initializer = Initialize();
623+ #ifdef _HAS_AUTO_INITIALIZE
624+ const NTSTATUS Initializer = MmInitialize();
625+ #endif
562626#endif
0 commit comments