[LDR] Load kernel32 in LdrpInitializeProcess.
[reactos.git] / dll / ntdll / ldr / ldrinit.c
index dc0a370..14f0272 100644 (file)
@@ -24,6 +24,7 @@ HANDLE Wow64ExecOptionsKey;
 UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options");
 UNICODE_STRING Wow64OptionsString = RTL_CONSTANT_STRING(L"");
 UNICODE_STRING NtDllString = RTL_CONSTANT_STRING(L"ntdll.dll");
+UNICODE_STRING Kernel32String = RTL_CONSTANT_STRING(L"kernel32.dll");
 
 BOOLEAN LdrpInLdrInit;
 LONG LdrpProcessInitialized;
@@ -41,6 +42,9 @@ extern PTEB LdrpTopLevelDllBeingLoadedTeb; // defined in rtlsupp.c!
 PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer;
 PLDR_DATA_TABLE_ENTRY LdrpNtDllDataTableEntry;
 
+static NTSTATUS (WINAPI *Kernel32ProcessInitPostImportFunction)(VOID);
+static BOOL (WINAPI *Kernel32BaseQueryModuleData)(IN LPSTR ModuleName, IN LPSTR Unk1, IN PVOID Unk2, IN PVOID Unk3, IN PVOID Unk4);
+
 RTL_BITMAP TlsBitMap;
 RTL_BITMAP TlsExpansionBitMap;
 RTL_BITMAP FlsBitMap;
@@ -552,30 +556,39 @@ LdrpInitializeThread(IN PCONTEXT Context)
                     RtlActivateActivationContextUnsafeFast(&ActCtx,
                                                            LdrEntry->EntryPointActivationContext);
 
-                    /* Check if it has TLS */
-                    if (LdrEntry->TlsIndex)
+                    _SEH2_TRY
                     {
+                        /* Check if it has TLS */
+                        if (LdrEntry->TlsIndex)
+                        {
+                            /* Make sure we're not shutting down */
+                            if (!LdrpShutdownInProgress)
+                            {
+                                /* Call TLS */
+                                LdrpCallTlsInitializers(LdrEntry, DLL_THREAD_ATTACH);
+                            }
+                        }
+
                         /* Make sure we're not shutting down */
                         if (!LdrpShutdownInProgress)
                         {
-                            /* Call TLS */
-                            LdrpCallTlsInitializers(LdrEntry->DllBase, DLL_THREAD_ATTACH);
+                            /* Call the Entrypoint */
+                            DPRINT("%wZ - Calling entry point at %p for thread attaching, %p/%p\n",
+                                   &LdrEntry->BaseDllName, LdrEntry->EntryPoint,
+                                   NtCurrentTeb()->RealClientId.UniqueProcess,
+                                   NtCurrentTeb()->RealClientId.UniqueThread);
+                            LdrpCallInitRoutine(LdrEntry->EntryPoint,
+                                                LdrEntry->DllBase,
+                                                DLL_THREAD_ATTACH,
+                                                NULL);
                         }
                     }
-
-                    /* Make sure we're not shutting down */
-                    if (!LdrpShutdownInProgress)
+                    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
                     {
-                        /* Call the Entrypoint */
-                        DPRINT("%wZ - Calling entry point at %p for thread attaching, %p/%p\n",
-                                &LdrEntry->BaseDllName, LdrEntry->EntryPoint,
-                                NtCurrentTeb()->RealClientId.UniqueProcess,
-                                NtCurrentTeb()->RealClientId.UniqueThread);
-                        LdrpCallInitRoutine(LdrEntry->EntryPoint,
-                                         LdrEntry->DllBase,
-                                         DLL_THREAD_ATTACH,
-                                         NULL);
+                        DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_THREAD_ATTACH) for %wZ\n",
+                                _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
                     }
+                    _SEH2_END;
 
                     /* Deactivate the ActCtx */
                     RtlDeactivateActivationContextUnsafeFast(&ActCtx);
