[LDR] Guard some sections where we grab a lock.
authorMark Jansen <mark.jansen@reactos.org>
Sun, 29 Jul 2018 15:40:42 +0000 (17:40 +0200)
committerMark Jansen <mark.jansen@reactos.org>
Mon, 13 Aug 2018 11:24:12 +0000 (13:24 +0200)
CORE-14532

dll/ntdll/ldr/ldrapi.c
dll/ntdll/ldr/ldrutils.c

index 15f36bb..b151163 100644 (file)
@@ -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);
index 5f55938..aa18d03 100644 (file)
@@ -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))