https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0a5a0a3501ec1371b55b2…
commit 0a5a0a3501ec1371b55b28cfc983656a30ef32ea
Author:     Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Sat Feb 24 14:55:11 2018 +0100
Commit:     Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sun Apr 22 18:51:21 2018 +0200
    [APPSHIM_APITEST] Add a test for the shim IgnoreFreeLibrary
---
 modules/rostests/apitests/appshim/CMakeLists.txt  |   1 +
 modules/rostests/apitests/appshim/ignorefreelib.c | 138 ++++++++++++++++++++++
 modules/rostests/apitests/appshim/testlist.c      |   2 +
 3 files changed, 141 insertions(+)
diff --git a/modules/rostests/apitests/appshim/CMakeLists.txt
b/modules/rostests/apitests/appshim/CMakeLists.txt
index 8884ce2606..b48600ceaa 100644
--- a/modules/rostests/apitests/appshim/CMakeLists.txt
+++ b/modules/rostests/apitests/appshim/CMakeLists.txt
@@ -4,6 +4,7 @@ add_definitions(-D__ROS_LONG64__)
 list(APPEND SOURCE
     dispmode.c
     genral_hooks.c
+    ignorefreelib.c
     layer_hooks.c
     versionlie.c
     testlist.c
diff --git a/modules/rostests/apitests/appshim/ignorefreelib.c
b/modules/rostests/apitests/appshim/ignorefreelib.c
new file mode 100644
index 0000000000..29b55449ce
--- /dev/null
+++ b/modules/rostests/apitests/appshim/ignorefreelib.c
@@ -0,0 +1,138 @@
+/*
+ * PROJECT:     appshim_apitest
+ * LICENSE:     GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Tests for IgnoreFreeLibrary shim
+ * COPYRIGHT:   Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org)
+ */
+
+#include <ntstatus.h>
+#define WIN32_NO_STATUS
+#include <windows.h>
+#include "wine/test.h"
+
+#include "appshim_apitest.h"
+
+static tGETHOOKAPIS pGetHookAPIs;
+
+typedef BOOL(WINAPI* FREELIBRARYPROC)(HMODULE);
+
+
+static void test_IgnoreFreeLibrary(VOID)
+{
+    DWORD num_shims = 0;
+    PHOOKAPI hook;
+    HMODULE avifil32, esent, msi;
+    FREELIBRARYPROC freeProc;
+
+    // Show that:
+    // * partial names (both start + end) do not work.
+    // * wildcards do not work
+    // * comparison is case insensitive
+    // * multiple dlls can be specified
+    hook = pGetHookAPIs("AvIFiL32.Dll;esent;esent*;ent.dll;msi.dll",
L"IgnoreFreeLibrary", &num_shims);
+
+    ok(hook != NULL, "Expected hook to be a valid pointer\n");
+    ok(num_shims == 1, "Expected num_shims to be 1, was: %u\n", num_shims);
+
+    if (!hook || !num_shims)
+        return;
+
+    ok_str(hook->LibraryName, "KERNEL32.DLL");
+    ok_str(hook->FunctionName, "FreeLibrary");
+
+    avifil32 = LoadLibraryA("avifil32.dll");
+    ok(avifil32 != NULL, "Unable to load avifil32\n");
+
+    esent = LoadLibraryA("esent.dll");
+    ok(esent != NULL, "Unable to load esent\n");
+
+    msi = LoadLibraryA("msi.dll");
+    ok(msi != NULL, "Unable to load msi\n");
+
+    hook->OriginalFunction = FreeLibrary;
+    freeProc = hook->ReplacementFunction;
+
+    ok(freeProc != NULL, "\n");
+
+    if (!freeProc)
+        return;
+
+    // Not unloading
+    ok(freeProc(avifil32), "Unable to unload avifil32\n");
+    avifil32 = GetModuleHandleA("avifil32.dll");
+    ok(avifil32 != NULL, "avifil32 should not unload\n");
+
+    // Unloading
+    ok(freeProc(esent), "Unable to unload esent\n");
+    esent = GetModuleHandleA("esent.dll");
+    ok(esent == NULL, "esent should be unloaded\n");
+
+    // Not unloading
+    ok(freeProc(msi), "Unable to unload msi\n");
+    msi = GetModuleHandleA("msi.dll");
+    ok(msi != NULL, "msi should not unload\n");
+}
+
+
+START_TEST(ignorefreelib)
+{
+    HMODULE avifil32, esent, msi;
+    LONG initial;
+
+    pGetHookAPIs = LoadShimDLL2(L"acgenral.dll");
+
+    if (!pGetHookAPIs)
+        return;
+
+    /* Ensure that we can freely load / unload avifil32, esent and msi */
+
+    initial = winetest_get_failures();
+
+    avifil32 = GetModuleHandleA("avifil32.dll");
+    ok_ptr(avifil32, NULL);
+    esent = GetModuleHandleA("esent.dll");
+    ok_ptr(esent, NULL);
+    msi = GetModuleHandleA("msi.dll");
+    ok_ptr(msi, NULL);
+
+    avifil32 = LoadLibraryA("avifil32.dll");
+    ok(avifil32 != NULL, "Unable to load avifil32\n");
+    esent = GetModuleHandleA("esent.dll");
+    ok_ptr(esent, NULL);
+    msi = GetModuleHandleA("msi.dll");
+    ok_ptr(msi, NULL);
+
+    ok(FreeLibrary(avifil32), "Unable to unload avifil32\n");
+    avifil32 = GetModuleHandleA("avifil32.dll");
+    ok_ptr(avifil32, NULL);
+
+    esent = LoadLibraryA("esent.dll");
+    ok(esent != NULL, "Unable to load esent\n");
+    avifil32 = GetModuleHandleA("avifil32.dll");
+    ok_ptr(avifil32, NULL);
+    msi = GetModuleHandleA("msi.dll");
+    ok_ptr(msi, NULL);
+
+    ok(FreeLibrary(esent), "Unable to unload esent\n");
+    esent = GetModuleHandleA("esent.dll");
+    ok_ptr(esent, NULL);
+
+    msi = LoadLibraryA("msi.dll");
+    ok(msi != NULL, "Unable to load msi\n");
+    avifil32 = GetModuleHandleA("avifil32.dll");
+    ok_ptr(avifil32, NULL);
+    esent = GetModuleHandleA("esent.dll");
+    ok_ptr(esent, NULL);
+
+    ok(FreeLibrary(msi), "Unable to unload msi\n");
+    msi = GetModuleHandleA("msi.dll");
+    ok_ptr(msi, NULL);
+
+    if (initial != winetest_get_failures())
+    {
+        // We cannot continue, one or more of our target dll's does not behave as
expected
+        return;
+    }
+
+    test_IgnoreFreeLibrary();
+}
diff --git a/modules/rostests/apitests/appshim/testlist.c
b/modules/rostests/apitests/appshim/testlist.c
index 45275de5cd..a3e7b7132d 100644
--- a/modules/rostests/apitests/appshim/testlist.c
+++ b/modules/rostests/apitests/appshim/testlist.c
@@ -5,6 +5,7 @@
 extern void func_dispmode(void);
 extern void func_genral_hooks(void);
+extern void func_ignorefreelib(void);
 extern void func_layer_hooks(void);
 extern void func_versionlie(void);
@@ -12,6 +13,7 @@ const struct test winetest_testlist[] =
 {
     { "dispmode", func_dispmode },
     { "genral_hooks", func_genral_hooks },
+    { "ignorefreelib", func_ignorefreelib },
     { "layer_hooks", func_layer_hooks },
     { "versionlie", func_versionlie },
     { 0, 0 }