[SDK][ACGENRAL] Add the shim IgnoreFreeLibrary
authorMark Jansen <mark.jansen@reactos.org>
Sat, 24 Feb 2018 13:57:56 +0000 (14:57 +0100)
committerMark Jansen <mark.jansen@reactos.org>
Sun, 22 Apr 2018 16:52:00 +0000 (18:52 +0200)
dll/appcompat/shims/genral/CMakeLists.txt
dll/appcompat/shims/genral/ignorefreelib.c [new file with mode: 0644]
media/sdb/sysmain.xml

index 725a2d8..86db9bb 100644 (file)
@@ -5,6 +5,7 @@ spec2def(acgenral.dll genral.spec)
 
 list(APPEND SOURCE
     ignoredbgout.c
+    ignorefreelib.c
     main.c
     themes.c
     genral.spec)
diff --git a/dll/appcompat/shims/genral/ignorefreelib.c b/dll/appcompat/shims/genral/ignorefreelib.c
new file mode 100644 (file)
index 0000000..b0c7ebb
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * PROJECT:     ReactOS 'General' Shim library
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Ignore FreeLibrary calls
+ * COPYRIGHT:   Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
+ */
+
+#define WIN32_NO_STATUS
+#include <windef.h>
+#include <winbase.h>
+#include <shimlib.h>
+#include <strsafe.h>
+
+
+#define SHIM_NS         IgnoreFreeLibrary
+#include <setup_shim.inl>
+
+typedef BOOL(WINAPI* FREELIBRARYPROC)(HMODULE);
+
+const char** g_Names;
+static int g_NameCount;
+
+BOOL WINAPI SHIM_OBJ_NAME(FreeLibrary)(HMODULE hModule)
+{
+    char Buffer[MAX_PATH], *Ptr = Buffer;
+    DWORD len, wanted = ARRAYSIZE(Buffer);
+    for (;;)
+    {
+        len = GetModuleFileNameA(hModule, Ptr, wanted);
+        if (len < wanted)
+            break;
+
+        wanted *= 2;
+        if (Ptr != Buffer)
+            ShimLib_ShimFree(Ptr);
+
+        Ptr = ShimLib_ShimMalloc(wanted);
+        if (!Ptr)
+            break;
+    }
+
+    if (Ptr && len)
+    {
+        char* ModuleName = NULL;
+        int n;
+        for (; len; len--)
+        {
+            ModuleName = Ptr + len;
+            if (ModuleName[-1] == '/' || ModuleName[-1] == '\\')
+                break;
+        }
+        for (n = 0; n < g_NameCount; ++n)
+        {
+            if (!stricmp(g_Names[n], ModuleName))
+            {
+                SHIM_INFO("Prevented unload of %s\n", ModuleName);
+                if (Ptr && Ptr != Buffer)
+                    ShimLib_ShimFree(Ptr);
+                return TRUE;
+            }
+        }
+    }
+
+    if (Ptr && Ptr != Buffer)
+        ShimLib_ShimFree(Ptr);
+
+    return CALL_SHIM(0, FREELIBRARYPROC)(hModule);
+}
+
+static VOID InitIgnoreFreeLibrary(PCSTR CommandLine)
+{
+    PCSTR prev, cur;
+    int count = 1, n = 0;
+    const char** names;
+
+    if (!CommandLine || !*CommandLine)
+        return;
+
+    prev = CommandLine;
+    while ((cur = strchr(prev, ';')))
+    {
+        count++;
+        prev = cur + 1;
+    }
+
+    names = ShimLib_ShimMalloc(sizeof(char*) * count);
+    if (!names)
+    {
+        SHIM_WARN("Unable to allocate %u bytes\n", sizeof(char*) * count);
+        return;
+    }
+
+    prev = CommandLine;
+    while ((cur = strchr(prev, ';')))
+    {
+        names[n] = ShimLib_StringNDuplicateA(prev, cur - prev + 1);
+        if (!names[n])
+        {
+            SHIM_WARN("Unable to allocate %u bytes\n", cur - prev + 2);
+            return;
+        }
+        n++;
+        prev = cur + 1;
+    }
+    names[n] = ShimLib_StringDuplicateA(prev);
+    if (!names[n])
+    {
+        SHIM_WARN("Unable to allocate last string\n");
+        return;
+    }
+
+    g_Names = names;
+    g_NameCount = count;
+}
+
+BOOL WINAPI SHIM_OBJ_NAME(Notify)(DWORD fdwReason, PVOID ptr)
+{
+    if (fdwReason == SHIM_NOTIFY_ATTACH)
+    {
+        SHIM_MSG("IgnoreFreeLibrary(%s)\n", SHIM_OBJ_NAME(g_szCommandLine));
+        InitIgnoreFreeLibrary(SHIM_OBJ_NAME(g_szCommandLine));
+    }
+    return TRUE;
+}
+
+
+#define SHIM_NOTIFY_FN SHIM_OBJ_NAME(Notify)
+#define SHIM_NUM_HOOKS  1
+#define SHIM_SETUP_HOOKS \
+    SHIM_HOOK(0, "KERNEL32.DLL", "FreeLibrary", SHIM_OBJ_NAME(FreeLibrary))
+
+#include <implement_shim.inl>
index c451c28..03b9b16 100644 (file)
             <SHIM NAME="DisableThemes">
                 <DLLFILE>acgenral.dll</DLLFILE>
             </SHIM>
+            <SHIM NAME="IgnoreFreeLibrary">
+                <DLLFILE>acgenral.dll</DLLFILE>
+            </SHIM>
             <SHIM NAME="VMHorizonSetup">
                 <DLLFILE>aclayers.dll</DLLFILE>
             </SHIM>