https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ad08c6631b4707c48b212…
commit ad08c6631b4707c48b2124821b5a80b8372e2468
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Sun Jul 29 17:40:42 2018 +0200
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Mon Aug 13 13:24:12 2018 +0200
[LDR] Guard some sections where we grab a lock.
CORE-14532
---
dll/ntdll/ldr/ldrapi.c | 117 ++++++++++++------------
dll/ntdll/ldr/ldrutils.c | 229 ++++++++++++++++++++++++-----------------------
2 files changed, 180 insertions(+), 166 deletions(-)
diff --git a/dll/ntdll/ldr/ldrapi.c b/dll/ntdll/ldr/ldrapi.c
index 15f36bb2be..b151163dd4 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 5f55938d13..aa18d0384f 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))