[NTDLL] Implement some basic shim engine integration. CORE-10368
authorMark Jansen <mark.jansen@reactos.org>
Sat, 4 Mar 2017 20:34:36 +0000 (20:34 +0000)
committerMark Jansen <mark.jansen@reactos.org>
Sat, 4 Mar 2017 20:34:36 +0000 (20:34 +0000)
svn path=/trunk/; revision=74064

reactos/dll/ntdll/include/ntdllp.h
reactos/dll/ntdll/ldr/ldrapi.c
reactos/dll/ntdll/ldr/ldrinit.c
reactos/dll/ntdll/ldr/ldrutils.c

index 4b9db90..8164a29 100644 (file)
@@ -47,6 +47,13 @@ extern BOOLEAN LdrpShutdownInProgress;
 extern UNICODE_STRING LdrpKnownDllPath;
 extern PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache, LdrpLoadedDllHandleCache;
 extern ULONG RtlpDphGlobalFlags;
+extern BOOLEAN g_ShimsEnabled;
+extern PVOID g_pShimEngineModule;
+extern PVOID g_pfnSE_DllLoaded;
+extern PVOID g_pfnSE_DllUnloaded;
+extern PVOID g_pfnSE_InstallBeforeInit;
+extern PVOID g_pfnSE_InstallAfterInit;
+extern PVOID g_pfnSE_ProcessDying;
 
 /* ldrinit.c */
 NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL);
@@ -139,6 +146,18 @@ LdrpFetchAddressOfEntryPoint(PVOID ImageBase);
 VOID NTAPI
 LdrpFreeUnicodeString(PUNICODE_STRING String);
 
+VOID NTAPI
+LdrpGetShimEngineInterface();
+
+VOID
+NTAPI
+LdrpLoadShimEngine(IN PWSTR ImageName,
+                   IN PUNICODE_STRING ProcessImage,
+                   IN PVOID pShimData);
+
+VOID NTAPI
+LdrpUnloadShimEngine();
+
 
 /* FIXME: Cleanup this mess */
 typedef NTSTATUS (NTAPI *PEPFUNC)(PPEB);
index 3414c6e..c49be3d 100644 (file)
@@ -1404,7 +1404,12 @@ LdrUnloadDll(IN PVOID BaseAddress)
                         LdrEntry->EntryPoint);
             }
 
-            /* FIXME: Call Shim Engine and notify */
+            /* Call Shim Engine and notify */
+            if (g_ShimsEnabled)
+            {
+                VOID (NTAPI* SE_DllUnloaded)(PVOID) = RtlDecodeSystemPointer(g_pfnSE_DllUnloaded);
+                SE_DllUnloaded(LdrEntry);
+            }
 
             /* Unlink it */
             CurrentEntry = LdrEntry;
index 71c2240..614c290 100644 (file)
@@ -901,10 +901,12 @@ LdrShutdownProcess(VOID)
     if (LdrpShutdownInProgress) return STATUS_SUCCESS;
 
     /* Tell the Shim Engine */
-    //if (ShimsEnabled)
-    //{
-        /* FIXME */
-    //}
+    if (g_ShimsEnabled)
+    {
+        VOID(NTAPI *SE_ProcessDying)();
+        SE_ProcessDying = RtlDecodeSystemPointer(g_pfnSE_ProcessDying);
+        SE_ProcessDying();
+    }
 
     /* Tell the world */
     if (ShowSnaps)