@@ -599,8 +612,16 @@ LdrpInitializeThread(IN PCONTEXT Context)
         RtlActivateActivationContextUnsafeFast(&ActCtx,
                                                LdrpImageEntry->EntryPointActivationContext);
 
-        /* Do TLS callbacks */
-        LdrpCallTlsInitializers(Peb->ImageBaseAddress, DLL_THREAD_ATTACH);
+        _SEH2_TRY
+        {
+            /* Do TLS callbacks */
+            LdrpCallTlsInitializers(LdrpImageEntry, DLL_THREAD_ATTACH);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* Do nothing */
+        }
+        _SEH2_END;
 
         /* Deactivate the ActCtx */
         RtlDeactivateActivationContextUnsafeFast(&ActCtx);
@@ -712,23 +733,28 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
         NextEntry = NextEntry->Flink;
     }
 
+    Status = STATUS_SUCCESS;
+
     /* If we got a context, then we have to call Kernel32 for TS support */
     if (Context)
     {
         /* Check if we have one */
-        //if (Kernel32ProcessInitPostImportfunction)
-        //{
+        if (Kernel32ProcessInitPostImportFunction)
+        {
             /* Call it */
-            //Kernel32ProcessInitPostImportfunction();
-        //}
-
+            Status = Kernel32ProcessInitPostImportFunction();
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("LDR: LdrpRunInitializeRoutines - Failed running kernel32 post-import function, Status=0x%08lx\n", Status);
+            }
+        }
         /* Clear it */
-        //Kernel32ProcessInitPostImportfunction = NULL;
-        //UNIMPLEMENTED;
+        Kernel32ProcessInitPostImportFunction = NULL;
     }
 
     /* No root entry? return */
-    if (!LdrRootEntry) return STATUS_SUCCESS;
+    if (!LdrRootEntry)
+        return Status;
 
     /* Set the TLD TEB */
     OldTldTeb = LdrpTopLevelDllBeingLoadedTeb;
@@ -796,23 +822,33 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
             RtlActivateActivationContextUnsafeFast(&ActCtx,
                                                    LdrEntry->EntryPointActivationContext);
 
-            /* Check if it has TLS */
-            if (LdrEntry->TlsIndex && Context)
+            _SEH2_TRY
             {
-                /* Call TLS */
-                LdrpCallTlsInitializers(LdrEntry->DllBase, DLL_PROCESS_ATTACH);
-            }
+                /* Check if it has TLS */
+                if (LdrEntry->TlsIndex && Context)
+                {
+                    /* Call TLS */
+                    LdrpCallTlsInitializers(LdrEntry, DLL_PROCESS_ATTACH);
+                }
 
-            /* Call the Entrypoint */
-            if (ShowSnaps)
+                /* Call the Entrypoint */
+                if (ShowSnaps)
+                {
+                    DPRINT1("%wZ - Calling entry point at %p for DLL_PROCESS_ATTACH\n",
+                            &LdrEntry->BaseDllName, EntryPoint);
+                }
+                DllStatus = LdrpCallInitRoutine(EntryPoint,
+                                                LdrEntry->DllBase,
+                                                DLL_PROCESS_ATTACH,
+                                                Context);
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                DPRINT1("%wZ - Calling entry point at %p for DLL_PROCESS_ATTACH\n",
-                        &LdrEntry->BaseDllName, EntryPoint);
+                DllStatus = FALSE;
+                DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_ATTACH) for %wZ\n",
+                        _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
             }
-            DllStatus = LdrpCallInitRoutine(EntryPoint,
-                                         LdrEntry->DllBase,
-                                         DLL_PROCESS_ATTACH,
-                                         Context);
+            _SEH2_END;
 
             /* Deactivate the ActCtx */
             RtlDeactivateActivationContextUnsafeFast(&ActCtx);
@@ -862,8 +898,16 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
         RtlActivateActivationContextUnsafeFast(&ActCtx,
                                                LdrpImageEntry->EntryPointActivationContext);
 
