1 /* 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) 6 */ 7 8 #include <ntstatus.h> 9 #define WIN32_NO_STATUS 10 #include <windows.h> 11 #include <ntndk.h> 12 #include "wine/test.h" 13 14 #include "appshim_apitest.h" 15 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; 22 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); 27 28 29 UINT 30 WINAPI 31 GetErrorMode(VOID) 32 { 33 NTSTATUS Status; 34 UINT ErrMode; 35 36 /* Query the current setting */ 37 Status = NtQueryInformationProcess(NtCurrentProcess(), 38 ProcessDefaultHardErrorMode, 39 &ErrMode, 40 sizeof(ErrMode), 41 NULL); 42 if (!NT_SUCCESS(Status)) 43 { 44 /* Fail if we couldn't query */ 45 return 0; 46 } 47 48 /* Check if NOT failing critical errors was requested */ 49 if (ErrMode & SEM_FAILCRITICALERRORS) 50 { 51 /* Mask it out, since the native API works differently */ 52 ErrMode &= ~SEM_FAILCRITICALERRORS; 53 } 54 else 55 { 56 /* OR it if the caller didn't, due to different native semantics */ 57 ErrMode |= SEM_FAILCRITICALERRORS; 58 } 59 60 /* Return the mode */ 61 return ErrMode; 62 } 63 64 static HMODULE WINAPI my_LoadLibraryA(PCSTR Name) 65 { 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; 70 } 71 72 static HMODULE WINAPI my_LoadLibraryExA(PCSTR Name, HANDLE hFile, DWORD dwFlags) 73 { 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; 78 } 79 80 static HMODULE WINAPI my_LoadLibraryW(PCWSTR Name) 81 { 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; 86 } 87 88 static HMODULE WINAPI my_LoadLibraryExW(PCWSTR Name, HANDLE hFile, DWORD dwFlags) 89 { 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; 94 } 95 96 97 static void test_LoadLibraryA(PHOOKAPI hook) 98 { 99 LOADLIBRARYAPROC proc; 100 DWORD dwErrorMode, dwOldErrorMode; 101 102 hook->OriginalFunction = my_LoadLibraryA; 103 proc = hook->ReplacementFunction; 104 105 dwOldErrorMode = GetErrorMode(); 106 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); 116 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); 124 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); 128 129 dwErrorMode = GetErrorMode(); 130 ok(dwErrorMode == dwOldErrorMode, "ErrorMode changed, was 0x%x, is 0x%x\n", dwOldErrorMode, dwErrorMode); 131 } 132 133 static void test_LoadLibraryW(PHOOKAPI hook) 134 { 135 LOADLIBRARYWPROC proc; 136 DWORD dwErrorMode, dwOldErrorMode; 137 138 hook->OriginalFunction = my_LoadLibraryW; 139 proc = hook->ReplacementFunction; 140 141 dwOldErrorMode = GetErrorMode(); 142 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); 152 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); 160 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); 164 165 dwErrorMode = GetErrorMode(); 166 ok(dwErrorMode == dwOldErrorMode, "ErrorMode changed, was 0x%x, is 0x%x\n", dwOldErrorMode, dwErrorMode); 167 } 168 169 static void test_LoadLibraryExA(PHOOKAPI hook) 170 { 171 LOADLIBRARYEXAPROC proc; 172 DWORD dwErrorMode, dwOldErrorMode; 173 174 hook->OriginalFunction = my_LoadLibraryExA; 175 proc = hook->ReplacementFunction; 176 177 dwOldErrorMode = GetErrorMode(); 178 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); 188 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); 196 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); 200 201 dwErrorMode = GetErrorMode(); 202 ok(dwErrorMode == dwOldErrorMode, "ErrorMode changed, was 0x%x, is 0x%x\n", dwOldErrorMode, dwErrorMode); 203 } 204 205 static void test_LoadLibraryExW(PHOOKAPI hook) 206 { 207 LOADLIBRARYEXWPROC proc; 208 DWORD dwErrorMode, dwOldErrorMode; 209 210 hook->OriginalFunction = my_LoadLibraryExW; 211 proc = hook->ReplacementFunction; 212 213 dwOldErrorMode = GetErrorMode(); 214 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); 224 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); 232 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); 236 237 dwErrorMode = GetErrorMode(); 238 ok(dwErrorMode == dwOldErrorMode, "ErrorMode changed, was 0x%x, is 0x%x\n", dwOldErrorMode, dwErrorMode); 239 } 240 241 /* versionlie.c */ 242 DWORD get_host_winver(void); 243 244 START_TEST(ignoreloadlib) 245 { 246 DWORD num_shims = 0, n, dwErrorMode; 247 PHOOKAPI hook; 248 249 g_WinVersion = get_host_winver(); 250 251 if (g_WinVersion < _WIN32_WINNT_WIN8) 252 pGetHookAPIs = LoadShimDLL2(L"aclayers.dll"); 253 else 254 pGetHookAPIs = LoadShimDLL2(L"acgenral.dll"); 255 256 if (!pGetHookAPIs) 257 { 258 skip("GetHookAPIs not found\n"); 259 return; 260 } 261 262 hook = pGetHookAPIs("test123.dll:123;test111:111;Something.mark:0;empty", L"IgnoreLoadLibrary", &num_shims); 263 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); 266 267 if (!hook || num_shims != 4) 268 return; 269 270 dwErrorMode = GetErrorMode(); 271 trace("Error mode: 0x%x\n", dwErrorMode); 272 273 for (n = 0; n < num_shims; ++n) 274 { 275 ok_str(hook[n].LibraryName, "KERNEL32.DLL"); 276 if (!_stricmp(hook[n].FunctionName, "LoadLibraryA")) 277 { 278 ok_int(n, 0); 279 test_LoadLibraryA(hook + n); 280 } 281 else if (!_stricmp(hook[n].FunctionName, "LoadLibraryExA")) 282 { 283 ok_int(n, 1); 284 test_LoadLibraryExA(hook + n); 285 } 286 else if (!_stricmp(hook[n].FunctionName, "LoadLibraryW")) 287 { 288 ok_int(n, 2); 289 test_LoadLibraryW(hook + n); 290 } 291 else if (!_stricmp(hook[n].FunctionName, "LoadLibraryExW")) 292 { 293 ok_int(n, 3); 294 test_LoadLibraryExW(hook + n); 295 } 296 else 297 { 298 ok(0, "Unknown function %s\n", hook[n].FunctionName); 299 } 300 } 301 } 302