From: Mark Jansen Date: Sun, 29 Jul 2018 15:40:42 +0000 (+0200) Subject: [LDR] Guard some sections where we grab a lock. X-Git-Tag: 0.4.11-dev~154 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=ad08c6631b4707c48b2124821b5a80b8372e2468 [LDR] Guard some sections where we grab a lock. CORE-14532 --- diff --git a/dll/ntdll/ldr/ldrapi.c b/dll/ntdll/ldr/ldrapi.c index 15f36bb2be7..b151163dd40 100644 --- a/dll/ntdll/ldr/ldrapi.c +++ b/dll/ntdll/ldr/ldrapi.c @@ -353,73 +353,80 @@ LdrLoadDll(IN PWSTR SearchPath OPTIONAL, /* Check if there's a TLD DLL being loaded */ OldTldDll = LdrpTopLevelDllBeingLoaded; - if (OldTldDll) + _SEH2_TRY { - /* This is a recursive load, do something about it? */ - if ((ShowSnaps) || (LdrpShowRecursiveLoads) || (LdrpBreakOnRecursiveDllLoads)) + + if (OldTldDll) { - /* Print out debug messages */ - DPRINT1("[%p, %p] LDR: Recursive DLL Load\n", - Teb->RealClientId.UniqueProcess, - Teb->RealClientId.UniqueThread); - DPRINT1("[%p, %p] Previous DLL being loaded \"%wZ\"\n", - Teb->RealClientId.UniqueProcess, - Teb->RealClientId.UniqueThread, - OldTldDll); - DPRINT1("[%p, %p] DLL being requested \"%wZ\"\n", - Teb->RealClientId.UniqueProcess, - Teb->RealClientId.UniqueThread, - DllName); - - /* Was it initializing too? */ - if (!LdrpCurrentDllInitializer) + /* This is a recursive load, do something about it? */ + if ((ShowSnaps) || (LdrpShowRecursiveLoads) || (LdrpBreakOnRecursiveDllLoads)) { - DPRINT1("[%p, %p] LDR: No DLL Initializer was running\n", + /* Print out debug messages */ + DPRINT1("[%p, %p] LDR: Recursive DLL Load\n", Teb->RealClientId.UniqueProcess, Teb->RealClientId.UniqueThread); - } - else - { - DPRINT1("[%p, %p] DLL whose initializer was currently running \"%wZ\"\n", - Teb->ClientId.UniqueProcess, - Teb->ClientId.UniqueThread, - &LdrpCurrentDllInitializer->BaseDllName); + DPRINT1("[%p, %p] Previous DLL being loaded \"%wZ\"\n", + Teb->RealClientId.UniqueProcess, + Teb->RealClientId.UniqueThread, + OldTldDll); + DPRINT1("[%p, %p] DLL being requested \"%wZ\"\n", + Teb->RealClientId.UniqueProcess, + Teb->RealClientId.UniqueThread, + DllName); + + /* Was it initializing too? */ + if (!LdrpCurrentDllInitializer) + { + DPRINT1("[%p, %p] LDR: No DLL Initializer was running\n", + Teb->RealClientId.UniqueProcess, + Teb->RealClientId.UniqueThread); + } + else + { + DPRINT1("[%p, %p] DLL whose initializer was currently running \"%wZ\"\n", + Teb->ClientId.UniqueProcess, + Teb->ClientId.UniqueThread, + &LdrpCurrentDllInitializer->BaseDllName); + } } } - } - /* Set this one as the TLD DLL being loaded*/ - LdrpTopLevelDllBeingLoaded = DllName; + /* Set this one as the TLD DLL being loaded*/ + LdrpTopLevelDllBeingLoaded = DllName; - /* Load the DLL */ - Status = LdrpLoadDll(RedirectedDll, - SearchPath, - DllCharacteristics, - DllName, - BaseAddress, - TRUE); - if (NT_SUCCESS(Status)) - { - Status = STATUS_SUCCESS; + /* Load the DLL */ + Status = LdrpLoadDll(RedirectedDll, + SearchPath, + DllCharacteristics, + DllName, + BaseAddress, + TRUE); + if (NT_SUCCESS(Status)) + { + Status = STATUS_SUCCESS; + } + else if ((Status != STATUS_NO_SUCH_FILE) && + (Status != STATUS_DLL_NOT_FOUND) && + (Status != STATUS_OBJECT_NAME_NOT_FOUND) && + (Status != STATUS_DLL_INIT_FAILED)) + { + DbgPrintEx(DPFLTR_LDR_ID, + DPFLTR_WARNING_LEVEL, + "LDR: %s - failing because LdrpLoadDll(%wZ) returned status %x\n", + __FUNCTION__, + DllName, + Status); + } } - else if ((Status != STATUS_NO_SUCH_FILE) && - (Status != STATUS_DLL_NOT_FOUND) && - (Status != STATUS_OBJECT_NAME_NOT_FOUND) && - (Status != STATUS_DLL_INIT_FAILED)) + _SEH2_FINALLY { - DbgPrintEx(DPFLTR_LDR_ID, - DPFLTR_WARNING_LEVEL, - "LDR: %s - failing because LdrpLoadDll(%wZ) returned status %x\n", - __FUNCTION__, - DllName, - Status); - } - - /* Restore the old TLD DLL */ - LdrpTopLevelDllBeingLoaded = OldTldDll; + /* Restore the old TLD DLL */ + LdrpTopLevelDllBeingLoaded = OldTldDll; - /* Release the lock */ - LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie); + /* Release the lock */ + LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie); + } + _SEH2_END; /* Do we have a redirect string? */ if (DllString2.Buffer) RtlFreeUnicodeString(&DllString2); diff --git a/dll/ntdll/ldr/ldrutils.c b/dll/ntdll/ldr/ldrutils.c index 5f55938d138..aa18d0384f4 100644 --- a/dll/ntdll/ldr/ldrutils.c +++ b/dll/ntdll/ldr/ldrutils.c @@ -2488,146 +2488,153 @@ LdrpLoadDll(IN BOOLEAN Redirected, /* Check for init flag and acquire lock */ if (!InInit) RtlEnterCriticalSection(&LdrpLoaderLock); - /* Show debug message */ - if (ShowSnaps) + _SEH2_TRY { - DPRINT1("LDR: LdrLoadDll, loading %wZ from %ws\n", - &RawDllName, - DllPath ? DllPath : L""); - } - - /* Check if the DLL is already loaded */ - if (!LdrpCheckForLoadedDll(DllPath, - &RawDllName, - FALSE, - Redirected, - &LdrEntry)) - { - /* Map it */ - Status = LdrpMapDll(DllPath, - DllPath, - NameBuffer, - DllCharacteristics, - FALSE, - Redirected, - &LdrEntry); - if (!NT_SUCCESS(Status)) goto Quickie; - - /* FIXME: Need to mark the DLL range for the stack DB */ - //RtlpStkMarkDllRange(LdrEntry); - - /* Check if IMAGE_FILE_EXECUTABLE_IMAGE was provided */ - if ((DllCharacteristics) && - (*DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) + /* Show debug message */ + if (ShowSnaps) { - /* This is not a DLL, so remove such data */ - LdrEntry->EntryPoint = NULL; - LdrEntry->Flags &= ~LDRP_IMAGE_DLL; + DPRINT1("LDR: LdrLoadDll, loading %wZ from %ws\n", + &RawDllName, + DllPath ? DllPath : L""); } - /* Make sure it's a DLL */ - if (LdrEntry->Flags & LDRP_IMAGE_DLL) + /* Check if the DLL is already loaded */ + if (!LdrpCheckForLoadedDll(DllPath, + &RawDllName, + FALSE, + Redirected, + &LdrEntry)) { - /* Check if this is a .NET Image */ - if (!(LdrEntry->Flags & LDRP_COR_IMAGE)) - { - /* Walk the Import Descriptor */ - Status = LdrpWalkImportDescriptor(DllPath, LdrEntry); - } + /* Map it */ + Status = LdrpMapDll(DllPath, + DllPath, + NameBuffer, + DllCharacteristics, + FALSE, + Redirected, + &LdrEntry); + if (!NT_SUCCESS(Status)) + _SEH2_LEAVE; - /* Update load count, unless it's locked */ - if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++; - LdrpUpdateLoadCount2(LdrEntry, LDRP_UPDATE_REFCOUNT); + /* FIXME: Need to mark the DLL range for the stack DB */ + //RtlpStkMarkDllRange(LdrEntry); - /* Check if we failed */ - if (!NT_SUCCESS(Status)) + /* Check if IMAGE_FILE_EXECUTABLE_IMAGE was provided */ + if ((DllCharacteristics) && + (*DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) { - /* Clear entrypoint, and insert into list */ + /* This is not a DLL, so remove such data */ LdrEntry->EntryPoint = NULL; - InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, - &LdrEntry->InInitializationOrderLinks); - - /* Cancel the load */ - LdrpClearLoadInProgress(); + LdrEntry->Flags &= ~LDRP_IMAGE_DLL; + } - /* Unload the DLL */ - if (ShowSnaps) + /* Make sure it's a DLL */ + if (LdrEntry->Flags & LDRP_IMAGE_DLL) + { + /* Check if this is a .NET Image */ + if (!(LdrEntry->Flags & LDRP_COR_IMAGE)) { - DbgPrint("LDR: Unloading %wZ due to error %x walking " - "import descriptors\n", - DllName, - Status); + /* Walk the Import Descriptor */ + Status = LdrpWalkImportDescriptor(DllPath, LdrEntry); } - LdrUnloadDll(LdrEntry->DllBase); - /* Return the error */ - goto Quickie; - } - } - else if (LdrEntry->LoadCount != 0xFFFF) - { - /* Increase load count */ - LdrEntry->LoadCount++; - } + /* Update load count, unless it's locked */ + if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++; + LdrpUpdateLoadCount2(LdrEntry, LDRP_UPDATE_REFCOUNT); - /* Insert it into the list */ - InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, - &LdrEntry->InInitializationOrderLinks); + /* Check if we failed */ + if (!NT_SUCCESS(Status)) + { + /* Clear entrypoint, and insert into list */ + LdrEntry->EntryPoint = NULL; + InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, + &LdrEntry->InInitializationOrderLinks); - /* If we have to run the entrypoint, make sure the DB is ready */ - if (CallInit && LdrpLdrDatabaseIsSetup) - { - /* Notify Shim Engine */ - if (g_ShimsEnabled) + /* Cancel the load */ + LdrpClearLoadInProgress(); + + /* Unload the DLL */ + if (ShowSnaps) + { + DbgPrint("LDR: Unloading %wZ due to error %x walking " + "import descriptors\n", + DllName, + Status); + } + LdrUnloadDll(LdrEntry->DllBase); + + /* Return the error */ + _SEH2_LEAVE; + } + } + else if (LdrEntry->LoadCount != 0xFFFF) { - VOID (NTAPI* SE_DllLoaded)(PLDR_DATA_TABLE_ENTRY) = RtlDecodeSystemPointer(g_pfnSE_DllLoaded); - SE_DllLoaded(LdrEntry); + /* Increase load count */ + LdrEntry->LoadCount++; } - /* Run the init routine */ - Status = LdrpRunInitializeRoutines(NULL); - if (!NT_SUCCESS(Status)) + /* Insert it into the list */ + InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, + &LdrEntry->InInitializationOrderLinks); + + /* If we have to run the entrypoint, make sure the DB is ready */ + if (CallInit && LdrpLdrDatabaseIsSetup) { - /* Failed, unload the DLL */ - if (ShowSnaps) + /* Notify Shim Engine */ + if (g_ShimsEnabled) { - DbgPrint("LDR: Unloading %wZ because either its init " - "routine or one of its static imports failed; " - "status = 0x%08lx\n", - DllName, - Status); + VOID (NTAPI* SE_DllLoaded)(PLDR_DATA_TABLE_ENTRY) = RtlDecodeSystemPointer(g_pfnSE_DllLoaded); + SE_DllLoaded(LdrEntry); + } + + /* Run the init routine */ + Status = LdrpRunInitializeRoutines(NULL); + if (!NT_SUCCESS(Status)) + { + /* Failed, unload the DLL */ + if (ShowSnaps) + { + DbgPrint("LDR: Unloading %wZ because either its init " + "routine or one of its static imports failed; " + "status = 0x%08lx\n", + DllName, + Status); + } + LdrUnloadDll(LdrEntry->DllBase); } - LdrUnloadDll(LdrEntry->DllBase); + } + else + { + /* The DB isn't ready, which means we were loaded because of a forwarder */ + Status = STATUS_SUCCESS; } } else { - /* The DB isn't ready, which means we were loaded because of a forwarder */ - Status = STATUS_SUCCESS; + /* We were already loaded. Are we a DLL? */ + if ((LdrEntry->Flags & LDRP_IMAGE_DLL) && (LdrEntry->LoadCount != 0xFFFF)) + { + /* Increase load count */ + LdrEntry->LoadCount++; + LdrpUpdateLoadCount2(LdrEntry, LDRP_UPDATE_REFCOUNT); + + /* Clear the load in progress */ + LdrpClearLoadInProgress(); + } + else + { + /* Not a DLL, just increase the load count */ + if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++; + } } + } - else + _SEH2_FINALLY { - /* We were already loaded. Are we a DLL? */ - if ((LdrEntry->Flags & LDRP_IMAGE_DLL) && (LdrEntry->LoadCount != 0xFFFF)) - { - /* Increase load count */ - LdrEntry->LoadCount++; - LdrpUpdateLoadCount2(LdrEntry, LDRP_UPDATE_REFCOUNT); - - /* Clear the load in progress */ - LdrpClearLoadInProgress(); - } - else - { - /* Not a DLL, just increase the load count */ - if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++; - } + /* Release the lock */ + if (!InInit) RtlLeaveCriticalSection(&LdrpLoaderLock); } - -Quickie: - /* Release the lock */ - if (!InInit) RtlLeaveCriticalSection(&LdrpLoaderLock); + _SEH2_END; /* Check for success */ if (NT_SUCCESS(Status))