2 * PROJECT: appshim_apitest
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Tests for IgnoreLoadLibrary shim
5 * COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
9 #define WIN32_NO_STATUS
12 #include "wine/test.h"
14 #include "appshim_apitest.h"
16 static DWORD g_WinVersion
;
17 static tGETHOOKAPIS pGetHookAPIs
;
18 static HMODULE g_hSentinelModule
= (HMODULE
)&pGetHookAPIs
; /* Not a valid hmodule, so a nice sentinel */
19 static HMODULE g_h123
= (HMODULE
)123;
20 static HMODULE g_h111
= (HMODULE
)111;
21 static HMODULE g_h0
= (HMODULE
)0;
23 typedef HMODULE(WINAPI
* LOADLIBRARYAPROC
)(LPCSTR lpLibFileName
);
24 typedef HMODULE(WINAPI
* LOADLIBRARYWPROC
)(LPCWSTR lpLibFileName
);
25 typedef HMODULE(WINAPI
* LOADLIBRARYEXAPROC
)(LPCSTR lpLibFileName
, HANDLE hFile
, DWORD dwFlags
);
26 typedef HMODULE(WINAPI
* LOADLIBRARYEXWPROC
)(LPCWSTR lpLibFileName
, HANDLE hFile
, DWORD dwFlags
);
36 /* Query the current setting */
37 Status
= NtQueryInformationProcess(NtCurrentProcess(),
38 ProcessDefaultHardErrorMode
,
42 if (!NT_SUCCESS(Status
))
44 /* Fail if we couldn't query */
48 /* Check if NOT failing critical errors was requested */
49 if (ErrMode
& SEM_FAILCRITICALERRORS
)
51 /* Mask it out, since the native API works differently */
52 ErrMode
&= ~SEM_FAILCRITICALERRORS
;
56 /* OR it if the caller didn't, due to different native semantics */
57 ErrMode
|= SEM_FAILCRITICALERRORS
;
64 static HMODULE WINAPI
my_LoadLibraryA(PCSTR Name
)
66 DWORD dwErrorMode
= GetErrorMode();
67 ok(dwErrorMode
== (SEM_FAILCRITICALERRORS
| SEM_NOGPFAULTERRORBOX
| SEM_NOOPENFILEERRORBOX
),
68 "Unexpected error mode: 0x%x\n", dwErrorMode
);
69 return g_hSentinelModule
;
72 static HMODULE WINAPI
my_LoadLibraryExA(PCSTR Name
, HANDLE hFile
, DWORD dwFlags
)
74 DWORD dwErrorMode
= GetErrorMode();
75 ok(dwErrorMode
== (SEM_FAILCRITICALERRORS
| SEM_NOGPFAULTERRORBOX
| SEM_NOOPENFILEERRORBOX
),
76 "Unexpected error mode: 0x%x\n", dwErrorMode
);
77 return g_hSentinelModule
;
80 static HMODULE WINAPI
my_LoadLibraryW(PCWSTR Name
)
82 DWORD dwErrorMode
= GetErrorMode();
83 ok(dwErrorMode
== (SEM_FAILCRITICALERRORS
| SEM_NOGPFAULTERRORBOX
| SEM_NOOPENFILEERRORBOX
),
84 "Unexpected error mode: 0x%x\n", dwErrorMode
);
85 return g_hSentinelModule
;
88 static HMODULE WINAPI
my_LoadLibraryExW(PCWSTR Name
, HANDLE hFile
, DWORD dwFlags
)
90 DWORD dwErrorMode
= GetErrorMode();
91 ok(dwErrorMode
== (SEM_FAILCRITICALERRORS
| SEM_NOGPFAULTERRORBOX
| SEM_NOOPENFILEERRORBOX
),
92 "Unexpected error mode: 0x%x\n", dwErrorMode
);
93 return g_hSentinelModule
;
97 static void test_LoadLibraryA(PHOOKAPI hook
)
99 LOADLIBRARYAPROC proc
;
100 DWORD dwErrorMode
, dwOldErrorMode
;
102 hook
->OriginalFunction
= my_LoadLibraryA
;
103 proc
= hook
->ReplacementFunction
;
105 dwOldErrorMode
= GetErrorMode();
107 /* Exact names return what is specified */
108 ok_ptr(proc("test123.dll"), g_h123
);
109 ok_ptr(proc("test111"), g_h111
);
110 /* Extension is not added */
111 ok_ptr(proc("test111.dll"), g_hSentinelModule
);
112 /* Zero can be specified */
113 ok_ptr(proc("Something.mark"), g_h0
);
114 /* Or default returned */
115 ok_ptr(proc("empty"), g_h0
);
117 /* Paths, do not have to be valid */
118 ok_ptr(proc("\\test123.dll"), g_h123
);
119 ok_ptr(proc("/test123.dll"), g_h123
);
120 ok_ptr(proc("\\\\\\\\test123.dll"), g_h123
);
121 ok_ptr(proc("////test123.dll"), g_h123
);
122 ok_ptr(proc("mypath:something\\does\\not\\matter\\test123.dll"), g_h123
);
123 ok_ptr(proc("/put/whatever/you/want/here/test123.dll"), g_h123
);
125 /* path separator is checked, not just any point in the path */
126 ok_ptr(proc("-test123.dll"), g_hSentinelModule
);
127 ok_ptr(proc("test123.dll-"), g_hSentinelModule
);
129 dwErrorMode
= GetErrorMode();
130 ok(dwErrorMode
== dwOldErrorMode
, "ErrorMode changed, was 0x%x, is 0x%x\n", dwOldErrorMode
, dwErrorMode
);
133 static void test_LoadLibraryW(PHOOKAPI hook
)
135 LOADLIBRARYWPROC proc
;
136 DWORD dwErrorMode
, dwOldErrorMode
;
138 hook
->OriginalFunction
= my_LoadLibraryW
;
139 proc
= hook
->ReplacementFunction
;
141 dwOldErrorMode
= GetErrorMode();
143 /* Exact names return what is specified */
144 ok_ptr(proc(L
"test123.dll"), g_h123
);
145 ok_ptr(proc(L
"test111"), g_h111
);
146 /* Extension is not added */
147 ok_ptr(proc(L
"test111.dll"), g_hSentinelModule
);
148 /* Zero can be specified */
149 ok_ptr(proc(L
"Something.mark"), g_h0
);
150 /* Or default returned */
151 ok_ptr(proc(L
"empty"), g_h0
);
153 /* Paths, do not have to be valid */
154 ok_ptr(proc(L
"\\test123.dll"), g_h123
);
155 ok_ptr(proc(L
"/test123.dll"), g_h123
);
156 ok_ptr(proc(L
"\\\\\\\\test123.dll"), g_h123
);
157 ok_ptr(proc(L
"////test123.dll"), g_h123
);
158 ok_ptr(proc(L
"mypath:something\\does\\not\\matter\\test123.dll"), g_h123
);
159 ok_ptr(proc(L
"/put/whatever/you/want/here/test123.dll"), g_h123
);
161 /* path separator is checked, not just any point in the path */
162 ok_ptr(proc(L
"-test123.dll"), g_hSentinelModule
);
163 ok_ptr(proc(L
"test123.dll-"), g_hSentinelModule
);
165 dwErrorMode
= GetErrorMode();
166 ok(dwErrorMode
== dwOldErrorMode
, "ErrorMode changed, was 0x%x, is 0x%x\n", dwOldErrorMode
, dwErrorMode
);
169 static void test_LoadLibraryExA(PHOOKAPI hook
)
171 LOADLIBRARYEXAPROC proc
;
172 DWORD dwErrorMode
, dwOldErrorMode
;
174 hook
->OriginalFunction
= my_LoadLibraryExA
;
175 proc
= hook
->ReplacementFunction
;
177 dwOldErrorMode
= GetErrorMode();
179 /* Exact names return what is specified */
180 ok_ptr(proc("test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
181 ok_ptr(proc("test111", INVALID_HANDLE_VALUE
, 0), g_h111
);
182 /* Extension is not added */
183 ok_ptr(proc("test111.dll", INVALID_HANDLE_VALUE
, 0), g_hSentinelModule
);
184 /* Zero can be specified */
185 ok_ptr(proc("Something.mark", INVALID_HANDLE_VALUE
, 0), g_h0
);
186 /* Or default returned */
187 ok_ptr(proc("empty", INVALID_HANDLE_VALUE
, 0), g_h0
);
189 /* Paths, do not have to be valid */
190 ok_ptr(proc("\\test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
191 ok_ptr(proc("/test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
192 ok_ptr(proc("\\\\\\\\test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
193 ok_ptr(proc("////test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
194 ok_ptr(proc("mypath:something\\does\\not\\matter\\test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
195 ok_ptr(proc("/put/whatever/you/want/here/test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
197 /* path separator is checked, not just any point in the path */
198 ok_ptr(proc("-test123.dll", INVALID_HANDLE_VALUE
, 0), g_hSentinelModule
);
199 ok_ptr(proc("test123.dll-", INVALID_HANDLE_VALUE
, 0), g_hSentinelModule
);
201 dwErrorMode
= GetErrorMode();
202 ok(dwErrorMode
== dwOldErrorMode
, "ErrorMode changed, was 0x%x, is 0x%x\n", dwOldErrorMode
, dwErrorMode
);
205 static void test_LoadLibraryExW(PHOOKAPI hook
)
207 LOADLIBRARYEXWPROC proc
;
208 DWORD dwErrorMode
, dwOldErrorMode
;
210 hook
->OriginalFunction
= my_LoadLibraryExW
;
211 proc
= hook
->ReplacementFunction
;
213 dwOldErrorMode
= GetErrorMode();
215 /* Exact names return what is specified */
216 ok_ptr(proc(L
"test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
217 ok_ptr(proc(L
"test111", INVALID_HANDLE_VALUE
, 0), g_h111
);
218 /* Extension is not added */
219 ok_ptr(proc(L
"test111.dll", INVALID_HANDLE_VALUE
, 0), g_hSentinelModule
);
220 /* Zero can be specified */
221 ok_ptr(proc(L
"Something.mark", INVALID_HANDLE_VALUE
, 0), g_h0
);
222 /* Or default returned */
223 ok_ptr(proc(L
"empty", INVALID_HANDLE_VALUE
, 0), g_h0
);
225 /* Paths, do not have to be valid */
226 ok_ptr(proc(L
"\\test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
227 ok_ptr(proc(L
"/test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
228 ok_ptr(proc(L
"\\\\\\\\test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
229 ok_ptr(proc(L
"////test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
230 ok_ptr(proc(L
"mypath:something\\does\\not\\matter\\test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
231 ok_ptr(proc(L
"/put/whatever/you/want/here/test123.dll", INVALID_HANDLE_VALUE
, 0), g_h123
);
233 /* path separator is checked, not just any point in the path */
234 ok_ptr(proc(L
"-test123.dll", INVALID_HANDLE_VALUE
, 0), g_hSentinelModule
);
235 ok_ptr(proc(L
"test123.dll-", INVALID_HANDLE_VALUE
, 0), g_hSentinelModule
);
237 dwErrorMode
= GetErrorMode();
238 ok(dwErrorMode
== dwOldErrorMode
, "ErrorMode changed, was 0x%x, is 0x%x\n", dwOldErrorMode
, dwErrorMode
);
242 DWORD
get_host_winver(void);
244 START_TEST(ignoreloadlib
)
246 DWORD num_shims
= 0, n
, dwErrorMode
;
249 g_WinVersion
= get_host_winver();
251 if (g_WinVersion
< _WIN32_WINNT_WIN8
)
252 pGetHookAPIs
= LoadShimDLL2(L
"aclayers.dll");
254 pGetHookAPIs
= LoadShimDLL2(L
"acgenral.dll");
258 skip("GetHookAPIs not found\n");
262 hook
= pGetHookAPIs("test123.dll:123;test111:111;Something.mark:0;empty", L
"IgnoreLoadLibrary", &num_shims
);
264 ok(hook
!= NULL
, "Expected hook to be a valid pointer\n");
265 ok(num_shims
== 4, "Expected num_shims to be 0, was: %u\n", num_shims
);
267 if (!hook
|| num_shims
!= 4)
270 dwErrorMode
= GetErrorMode();
271 trace("Error mode: 0x%x\n", dwErrorMode
);
273 for (n
= 0; n
< num_shims
; ++n
)
275 ok_str(hook
[n
].LibraryName
, "KERNEL32.DLL");
276 if (!_stricmp(hook
[n
].FunctionName
, "LoadLibraryA"))
279 test_LoadLibraryA(hook
+ n
);
281 else if (!_stricmp(hook
[n
].FunctionName
, "LoadLibraryExA"))
284 test_LoadLibraryExA(hook
+ n
);
286 else if (!_stricmp(hook
[n
].FunctionName
, "LoadLibraryW"))
289 test_LoadLibraryW(hook
+ n
);
291 else if (!_stricmp(hook
[n
].FunctionName
, "LoadLibraryExW"))
294 test_LoadLibraryExW(hook
+ n
);
298 ok(0, "Unknown function %s\n", hook
[n
].FunctionName
);