1 /*
2  * PROJECT:     appshim_apitest
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     Tests for IgnoreFreeLibrary shim
5  * COPYRIGHT:   Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
6  */
7 
8 #include <ntstatus.h>
9 #define WIN32_NO_STATUS
10 #include <windows.h>
11 #include "wine/test.h"
12 
13 #include "appshim_apitest.h"
14 
15 static tGETHOOKAPIS pGetHookAPIs;
16 
17 typedef BOOL(WINAPI* FREELIBRARYPROC)(HMODULE);
18 
19 
20 static void test_IgnoreFreeLibrary(VOID)
21 {
22     DWORD num_shims = 0;
23     PHOOKAPI hook;
24     HMODULE avifil32, esent, msi;
25     FREELIBRARYPROC freeProc;
26 
27     // Show that:
28     // * partial names (both start + end) do not work.
29     // * wildcards do not work
30     // * comparison is case insensitive
31     // * multiple dlls can be specified
32     hook = pGetHookAPIs("AvIFiL32.Dll;esent;esent*;ent.dll;msi.dll", L"IgnoreFreeLibrary", &num_shims);
33 
34     ok(hook != NULL, "Expected hook to be a valid pointer\n");
35     ok(num_shims == 1, "Expected num_shims to be 1, was: %u\n", num_shims);
36 
37     if (!hook || !num_shims)
38         return;
39 
40     ok_str(hook->LibraryName, "KERNEL32.DLL");
41     ok_str(hook->FunctionName, "FreeLibrary");
42 
43     avifil32 = LoadLibraryA("avifil32.dll");
44     ok(avifil32 != NULL, "Unable to load avifil32\n");
45 
46     esent = LoadLibraryA("esent.dll");
47     ok(esent != NULL, "Unable to load esent\n");
48 
49     msi = LoadLibraryA("msi.dll");
50     ok(msi != NULL, "Unable to load msi\n");
51 
52     hook->OriginalFunction = FreeLibrary;
53     freeProc = hook->ReplacementFunction;
54 
55     ok(freeProc != NULL, "\n");
56 
57     if (!freeProc)
58         return;
59 
60     // Not unloading
61     ok(freeProc(avifil32), "Unable to unload avifil32\n");
62     avifil32 = GetModuleHandleA("avifil32.dll");
63     ok(avifil32 != NULL, "avifil32 should not unload\n");
64 
65     // Unloading
66     ok(freeProc(esent), "Unable to unload esent\n");
67     esent = GetModuleHandleA("esent.dll");
68     ok(esent == NULL, "esent should be unloaded\n");
69 
70     // Not unloading
71     ok(freeProc(msi), "Unable to unload msi\n");
72     msi = GetModuleHandleA("msi.dll");
73     ok(msi != NULL, "msi should not unload\n");
74 }
75 
76 
77 START_TEST(ignorefreelib)
78 {
79     HMODULE avifil32, esent, msi;
80     LONG initial;
81 
82     pGetHookAPIs = LoadShimDLL2(L"acgenral.dll");
83 
84     if (!pGetHookAPIs)
85         return;
86 
87     /* Ensure that we can freely load / unload avifil32, esent and msi */
88 
89     initial = winetest_get_failures();
90 
91     avifil32 = GetModuleHandleA("avifil32.dll");
92     ok_ptr(avifil32, NULL);
93     esent = GetModuleHandleA("esent.dll");
94     ok_ptr(esent, NULL);
95     msi = GetModuleHandleA("msi.dll");
96     ok_ptr(msi, NULL);
97 
98     avifil32 = LoadLibraryA("avifil32.dll");
99     ok(avifil32 != NULL, "Unable to load avifil32\n");
100     esent = GetModuleHandleA("esent.dll");
101     ok_ptr(esent, NULL);
102     msi = GetModuleHandleA("msi.dll");
103     ok_ptr(msi, NULL);
104 
105     ok(FreeLibrary(avifil32), "Unable to unload avifil32\n");
106     avifil32 = GetModuleHandleA("avifil32.dll");
107     ok_ptr(avifil32, NULL);
108 
109     esent = LoadLibraryA("esent.dll");
110     ok(esent != NULL, "Unable to load esent\n");
111     avifil32 = GetModuleHandleA("avifil32.dll");
112     ok_ptr(avifil32, NULL);
113     msi = GetModuleHandleA("msi.dll");
114     ok_ptr(msi, NULL);
115 
116     ok(FreeLibrary(esent), "Unable to unload esent\n");
117     esent = GetModuleHandleA("esent.dll");
118     ok_ptr(esent, NULL);
119 
120     msi = LoadLibraryA("msi.dll");
121     ok(msi != NULL, "Unable to load msi\n");
122     avifil32 = GetModuleHandleA("avifil32.dll");
123     ok_ptr(avifil32, NULL);
124     esent = GetModuleHandleA("esent.dll");
125     ok_ptr(esent, NULL);
126 
127     ok(FreeLibrary(msi), "Unable to unload msi\n");
128     msi = GetModuleHandleA("msi.dll");
129     ok_ptr(msi, NULL);
130 
131     if (initial != winetest_get_failures())
132     {
133         // We cannot continue, one or more of our target dll's does not behave as expected
134         return;
135     }
136 
137     test_IgnoreFreeLibrary();
138 }
139