-        /* Do TLS callbacks */
-        LdrpCallTlsInitializers(Peb->ImageBaseAddress, DLL_PROCESS_ATTACH);
+        _SEH2_TRY
+        {
+            /* Do TLS callbacks */
+            LdrpCallTlsInitializers(LdrpImageEntry, DLL_PROCESS_ATTACH);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* Do nothing */
+        }
+        _SEH2_END;
 
         /* Deactivate the ActCtx */
         RtlDeactivateActivationContextUnsafeFast(&ActCtx);
@@ -958,20 +1002,29 @@ LdrShutdownProcess(VOID)
                 RtlActivateActivationContextUnsafeFast(&ActCtx,
                                                        LdrEntry->EntryPointActivationContext);
 
-                /* Check if it has TLS */
-                if (LdrEntry->TlsIndex)
+                _SEH2_TRY
                 {
-                    /* Call TLS */
-                    LdrpCallTlsInitializers(LdrEntry->DllBase, DLL_PROCESS_DETACH);
-                }
+                    /* Check if it has TLS */
+                    if (LdrEntry->TlsIndex)
+                    {
+                        /* Call TLS */
+                        LdrpCallTlsInitializers(LdrEntry, DLL_PROCESS_DETACH);
+                    }
 
-                /* Call the Entrypoint */
-                DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
-                        &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
-                LdrpCallInitRoutine(EntryPoint,
-                                 LdrEntry->DllBase,
-                                 DLL_PROCESS_DETACH,
-                                 (PVOID)1);
+                    /* Call the Entrypoint */
+                    DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
+                           &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
+                    LdrpCallInitRoutine(EntryPoint,
+                                        LdrEntry->DllBase,
+                                        DLL_PROCESS_DETACH,
+                                        (PVOID)1);
+                }
+                _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+                {
+                    DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_DETACH) for %wZ\n",
+                            _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
+                }
+                _SEH2_END;
 
                 /* Deactivate the ActCtx */
                 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
@@ -991,8 +1044,16 @@ LdrShutdownProcess(VOID)
         RtlActivateActivationContextUnsafeFast(&ActCtx,
                                                LdrpImageEntry->EntryPointActivationContext);
 
-        /* Do TLS callbacks */
-        LdrpCallTlsInitializers(Peb->ImageBaseAddress, DLL_PROCESS_DETACH);
+        _SEH2_TRY
+        {
+            /* Do TLS callbacks */
+            LdrpCallTlsInitializers(LdrpImageEntry, DLL_PROCESS_DETACH);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* Do nothing */
+        }
+        _SEH2_END;
 
         /* Deactivate the ActCtx */
         RtlDeactivateActivationContextUnsafeFast(&ActCtx);
@@ -1066,28 +1127,37 @@ LdrShutdownThread(VOID)
                     RtlActivateActivationContextUnsafeFast(&ActCtx,
                                                            LdrEntry->EntryPointActivationContext);
 
-                    /* Check if it has TLS */
-                    if (LdrEntry->TlsIndex)
+                    _SEH2_TRY
                     {
+                        /* Check if it has TLS */
+                        if (LdrEntry->TlsIndex)
+                        {
+                            /* Make sure we're not shutting down */
+                            if (!LdrpShutdownInProgress)
+                            {
+                                /* Call TLS */
+                                LdrpCallTlsInitializers(LdrEntry, DLL_THREAD_DETACH);
+                            }
+                        }
+
                         /* Make sure we're not shutting down */
                         if (!LdrpShutdownInProgress)
                         {
-                            /* Call TLS */
-                            LdrpCallTlsInitializers(LdrEntry->DllBase, DLL_THREAD_DETACH);
+                            /* Call the Entrypoint */
+                            DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
+                                   &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
+                            LdrpCallInitRoutine(EntryPoint,
+                                                LdrEntry->DllBase,
+                                                DLL_THREAD_DETACH,
+                                                NULL);
                         }
                     }
