[RAPPS] Stopped GCC whining (fixed GCC build)
[reactos.git] / rostests / apitests / sdk / delayimp.cpp
1 /*
2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Tests for delayload
5 * PROGRAMMER: Mark Jansen
6 */
7
8 #include <apitest.h>
9
10 #include <apitest.h>
11 #include <strsafe.h>
12 #include <delayimp.h>
13
14 /* Some libraries to test against */
15 #include <mmsystem.h>
16 #include <winver.h>
17 #include <shlwapi.h>
18 #include <intshcut.h>
19 #include <sfc.h>
20 #include <imagehlp.h>
21
22 /* Compatibility with the MS defines */
23
24 #ifndef FACILITY_VISUALCPP
25 #define FACILITY_VISUALCPP ((LONG)0x6d)
26 #endif
27
28 #ifndef VcppException
29 #define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err)
30 #endif
31
32 #ifdef __REACTOS__
33 #define WINMM_DLLNAME "winmm.dll"
34 #else
35 #define WINMM_DLLNAME "WINMM.dll"
36 #endif
37
38 bool g_BreakFunctionName = false;
39 bool g_BrokenFunctionName = false;
40 bool g_BypassMost = false;
41 bool g_ExceptionIsModule = false;
42 bool g_ImportByName = true;
43 const char* g_ExpectedDll = NULL;
44 const char* g_ExpectedName = NULL;
45 char g_Target[100] = { 0 };
46
47 char* target(PDelayLoadInfo pdli)
48 {
49 if (g_Target[0] == '\0' && pdli)
50 {
51 if (pdli->dlp.fImportByName)
52 sprintf(g_Target, "%s!%s", pdli->szDll, pdli->dlp.szProcName);
53 else
54 sprintf(g_Target, "%s!#%lu", pdli->szDll, pdli->dlp.dwOrdinal);
55 }
56 return g_Target;
57 }
58
59
60 struct UnProtect
61 {
62 UnProtect(PVOID addr)
63 :mAddr(NULL), mProt(0)
64 {
65 if (IsBadWritePtr(addr, 1))
66 {
67 mAddr = addr;
68 VirtualProtect(addr, 1, PAGE_EXECUTE_READWRITE, &mProt);
69 }
70 }
71 ~UnProtect()
72 {
73 DWORD dwOld;
74 if (mAddr)
75 VirtualProtect(mAddr, 1, mProt, &dwOld);
76 }
77
78 PVOID mAddr;
79 DWORD mProt;
80 };
81
82
83 unsigned* g_DliHookExpected = NULL;
84 size_t g_DliHookIndex = 0;
85 #define LAST_DLI 333
86
87 static void SetExpectedDli(unsigned* order)
88 {
89 g_DliHookExpected = order;
90 g_DliHookIndex = 0;
91 g_Target[0] = '\0';
92 }
93
94 static void CheckDli_imp(unsigned dliNotify, PDelayLoadInfo pdli, BOOL ErrorHandler)
95 {
96 if (!g_DliHookExpected) return;
97
98 winetest_ok(dliNotify == g_DliHookExpected[g_DliHookIndex], "Expected dliNotify to be %u, was: %u for %s\n",
99 g_DliHookExpected[g_DliHookIndex], dliNotify, target(pdli));
100 if (ErrorHandler)
101 {
102 winetest_ok(dliNotify == dliFailGetProc || dliNotify == dliFailLoadLib,
103 "Expected code %u to be processed by the Hook, not the ErrorHandler for %s\n", dliNotify, target(pdli));
104 }
105 else
106 {
107 winetest_ok(dliNotify == dliStartProcessing || dliNotify == dliNotePreLoadLibrary ||
108 dliNotify == dliNotePreGetProcAddress || dliNotify == dliNoteEndProcessing,
109 "Expected code %u to be processed by the ErrorHandler, not the Hook for %s\n", dliNotify, target(pdli));
110 }
111 if (g_DliHookExpected[g_DliHookIndex] != LAST_DLI)
112 g_DliHookIndex++;
113 }
114
115 static void CheckDliDone_imp()
116 {
117 if (!g_DliHookExpected) return;
118 winetest_ok(LAST_DLI == g_DliHookExpected[g_DliHookIndex],
119 "Expected g_DliHookExpected[g_DliHookIndex] to be %u, was: %u for %s\n",
120 LAST_DLI, g_DliHookExpected[g_DliHookIndex], target(NULL));
121 g_DliHookExpected = NULL;
122 g_Target[0] = '\0';
123 }
124
125 #define CheckDli (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : CheckDli_imp
126 #define CheckDliDone (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : CheckDliDone_imp
127
128
129 /* Replacement functions */
130 INT_PTR WINAPI MyFunction()
131 {
132 return 123;
133 }
134
135 BOOL WINAPI MySfcIsKeyProtected(HKEY KeyHandle, LPCWSTR SubKeyName, REGSAM KeySam)
136 {
137 return 12345;
138 }
139
140
141 static HMODULE g_VersionDll;
142 FARPROC WINAPI DliHook(unsigned dliNotify, PDelayLoadInfo pdli)
143 {
144 ok(pdli && pdli->cb >= 36, "Expected a valid pointer with a struct that is big enough: %p, %lu\n",
145 pdli, pdli ? pdli->cb : 0u);
146 if (!pdli || pdli->cb < 36) return NULL;
147
148 CheckDli(dliNotify, pdli, FALSE);
149
150 if (g_BreakFunctionName && pdli->dlp.fImportByName)
151 {
152 g_BreakFunctionName = false;
153 g_BrokenFunctionName = true;
154 char* procname = (char*)pdli->dlp.szProcName;
155 UnProtect prot(procname);
156 char c = procname[0];
157 procname[0] = isupper(c) ? tolower(c) : toupper(c);
158 }
159
160 /* Validate dll name when required */
161 if (g_ExpectedDll && g_ExpectedName && !g_BrokenFunctionName)
162 {
163 ok(!strcmp(g_ExpectedDll, pdli->szDll), "Expected szDll to be '%s', but was: '%s'\n", g_ExpectedDll, pdli->szDll);
164 ok(pdli->dlp.fImportByName, "Expected import by name (%s!%s)\n", g_ExpectedDll, g_ExpectedName);
165 if (pdli->dlp.fImportByName)
166 {
167 ok(!strcmp(g_ExpectedName, pdli->dlp.szProcName), "Expected szProcName to be '%s', but was: '%s'\n",
168 g_ExpectedName, pdli->dlp.szProcName);
169 }
170 }
171
172
173 if (dliNotify == dliStartProcessing)
174 {
175 /* Test loadlib fail */
176 if (!_stricmp(pdli->szDll, "sfc_os.dll"))
177 {
178 char* dll = (char*)pdli->szDll;
179 UnProtect u(dll);
180 dll[0] = 'l'; dll[1] = '_'; dll[2] = 'm';
181 }
182 if (!_stricmp(pdli->szDll, "imagehlp.dll"))
183 {
184 char* dll = (char*)pdli->szDll;
185 UnProtect u(dll);
186 dll[0] = 'x'; dll[1] = 'x'; dll[2] = 'x'; dll[3] = 'x'; dll[4] = 'x';
187 }
188 /* Test bypass */
189 if (!_stricmp(pdli->szDll, "dbghelp.dll"))
190 return MyFunction;
191 }
192 else if (dliNotify == dliNotePreLoadLibrary)
193 {
194 /* Show that this value is actually used! */
195 if (!_stricmp(pdli->szDll, "version.dll"))
196 {
197 g_VersionDll = LoadLibraryA("version.dll");
198 return (FARPROC)1;
199 }
200
201 }
202 else if (dliNotify == dliNotePreGetProcAddress)
203 {
204 if (pdli->dlp.fImportByName && !strcmp(pdli->dlp.szProcName, "SfcIsKeyProtected"))
205 {
206 return (FARPROC)MySfcIsKeyProtected;
207 }
208 }
209
210 /* Parameter validation */
211 ok(pdli->ppfn != NULL, "Expected ppfn to be valid, was NULL for %s\n", target(pdli));
212 ok(pdli->szDll != NULL, "Expected szDll to be valid, was NULL for %s\n", target(pdli));
213 ok(pdli->dwLastError == ERROR_SUCCESS,
214 "Expected dwLastError to be ERROR_SUCCESS, was: %lu for %s\n", pdli->dwLastError, target(pdli));
215 ok(g_ImportByName == !!pdli->dlp.fImportByName, "Expected pdli->dlp.fImportByName to equal g_ImportByname\n");
216 if (pdli->dlp.fImportByName)
217 ok(pdli->dlp.szProcName != NULL, "Expected szProcName to be valid, was NULL for %s\n", target(pdli));
218 else
219 ok(pdli->dlp.dwOrdinal != 0, "Expected dwOrdinal to be valid, was NULL for %s\n", target(pdli));
220 switch(dliNotify)
221 {
222 case dliStartProcessing:
223 ok(pdli->hmodCur == NULL, "Expected hmodCur to be NULL, was: %p for %s\n", pdli->hmodCur, target(pdli));
224 ok(pdli->pfnCur == NULL, "Expected pfnCur to be NULL, was: %p for %s\n", pdli->pfnCur, target(pdli));
225 break;
226 case dliNotePreLoadLibrary:
227 ok(pdli->hmodCur == NULL, "Expected hmodCur to be NULL, was: %p for %s\n", pdli->hmodCur, target(pdli));
228 ok(pdli->pfnCur == NULL, "Expected pfnCur to be NULL, was: %p for %s\n", pdli->pfnCur, target(pdli));
229 break;
230 case dliNotePreGetProcAddress:
231 ok(pdli->hmodCur != NULL, "Expected hmodCur to be valid, was NULL for %s\n", target(pdli));
232 ok(pdli->pfnCur == NULL, "Expected pfnCur to be NULL, was: %p for %s\n", pdli->pfnCur, target(pdli));
233 break;
234 case dliNoteEndProcessing:
235 if (!g_BypassMost)
236 ok(pdli->hmodCur != NULL, "Expected hmodCur to be valid, was NULL for %s\n", target(pdli));
237 ok(pdli->pfnCur != NULL, "Expected pfnCur to be a valid pointer, was NULL for %s\n", target(pdli));
238 if (g_ExpectedDll && g_ExpectedName && !g_BrokenFunctionName)
239 {
240 FARPROC targetProc = GetProcAddress(GetModuleHandleA(g_ExpectedDll), g_ExpectedName);
241 ok(targetProc != NULL, "This should not happen, the function i need is unavail! (%s!%s)\n",
242 g_ExpectedDll, g_ExpectedName);
243 ok(targetProc == pdli->pfnCur, "Expected pfnCur to be %p, was %p for %s\n", targetProc, pdli->pfnCur, target(pdli));
244 ok(pdli->ppfn && targetProc == *pdli->ppfn,
245 "Expected ppfn to be valid and to result in %p, was: %p(%p) for %s\n",
246 target, pdli->ppfn, pdli->ppfn ? *pdli->ppfn : NULL, target(pdli));
247 }
248 break;
249 default:
250 break;
251 }
252 return NULL;
253 }
254
255 FARPROC WINAPI DliFailHook(unsigned dliNotify, PDelayLoadInfo pdli)
256 {
257 ok(pdli && pdli->cb >= 36,
258 "Expected a valid pointer with a struct that is big enough: %p, %lu\n", pdli, pdli ? pdli->cb : 0u);
259 if (!pdli || pdli->cb < 36) return NULL;
260
261 CheckDli(dliNotify, pdli, TRUE);
262
263 /* Redirections / fixes */
264 if (dliNotify == dliFailLoadLib)
265 {
266 if (!_stricmp(pdli->szDll, "l_m_os.dll"))
267 return (FARPROC)LoadLibraryA("sfc_os.dll");
268 }
269 else if (dliNotify == dliFailGetProc)
270 {
271 if (pdli->dlp.fImportByName && pdli->hmodCur == (HMODULE)1)
272 {
273 return GetProcAddress(g_VersionDll, pdli->dlp.szProcName);
274 }
275 }
276
277 /* Parameter validation */
278 ok(pdli->ppfn != NULL, "Expected ppfn to be valid, was NULL for %s\n", target(pdli));
279 ok(pdli->szDll != NULL, "Expected szDll to be valid, was NULL for %s\n", target(pdli));
280 if (pdli->dlp.fImportByName)
281 ok(pdli->dlp.szProcName != NULL, "Expected szProcName to be valid, was NULL for %s\n", target(pdli));
282 else
283 ok(pdli->dlp.dwOrdinal != 0, "Expected dwOrdinal to be valid, was NULL for %s\n", target(pdli));
284 switch(dliNotify)
285 {
286 case dliFailLoadLib:
287 ok(pdli->hmodCur == NULL, "Expected hmodCur to be NULL, was: %p for %s\n", pdli->hmodCur, target(pdli));
288 ok(pdli->pfnCur == NULL, "Expected pfnCur to be NULL, was: %p for %s\n", pdli->pfnCur, target(pdli));
289 ok(pdli->dwLastError == ERROR_MOD_NOT_FOUND,
290 "Expected dwLastError to be ERROR_MOD_NOT_FOUND, was: %lu for %s\n", pdli->dwLastError, target(pdli));
291 break;
292 case dliFailGetProc:
293 ok(pdli->hmodCur != NULL, "Expected hmodCur to be valid, was NULL for %s\n", target(pdli));
294 ok(pdli->pfnCur == NULL, "Expected pfnCur to be NULL, was: %p for %s\n", pdli->pfnCur, target(pdli));
295 ok(pdli->dwLastError == ERROR_PROC_NOT_FOUND,
296 "Expected dwLastError to be ERROR_PROC_NOT_FOUND, was: %lu for %s\n", pdli->dwLastError, target(pdli));
297 break;
298 }
299
300 return NULL;
301 }
302
303
304 LONG ExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo, ULONG ExceptionCode)
305 {
306 DWORD expected = VcppException(ERROR_SEVERITY_ERROR, (g_ExceptionIsModule ? ERROR_MOD_NOT_FOUND : ERROR_PROC_NOT_FOUND));
307 ok(ExceptionCode == expected, "Expected code to be 0x%lx, was: 0x%lx\n", expected, ExceptionCode);
308 ok(ExceptionInfo != NULL, "Expected to get exception info\n");
309 ok(ExceptionInfo->ExceptionRecord != NULL, "Expected to get a valid record info\n");
310
311 if (ExceptionCode != expected)
312 {
313 skip("Skipping other checks, this was not the exception we expected!\n");
314 return EXCEPTION_EXECUTE_HANDLER;
315 }
316
317 if (ExceptionInfo && ExceptionInfo->ExceptionRecord)
318 {
319 PEXCEPTION_RECORD ExceptionRecord = ExceptionInfo->ExceptionRecord;
320 ok(ExceptionRecord->ExceptionCode == expected, "Expected ExceptionCode to be 0x%lx, was 0x%lx\n",
321 expected, ExceptionRecord->ExceptionCode);
322 /* We can still continue. */
323 ok(ExceptionRecord->ExceptionFlags == 0, "Expected ExceptionFlags to be 0, was: 0x%lx\n",
324 ExceptionRecord->ExceptionFlags);
325 ok(ExceptionRecord->NumberParameters == 1, "Expected 1 parameter, got %lu\n",
326 ExceptionRecord->NumberParameters);
327 if (ExceptionRecord->NumberParameters == 1)
328 {
329 PDelayLoadInfo LoadInfo = (PDelayLoadInfo)ExceptionRecord->ExceptionInformation[0];
330 ok(LoadInfo && LoadInfo->cb >= 36, "Expected a valid pointer with a struct that is big enough: %p, %lu\n",
331 LoadInfo, LoadInfo ? LoadInfo->cb : 0);
332
333 if (g_ExpectedDll)
334 ok(!strcmp(g_ExpectedDll, LoadInfo->szDll), "Expected szDll to be '%s', but was: '%s'\n",
335 g_ExpectedDll, LoadInfo->szDll);
336 if (g_ExpectedName)
337 {
338 ok(LoadInfo->dlp.fImportByName, "Expected import by name\n");
339 if (LoadInfo->dlp.fImportByName)
340 {
341 ok(!strcmp(g_ExpectedName, LoadInfo->dlp.szProcName),
342 "Expected szProcName to be '%s', but was: '%s'\n", g_ExpectedName, LoadInfo->dlp.szProcName);
343
344 if (g_ExceptionIsModule)
345 {
346 HMODULE mod = LoadLibraryA("imagehlp.dll");
347 LoadInfo->pfnCur = GetProcAddress(mod, g_ExpectedName);
348 }
349 else
350 {
351 char buf[100];
352 char first = isupper(g_ExpectedName[0]) ? tolower(g_ExpectedName[0]) : toupper(g_ExpectedName[0]);
353 sprintf(buf, "%c%s", first, g_ExpectedName + 1);
354 LoadInfo->pfnCur = GetProcAddress(GetModuleHandleA(g_ExpectedDll), buf);
355 }
356 return LoadInfo->pfnCur ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER;
357 }
358 }
359 }
360 }
361
362 return EXCEPTION_EXECUTE_HANDLER;
363 }
364
365 /* We register one hook the 'default' way and one manually,
366 so that we can check that both fallback and registration work*/
367 extern "C"
368 {
369 PfnDliHook __pfnDliNotifyHook2 = DliHook;
370 //PfnDliHook __pfnDliFailureHook2 = DliFailHook;
371 }
372
373
374 bool g_UsePointers = false;
375
376 template<typename PTR>
377 PTR Rva2Addr(PIMAGE_DOS_HEADER dos, RVA rva)
378 {
379 /* Old delayload type */
380 if (g_UsePointers)
381 return reinterpret_cast<PTR>(rva);
382 return reinterpret_cast<PTR>((reinterpret_cast<PBYTE>(dos) + rva));
383 }
384
385
386 unsigned g_winmm_snd_play_a[] = { dliStartProcessing, dliNotePreLoadLibrary, dliNotePreGetProcAddress, dliNoteEndProcessing, LAST_DLI };
387 unsigned g_winmm_snd_play_w[] = { dliStartProcessing, dliNotePreGetProcAddress, dliNoteEndProcessing, LAST_DLI };
388 unsigned g_winmm_play_w[] = { dliStartProcessing, dliNotePreGetProcAddress, dliFailGetProc, dliNoteEndProcessing, LAST_DLI };
389 unsigned g_sfc_key[] = { dliStartProcessing, dliNotePreLoadLibrary, dliFailLoadLib, dliNotePreGetProcAddress, dliNoteEndProcessing, LAST_DLI };
390 unsigned g_sfc_file[] = { dliStartProcessing, dliNotePreGetProcAddress, dliNoteEndProcessing, LAST_DLI };
391 unsigned g_version_a[] = { dliStartProcessing, dliNotePreLoadLibrary, dliNotePreGetProcAddress, dliFailGetProc, dliNoteEndProcessing, LAST_DLI };
392 unsigned g_version_w[] = { dliStartProcessing, dliNotePreGetProcAddress, dliFailGetProc, dliNoteEndProcessing, LAST_DLI };
393 unsigned g_scard[] = { dliStartProcessing, dliNoteEndProcessing, LAST_DLI };
394 unsigned g_shlwapi[] = { dliStartProcessing, dliNotePreLoadLibrary, dliNotePreGetProcAddress, dliNoteEndProcessing, LAST_DLI };
395 unsigned g_imagehlp[] = { dliStartProcessing, dliNotePreLoadLibrary, dliFailLoadLib, LAST_DLI }; /* This exception does not fire EndProcessing! */
396
397
398 //#define DELAYLOAD_SUPPORTS_UNLOADING
399 START_TEST(delayimp)
400 {
401 /* Verify that both scenario's work */
402 ok(__pfnDliNotifyHook2 == DliHook, "Expected __pfnDliNotifyHook2 to be DliHook(%p), but was: %p\n",
403 DliHook, __pfnDliNotifyHook2);
404 ok(__pfnDliFailureHook2 == NULL, "Expected __pfnDliFailureHook2 to be NULL, but was: %p\n",
405 __pfnDliFailureHook2);
406
407 __pfnDliFailureHook2 = DliFailHook;
408
409
410 PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)GetModuleHandle(NULL);
411
412 ok(dos->e_magic == IMAGE_DOS_SIGNATURE, "Expected a DOS header\n");
413 if (dos->e_magic != IMAGE_DOS_SIGNATURE)
414 return;
415
416 PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)((PBYTE)dos + dos->e_lfanew);
417 PIMAGE_DATA_DIRECTORY delaydir = nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT;
418
419 /* Test some advanced features (loading / unloading) */
420 if (delaydir->Size != 0)
421 {
422 #if defined(_DELAY_IMP_VER) && _DELAY_IMP_VER == 2 && defined(DELAYLOAD_SUPPORTS_UNLOADING)
423 /* First, before mangling the delayload stuff, let's try some v2 functions */
424 HMODULE mod = GetModuleHandleA(WINMM_DLLNAME);
425 ok(mod == NULL, "Expected mod to be NULL, was %p\n", mod);
426 /* Now, a mistyped module (case sensitive!) */
427 HRESULT hr = __HrLoadAllImportsForDll("WiNmM.DlL");
428 ok(hr == HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND), "Expected hr to be HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND), was %lu\n", hr);
429 mod = GetModuleHandleA(WINMM_DLLNAME);
430 ok(mod == NULL, "Expected mod to be NULL, was %p\n", mod);
431
432 /* Let's load it */
433 hr = __HrLoadAllImportsForDll(WINMM_DLLNAME);
434 ok(hr == S_OK, "Expected hr to be S_OK, was %lu\n", hr);
435 mod = GetModuleHandleA(WINMM_DLLNAME);
436 ok(mod != NULL, "Expected mod to be valid, was NULL\n");
437
438 BOOL status = __FUnloadDelayLoadedDLL2(WINMM_DLLNAME);
439 ok(status == TRUE, "Expected __FUnloadDelayLoadedDLL2 to succeed\n");
440 mod = GetModuleHandleA(WINMM_DLLNAME);
441 ok(mod == NULL, "Expected mod to be NULL, was %p\n", mod);
442 #else
443 trace("Binary compiled without support for unloading\n");
444 #endif
445 }
446 else
447 {
448 skip("No IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT found, some advanced features might not work!\n");
449 }
450
451 /* Test the normal flow without a dll loaded */
452 BOOL ret = 123;
453 SetExpectedDli(g_winmm_snd_play_a);
454 g_ExpectedDll = WINMM_DLLNAME;
455 g_ExpectedName = "sndPlaySoundA";
456 ret = sndPlaySoundA(NULL, SND_NOWAIT | SND_NOSTOP);
457 ok(ret == TRUE, "Expected ret to be TRUE, was %u\n", ret);
458 CheckDliDone();
459
460 /* Test the normal flow with a dll loaded */
461 SetExpectedDli(g_winmm_snd_play_w);
462 g_ExpectedDll = WINMM_DLLNAME;
463 g_ExpectedName = "sndPlaySoundW";
464 ret = sndPlaySoundW(NULL, SND_NOWAIT | SND_NOSTOP);
465 ok(ret == TRUE, "Expected ret to be TRUE, was %u\n", ret);
466 CheckDliDone();
467
468 /* Make sure GetProcAddress fails, also ignore the Failure hook, use the exception to set the address */
469 SetExpectedDli(g_winmm_play_w);
470 g_ExpectedDll = WINMM_DLLNAME;
471 g_ExpectedName = "playSoundW";
472 g_BreakFunctionName = true;
473 ret = 123;
474 _SEH2_TRY
475 {
476 ret = PlaySoundW(NULL, NULL, SND_NOWAIT | SND_NOSTOP);
477 }
478 _SEH2_EXCEPT(ExceptionFilter(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
479 {
480 ;
481 }
482 _SEH2_END;
483 ok(ret == TRUE, "Expected ret to be TRUE, was %u\n", ret);
484 CheckDliDone();
485 ok(g_BreakFunctionName == false, "Expected the functionname to be changed\n");
486
487 /* Make the LoadLib fail, manually load the library in the Failure Hook,
488 Respond to the dliNotePreGetProcAddress with an alternate function address */
489 SetExpectedDli(g_sfc_key);
490 ret = SfcIsKeyProtected(NULL, NULL, NULL);
491 ok(ret == 12345, "Expected ret to be 12345, was %u\n", ret); /* The original function returns FALSE! */
492 CheckDliDone();
493
494 /* Show that it works with the manually returned dll */
495 SetExpectedDli(g_sfc_file);
496 ret = SfcGetNextProtectedFile(NULL, NULL);
497 ok(ret == FALSE, "Expected ret to be FALSE, was %u\n", ret);
498 CheckDliDone();
499
500 /* Return a fake dll handle, so that we can see when it is being used, and manually return a function in the Failure Hook */
501 SetExpectedDli(g_version_a);
502 ret = GetFileVersionInfoA(NULL, NULL, NULL, NULL);
503 ok(ret == FALSE, "Expected ret to be FALSE, was %u\n", ret);
504 CheckDliDone();
505
506 /* Manually return a function in the failure hook, when the module is the previously set bad one */
507 SetExpectedDli(g_version_w);
508 ret = GetFileVersionInfoW(NULL, NULL, NULL, NULL);
509 ok(ret == FALSE, "Expected ret to be FALSE, was %u\n", ret);
510 CheckDliDone();
511
512 if (HIWORD(SymGetOptions) == NULL)
513 {
514 skip("SymGetOptions until CORE-6504 is fixed\n");
515 }
516 else
517 {
518 /* Completely bypass most hooks, by directly replying with a function address */
519 SetExpectedDli(g_scard);
520 g_BypassMost = true;
521 DWORD opt = SymGetOptions();
522 g_BypassMost = false;
523 ok(opt == 123, "Expected opt to be 123, was %lu\n", opt); /* The original function returns ERROR_INVALID_HANDLE */
524 CheckDliDone();
525 }
526
527 /* Import by ordinal */
528 g_ImportByName = false;
529 SetExpectedDli(g_shlwapi);
530 PARSEDURLA pua = { sizeof(pua), 0 };
531 HRESULT hr = ParseURLA("", &pua);
532 ok(hr == URL_E_INVALID_SYNTAX, "Expected tmp to be URL_E_INVALID_SYNTAX, was %lx\n", hr);
533 CheckDliDone();
534 g_ImportByName = true;
535
536 /* Handle LoadLib failure with an exception handler */
537 if (HIWORD(MapAndLoad) == NULL)
538 {
539 skip("MapAndLoad until CORE-6504 is fixed\n");
540 }
541 else
542 {
543 SetExpectedDli(g_imagehlp);
544 LOADED_IMAGE img = {0};
545 ret = 123;
546 g_ExceptionIsModule = true;
547 g_ExpectedDll = "xxxxxhlp.dll";
548 g_ExpectedName = "MapAndLoad";
549 _SEH2_TRY
550 {
551 ret = MapAndLoad("some_not_existing_file.aabbcc", NULL, &img, FALSE, TRUE);
552 }
553 _SEH2_EXCEPT(ExceptionFilter(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
554 {
555 ;
556 }
557 _SEH2_END;
558 g_ExceptionIsModule = false;
559 ok(ret == FALSE, "Expected ret to be FALSE, was %u\n", ret);
560 CheckDliDone();
561 }
562 }