@@ -2110,8 +2112,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
     {
         /* Load the Shim Engine */
         Peb->AppCompatInfo = NULL;
-        //LdrpLoadShimEngine(OldShimData, ImagePathName, OldShimData);
-        DPRINT1("We do not support shims yet\n");
+        LdrpLoadShimEngine(OldShimData, &ImagePathName, OldShimData);
     }
     else
     {
@@ -2134,7 +2135,13 @@ LdrpInitializeProcess(IN PCONTEXT Context,
         return Status;
     }
 
-    /* FIXME: Unload the Shim Engine if it was loaded */
+    /* Notify Shim Engine */
+    if (g_ShimsEnabled)
+    {
+        VOID(NTAPI *SE_InstallAfterInit)(PUNICODE_STRING, PVOID);
+        SE_InstallAfterInit = RtlDecodeSystemPointer(g_pfnSE_InstallAfterInit);
+        SE_InstallAfterInit(&ImagePathName, OldShimData);
+    }
 
     /* Check if we have a user-defined Post Process Routine */
     if (NT_SUCCESS(Status) && Peb->PostProcessInitRoutine)
index 84ab7bf..d960c7f 100644 (file)
 /* GLOBALS *******************************************************************/
 
 PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache, LdrpGetModuleHandleCache;
+
 BOOLEAN g_ShimsEnabled;
+PVOID g_pShimEngineModule;
+PVOID g_pfnSE_DllLoaded;
+PVOID g_pfnSE_DllUnloaded;
+PVOID g_pfnSE_InstallBeforeInit;
+PVOID g_pfnSE_InstallAfterInit;
+PVOID g_pfnSE_ProcessDying;
 
 /* FUNCTIONS *****************************************************************/
 
@@ -2548,12 +2555,11 @@ LdrpLoadDll(IN BOOLEAN Redirected,
         /* If we have to run the entrypoint, make sure the DB is ready */
         if (CallInit && LdrpLdrDatabaseIsSetup)
         {
-            /* FIXME: Notify Shim Engine */
+            /* Notify Shim Engine */
             if (g_ShimsEnabled)
             {
-                /* Call it */
-                //ShimLoadCallback = RtlDecodeSystemPointer(g_pfnSE_DllLoaded);
-                //ShimLoadCallback(LdrEntry);
+                VOID (NTAPI* SE_DllLoaded)(PLDR_DATA_TABLE_ENTRY) = RtlDecodeSystemPointer(g_pfnSE_DllLoaded);
+                SE_DllLoaded(LdrEntry);
             }
 
             /* Run the init routine */
@@ -2654,4 +2660,72 @@ LdrpClearLoadInProgress(VOID)
     return ModulesCount;
 }
 
+PVOID LdrpGetShimEngineFunction(PCSZ FunctionName)
+{
+    ANSI_STRING Function;
+    NTSTATUS Status;
+    PVOID Address;
+    RtlInitAnsiString(&Function, FunctionName);
+    Status = LdrGetProcedureAddress(g_pShimEngineModule, &Function, 0, &Address);
+    return NT_SUCCESS(Status) ? Address : NULL;
+}
+
+VOID
+NTAPI
+LdrpGetShimEngineInterface()
+{
+    PVOID SE_DllLoaded = LdrpGetShimEngineFunction("SE_DllLoaded");
+    PVOID SE_DllUnloaded = LdrpGetShimEngineFunction("SE_DllUnloaded");
+    PVOID SE_InstallBeforeInit = LdrpGetShimEngineFunction("SE_InstallBeforeInit");
+    PVOID SE_InstallAfterInit = LdrpGetShimEngineFunction("SE_InstallAfterInit");
+    PVOID SE_ProcessDying = LdrpGetShimEngineFunction("SE_ProcessDying");
+
+    if (SE_DllLoaded && SE_DllUnloaded && SE_InstallBeforeInit && SE_InstallAfterInit && SE_ProcessDying)
+    {
+        g_pfnSE_DllLoaded = RtlEncodeSystemPointer(SE_DllLoaded);
+        g_pfnSE_DllUnloaded = RtlEncodeSystemPointer(SE_DllUnloaded);
+        g_pfnSE_InstallBeforeInit = RtlEncodeSystemPointer(SE_InstallBeforeInit);
+        g_pfnSE_InstallAfterInit = RtlEncodeSystemPointer(SE_InstallAfterInit);
+        g_pfnSE_ProcessDying = RtlEncodeSystemPointer(SE_ProcessDying);
+        g_ShimsEnabled = TRUE;
+    }
+    else
+    {
+        LdrpUnloadShimEngine();
+    }
+}
+
+
+VOID
+NTAPI
+LdrpLoadShimEngine(IN PWSTR ImageName, IN PUNICODE_STRING ProcessImage, IN PVOID pShimData)
+{
+    UNICODE_STRING ShimLibraryName;
+    PVOID ShimLibrary;
+    NTSTATUS Status;
+    RtlInitUnicodeString(&ShimLibraryName, ImageName);
+    Status = LdrpLoadDll(FALSE, NULL, NULL, &ShimLibraryName, &ShimLibrary, TRUE);
+    if (NT_SUCCESS(Status))
+    {
+        g_pShimEngineModule = ShimLibrary;
+        LdrpGetShimEngineInterface();
+        if (g_ShimsEnabled)
+        {
+            VOID(NTAPI *SE_InstallBeforeInit)(PUNICODE_STRING, PVOID);
+            SE_InstallBeforeInit = RtlDecodeSystemPointer(g_pfnSE_InstallBeforeInit);
+            SE_InstallBeforeInit(ProcessImage, pShimData);
+        }
+    }
+}
+
+VOID
+NTAPI
+LdrpUnloadShimEngine()
+{
+    /* Make sure we do not call into the shim engine anymore */
+    g_ShimsEnabled = FALSE;
+    LdrUnloadDll(g_pShimEngineModule);
+    g_pShimEngineModule = NULL;
+}
+
 /* EOF */