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
14 /* Some libraries to test against */
22 /* Compatibility with the MS defines */
24 #ifndef FACILITY_VISUALCPP
25 #define FACILITY_VISUALCPP ((LONG)0x6d)
29 #define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err)
33 #define WINMM_DLLNAME "winmm.dll"
35 #define WINMM_DLLNAME "WINMM.dll"
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 };
47 char* target(PDelayLoadInfo pdli
)
49 if (g_Target
[0] == '\0' && pdli
)
51 if (pdli
->dlp
.fImportByName
)
52 sprintf(g_Target
, "%s!%s", pdli
->szDll
, pdli
->dlp
.szProcName
);
54 sprintf(g_Target
, "%s!#%lu", pdli
->szDll
, pdli
->dlp
.dwOrdinal
);
63 :mAddr(NULL
), mProt(0)
65 if (IsBadWritePtr(addr
, 1))
68 VirtualProtect(addr
, 1, PAGE_EXECUTE_READWRITE
, &mProt
);
75 VirtualProtect(mAddr
, 1, mProt
, &dwOld
);
83 unsigned* g_DliHookExpected
= NULL
;
84 size_t g_DliHookIndex
= 0;
87 static void SetExpectedDli(unsigned* order
)
89 g_DliHookExpected
= order
;
94 static void CheckDli_imp(unsigned dliNotify
, PDelayLoadInfo pdli
, BOOL ErrorHandler
)
96 if (!g_DliHookExpected
) return;
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
));
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
));
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
));
111 if (g_DliHookExpected
[g_DliHookIndex
] != LAST_DLI
)
115 static void CheckDliDone_imp()
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
;
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
129 /* Replacement functions */
130 INT_PTR WINAPI
MyFunction()
135 BOOL WINAPI
MySfcIsKeyProtected(HKEY KeyHandle
, LPCWSTR SubKeyName
, REGSAM KeySam
)
141 static HMODULE g_VersionDll
;
142 FARPROC WINAPI
DliHook(unsigned dliNotify
, PDelayLoadInfo pdli
)
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
;
148 CheckDli(dliNotify
, pdli
, FALSE
);
150 if (g_BreakFunctionName
&& pdli
->dlp
.fImportByName
)
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
);
160 /* Validate dll name when required */
161 if (g_ExpectedDll
&& g_ExpectedName
&& !g_BrokenFunctionName
)
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
)
167 ok(!strcmp(g_ExpectedName
, pdli
->dlp
.szProcName
), "Expected szProcName to be '%s', but was: '%s'\n",
168 g_ExpectedName
, pdli
->dlp
.szProcName
);
173 if (dliNotify
== dliStartProcessing
)
175 /* Test loadlib fail */
176 if (!_stricmp(pdli
->szDll
, "sfc_os.dll"))
178 char* dll
= (char*)pdli
->szDll
;
180 dll
[0] = 'l'; dll
[1] = '_'; dll
[2] = 'm';
182 if (!_stricmp(pdli
->szDll
, "imagehlp.dll"))
184 char* dll
= (char*)pdli
->szDll
;
186 dll
[0] = 'x'; dll
[1] = 'x'; dll
[2] = 'x'; dll
[3] = 'x'; dll
[4] = 'x';
189 if (!_stricmp(pdli
->szDll
, "dbghelp.dll"))
192 else if (dliNotify
== dliNotePreLoadLibrary
)
194 /* Show that this value is actually used! */
195 if (!_stricmp(pdli
->szDll
, "version.dll"))
197 g_VersionDll
= LoadLibraryA("version.dll");
202 else if (dliNotify
== dliNotePreGetProcAddress
)
204 if (pdli
->dlp
.fImportByName
&& !strcmp(pdli
->dlp
.szProcName
, "SfcIsKeyProtected"))
206 return (FARPROC
)MySfcIsKeyProtected
;
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
));
219 ok(pdli
->dlp
.dwOrdinal
!= 0, "Expected dwOrdinal to be valid, was NULL for %s\n", target(pdli
));
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
));
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
));
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
));
234 case dliNoteEndProcessing
:
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
)
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
));
255 FARPROC WINAPI
DliFailHook(unsigned dliNotify
, PDelayLoadInfo pdli
)
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
;
261 CheckDli(dliNotify
, pdli
, TRUE
);
263 /* Redirections / fixes */
264 if (dliNotify
== dliFailLoadLib
)
266 if (!_stricmp(pdli
->szDll
, "l_m_os.dll"))
267 return (FARPROC
)LoadLibraryA("sfc_os.dll");
269 else if (dliNotify
== dliFailGetProc
)
271 if (pdli
->dlp
.fImportByName
&& pdli
->hmodCur
== (HMODULE
)1)
273 return GetProcAddress(g_VersionDll
, pdli
->dlp
.szProcName
);
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
));
283 ok(pdli
->dlp
.dwOrdinal
!= 0, "Expected dwOrdinal to be valid, was NULL for %s\n", target(pdli
));
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
));
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
));
304 LONG
ExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo
, ULONG ExceptionCode
)
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");
311 if (ExceptionCode
!= expected
)
313 skip("Skipping other checks, this was not the exception we expected!\n");
314 return EXCEPTION_EXECUTE_HANDLER
;
317 if (ExceptionInfo
&& ExceptionInfo
->ExceptionRecord
)
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)
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);
334 ok(!strcmp(g_ExpectedDll
, LoadInfo
->szDll
), "Expected szDll to be '%s', but was: '%s'\n",
335 g_ExpectedDll
, LoadInfo
->szDll
);
338 ok(LoadInfo
->dlp
.fImportByName
, "Expected import by name\n");
339 if (LoadInfo
->dlp
.fImportByName
)
341 ok(!strcmp(g_ExpectedName
, LoadInfo
->dlp
.szProcName
),
342 "Expected szProcName to be '%s', but was: '%s'\n", g_ExpectedName
, LoadInfo
->dlp
.szProcName
);
344 if (g_ExceptionIsModule
)
346 HMODULE mod
= LoadLibraryA("imagehlp.dll");
347 LoadInfo
->pfnCur
= GetProcAddress(mod
, g_ExpectedName
);
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
);
356 return LoadInfo
->pfnCur
? EXCEPTION_CONTINUE_EXECUTION
: EXCEPTION_EXECUTE_HANDLER
;
362 return EXCEPTION_EXECUTE_HANDLER
;
365 /* We register one hook the 'default' way and one manually,
366 so that we can check that both fallback and registration work*/
369 PfnDliHook __pfnDliNotifyHook2
= DliHook
;
370 //PfnDliHook __pfnDliFailureHook2 = DliFailHook;
374 bool g_UsePointers
= false;
376 template<typename PTR
>
377 PTR
Rva2Addr(PIMAGE_DOS_HEADER dos
, RVA rva
)
379 /* Old delayload type */
381 return reinterpret_cast<PTR
>(rva
);
382 return reinterpret_cast<PTR
>((reinterpret_cast<PBYTE
>(dos
) + rva
));
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! */
398 //#define DELAYLOAD_SUPPORTS_UNLOADING
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
);
407 __pfnDliFailureHook2
= DliFailHook
;
410 PIMAGE_DOS_HEADER dos
= (PIMAGE_DOS_HEADER
)GetModuleHandle(NULL
);
412 ok(dos
->e_magic
== IMAGE_DOS_SIGNATURE
, "Expected a DOS header\n");
413 if (dos
->e_magic
!= IMAGE_DOS_SIGNATURE
)
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
;
419 /* Test some advanced features (loading / unloading) */
420 if (delaydir
->Size
!= 0)
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
);
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");
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
);
443 trace("Binary compiled without support for unloading\n");
448 skip("No IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT found, some advanced features might not work!\n");
451 /* Test the normal flow without a dll loaded */
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
);
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
);
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;
476 ret
= PlaySoundW(NULL
, NULL
, SND_NOWAIT
| SND_NOSTOP
);
478 _SEH2_EXCEPT(ExceptionFilter(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
483 ok(ret
== TRUE
, "Expected ret to be TRUE, was %u\n", ret
);
485 ok(g_BreakFunctionName
== false, "Expected the functionname to be changed\n");
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! */
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
);
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
);
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
);
512 if (HIWORD(SymGetOptions
) == NULL
)
514 skip("SymGetOptions until CORE-6504 is fixed\n");
518 /* Completely bypass most hooks, by directly replying with a function address */
519 SetExpectedDli(g_scard
);
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 */
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
);
534 g_ImportByName
= true;
536 /* Handle LoadLib failure with an exception handler */
537 if (HIWORD(MapAndLoad
) == NULL
)
539 skip("MapAndLoad until CORE-6504 is fixed\n");
543 SetExpectedDli(g_imagehlp
);
544 LOADED_IMAGE img
= {0};
546 g_ExceptionIsModule
= true;
547 g_ExpectedDll
= "xxxxxhlp.dll";
548 g_ExpectedName
= "MapAndLoad";
551 ret
= MapAndLoad("some_not_existing_file.aabbcc", NULL
, &img
, FALSE
, TRUE
);
553 _SEH2_EXCEPT(ExceptionFilter(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
558 g_ExceptionIsModule
= false;
559 ok(ret
== FALSE
, "Expected ret to be FALSE, was %u\n", ret
);