-
-                    /* Make sure we're not shutting down */
-                    if (!LdrpShutdownInProgress)
+                    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
                     {
-                        /* Call the Entrypoint */
-                        DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
-                                &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
-                        LdrpCallInitRoutine(EntryPoint,
-                                         LdrEntry->DllBase,
-                                         DLL_THREAD_DETACH,
-                                         NULL);
+                        DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_THREAD_DETACH) for %wZ\n",
+                                _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
                     }
+                    _SEH2_END;
 
                     /* Deactivate the ActCtx */
                     RtlDeactivateActivationContextUnsafeFast(&ActCtx);
@@ -1108,8 +1178,16 @@ LdrShutdownThread(VOID)
         RtlActivateActivationContextUnsafeFast(&ActCtx,
                                                LdrpImageEntry->EntryPointActivationContext);
 
-        /* Do TLS callbacks */
-        LdrpCallTlsInitializers(Peb->ImageBaseAddress, DLL_THREAD_DETACH);
+        _SEH2_TRY
+        {
+            /* Do TLS callbacks */
+            LdrpCallTlsInitializers(LdrpImageEntry, DLL_THREAD_DETACH);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* Do nothing */
+        }
+        _SEH2_END;
 
         /* Deactivate the ActCtx */
         RtlDeactivateActivationContextUnsafeFast(&ActCtx);
@@ -1534,7 +1612,8 @@ LdrpInitializeProcess(IN PCONTEXT Context,
 {
     RTL_HEAP_PARAMETERS HeapParameters;
     ULONG ComSectionSize;
-    //ANSI_STRING FunctionName = RTL_CONSTANT_STRING("BaseQueryModuleData");
+    ANSI_STRING BaseProcessInitPostImportName = RTL_CONSTANT_STRING("BaseProcessInitPostImport");
+    ANSI_STRING BaseQueryModuleDataName = RTL_CONSTANT_STRING("BaseQueryModuleData");
     PVOID OldShimData;
     OBJECT_ATTRIBUTES ObjectAttributes;
     //UNICODE_STRING LocalFileName, FullImageName;
@@ -2051,11 +2130,46 @@ LdrpInitializeProcess(IN PCONTEXT Context,
         DPRINT1("We don't support .NET applications yet\n");
     }
 
-    /* FIXME: Load support for Terminal Services */
-    if (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI)
+    if (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI ||
+        NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
     {
-        /* Load kernel32 and call BasePostImportInit... */
-        DPRINT("Unimplemented codepath!\n");
+        PVOID Kernel32BaseAddress;
+        PVOID FunctionAddress;
+
+        Status = LdrLoadDll(NULL, NULL, &Kernel32String, &Kernel32BaseAddress);
+
+        if (!NT_SUCCESS(Status))
+        {
+            if (ShowSnaps)
+                DPRINT1("LDR: Unable to load %wZ, Status=0x%08lx\n", &Kernel32String, Status);
+            return Status;
+        }
+
+        Status = LdrGetProcedureAddress(Kernel32BaseAddress,
+                                        &BaseProcessInitPostImportName,
+                                        0,
+                                        &FunctionAddress);
+
+        if (!NT_SUCCESS(Status))
+        {
+            if (ShowSnaps)
+                DPRINT1("LDR: Unable to find post-import process init function, Status=0x%08lx\n", &Kernel32String, Status);
+            return Status;
+        }
+        Kernel32ProcessInitPostImportFunction = FunctionAddress;
+
+        Status = LdrGetProcedureAddress(Kernel32BaseAddress,
+                                        &BaseQueryModuleDataName,
+                                        0,
+                                        &FunctionAddress);
+
+        if (!NT_SUCCESS(Status))
+        {
+            if (ShowSnaps)
+                DPRINT1("LDR: Unable to find BaseQueryModuleData, Status=0x%08lx\n", &Kernel32String, Status);
+            return Status;
+        }
+        Kernel32BaseQueryModuleData = FunctionAddress;
     }
 
     /* Walk the IAT and load all the DLLs */