Reactos
at master 1950 lines 77 kB view raw
1/* 2 * Unit tests for module/DLL/library API 3 * 4 * Copyright (c) 2004 Eric Pouech 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21#include <stdio.h> 22#include "ntstatus.h" 23#define WIN32_NO_STATUS 24#include "windef.h" 25#include "winbase.h" 26#include "winnls.h" 27#include "winternl.h" 28#include <psapi.h> 29#include "wine/test.h" 30 31static DWORD (WINAPI *pGetDllDirectoryA)(DWORD,LPSTR); 32static DWORD (WINAPI *pGetDllDirectoryW)(DWORD,LPWSTR); 33static BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR); 34static DLL_DIRECTORY_COOKIE (WINAPI *pAddDllDirectory)(const WCHAR*); 35static BOOL (WINAPI *pRemoveDllDirectory)(DLL_DIRECTORY_COOKIE); 36static BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD); 37static BOOL (WINAPI *pK32GetModuleInformation)(HANDLE process, HMODULE module, 38 MODULEINFO *modinfo, DWORD cb); 39 40static NTSTATUS (WINAPI *pApiSetQueryApiSetPresence)(const UNICODE_STRING*,BOOLEAN*); 41static NTSTATUS (WINAPI *pApiSetQueryApiSetPresenceEx)(const UNICODE_STRING*,BOOLEAN*,BOOLEAN*); 42static NTSTATUS (WINAPI *pLdrGetDllDirectory)(UNICODE_STRING*); 43static NTSTATUS (WINAPI *pLdrSetDllDirectory)(UNICODE_STRING*); 44static NTSTATUS (WINAPI *pLdrGetDllHandle)( LPCWSTR load_path, ULONG flags, const UNICODE_STRING *name, HMODULE *base ); 45static NTSTATUS (WINAPI *pLdrGetDllHandleEx)( ULONG flags, LPCWSTR load_path, ULONG *dll_characteristics, 46 const UNICODE_STRING *name, HMODULE *base ); 47static NTSTATUS (WINAPI *pLdrGetDllFullName)( HMODULE module, UNICODE_STRING *name ); 48 49static BOOL (WINAPI *pIsApiSetImplemented)(LPCSTR); 50 51static NTSTATUS (WINAPI *pRtlHashUnicodeString)( const UNICODE_STRING *, BOOLEAN, ULONG, ULONG * ); 52 53static BOOL is_unicode_enabled = TRUE; 54 55static BOOL cmpStrAW(const char* a, const WCHAR* b, DWORD lenA, DWORD lenB) 56{ 57 WCHAR aw[1024]; 58 59 DWORD len = MultiByteToWideChar( AreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, 60 a, lenA, aw, ARRAY_SIZE(aw)); 61 if (len != lenB) return FALSE; 62 return memcmp(aw, b, len * sizeof(WCHAR)) == 0; 63} 64 65static const struct 66{ 67 IMAGE_DOS_HEADER dos; 68 IMAGE_NT_HEADERS nt; 69 IMAGE_SECTION_HEADER section; 70} dll_image = 71{ 72 { IMAGE_DOS_SIGNATURE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 }, 0, 0, { 0 }, 73 sizeof(IMAGE_DOS_HEADER) }, 74 { 75 IMAGE_NT_SIGNATURE, /* Signature */ 76 { 77#if defined __i386__ 78 IMAGE_FILE_MACHINE_I386, /* Machine */ 79#elif defined __x86_64__ 80 IMAGE_FILE_MACHINE_AMD64, /* Machine */ 81#elif defined __arm__ 82 IMAGE_FILE_MACHINE_ARMNT, /* Machine */ 83#elif defined __aarch64__ 84 IMAGE_FILE_MACHINE_ARM64, /* Machine */ 85#else 86# error You must specify the machine type 87#endif 88 1, /* NumberOfSections */ 89 0, /* TimeDateStamp */ 90 0, /* PointerToSymbolTable */ 91 0, /* NumberOfSymbols */ 92 sizeof(IMAGE_OPTIONAL_HEADER), /* SizeOfOptionalHeader */ 93 IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL /* Characteristics */ 94 }, 95 { IMAGE_NT_OPTIONAL_HDR_MAGIC, /* Magic */ 96 1, /* MajorLinkerVersion */ 97 0, /* MinorLinkerVersion */ 98 0, /* SizeOfCode */ 99 0, /* SizeOfInitializedData */ 100 0, /* SizeOfUninitializedData */ 101 0, /* AddressOfEntryPoint */ 102 0x1000, /* BaseOfCode */ 103#ifndef _WIN64 104 0, /* BaseOfData */ 105#endif 106 0x10000000, /* ImageBase */ 107 0x1000, /* SectionAlignment */ 108 0x1000, /* FileAlignment */ 109 4, /* MajorOperatingSystemVersion */ 110 0, /* MinorOperatingSystemVersion */ 111 1, /* MajorImageVersion */ 112 0, /* MinorImageVersion */ 113 4, /* MajorSubsystemVersion */ 114 0, /* MinorSubsystemVersion */ 115 0, /* Win32VersionValue */ 116 0x2000, /* SizeOfImage */ 117 sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS), /* SizeOfHeaders */ 118 0, /* CheckSum */ 119 IMAGE_SUBSYSTEM_WINDOWS_CUI, /* Subsystem */ 120 IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT, /* DllCharacteristics */ 121 0, /* SizeOfStackReserve */ 122 0, /* SizeOfStackCommit */ 123 0, /* SizeOfHeapReserve */ 124 0, /* SizeOfHeapCommit */ 125 0, /* LoaderFlags */ 126 0, /* NumberOfRvaAndSizes */ 127 { { 0 } } /* DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] */ 128 } 129 }, 130 { ".rodata", { 0 }, 0x1000, 0x1000, 0, 0, 0, 0, 0, 131 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ } 132}; 133 134static void create_test_dll( const char *name ) 135{ 136 DWORD dummy; 137 HANDLE handle = CreateFileA( name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0 ); 138 139 ok( handle != INVALID_HANDLE_VALUE, "failed to create file err %lu\n", GetLastError() ); 140 WriteFile( handle, &dll_image, sizeof(dll_image), &dummy, NULL ); 141 SetFilePointer( handle, dll_image.nt.OptionalHeader.SizeOfImage, NULL, FILE_BEGIN ); 142 SetEndOfFile( handle ); 143 CloseHandle( handle ); 144} 145 146static BOOL is_old_loader_struct(void) 147{ 148 LDR_DATA_TABLE_ENTRY *mod, *mod2; 149 LDR_DDAG_NODE *ddag_node; 150 NTSTATUS status; 151 HMODULE hexe; 152 153 /* Check for old LDR data strcuture. */ 154#ifdef __REACTOS__ 155 if (GetNTVersion() < _WIN32_WINNT_VISTA) 156 return TRUE; 157#endif 158 hexe = GetModuleHandleW( NULL ); 159 ok( !!hexe, "Got NULL exe handle.\n" ); 160 status = LdrFindEntryForAddress( hexe, &mod ); 161 ok( !status, "got %#lx.\n", status ); 162 if (!(ddag_node = mod->DdagNode)) 163 { 164 win_skip( "DdagNode is NULL, skipping tests.\n" ); 165 return TRUE; 166 } 167 ok( !!ddag_node->Modules.Flink, "Got NULL module link.\n" ); 168 mod2 = CONTAINING_RECORD(ddag_node->Modules.Flink, LDR_DATA_TABLE_ENTRY, NodeModuleLink); 169 ok( mod2 == mod || broken( (void **)mod2 == (void **)mod - 1 ), "got %p, expected %p.\n", mod2, mod ); 170 if (mod2 != mod) 171 { 172 win_skip( "Old LDR_DATA_TABLE_ENTRY structure, skipping tests.\n" ); 173 return TRUE; 174 } 175 return FALSE; 176} 177 178static void testGetModuleFileName(const char* name) 179{ 180 HMODULE hMod; 181 char bufA[MAX_PATH]; 182 WCHAR bufW[MAX_PATH]; 183 DWORD len1A, len1W = 0, len2A, len2W = 0; 184 185 hMod = (name) ? GetModuleHandleA(name) : NULL; 186 187 /* first test, with enough space in buffer */ 188 memset(bufA, '-', sizeof(bufA)); 189 SetLastError(0xdeadbeef); 190 len1A = GetModuleFileNameA(hMod, bufA, sizeof(bufA)); 191 ok(GetLastError() == ERROR_SUCCESS || 192 broken(GetLastError() == 0xdeadbeef), /* <= XP SP3 */ 193 "LastError was not reset: %lu\n", GetLastError()); 194 ok(len1A > 0, "Getting module filename for handle %p\n", hMod); 195 196 if (is_unicode_enabled) 197 { 198 memset(bufW, '-', sizeof(bufW)); 199 SetLastError(0xdeadbeef); 200 len1W = GetModuleFileNameW(hMod, bufW, ARRAY_SIZE(bufW)); 201 ok(GetLastError() == ERROR_SUCCESS || 202 broken(GetLastError() == 0xdeadbeef), /* <= XP SP3 */ 203 "LastError was not reset: %lu\n", GetLastError()); 204 ok(len1W > 0, "Getting module filename for handle %p\n", hMod); 205 } 206 207 ok(len1A == strlen(bufA), "Unexpected length of GetModuleFilenameA (%ld/%d)\n", len1A, lstrlenA(bufA)); 208 209 if (is_unicode_enabled) 210 { 211 ok(len1W == lstrlenW(bufW), "Unexpected length of GetModuleFilenameW (%ld/%d)\n", len1W, lstrlenW(bufW)); 212 ok(cmpStrAW(bufA, bufW, len1A, len1W), "Comparing GetModuleFilenameAW results\n"); 213 } 214 215 /* second test with a buffer too small */ 216 memset(bufA, '-', sizeof(bufA)); 217 len2A = GetModuleFileNameA(hMod, bufA, len1A / 2); 218 ok(len2A > 0, "Getting module filename for handle %p\n", hMod); 219 220 if (is_unicode_enabled) 221 { 222 memset(bufW, '-', sizeof(bufW)); 223 len2W = GetModuleFileNameW(hMod, bufW, len1W / 2); 224 ok(len2W > 0, "Getting module filename for handle %p\n", hMod); 225 ok(cmpStrAW(bufA, bufW, len2A, len2W), "Comparing GetModuleFilenameAW results with buffer too small\n" ); 226 ok(len1W / 2 == len2W, "Correct length in GetModuleFilenameW with buffer too small (%ld/%ld)\n", len1W / 2, len2W); 227 } 228 229 ok(len1A / 2 == len2A, 230 "Correct length in GetModuleFilenameA with buffer too small (%ld/%ld)\n", len1A / 2, len2A); 231 232 len1A = GetModuleFileNameA(hMod, bufA, 0x10000); 233 ok(len1A > 0, "Getting module filename for handle %p\n", hMod); 234 len1W = GetModuleFileNameW(hMod, bufW, 0x10000); 235 ok(len1W > 0, "Getting module filename for handle %p\n", hMod); 236} 237 238static void testGetModuleFileName_Wrong(void) 239{ 240 char bufA[MAX_PATH]; 241 WCHAR bufW[MAX_PATH]; 242 243 /* test wrong handle */ 244 if (is_unicode_enabled) 245 { 246 bufW[0] = '*'; 247 ok(GetModuleFileNameW((void*)0xffffffff, bufW, ARRAY_SIZE(bufW)) == 0, 248 "Unexpected success in module handle\n"); 249 ok(bufW[0] == '*', "When failing, buffer shouldn't be written to\n"); 250 } 251 252 bufA[0] = '*'; 253 ok(GetModuleFileNameA((void*)0xffffffff, bufA, sizeof(bufA)) == 0, "Unexpected success in module handle\n"); 254 ok(bufA[0] == '*', "When failing, buffer shouldn't be written to\n"); 255} 256 257static void testLoadLibraryA(void) 258{ 259 HMODULE hModule, hModule1; 260 FARPROC fp; 261 262 SetLastError(0xdeadbeef); 263 hModule = LoadLibraryA("kernel32.dll"); 264 ok( hModule != NULL, "kernel32.dll should be loadable\n"); 265 ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %ld\n", GetLastError()); 266 267 fp = GetProcAddress(hModule, "CreateFileA"); 268 ok( fp != NULL, "CreateFileA should be there\n"); 269 ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %ld\n", GetLastError()); 270 271 SetLastError(0xdeadbeef); 272 hModule1 = LoadLibraryA("kernel32 "); 273 ok( hModule1 != NULL, "\"kernel32 \" should be loadable\n" ); 274 ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %ld\n", GetLastError() ); 275 ok( hModule == hModule1, "Loaded wrong module\n" ); 276 FreeLibrary(hModule1); 277 FreeLibrary(hModule); 278} 279 280static void testNestedLoadLibraryA(void) 281{ 282 static const char dllname[] = "shell32.dll"; 283 char path1[MAX_PATH], path2[MAX_PATH]; 284 HMODULE hModule1, hModule2, hModule3; 285 286 /* This is not really a Windows conformance test, but more a Wine 287 * regression test. Wine's builtin dlls can be loaded from multiple paths, 288 * and this test tries to make sure that Wine does not get confused and 289 * really unloads the Unix .so file at the right time. Failure to do so 290 * will result in the dll being unloadable. 291 * This test must be done with a dll that can be unloaded, which means: 292 * - it must not already be loaded 293 * - it must not have a 16-bit counterpart 294 */ 295 GetWindowsDirectoryA(path1, sizeof(path1)); 296 strcat(path1, "\\system\\"); 297 strcat(path1, dllname); 298 hModule1 = LoadLibraryA(path1); 299 if (!hModule1) 300 { 301 /* We must be on Windows, so we cannot test */ 302 return; 303 } 304 305 GetWindowsDirectoryA(path2, sizeof(path2)); 306 strcat(path2, "\\system32\\"); 307 strcat(path2, dllname); 308 hModule2 = LoadLibraryA(path2); 309 ok(hModule2 != NULL, "LoadLibrary(%s) failed\n", path2); 310 311 /* The first LoadLibrary() call may have registered the dll under the 312 * system32 path. So load it, again, under the '...\system\...' path so 313 * Wine does not immediately notice that it is already loaded. 314 */ 315 hModule3 = LoadLibraryA(path1); 316 ok(hModule3 != NULL, "LoadLibrary(%s) failed\n", path1); 317 318 /* Now fully unload the dll */ 319 ok(FreeLibrary(hModule3), "FreeLibrary() failed\n"); 320 ok(FreeLibrary(hModule2), "FreeLibrary() failed\n"); 321 ok(FreeLibrary(hModule1), "FreeLibrary() failed\n"); 322 ok(GetModuleHandleA(dllname) == NULL, "%s was not fully unloaded\n", dllname); 323 324 /* Try to load the dll again, if refcounting is ok, this should work */ 325 hModule1 = LoadLibraryA(path1); 326 ok(hModule1 != NULL, "LoadLibrary(%s) failed\n", path1); 327 if (hModule1 != NULL) 328 ok(FreeLibrary(hModule1), "FreeLibrary() failed\n"); 329} 330 331static void testLoadLibraryA_Wrong(void) 332{ 333 HMODULE hModule; 334 335 /* Try to load a nonexistent dll */ 336 SetLastError(0xdeadbeef); 337 hModule = LoadLibraryA("non_ex_pv.dll"); 338 ok( !hModule, "non_ex_pv.dll should be not loadable\n"); 339 ok( GetLastError() == ERROR_MOD_NOT_FOUND, "Expected ERROR_MOD_NOT_FOUND, got %ld\n", GetLastError() ); 340 341 /* Just in case */ 342 FreeLibrary(hModule); 343} 344 345static void testGetProcAddress_Wrong(void) 346{ 347 FARPROC fp; 348 349 SetLastError(0xdeadbeef); 350 fp = GetProcAddress(NULL, "non_ex_call"); 351 ok( !fp, "non_ex_call should not be found\n"); 352 ok( GetLastError() == ERROR_PROC_NOT_FOUND, "Expected ERROR_PROC_NOT_FOUND, got %ld\n", GetLastError() ); 353 354 SetLastError(0xdeadbeef); 355 fp = GetProcAddress((HMODULE)0xdeadbeef, "non_ex_call"); 356 ok( !fp, "non_ex_call should not be found\n"); 357 ok( GetLastError() == ERROR_MOD_NOT_FOUND, "Expected ERROR_MOD_NOT_FOUND, got %ld\n", GetLastError() ); 358} 359 360static void testLoadLibraryEx(void) 361{ 362 CHAR path[MAX_PATH]; 363 HMODULE hmodule; 364 HANDLE hfile; 365 BOOL ret; 366 367 hfile = CreateFileA("testfile.dll", GENERIC_READ | GENERIC_WRITE, 368 FILE_SHARE_READ | FILE_SHARE_WRITE, 369 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 370 ok(hfile != INVALID_HANDLE_VALUE, "Expected a valid file handle\n"); 371 372 /* NULL lpFileName */ 373 SetLastError(0xdeadbeef); 374 hmodule = LoadLibraryExA(NULL, NULL, 0); 375 ok(hmodule == 0, "Expected 0, got %p\n", hmodule); 376 ok(GetLastError() == ERROR_MOD_NOT_FOUND || 377 GetLastError() == ERROR_INVALID_PARAMETER, 378 "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); 379 380 /* empty lpFileName */ 381 SetLastError(0xdeadbeef); 382 hmodule = LoadLibraryExA("", NULL, 0); 383 ok(hmodule == 0, "Expected 0, got %p\n", hmodule); 384 ok(GetLastError() == ERROR_MOD_NOT_FOUND || 385 GetLastError() == ERROR_INVALID_PARAMETER /* win8 */, 386 "Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND, got %ld\n", GetLastError()); 387 388 /* hFile is non-NULL */ 389 SetLastError(0xdeadbeef); 390 hmodule = LoadLibraryExA("testfile.dll", hfile, 0); 391 ok(hmodule == 0, "Expected 0, got %p\n", hmodule); 392 ok(GetLastError() == ERROR_SHARING_VIOLATION || 393 GetLastError() == ERROR_INVALID_PARAMETER, /* win2k3 */ 394 "Unexpected last error, got %ld\n", GetLastError()); 395 396 SetLastError(0xdeadbeef); 397 hmodule = LoadLibraryExA("testfile.dll", (HANDLE)0xdeadbeef, 0); 398 ok(hmodule == 0, "Expected 0, got %p\n", hmodule); 399 ok(GetLastError() == ERROR_SHARING_VIOLATION || 400 GetLastError() == ERROR_INVALID_PARAMETER, /* win2k3 */ 401 "Unexpected last error, got %ld\n", GetLastError()); 402 403 /* try to open a file that is locked */ 404 SetLastError(0xdeadbeef); 405 hmodule = LoadLibraryExA("testfile.dll", NULL, 0); 406 ok(hmodule == 0, "Expected 0, got %p\n", hmodule); 407 ok(GetLastError() == ERROR_SHARING_VIOLATION, 408 "Expected ERROR_SHARING_VIOLATION, got %ld\n", GetLastError()); 409 410 /* lpFileName does not matter */ 411 if (is_unicode_enabled) 412 { 413 SetLastError(0xdeadbeef); 414 hmodule = LoadLibraryExA(NULL, hfile, 0); 415 ok(hmodule == 0, "Expected 0, got %p\n", hmodule); 416 ok(GetLastError() == ERROR_MOD_NOT_FOUND || 417 GetLastError() == ERROR_INVALID_PARAMETER, /* win2k3 */ 418 "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); 419 } 420 421 CloseHandle(hfile); 422 423 /* load empty file */ 424 SetLastError(0xdeadbeef); 425 hmodule = LoadLibraryExA("testfile.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); 426 ok(hmodule == 0, "Expected 0, got %p\n", hmodule); 427 ok(GetLastError() == ERROR_FILE_INVALID, "Expected ERROR_FILE_INVALID, got %ld\n", GetLastError()); 428 429 DeleteFileA("testfile.dll"); 430 431 GetSystemDirectoryA(path, MAX_PATH); 432 if (path[lstrlenA(path) - 1] != '\\') 433 lstrcatA(path, "\\"); 434 lstrcatA(path, "kernel32.dll"); 435 436 /* load kernel32.dll with an absolute path */ 437 SetLastError(0xdeadbeef); 438 hmodule = LoadLibraryExA(path, NULL, LOAD_LIBRARY_AS_DATAFILE); 439 ok(hmodule != 0, "Expected valid module handle\n"); 440 ok(GetLastError() == 0xdeadbeef || 441 GetLastError() == ERROR_SUCCESS, 442 "Expected 0xdeadbeef or ERROR_SUCCESS, got %ld\n", GetLastError()); 443 444 /* try invalid file handle */ 445 SetLastError(0xdeadbeef); 446 hmodule = LoadLibraryExA(path, (HANDLE)0xdeadbeef, 0); 447 if (!hmodule) /* succeeds on xp and older */ 448 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError()); 449 450 FreeLibrary(hmodule); 451 452 /* load kernel32.dll with no path */ 453 SetLastError(0xdeadbeef); 454 hmodule = LoadLibraryExA("kernel32.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); 455 ok(hmodule != 0, "Expected valid module handle\n"); 456 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); 457 458 FreeLibrary(hmodule); 459 460 GetCurrentDirectoryA(MAX_PATH, path); 461 if (path[lstrlenA(path) - 1] != '\\') 462 lstrcatA(path, "\\"); 463 lstrcatA(path, "kernel32.dll"); 464 465 /* load kernel32.dll with an absolute path that does not exist */ 466 SetLastError(0xdeadbeef); 467 hmodule = LoadLibraryExA(path, NULL, LOAD_LIBRARY_AS_DATAFILE); 468 ok(hmodule == 0, "Expected 0, got %p\n", hmodule); 469 ok(GetLastError() == ERROR_FILE_NOT_FOUND, 470 "Expected ERROR_FILE_NOT_FOUND, got %ld\n", GetLastError()); 471 472 /* Free the loaded dll when it's the first time this dll is loaded 473 in process - First time should pass, second fail */ 474 SetLastError(0xdeadbeef); 475 hmodule = LoadLibraryExA("comctl32.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); 476 ok(hmodule != 0, "Expected valid module handle\n"); 477 478 SetLastError(0xdeadbeef); 479 ret = FreeLibrary( (HMODULE)((ULONG_PTR)hmodule + 0x1230)); 480 ok(!ret, "Free succeeded on wrong handle\n"); 481 ok(GetLastError() == ERROR_BAD_EXE_FORMAT, "wrong error %lu\n", GetLastError()); 482 483 SetLastError(0xdeadbeef); 484 ret = FreeLibrary(hmodule); 485 ok(ret, "Expected to be able to free the module, failed with %ld\n", GetLastError()); 486 SetLastError(0xdeadbeef); 487 ret = FreeLibrary(hmodule); 488 ok(!ret, "Unexpected ability to free the module, failed with %ld\n", GetLastError()); 489 490 /* load with full path, name without extension */ 491 GetSystemDirectoryA(path, MAX_PATH); 492 if (path[lstrlenA(path) - 1] != '\\') 493 lstrcatA(path, "\\"); 494 lstrcatA(path, "kernel32"); 495 hmodule = LoadLibraryExA(path, NULL, 0); 496 ok(hmodule != NULL, "got %p\n", hmodule); 497 FreeLibrary(hmodule); 498 499 /* same with alterate search path */ 500 hmodule = LoadLibraryExA(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); 501 ok(hmodule != NULL, "got %p\n", hmodule); 502 FreeLibrary(hmodule); 503} 504 505static void test_LoadLibraryEx_search_flags(void) 506{ 507 static const char apiset_dll[] = "api-ms-win-shcore-obsolete-l1-1-0.dll"; 508 static const struct 509 { 510 int add_dirs[4]; 511 int dll_dir; 512 int expect; 513 } tests[] = 514 { 515 { { 1, 2, 3 }, 4, 3 }, /* 0 */ 516 { { 1, 3, 2 }, 4, 2 }, 517 { { 3, 1 }, 4, 1 }, 518 { { 5, 6 }, 4, 4 }, 519 { { 5, 2 }, 4, 2 }, 520 { { 0 }, 4, 4 }, /* 5 */ 521 { { 0 }, 0, 0 }, 522 { { 6, 5 }, 5, 0 }, 523 { { 1, 1, 2 }, 0, 2 }, 524 }; 525 char *p, path[MAX_PATH], buf[MAX_PATH], curdir[MAX_PATH]; 526 WCHAR bufW[MAX_PATH]; 527 DLL_DIRECTORY_COOKIE cookies[4]; 528 unsigned int i, j, k; 529 BOOL ret; 530 HMODULE mod; 531 532 GetTempPathA( sizeof(path), path ); 533 GetTempFileNameA( path, "tmp", 0, buf ); 534 DeleteFileA( buf ); 535 ret = CreateDirectoryA( buf, NULL ); 536 ok( ret, "CreateDirectory failed err %lu\n", GetLastError() ); 537 p = buf + strlen( buf ); 538 for (i = 1; i <= 6; i++) 539 { 540 sprintf( p, "\\%u", i ); 541 ret = CreateDirectoryA( buf, NULL ); 542 ok( ret, "CreateDirectory failed err %lu\n", GetLastError() ); 543 if (i >= 5) continue; /* dirs 5 and 6 are left empty */ 544 sprintf( p, "\\%u\\winetestdll.dll", i ); 545 create_test_dll( buf ); 546 } 547 548 GetCurrentDirectoryA( MAX_PATH, curdir ); 549 *p = 0; 550 SetCurrentDirectoryA( buf ); 551 552 SetLastError( 0xdeadbeef ); 553 mod = LoadLibraryA( "1\\winetestdll.dll" ); 554 ok( mod != NULL, "LoadLibrary failed err %lu\n", GetLastError() ); 555 FreeLibrary( mod ); 556 557 SetLastError( 0xdeadbeef ); 558 sprintf( path, "%c:1\\winetestdll.dll", buf[0] ); 559 mod = LoadLibraryA( path ); 560 ok( mod != NULL, "LoadLibrary failed err %lu\n", GetLastError() ); 561 FreeLibrary( mod ); 562 563 if (pAddDllDirectory) 564 { 565 SetLastError( 0xdeadbeef ); 566 mod = LoadLibraryExA( "1\\winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_SYSTEM32 ); 567 ok( !mod, "LoadLibrary succeeded\n" ); 568 ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %lu\n", GetLastError() ); 569 570 SetLastError( 0xdeadbeef ); 571 mod = LoadLibraryExA( path, 0, LOAD_LIBRARY_SEARCH_SYSTEM32 ); 572 ok( mod != NULL, "LoadLibrary failed err %lu\n", GetLastError() ); 573 FreeLibrary( mod ); 574 } 575 576 strcpy( p, "\\1" ); 577 SetCurrentDirectoryA( buf ); 578 579 SetLastError( 0xdeadbeef ); 580 mod = LoadLibraryA( "winetestdll.dll" ); 581 ok( mod != NULL, "LoadLibrary failed err %lu\n", GetLastError() ); 582 FreeLibrary( mod ); 583 584 SetLastError( 0xdeadbeef ); 585 sprintf( path, "%c:winetestdll.dll", buf[0] ); 586 mod = LoadLibraryA( path ); 587 ok( mod != NULL || broken(!mod), /* win10 disallows this but allows c:1\\winetestdll.dll */ 588 "LoadLibrary failed err %lu\n", GetLastError() ); 589 if (!mod) ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %lu\n", GetLastError() ); 590 else FreeLibrary( mod ); 591 592 SetLastError( 0xdeadbeef ); 593 sprintf( path, "%s\\winetestdll.dll", buf + 2 ); 594 mod = LoadLibraryA( path ); 595 ok( mod != NULL, "LoadLibrary failed err %lu\n", GetLastError() ); 596 FreeLibrary( mod ); 597 598 if (pAddDllDirectory) 599 { 600 SetLastError( 0xdeadbeef ); 601 mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_SYSTEM32 ); 602 ok( !mod, "LoadLibrary succeeded\n" ); 603 ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %lu\n", GetLastError() ); 604 605 SetLastError( 0xdeadbeef ); 606 mod = LoadLibraryExA( path, 0, LOAD_LIBRARY_SEARCH_SYSTEM32 ); 607 ok( mod != NULL, "LoadLibrary failed err %lu\n", GetLastError() ); 608 FreeLibrary( mod ); 609 610 SetLastError( 0xdeadbeef ); 611 sprintf( path, "%s\\winetestdll.dll", buf + 2 ); 612 mod = LoadLibraryExA( path, 0, LOAD_LIBRARY_SEARCH_SYSTEM32 ); 613 ok( mod != NULL, "LoadLibrary failed err %lu\n", GetLastError() ); 614 FreeLibrary( mod ); 615 616 SetLastError( 0xdeadbeef ); 617 mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_WITH_ALTERED_SEARCH_PATH ); 618 ok( !mod, "LoadLibrary succeeded\n" ); 619 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 620 621 SetLastError( 0xdeadbeef ); 622 mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_WITH_ALTERED_SEARCH_PATH ); 623 ok( !mod, "LoadLibrary succeeded\n" ); 624 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 625 626 SetLastError( 0xdeadbeef ); 627 mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_SYSTEM32 | LOAD_WITH_ALTERED_SEARCH_PATH ); 628 ok( !mod, "LoadLibrary succeeded\n" ); 629 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 630 631 SetLastError( 0xdeadbeef ); 632 mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_WITH_ALTERED_SEARCH_PATH ); 633 ok( !mod, "LoadLibrary succeeded\n" ); 634 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 635 636 SetLastError( 0xdeadbeef ); 637 mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_USER_DIRS | LOAD_WITH_ALTERED_SEARCH_PATH ); 638 ok( !mod, "LoadLibrary succeeded\n" ); 639 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 640 } 641 642 SetCurrentDirectoryA( curdir ); 643 644 if (!pAddDllDirectory || !pSetDllDirectoryA) goto done; 645 646 SetLastError( 0xdeadbeef ); 647 mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR ); 648 ok( !mod, "LoadLibrary succeeded\n" ); 649 ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %lu\n", GetLastError() ); 650 651 if (0) /* crashes on win10 */ 652 { 653 SetLastError( 0xdeadbeef ); 654 mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_USER_DIRS ); 655 ok( !mod, "LoadLibrary succeeded\n" ); 656 ok( GetLastError() == ERROR_MOD_NOT_FOUND || broken(GetLastError() == ERROR_NOT_ENOUGH_MEMORY), 657 "wrong error %lu\n", GetLastError() ); 658 } 659 660 SetLastError( 0xdeadbeef ); 661 mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_SYSTEM32 ); 662 ok( !mod, "LoadLibrary succeeded\n" ); 663 ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %lu\n", GetLastError() ); 664 665 SetLastError( 0xdeadbeef ); 666 mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR ); 667 ok( !mod, "LoadLibrary succeeded\n" ); 668 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 669 670 SetLastError( 0xdeadbeef ); 671 mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32 ); 672 ok( !mod, "LoadLibrary succeeded\n" ); 673 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 674 675 SetLastError( 0xdeadbeef ); 676 mod = LoadLibraryExA( "foo\\winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR ); 677 ok( !mod, "LoadLibrary succeeded\n" ); 678 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 679 680 SetLastError( 0xdeadbeef ); 681 mod = LoadLibraryExA( "\\windows\\winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR ); 682 ok( !mod, "LoadLibrary succeeded\n" ); 683 ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %lu\n", GetLastError() ); 684 685 SetLastError( 0xdeadbeef ); 686 mod = LoadLibraryA( "1\\winetestdll.dll" ); 687 ok( !mod, "LoadLibrary succeeded\n" ); 688 ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %lu\n", GetLastError() ); 689 690 for (j = 0; j < ARRAY_SIZE(tests); j++) 691 { 692 for (k = 0; tests[j].add_dirs[k]; k++) 693 { 694 sprintf( p, "\\%u", tests[j].add_dirs[k] ); 695 MultiByteToWideChar( CP_ACP, 0, buf, -1, bufW, MAX_PATH ); 696 cookies[k] = pAddDllDirectory( bufW ); 697 ok( cookies[k] != NULL, "failed to add %s\n", buf ); 698 } 699 if (tests[j].dll_dir) 700 { 701 sprintf( p, "\\%u", tests[j].dll_dir ); 702 pSetDllDirectoryA( buf ); 703 } 704 else pSetDllDirectoryA( NULL ); 705 706 SetLastError( 0xdeadbeef ); 707 mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_USER_DIRS ); 708 if (tests[j].expect) 709 { 710 ok( mod != NULL, "%u: LoadLibrary failed err %lu\n", j, GetLastError() ); 711 GetModuleFileNameA( mod, path, MAX_PATH ); 712 sprintf( p, "\\%u\\winetestdll.dll", tests[j].expect ); 713 ok( !lstrcmpiA( path, buf ), "%u: wrong module %s expected %s\n", j, path, buf ); 714 } 715 else 716 { 717 ok( !mod, "%u: LoadLibrary succeeded\n", j ); 718 ok( GetLastError() == ERROR_MOD_NOT_FOUND || broken(GetLastError() == ERROR_NOT_ENOUGH_MEMORY), 719 "%u: wrong error %lu\n", j, GetLastError() ); 720 } 721 FreeLibrary( mod ); 722 723 for (k = 0; tests[j].add_dirs[k]; k++) pRemoveDllDirectory( cookies[k] ); 724 } 725 726 mod = GetModuleHandleA( apiset_dll ); 727 if (mod) 728 { 729 win_skip( "%s already referenced, skipping test.\n", apiset_dll ); 730 } 731 else 732 { 733 LoadLibraryA( "ole32.dll" ); /* FIXME: make sure the dependencies are loaded */ 734 mod = LoadLibraryA( apiset_dll ); 735 if (mod) 736 { 737 HMODULE shcore; 738 char buffer[MAX_PATH]; 739 740 FreeLibrary(mod); 741 mod = LoadLibraryExA( apiset_dll, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR ); 742 ok( !!mod, "Got NULL module, error %lu.\n", GetLastError() ); 743 ok( !!GetModuleHandleA( apiset_dll ), "Got NULL handle.\n" ); 744 shcore = GetModuleHandleA( "shcore.dll" ); 745 ok( mod == shcore, "wrong module %p/%p\n", mod, shcore ); 746 ret = FreeLibrary( mod ); 747 ok( ret, "FreeLibrary failed, error %lu.\n", GetLastError() ); 748 shcore = GetModuleHandleA( "shcore.dll" ); 749 ok( !shcore, "shcore not unloaded\n" ); 750 751 /* api set without .dll */ 752 strcpy( buffer, apiset_dll ); 753 buffer[strlen(buffer) - 4] = 0; 754 mod = LoadLibraryExA( buffer, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR ); 755 ok( !!mod, "Got NULL module, error %lu.\n", GetLastError() ); 756 ok( !!GetModuleHandleA( apiset_dll ), "Got NULL handle.\n" ); 757 shcore = GetModuleHandleA( "shcore.dll" ); 758 ok( mod == shcore, "wrong module %p/%p\n", mod, shcore ); 759 ret = FreeLibrary( mod ); 760 ok( ret, "FreeLibrary failed, error %lu.\n", GetLastError() ); 761 shcore = GetModuleHandleA( "shcore.dll" ); 762 ok( !shcore, "shcore not unloaded\n" ); 763 764 /* api set with different version */ 765 strcpy( buffer, apiset_dll ); 766 buffer[strlen(buffer) - 5] = '9'; 767 mod = LoadLibraryExA( buffer, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR ); 768 ok( !!mod || broken(!mod) /* win8 */, "Got NULL module, error %lu.\n", GetLastError() ); 769 if (mod) 770 { 771 ok( !!GetModuleHandleA( apiset_dll ), "Got NULL handle.\n" ); 772 shcore = GetModuleHandleA( "shcore.dll" ); 773 ok( mod == shcore, "wrong module %p/%p\n", mod, shcore ); 774 ret = FreeLibrary( mod ); 775 ok( ret, "FreeLibrary failed, error %lu.\n", GetLastError() ); 776 } 777 shcore = GetModuleHandleA( "shcore.dll" ); 778 ok( !shcore, "shcore not unloaded\n" ); 779 780 /* api set with full path */ 781 GetWindowsDirectoryA( buffer, MAX_PATH ); 782 strcat( buffer, "\\" ); 783 strcat( buffer, apiset_dll ); 784 SetLastError( 0xdeadbeef ); 785 mod = LoadLibraryExA( buffer, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR ); 786 ok( !mod, "Loaded %s\n", debugstr_a(buffer) ); 787 ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %lu\n", GetLastError() ); 788 SetLastError( 0xdeadbeef ); 789 mod = LoadLibraryA( buffer ); 790 ok( !mod, "Loaded %s\n", debugstr_a(buffer) ); 791 ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %lu\n", GetLastError() ); 792 } 793 else 794 { 795 win_skip( "%s not found, skipping test.\n", apiset_dll ); 796 } 797 798 /* try a library with dependencies */ 799 mod = GetModuleHandleA( "rasapi32.dll" ); 800 ok( !mod, "rasapi32 already loaded\n" ); 801 mod = LoadLibraryA( "rasapi32.dll" ); 802 ok( !!mod, "rasapi32 not found %lu\n", GetLastError() ); 803 FreeLibrary( mod ); 804 SetLastError( 0xdeadbeef ); 805 mod = LoadLibraryExA( "rasapi32.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR ); 806 ok( !mod, "rasapi32 loaded\n" ); 807 ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %lu\n", GetLastError() ); 808 SetLastError( 0xdeadbeef ); 809 mod = LoadLibraryExA( "ext-ms-win-ras-rasapi32-l1-1-0.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR ); 810 todo_wine /* rasapi32 doesn't have interesting dependencies on wine */ 811 ok( !mod, "rasapi32 loaded\n" ); 812 if (mod) FreeLibrary( mod ); 813 else ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %lu\n", GetLastError() ); 814 mod = LoadLibraryA( "ext-ms-win-ras-rasapi32-l1-1-0.dll" ); 815 ok( !!mod || broken(!mod) /* win7 */, "rasapi32 not found %lu\n", GetLastError() ); 816 if (mod) FreeLibrary( mod ); 817 mod = GetModuleHandleA( "rasapi32.dll" ); 818 ok( !mod, "rasapi32 still loaded\n" ); 819 } 820done: 821 for (i = 1; i <= 6; i++) 822 { 823 sprintf( p, "\\%u\\winetestdll.dll", i ); 824 DeleteFileA( buf ); 825 sprintf( p, "\\%u", i ); 826 RemoveDirectoryA( buf ); 827 } 828 *p = 0; 829 RemoveDirectoryA( buf ); 830} 831 832static void testGetDllDirectory(void) 833{ 834 CHAR bufferA[MAX_PATH]; 835 WCHAR bufferW[MAX_PATH]; 836 DWORD length, ret; 837 int i; 838 static const char *dll_directories[] = 839 { 840 "", 841 "C:\\Some\\Path", 842 "C:\\Some\\Path\\", 843 "Q:\\A\\Long\\Path with spaces that\\probably\\doesn't exist!", 844 }; 845 const int test_count = ARRAY_SIZE(dll_directories); 846 847 if (!pGetDllDirectoryA || !pGetDllDirectoryW) 848 { 849 win_skip("GetDllDirectory not available\n"); 850 return; 851 } 852 if (!pSetDllDirectoryA) 853 { 854 win_skip("SetDllDirectoryA not available\n"); 855 return; 856 } 857 858 for (i = 0; i < test_count; i++) 859 { 860 length = strlen(dll_directories[i]); 861 if (!pSetDllDirectoryA(dll_directories[i])) 862 { 863 skip("i=%d, SetDllDirectoryA failed\n", i); 864 continue; 865 } 866 867 /* no buffer, determine length */ 868 ret = pGetDllDirectoryA(0, NULL); 869 ok(ret == length + 1, "Expected %lu, got %lu\n", length + 1, ret); 870 871 ret = pGetDllDirectoryW(0, NULL); 872 ok(ret == length + 1, "Expected %lu, got %lu\n", length + 1, ret); 873 874 /* buffer of exactly the right size */ 875 bufferA[length] = 'A'; 876 bufferA[length + 1] = 'A'; 877 ret = pGetDllDirectoryA(length + 1, bufferA); 878 ok(ret == length || broken(ret + 1 == length) /* win8 */, 879 "i=%d, Expected %lu(+1), got %lu\n", i, length, ret); 880 ok(bufferA[length + 1] == 'A', "i=%d, Buffer overflow\n", i); 881 ok(strcmp(bufferA, dll_directories[i]) == 0, "i=%d, Wrong path returned: '%s'\n", i, bufferA); 882 883 bufferW[length] = 'A'; 884 bufferW[length + 1] = 'A'; 885 ret = pGetDllDirectoryW(length + 1, bufferW); 886 ok(ret == length, "i=%d, Expected %lu, got %lu\n", i, length, ret); 887 ok(bufferW[length + 1] == 'A', "i=%d, Buffer overflow\n", i); 888 ok(cmpStrAW(dll_directories[i], bufferW, length, length), 889 "i=%d, Wrong path returned: %s\n", i, wine_dbgstr_w(bufferW)); 890 891 /* Zero size buffer. The buffer may or may not be terminated depending 892 * on the Windows version and whether the A or W API is called. */ 893 bufferA[0] = 'A'; 894 ret = pGetDllDirectoryA(0, bufferA); 895 ok(ret == length + 1, "i=%d, Expected %lu, got %lu\n", i, length + 1, ret); 896 897 bufferW[0] = 'A'; 898 ret = pGetDllDirectoryW(0, bufferW); 899 ok(ret == length + 1, "i=%d, Expected %lu, got %lu\n", i, length + 1, ret); 900 ok(bufferW[0] == 'A' || broken(bufferW[0] == 0), /* XP, 2003 */ 901 "i=%d, Buffer overflow\n", i); 902 903 /* buffer just one too short */ 904 bufferA[0] = 'A'; 905 ret = pGetDllDirectoryA(length, bufferA); 906 ok(ret == length + 1, "i=%d, Expected %lu, got %lu\n", i, length + 1, ret); 907 if (length != 0) 908 ok(bufferA[0] == 0, "i=%d, Buffer not null terminated\n", i); 909 910 bufferW[0] = 'A'; 911 ret = pGetDllDirectoryW(length, bufferW); 912 ok(ret == length + 1, "i=%d, Expected %lu, got %lu\n", i, length + 1, ret); 913 if (length != 0) 914 ok(bufferW[0] == 0, "i=%d, Buffer overflow\n", i); 915 916 if (0) 917 { 918 /* crashes on win8 */ 919 /* no buffer, but too short length */ 920 ret = pGetDllDirectoryA(length, NULL); 921 ok(ret == length + 1, "i=%d, Expected %lu, got %lu\n", i, length + 1, ret); 922 923 ret = pGetDllDirectoryW(length, NULL); 924 ok(ret == length + 1, "i=%d, Expected %lu, got %lu\n", i, length + 1, ret); 925 } 926 927 if (pLdrGetDllDirectory) 928 { 929 UNICODE_STRING str; 930 NTSTATUS status; 931 str.Buffer = bufferW; 932 str.MaximumLength = sizeof(bufferW); 933 status = pLdrGetDllDirectory( &str ); 934 ok( !status, "LdrGetDllDirectory failed %lx\n", status ); 935 ok( cmpStrAW( dll_directories[i], bufferW, strlen(dll_directories[i]), 936 str.Length / sizeof(WCHAR) ), "%u: got %s instead of %s\n", 937 i, wine_dbgstr_w(bufferW), dll_directories[i] ); 938 if (dll_directories[i][0]) 939 { 940 memset( bufferW, 0xcc, sizeof(bufferW) ); 941 str.MaximumLength = (strlen( dll_directories[i] ) - 1) * sizeof(WCHAR); 942 status = pLdrGetDllDirectory( &str ); 943 ok( status == STATUS_BUFFER_TOO_SMALL, "%u: LdrGetDllDirectory failed %lx\n", i, status ); 944 ok( bufferW[0] == 0 && bufferW[1] == 0xcccc, 945 "%u: buffer %x %x\n", i, bufferW[0], bufferW[1] ); 946 length = (strlen( dll_directories[i] ) + 1) * sizeof(WCHAR); 947 ok( str.Length == length, "%u: wrong len %u / %lu\n", i, str.Length, length ); 948 } 949 } 950 } 951 952 /* unset whatever we did so following tests won't be affected */ 953 pSetDllDirectoryA(NULL); 954} 955 956static void init_pointers(void) 957{ 958 HMODULE mod = GetModuleHandleA("kernel32.dll"); 959 960#define MAKEFUNC(f) (p##f = (void*)GetProcAddress(mod, #f)) 961 MAKEFUNC(GetDllDirectoryA); 962 MAKEFUNC(GetDllDirectoryW); 963 MAKEFUNC(SetDllDirectoryA); 964 MAKEFUNC(AddDllDirectory); 965 MAKEFUNC(RemoveDllDirectory); 966 MAKEFUNC(SetDefaultDllDirectories); 967 MAKEFUNC(K32GetModuleInformation); 968 mod = GetModuleHandleA( "ntdll.dll" ); 969 MAKEFUNC(ApiSetQueryApiSetPresence); 970 MAKEFUNC(ApiSetQueryApiSetPresenceEx); 971 MAKEFUNC(LdrGetDllDirectory); 972 MAKEFUNC(LdrSetDllDirectory); 973 MAKEFUNC(LdrGetDllHandle); 974 MAKEFUNC(LdrGetDllHandleEx); 975 MAKEFUNC(LdrGetDllFullName); 976 MAKEFUNC(RtlHashUnicodeString); 977 mod = GetModuleHandleA( "kernelbase.dll" ); 978 MAKEFUNC(IsApiSetImplemented); 979#undef MAKEFUNC 980 981 /* before Windows 7 this was not exported in kernel32 */ 982 if (!pK32GetModuleInformation) 983 { 984 HMODULE hPsapi = LoadLibraryA("psapi.dll"); 985 pK32GetModuleInformation = (void *)GetProcAddress(hPsapi, "GetModuleInformation"); 986 } 987} 988 989static void testGetModuleHandleEx(void) 990{ 991 static const char longname[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 992 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 993 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 994 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 995 static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2',0}; 996 static const WCHAR nosuchmodW[] = {'n','o','s','u','c','h','m','o','d',0}; 997 BOOL ret; 998 DWORD error; 999 HMODULE mod, mod_kernel32; 1000 1001 SetLastError( 0xdeadbeef ); 1002 ret = GetModuleHandleExA( 0, NULL, NULL ); 1003 error = GetLastError(); 1004 ok( !ret, "unexpected success\n" ); 1005 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1006 1007 SetLastError( 0xdeadbeef ); 1008 ret = GetModuleHandleExA( 0, "kernel32", NULL ); 1009 error = GetLastError(); 1010 ok( !ret, "unexpected success\n" ); 1011 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1012 1013 SetLastError( 0xdeadbeef ); 1014 mod = (HMODULE)0xdeadbeef; 1015 ret = GetModuleHandleExA( 0, "kernel32", &mod ); 1016 ok( ret, "unexpected failure %lu\n", GetLastError() ); 1017 ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod ); 1018 FreeLibrary( mod ); 1019 1020 SetLastError( 0xdeadbeef ); 1021 mod = (HMODULE)0xdeadbeef; 1022 ret = GetModuleHandleExA( 0, "nosuchmod", &mod ); 1023 error = GetLastError(); 1024 ok( !ret, "unexpected success\n" ); 1025 ok( error == ERROR_MOD_NOT_FOUND, "got %lu\n", error ); 1026 ok( mod == NULL, "got %p\n", mod ); 1027 1028 SetLastError( 0xdeadbeef ); 1029 ret = GetModuleHandleExA( 0, longname, NULL ); 1030 error = GetLastError(); 1031 ok( !ret, "unexpected success\n" ); 1032 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1033 1034 SetLastError( 0xdeadbeef ); 1035 mod = (HMODULE)0xdeadbeef; 1036 ret = GetModuleHandleExA( 0, longname, &mod ); 1037 error = GetLastError(); 1038 ok( !ret, "unexpected success\n" ); 1039#ifdef __REACTOS__ 1040 ok( error == ERROR_MOD_NOT_FOUND || broken(error == ERROR_FILENAME_EXCED_RANGE) /* WS03 */, "got %lu\n", error ); 1041#else 1042 ok( error == ERROR_MOD_NOT_FOUND, "got %lu\n", error ); 1043#endif 1044 ok( mod == NULL, "got %p\n", mod ); 1045 1046 SetLastError( 0xdeadbeef ); 1047 ret = GetModuleHandleExW( 0, NULL, NULL ); 1048 error = GetLastError(); 1049 ok( !ret, "unexpected success\n" ); 1050 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1051 1052 SetLastError( 0xdeadbeef ); 1053 ret = GetModuleHandleExW( 0, kernel32W, NULL ); 1054 error = GetLastError(); 1055 ok( !ret, "unexpected success\n" ); 1056 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1057 1058 SetLastError( 0xdeadbeef ); 1059 mod = (HMODULE)0xdeadbeef; 1060 ret = GetModuleHandleExW( 0, kernel32W, &mod ); 1061 ok( ret, "unexpected failure %lu\n", GetLastError() ); 1062 ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod ); 1063 FreeLibrary( mod ); 1064 1065 SetLastError( 0xdeadbeef ); 1066 mod = (HMODULE)0xdeadbeef; 1067 ret = GetModuleHandleExW( 0, nosuchmodW, &mod ); 1068 error = GetLastError(); 1069 ok( !ret, "unexpected success\n" ); 1070 ok( error == ERROR_MOD_NOT_FOUND, "got %lu\n", error ); 1071 ok( mod == NULL, "got %p\n", mod ); 1072 1073 SetLastError( 0xdeadbeef ); 1074 ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL ); 1075 error = GetLastError(); 1076 ok( !ret, "unexpected success\n" ); 1077 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1078 1079 SetLastError( 0xdeadbeef ); 1080 ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", NULL ); 1081 error = GetLastError(); 1082 ok( !ret, "unexpected success\n" ); 1083 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1084 1085 SetLastError( 0xdeadbeef ); 1086 mod = (HMODULE)0xdeadbeef; 1087 ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", &mod ); 1088 ok( ret, "unexpected failure %lu\n", GetLastError() ); 1089 ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod ); 1090 1091 SetLastError( 0xdeadbeef ); 1092 mod = (HMODULE)0xdeadbeef; 1093 ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "nosuchmod", &mod ); 1094 error = GetLastError(); 1095 ok( !ret, "unexpected success\n" ); 1096 ok( error == ERROR_MOD_NOT_FOUND, "got %lu\n", error ); 1097 ok( mod == NULL, "got %p\n", mod ); 1098 1099 SetLastError( 0xdeadbeef ); 1100 ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL ); 1101 error = GetLastError(); 1102 ok( !ret, "unexpected success\n" ); 1103 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1104 1105 SetLastError( 0xdeadbeef ); 1106 ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, NULL ); 1107 error = GetLastError(); 1108 ok( !ret, "unexpected success\n" ); 1109 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1110 1111 SetLastError( 0xdeadbeef ); 1112 mod = (HMODULE)0xdeadbeef; 1113 ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, &mod ); 1114 ok( ret, "unexpected failure %lu\n", GetLastError() ); 1115 ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod ); 1116 1117 SetLastError( 0xdeadbeef ); 1118 mod = (HMODULE)0xdeadbeef; 1119 ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, nosuchmodW, &mod ); 1120 error = GetLastError(); 1121 ok( !ret, "unexpected success\n" ); 1122 ok( error == ERROR_MOD_NOT_FOUND, "got %lu\n", error ); 1123 ok( mod == NULL, "got %p\n", mod ); 1124 1125 mod_kernel32 = LoadLibraryA( "kernel32" ); 1126 1127 SetLastError( 0xdeadbeef ); 1128 ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL ); 1129 error = GetLastError(); 1130 ok( !ret, "unexpected success\n" ); 1131 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1132 1133 SetLastError( 0xdeadbeef ); 1134 ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, NULL ); 1135 error = GetLastError(); 1136 ok( !ret, "unexpected success\n" ); 1137 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1138 1139 SetLastError( 0xdeadbeef ); 1140 mod = (HMODULE)0xdeadbeef; 1141 ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, &mod ); 1142 ok( ret, "unexpected failure %lu\n", GetLastError() ); 1143 ok( mod == mod_kernel32, "got %p\n", mod ); 1144 FreeLibrary( mod ); 1145 1146 SetLastError( 0xdeadbeef ); 1147 mod = (HMODULE)0xdeadbeef; 1148 ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)0xbeefdead, &mod ); 1149 error = GetLastError(); 1150 ok( !ret, "unexpected success\n" ); 1151 ok( error == ERROR_MOD_NOT_FOUND, "got %lu\n", error ); 1152 ok( mod == NULL, "got %p\n", mod ); 1153 1154 SetLastError( 0xdeadbeef ); 1155 ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL ); 1156 error = GetLastError(); 1157 ok( !ret, "unexpected success\n" ); 1158 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1159 1160 SetLastError( 0xdeadbeef ); 1161 ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, NULL ); 1162 error = GetLastError(); 1163 ok( !ret, "unexpected success\n" ); 1164 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1165 1166 SetLastError( 0xdeadbeef ); 1167 mod = (HMODULE)0xdeadbeef; 1168 ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, &mod ); 1169 ok( ret, "unexpected failure %lu\n", GetLastError() ); 1170 ok( mod == mod_kernel32, "got %p\n", mod ); 1171 FreeLibrary( mod ); 1172 1173 SetLastError( 0xdeadbeef ); 1174 mod = (HMODULE)0xdeadbeef; 1175 ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)0xbeefdead, &mod ); 1176 error = GetLastError(); 1177 ok( !ret, "unexpected success\n" ); 1178 ok( error == ERROR_MOD_NOT_FOUND, "got %lu\n", error ); 1179 ok( mod == NULL, "got %p\n", mod ); 1180 1181 SetLastError( 0xdeadbeef ); 1182 mod = (HMODULE)0xdeadbeef; 1183 ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 1184 | GET_MODULE_HANDLE_EX_FLAG_PIN, (LPCWSTR)mod_kernel32, &mod ); 1185 error = GetLastError(); 1186 ok( !ret, "unexpected success\n" ); 1187 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1188 ok( mod == NULL, "got %p\n", mod ); 1189 1190 SetLastError( 0xdeadbeef ); 1191 mod = (HMODULE)0xdeadbeef; 1192 ret = GetModuleHandleExW( 8, kernel32W, &mod ); 1193 error = GetLastError(); 1194 ok( !ret, "unexpected success\n" ); 1195 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); 1196 ok( mod == NULL, "got %p\n", mod ); 1197 1198 FreeLibrary( mod_kernel32 ); 1199} 1200 1201static void testK32GetModuleInformation(void) 1202{ 1203 MODULEINFO info; 1204 HMODULE mod; 1205 BOOL ret; 1206 1207 mod = GetModuleHandleA(NULL); 1208 memset(&info, 0xAA, sizeof(info)); 1209 ret = pK32GetModuleInformation(GetCurrentProcess(), mod, &info, sizeof(info)); 1210 ok(ret, "K32GetModuleInformation failed for main module\n"); 1211 ok(info.lpBaseOfDll == mod, "Wrong info.lpBaseOfDll = %p, expected %p\n", info.lpBaseOfDll, mod); 1212 ok(info.EntryPoint != NULL, "Expected nonzero entrypoint\n"); 1213 1214 mod = GetModuleHandleA("kernel32.dll"); 1215 memset(&info, 0xAA, sizeof(info)); 1216 ret = pK32GetModuleInformation(GetCurrentProcess(), mod, &info, sizeof(info)); 1217 ok(ret, "K32GetModuleInformation failed for kernel32 module\n"); 1218 ok(info.lpBaseOfDll == mod, "Wrong info.lpBaseOfDll = %p, expected %p\n", info.lpBaseOfDll, mod); 1219 ok(info.EntryPoint != NULL, "Expected nonzero entrypoint\n"); 1220} 1221 1222static void test_AddDllDirectory(void) 1223{ 1224 static const WCHAR tmpW[] = {'t','m','p',0}; 1225 static const WCHAR dotW[] = {'.','\\','.',0}; 1226 static const WCHAR rootW[] = {'\\',0}; 1227 WCHAR path[MAX_PATH], buf[MAX_PATH]; 1228 DLL_DIRECTORY_COOKIE cookie; 1229 BOOL ret; 1230 1231 if (!pAddDllDirectory || !pRemoveDllDirectory) 1232 { 1233 win_skip( "AddDllDirectory not available\n" ); 1234 return; 1235 } 1236 1237 buf[0] = '\0'; 1238 GetTempPathW(ARRAY_SIZE(path), path ); 1239 ret = GetTempFileNameW( path, tmpW, 0, buf ); 1240 ok( ret, "GetTempFileName failed err %lu\n", GetLastError() ); 1241 SetLastError( 0xdeadbeef ); 1242 cookie = pAddDllDirectory( buf ); 1243 ok( cookie != NULL, "AddDllDirectory failed err %lu\n", GetLastError() ); 1244 SetLastError( 0xdeadbeef ); 1245 ret = pRemoveDllDirectory( cookie ); 1246 ok( ret, "RemoveDllDirectory failed err %lu\n", GetLastError() ); 1247 1248 DeleteFileW( buf ); 1249 SetLastError( 0xdeadbeef ); 1250 cookie = pAddDllDirectory( buf ); 1251 ok( !cookie, "AddDllDirectory succeeded\n" ); 1252 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %lu\n", GetLastError() ); 1253 cookie = pAddDllDirectory( dotW ); 1254 ok( !cookie, "AddDllDirectory succeeded\n" ); 1255 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 1256 cookie = pAddDllDirectory( rootW ); 1257 ok( cookie != NULL, "AddDllDirectory failed err %lu\n", GetLastError() ); 1258 SetLastError( 0xdeadbeef ); 1259 ret = pRemoveDllDirectory( cookie ); 1260 ok( ret, "RemoveDllDirectory failed err %lu\n", GetLastError() ); 1261 GetWindowsDirectoryW( buf, MAX_PATH ); 1262 lstrcpyW( buf + 2, tmpW ); 1263 cookie = pAddDllDirectory( buf ); 1264 ok( !cookie, "AddDllDirectory succeeded\n" ); 1265 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 1266} 1267 1268static void test_SetDefaultDllDirectories(void) 1269{ 1270 HMODULE mod; 1271 BOOL ret; 1272 1273 if (!pSetDefaultDllDirectories) 1274 { 1275 win_skip( "SetDefaultDllDirectories not available\n" ); 1276 return; 1277 } 1278 1279 mod = LoadLibraryA( "authz.dll" ); 1280 ok( mod != NULL, "loading authz failed\n" ); 1281 FreeLibrary( mod ); 1282 ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_USER_DIRS ); 1283 ok( ret, "SetDefaultDllDirectories failed err %lu\n", GetLastError() ); 1284 mod = LoadLibraryA( "authz.dll" ); 1285 ok( !mod, "loading authz succeeded\n" ); 1286 FreeLibrary( mod ); 1287 ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_SYSTEM32 ); 1288 ok( ret, "SetDefaultDllDirectories failed err %lu\n", GetLastError() ); 1289 mod = LoadLibraryA( "authz.dll" ); 1290 ok( mod != NULL, "loading authz failed\n" ); 1291 FreeLibrary( mod ); 1292 mod = LoadLibraryExA( "authz.dll", 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR ); 1293 ok( !mod, "loading authz succeeded\n" ); 1294 FreeLibrary( mod ); 1295 ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_APPLICATION_DIR ); 1296 ok( ret, "SetDefaultDllDirectories failed err %lu\n", GetLastError() ); 1297 mod = LoadLibraryA( "authz.dll" ); 1298 ok( !mod, "loading authz succeeded\n" ); 1299 FreeLibrary( mod ); 1300 ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_DEFAULT_DIRS ); 1301 ok( ret, "SetDefaultDllDirectories failed err %lu\n", GetLastError() ); 1302 mod = LoadLibraryA( "authz.dll" ); 1303 ok( mod != NULL, "loading authz failed\n" ); 1304 FreeLibrary( mod ); 1305 1306 SetLastError( 0xdeadbeef ); 1307 ret = pSetDefaultDllDirectories( 0 ); 1308 ok( !ret, "SetDefaultDllDirectories succeeded\n" ); 1309 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 1310 1311 SetLastError( 0xdeadbeef ); 1312 ret = pSetDefaultDllDirectories( 3 ); 1313 ok( !ret, "SetDefaultDllDirectories succeeded\n" ); 1314 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 1315 1316 SetLastError( 0xdeadbeef ); 1317 ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_APPLICATION_DIR | 0x8000 ); 1318 ok( !ret, "SetDefaultDllDirectories succeeded\n" ); 1319 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 1320 1321 SetLastError( 0xdeadbeef ); 1322 ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR ); 1323 ok( !ret || broken(ret) /* win7 */, "SetDefaultDllDirectories succeeded\n" ); 1324 if (!ret) ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 1325 1326 SetLastError( 0xdeadbeef ); 1327 ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_USER_DIRS ); 1328 ok( !ret || broken(ret) /* win7 */, "SetDefaultDllDirectories succeeded\n" ); 1329 if (!ret) ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 1330 1331 /* restore some sane defaults */ 1332 pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_DEFAULT_DIRS ); 1333} 1334 1335static void check_refcount( HMODULE mod, unsigned int refcount ) 1336{ 1337 unsigned int i; 1338 BOOL ret; 1339 1340 for (i = 0; i < min( refcount, 10 ); ++i) 1341 { 1342 ret = FreeLibrary( mod ); 1343#ifdef __REACTOS__ 1344 ok( ret || broken( refcount == ~0u && GetLastError() == ERROR_MOD_NOT_FOUND && (i == 2) ) /* Win8 */ || broken( refcount == 2 && GetLastError() == ERROR_MOD_NOT_FOUND && i == 1 ) /* WS03 */, 1345#else 1346 ok( ret || broken( refcount == ~0u && GetLastError() == ERROR_MOD_NOT_FOUND && i == 2 ) /* Win8 */, 1347#endif 1348 "Refcount test failed, i %u, error %lu.\n", i, GetLastError(), refcount ); 1349 if (!ret) return; 1350 } 1351 if (refcount != ~0u) 1352 { 1353 ret = FreeLibrary( mod ); 1354 ok( !ret && GetLastError() == ERROR_MOD_NOT_FOUND, "Refcount test failed, ret %d, error %lu.\n", 1355 ret, GetLastError() ); 1356 } 1357} 1358 1359static void test_LdrGetDllHandleEx(void) 1360{ 1361 HMODULE mod, loaded_mod; 1362 UNICODE_STRING name; 1363 WCHAR path[MAX_PATH]; 1364 NTSTATUS status; 1365 unsigned int i; 1366 BOOL bret; 1367 1368 if (!pLdrGetDllHandleEx) 1369 { 1370 win_skip( "LdrGetDllHandleEx is not available.\n" ); 1371 return; 1372 } 1373 1374 RtlInitUnicodeString( &name, L"unknown.dll" ); 1375 status = pLdrGetDllHandleEx( 0, NULL, NULL, &name, &mod ); 1376 ok( status == STATUS_DLL_NOT_FOUND, "Got unexpected status %#lx.\n", status ); 1377 1378 RtlInitUnicodeString( &name, L"authz.dll" ); 1379 loaded_mod = LoadLibraryW( name.Buffer ); 1380 ok( !!loaded_mod, "Failed to load module.\n" ); 1381 status = pLdrGetDllHandleEx( 0, NULL, NULL, &name, &mod ); 1382 ok( !status, "Got unexpected status %#lx.\n", status ); 1383 ok( mod == loaded_mod, "got %p\n", mod ); 1384 winetest_push_context( "Flags 0" ); 1385 check_refcount( loaded_mod, 2 ); 1386 winetest_pop_context(); 1387 1388 loaded_mod = LoadLibraryW( name.Buffer ); 1389 ok( !!loaded_mod, "Failed to load module.\n" ); 1390 status = pLdrGetDllHandleEx( LDR_GET_DLL_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, 1391 NULL, &name, &mod ); 1392 ok( !status, "Got unexpected status %#lx.\n", status ); 1393 ok( mod == loaded_mod, "got %p\n", mod ); 1394 winetest_push_context( "LDR_GET_DLL_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT" ); 1395 check_refcount( loaded_mod, 1 ); 1396 winetest_pop_context(); 1397 1398 loaded_mod = LoadLibraryW( name.Buffer ); 1399 ok( !!loaded_mod, "Failed to load module.\n" ); 1400 status = pLdrGetDllHandle( NULL, ~0u, &name, &mod ); 1401 ok( !status, "Got unexpected status %#lx.\n", status ); 1402 ok( mod == loaded_mod, "got %p\n", mod ); 1403 winetest_push_context( "LdrGetDllHandle" ); 1404 check_refcount( loaded_mod, 1 ); 1405 winetest_pop_context(); 1406 1407 loaded_mod = LoadLibraryW( name.Buffer ); 1408 ok( !!loaded_mod, "Failed to load module.\n" ); 1409 status = pLdrGetDllHandleEx( 4, NULL, NULL, (void *)&name, &mod ); 1410#ifdef __REACTOS__ 1411 ok( !status || broken(status == STATUS_INVALID_PARAMETER) /* WS03 */, "Got unexpected status %#lx.\n", status ); 1412 ok( mod == loaded_mod || broken(mod == NULL) /* WS03 */, "got %p\n", mod ); 1413#else 1414 ok( !status, "Got unexpected status %#lx.\n", status ); 1415 ok( mod == loaded_mod, "got %p\n", mod ); 1416#endif 1417 winetest_push_context( "Flag 4" ); 1418 check_refcount( loaded_mod, 2 ); 1419 winetest_pop_context(); 1420 1421 for (i = 3; i < 32; ++i) 1422 { 1423 loaded_mod = LoadLibraryW( name.Buffer ); 1424 ok( !!loaded_mod, "Failed to load module.\n" ); 1425 status = pLdrGetDllHandleEx( 1 << i, NULL, NULL, &name, &mod ); 1426 ok( status == STATUS_INVALID_PARAMETER, "Got unexpected status %#lx.\n", status ); 1427 winetest_push_context( "Invalid flags, i %u", i ); 1428 check_refcount( loaded_mod, 1 ); 1429 winetest_pop_context(); 1430 } 1431 1432 status = pLdrGetDllHandleEx( LDR_GET_DLL_HANDLE_EX_FLAG_PIN | LDR_GET_DLL_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 1433 NULL, NULL, &name, &mod ); 1434 ok( status == STATUS_INVALID_PARAMETER, "Got unexpected status %#lx.\n", status ); 1435 1436 loaded_mod = LoadLibraryW( name.Buffer ); 1437 ok( !!loaded_mod, "Failed to load module.\n" ); 1438 status = pLdrGetDllHandleEx( LDR_GET_DLL_HANDLE_EX_FLAG_PIN, NULL, 1439 NULL, &name, &mod ); 1440 ok( !status, "Got unexpected status %#lx.\n", status ); 1441 ok( mod == loaded_mod, "got %p\n", mod ); 1442 winetest_push_context( "LDR_GET_DLL_HANDLE_EX_FLAG_PIN" ); 1443 check_refcount( loaded_mod, ~0u ); 1444 winetest_pop_context(); 1445 1446 GetCurrentDirectoryW( ARRAY_SIZE(path), path ); 1447 if (pAddDllDirectory) pAddDllDirectory( path ); 1448 create_test_dll( "d01.dll" ); 1449 mod = LoadLibraryA( "d01.dll" ); 1450 ok( !!mod, "got error %lu.\n", GetLastError() ); 1451 RtlInitUnicodeString( &name, L"d01.dll" ); 1452 status = pLdrGetDllHandleEx( LDR_GET_DLL_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL, &name, &loaded_mod ); 1453 ok( !status, "got %#lx.\n", status ); 1454 1455 RtlInitUnicodeString( &name, L"d02.dll" ); 1456 status = pLdrGetDllHandleEx( LDR_GET_DLL_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL, &name, &loaded_mod ); 1457 ok( status == STATUS_DLL_NOT_FOUND, "got %#lx.\n", status ); 1458 1459 /* Same (moved) file, different name: not found in loaded modules with short name but found with path. */ 1460 DeleteFileA( "d02.dll" ); 1461 bret = MoveFileA( "d01.dll", "d02.dll" ); 1462 ok( bret, "got error %lu.\n", GetLastError() ); 1463 status = pLdrGetDllHandleEx( LDR_GET_DLL_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL, &name, &loaded_mod ); 1464 ok( status == STATUS_DLL_NOT_FOUND, "got %#lx.\n", status ); 1465 CreateDirectoryA( "testdir", NULL ); 1466 DeleteFileA( "testdir\\d02.dll" ); 1467 bret = MoveFileA( "d02.dll", "testdir\\d02.dll" ); 1468 ok( bret, "got error %lu.\n", GetLastError() ); 1469 RtlInitUnicodeString( &name, L"testdir\\d02.dll" ); 1470 status = pLdrGetDllHandleEx( LDR_GET_DLL_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL, &name, &loaded_mod ); 1471 ok( !status, "got %#lx.\n", status ); 1472 ok( loaded_mod == mod, "got %p, %p.\n", loaded_mod, mod ); 1473 FreeLibrary( mod ); 1474 status = pLdrGetDllHandleEx( LDR_GET_DLL_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL, &name, &loaded_mod ); 1475 ok( status == STATUS_DLL_NOT_FOUND, "got %#lx.\n", status ); 1476 1477 DeleteFileA( "testdir\\d02.dll" ); 1478 RemoveDirectoryA( "testdir" ); 1479} 1480 1481static void test_LdrGetDllFullName(void) 1482{ 1483 WCHAR expected_path[MAX_PATH], path_buffer[MAX_PATH]; 1484 UNICODE_STRING path = {0, 0, path_buffer}; 1485 WCHAR expected_terminator; 1486 NTSTATUS status; 1487 HMODULE ntdll; 1488 1489 if (!pLdrGetDllFullName) 1490 { 1491 win_skip( "LdrGetDllFullName not available.\n" ); 1492 return; 1493 } 1494 1495 if (0) /* crashes on Windows */ 1496 pLdrGetDllFullName( ntdll, NULL ); 1497 1498 ntdll = GetModuleHandleW( L"ntdll.dll" ); 1499 1500 memset( path_buffer, 0x23, sizeof(path_buffer) ); 1501 1502 status = pLdrGetDllFullName( ntdll, &path ); 1503 ok( status == STATUS_BUFFER_TOO_SMALL, "Got unexpected status %#lx.\n", status ); 1504 ok( path.Length == 0, "Expected length 0, got %d.\n", path.Length ); 1505 ok( path_buffer[0] == 0x2323, "Expected 0x2323, got 0x%x.\n", path_buffer[0] ); 1506 1507 GetSystemDirectoryW( expected_path, ARRAY_SIZE(expected_path) ); 1508 path.MaximumLength = 5; /* odd numbers produce partially copied characters */ 1509 1510 status = pLdrGetDllFullName( ntdll, &path ); 1511 ok( status == STATUS_BUFFER_TOO_SMALL, "Got unexpected status %#lx.\n", status ); 1512 ok( path.Length == path.MaximumLength, "Expected length %u, got %u.\n", path.MaximumLength, path.Length ); 1513 expected_terminator = 0x2300 | (expected_path[path.MaximumLength / sizeof(WCHAR)] & 0xFF); 1514 ok( path_buffer[path.MaximumLength / sizeof(WCHAR)] == expected_terminator, 1515 "Expected 0x%x, got 0x%x.\n", expected_terminator, path_buffer[path.MaximumLength / 2] ); 1516 path_buffer[path.MaximumLength / sizeof(WCHAR)] = 0; 1517 expected_path[path.MaximumLength / sizeof(WCHAR)] = 0; 1518 ok( lstrcmpW(path_buffer, expected_path) == 0, "Expected %s, got %s.\n", 1519 wine_dbgstr_w(expected_path), wine_dbgstr_w(path_buffer) ); 1520 1521 GetSystemDirectoryW( expected_path, ARRAY_SIZE(expected_path) ); 1522 lstrcatW( expected_path, L"\\ntdll.dll" ); 1523 path.MaximumLength = sizeof(path_buffer); 1524 1525 status = pLdrGetDllFullName( ntdll, &path ); 1526 ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status ); 1527 ok( !lstrcmpiW(path_buffer, expected_path), "Expected %s, got %s\n", 1528 wine_dbgstr_w(expected_path), wine_dbgstr_w(path_buffer) ); 1529 1530 status = pLdrGetDllFullName( NULL, &path ); 1531 ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status ); 1532 GetModuleFileNameW( NULL, expected_path, ARRAY_SIZE(expected_path) ); 1533 ok( !lstrcmpiW(path_buffer, expected_path), "Expected %s, got %s.\n", 1534 wine_dbgstr_w(expected_path), wine_dbgstr_w(path_buffer) ); 1535} 1536 1537static void test_apisets(void) 1538{ 1539 static const struct 1540 { 1541 const char *name; 1542 BOOLEAN present; 1543 NTSTATUS status; 1544 BOOLEAN present_ex, in_schema, broken; 1545 } 1546 tests[] = 1547 { 1548 { "api-ms-win-core-console-l1-1-0", TRUE, STATUS_SUCCESS, TRUE, TRUE }, 1549 { "api-ms-win-core-console-l1-1-0.dll", TRUE, STATUS_INVALID_PARAMETER }, 1550 { "api-ms-win-core-console-l1-1-9", TRUE, STATUS_SUCCESS, FALSE, FALSE, TRUE }, 1551 { "api-ms-win-core-console-l1-1-9.dll", TRUE, STATUS_INVALID_PARAMETER, FALSE, FALSE, TRUE }, 1552 { "api-ms-win-core-console-l1-1", FALSE, STATUS_SUCCESS }, 1553 { "api-ms-win-core-console-l1-1-0.fake", TRUE, STATUS_INVALID_PARAMETER, FALSE, FALSE, TRUE }, 1554 { "api-ms-win-foo-bar-l1-1-0", FALSE, STATUS_SUCCESS }, 1555 { "api-ms-win-foo-bar-l1-1-0.dll", FALSE, STATUS_INVALID_PARAMETER }, 1556 { "ext-ms-win-gdi-draw-l1-1-1", TRUE, STATUS_SUCCESS, TRUE, TRUE }, 1557 { "ext-ms-win-gdi-draw-l1-1-1.dll", TRUE, STATUS_INVALID_PARAMETER }, 1558 { "api-ms-win-deprecated-apis-advapi-l1-1-0", FALSE, STATUS_SUCCESS, FALSE, TRUE }, 1559 { "foo", FALSE, STATUS_INVALID_PARAMETER }, 1560 { "foo.dll", FALSE, STATUS_INVALID_PARAMETER }, 1561 { "", FALSE, STATUS_INVALID_PARAMETER }, 1562 }; 1563 unsigned int i; 1564 NTSTATUS status; 1565 BOOLEAN present, in_schema; 1566 UNICODE_STRING name; 1567 1568 if (!pApiSetQueryApiSetPresence) 1569 { 1570 win_skip( "ApiSetQueryApiSetPresence not implemented\n" ); 1571 return; 1572 } 1573 if (!pApiSetQueryApiSetPresenceEx) win_skip( "ApiSetQueryApiSetPresenceEx not implemented\n" ); 1574 if (!pIsApiSetImplemented) win_skip( "IsApiSetImplemented not implemented\n" ); 1575 1576 for (i = 0; i < ARRAY_SIZE(tests); i++) 1577 { 1578 RtlCreateUnicodeStringFromAsciiz( &name, tests[i].name ); 1579 name.Buffer[name.Length / sizeof(WCHAR)] = 0xcccc; /* test without null termination */ 1580 winetest_push_context( "%u:%s", i, tests[i].name ); 1581 present = 0xff; 1582 status = pApiSetQueryApiSetPresence( &name, &present ); 1583 ok( status == STATUS_SUCCESS, "wrong ret %lx\n", status ); 1584 ok( present == tests[i].present || broken(!present && tests[i].broken) /* win8 */, 1585 "wrong present %u\n", present ); 1586 if (pApiSetQueryApiSetPresenceEx) 1587 { 1588 present = in_schema = 0xff; 1589 status = pApiSetQueryApiSetPresenceEx( &name, &in_schema, &present ); 1590 ok( status == tests[i].status, "wrong ret %lx\n", status ); 1591 if (!status) 1592 { 1593 ok( in_schema == tests[i].in_schema, "wrong in_schema %u\n", in_schema ); 1594 ok( present == tests[i].present_ex, "wrong present %u\n", present ); 1595 } 1596 else 1597 { 1598 ok( in_schema == 0xff, "wrong in_schema %u\n", in_schema ); 1599 ok( present == 0xff, "wrong present %u\n", present ); 1600 } 1601 } 1602 if (pIsApiSetImplemented) 1603 { 1604 BOOL ret = pIsApiSetImplemented( tests[i].name ); 1605 ok( ret == (!tests[i].status && tests[i].present_ex), "wrong result %u\n", ret ); 1606 } 1607 winetest_pop_context(); 1608 RtlFreeUnicodeString( &name ); 1609 } 1610} 1611 1612static void test_ddag_node(void) 1613{ 1614#if defined(__REACTOS__) && defined(_MSC_VER) 1615 struct dll_dependency { 1616 const WCHAR *dllname; 1617 BOOL optional; 1618 }; 1619 1620 static struct dll_dependency expected_exe_dependencies_Old[] = { 1621 { L"advapi32.dll" }, 1622 { L"msvcrt.dll", TRUE }, 1623 { L"user32.dll", TRUE }, 1624 }; 1625 1626 static struct dll_dependency expected_exe_dependencies_Win8[] = { 1627 { L"user32.dll" }, 1628 { L"advapi32.dll", TRUE }, 1629 { L"msvcrt.dll", TRUE }, 1630 }; 1631 1632 static struct dll_dependency* expected_exe_dependencies; 1633 static int expected_exe_dependencies_size; 1634#else 1635 static const struct 1636 { 1637 const WCHAR *dllname; 1638 BOOL optional; 1639 } 1640 expected_exe_dependencies[] = 1641 { 1642 { L"advapi32.dll" }, 1643 { L"msvcrt.dll", TRUE }, 1644 { L"user32.dll", TRUE }, 1645 }; 1646#endif 1647 LDR_DDAG_NODE *node, *dep_node, *prev_node; 1648 LDR_DATA_TABLE_ENTRY *mod, *mod2; 1649 SINGLE_LIST_ENTRY *se, *se2; 1650 LDR_DEPENDENCY *dep, *dep2; 1651 NTSTATUS status; 1652 unsigned int i; 1653 HMODULE hexe; 1654 1655#ifdef __REACTOS__ 1656 if (GetNTVersion() < _WIN32_WINNT_VISTA) { 1657 skip("test_ddag_node() crashes on WS03.\n"); 1658 return; 1659 } 1660#endif 1661 hexe = GetModuleHandleW( NULL ); 1662 ok( !!hexe, "Got NULL exe handle.\n" ); 1663 1664 status = LdrFindEntryForAddress( hexe, &mod ); 1665 ok( !status, "Got unexpected status %#lx.\n", status ); 1666 1667 if (!(node = mod->DdagNode)) 1668 { 1669 win_skip( "DdagNode is NULL, skipping tests.\n" ); 1670 return; 1671 } 1672 1673 ok( !!node->Modules.Flink, "Got NULL module link.\n" ); 1674 mod2 = CONTAINING_RECORD(node->Modules.Flink, LDR_DATA_TABLE_ENTRY, NodeModuleLink); 1675 ok( mod2 == mod || broken( (void **)mod2 == (void **)mod - 1 ), "Got unexpected mod2 %p, expected %p.\n", 1676 mod2, mod ); 1677 if (mod2 != mod) 1678 { 1679 win_skip( "Old LDR_DATA_TABLE_ENTRY structure, skipping tests.\n" ); 1680 return; 1681 } 1682 ok( node->Modules.Flink->Flink == &node->Modules, "Expected one element in list.\n" ); 1683 1684 ok( !node->IncomingDependencies.Tail, "Expected empty incoming dependencies list.\n" ); 1685 1686 /* node->Dependencies.Tail is NULL on Windows 10 1507-1607 32 bit test, maybe due to broken structure layout. */ 1687 ok( !!node->Dependencies.Tail || broken( sizeof(void *) == 4 && !node->Dependencies.Tail ), 1688 "Expected nonempty dependencies list.\n" ); 1689 if (!node->Dependencies.Tail) 1690 { 1691 win_skip( "Empty dependencies list.\n" ); 1692 return; 1693 } 1694 todo_wine ok( node->LoadCount == -1, "Got unexpected LoadCount %ld.\n", node->LoadCount ); 1695 1696 prev_node = NULL; 1697 se = node->Dependencies.Tail; 1698#if defined(__REACTOS__) && defined(_MSC_VER) 1699 if (GetNTVersion() >= _WIN32_WINNT_WIN8) { 1700 expected_exe_dependencies = expected_exe_dependencies_Win8; 1701 expected_exe_dependencies_size = ARRAY_SIZE(expected_exe_dependencies_Win8); 1702 } else { 1703 expected_exe_dependencies = expected_exe_dependencies_Old; 1704 expected_exe_dependencies_size = ARRAY_SIZE(expected_exe_dependencies_Old); 1705 } 1706 for (i = 0; i < expected_exe_dependencies_size; ++i) 1707#else 1708 for (i = 0; i < ARRAY_SIZE(expected_exe_dependencies); ++i) 1709#endif 1710 { 1711 winetest_push_context( "Dep %u (%s)", i, debugstr_w(expected_exe_dependencies[i].dllname) ); 1712 1713 se = se->Next; 1714 1715 ok( !!se, "Got NULL list element.\n" ); 1716 dep = CONTAINING_RECORD(se, LDR_DEPENDENCY, dependency_to_entry); 1717 ok( dep->dependency_from == node, "Got unexpected dependency_from %p.\n", dep->dependency_from ); 1718 ok( !!dep->dependency_to, "Got null dependency_to.\n" ); 1719 dep_node = dep->dependency_to; 1720 ok( !!dep_node, "Got NULL dep_node.\n" ); 1721 1722 if (dep_node == prev_node && expected_exe_dependencies[i].optional) 1723 { 1724 win_skip( "Module is not directly referenced.\n" ); 1725 winetest_pop_context(); 1726 prev_node = dep_node; 1727 continue; 1728 } 1729 1730 mod2 = CONTAINING_RECORD(dep_node->Modules.Flink, LDR_DATA_TABLE_ENTRY, NodeModuleLink); 1731 ok( !lstrcmpW( mod2->BaseDllName.Buffer, expected_exe_dependencies[i].dllname ), 1732 "Got unexpected module %s.\n", debugstr_w(mod2->BaseDllName.Buffer)); 1733 1734 se2 = dep_node->IncomingDependencies.Tail; 1735 ok( !!se2, "Got empty incoming dependencies list.\n" ); 1736 do 1737 { 1738 se2 = se2->Next; 1739 dep2 = CONTAINING_RECORD(se2, LDR_DEPENDENCY, dependency_from_entry); 1740 } 1741 while (dep2 != dep && se2 != dep_node->IncomingDependencies.Tail); 1742 ok( dep2 == dep, "Dependency not found in incoming deps list.\n" ); 1743 1744 todo_wine ok( dep_node->LoadCount > 0 || broken(!dep_node->LoadCount) /* Win8 */, 1745 "Got unexpected LoadCount %ld.\n", dep_node->LoadCount ); 1746 1747 winetest_pop_context(); 1748 prev_node = dep_node; 1749 } 1750 ok( se == node->Dependencies.Tail, "Expected end of the list.\n" ); 1751} 1752 1753static HANDLE test_tls_links_started, test_tls_links_done; 1754 1755static DWORD WINAPI test_tls_links_thread(void* tlsidx_v) 1756{ 1757 SetEvent(test_tls_links_started); 1758 WaitForSingleObject(test_tls_links_done, INFINITE); 1759 return 0; 1760} 1761 1762static void test_tls_links(void) 1763{ 1764 TEB *teb = NtCurrentTeb(), *thread_teb; 1765 THREAD_BASIC_INFORMATION tbi; 1766 NTSTATUS status; 1767 HANDLE thread; 1768 1769 ok(!!teb->ThreadLocalStoragePointer, "got NULL.\n"); 1770 1771 test_tls_links_started = CreateEventW(NULL, FALSE, FALSE, NULL); 1772 test_tls_links_done = CreateEventW(NULL, FALSE, FALSE, NULL); 1773 1774 thread = CreateThread(NULL, 0, test_tls_links_thread, NULL, CREATE_SUSPENDED, NULL); 1775 do 1776 { 1777 /* workaround currently present Wine bug when thread teb may be not available immediately 1778 * after creating a thread before it is initialized on the Unix side. */ 1779 Sleep(1); 1780 status = NtQueryInformationThread(thread, ThreadBasicInformation, &tbi, sizeof(tbi), NULL); 1781 ok(!status, "got %#lx.\n", status ); 1782 } while (!(thread_teb = tbi.TebBaseAddress)); 1783 ok(!thread_teb->ThreadLocalStoragePointer, "got %p.\n", thread_teb->ThreadLocalStoragePointer); 1784 ResumeThread(thread); 1785 WaitForSingleObject(test_tls_links_started, INFINITE); 1786 1787 ok(!!thread_teb->ThreadLocalStoragePointer, "got NULL.\n"); 1788 ok(!teb->TlsLinks.Flink, "got %p.\n", teb->TlsLinks.Flink); 1789 ok(!teb->TlsLinks.Blink, "got %p.\n", teb->TlsLinks.Blink); 1790 ok(!thread_teb->TlsLinks.Flink, "got %p.\n", thread_teb->TlsLinks.Flink); 1791 ok(!thread_teb->TlsLinks.Blink, "got %p.\n", thread_teb->TlsLinks.Blink); 1792 SetEvent(test_tls_links_done); 1793 WaitForSingleObject(thread, INFINITE); 1794 1795 CloseHandle(thread); 1796 CloseHandle(test_tls_links_started); 1797 CloseHandle(test_tls_links_done); 1798} 1799 1800 1801static RTL_BALANCED_NODE *rtl_node_parent( RTL_BALANCED_NODE *node ) 1802{ 1803 return (RTL_BALANCED_NODE *)(node->ParentValue & ~(ULONG_PTR)RTL_BALANCED_NODE_RESERVED_PARENT_MASK); 1804} 1805 1806static unsigned int check_address_index_tree( RTL_BALANCED_NODE *node ) 1807{ 1808 LDR_DATA_TABLE_ENTRY *mod; 1809 unsigned int count; 1810 char *base; 1811 1812 if (!node) return 0; 1813 ok( (node->ParentValue & RTL_BALANCED_NODE_RESERVED_PARENT_MASK) <= 1, "got ParentValue %#Ix.\n", 1814 node->ParentValue ); 1815 1816 mod = CONTAINING_RECORD(node, LDR_DATA_TABLE_ENTRY, BaseAddressIndexNode); 1817 base = mod->DllBase; 1818 if (node->Left) 1819 { 1820 mod = CONTAINING_RECORD(node->Left, LDR_DATA_TABLE_ENTRY, BaseAddressIndexNode); 1821 ok( (char *)mod->DllBase < base, "wrong ordering.\n" ); 1822 } 1823 if (node->Right) 1824 { 1825 mod = CONTAINING_RECORD(node->Right, LDR_DATA_TABLE_ENTRY, BaseAddressIndexNode); 1826 ok( (char *)mod->DllBase > base, "wrong ordering.\n" ); 1827 } 1828 1829 count = check_address_index_tree( node->Left ); 1830 count += check_address_index_tree( node->Right ); 1831 return count + 1; 1832} 1833 1834static void test_base_address_index_tree(void) 1835{ 1836 LIST_ENTRY *first = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList; 1837 unsigned int tree_count, list_count = 0; 1838 LDR_DATA_TABLE_ENTRY *mod, *mod2; 1839 RTL_BALANCED_NODE *root, *node; 1840 char *base; 1841 1842 if (is_old_loader_struct()) return; 1843 1844 mod = CONTAINING_RECORD(first->Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 1845 ok( mod->BaseAddressIndexNode.ParentValue || mod->BaseAddressIndexNode.Left || mod->BaseAddressIndexNode.Right, 1846 "got zero BaseAddressIndexNode.\n" ); 1847 root = &mod->BaseAddressIndexNode; 1848 while (rtl_node_parent( root )) 1849 root = rtl_node_parent( root ); 1850 tree_count = check_address_index_tree( root ); 1851 for (LIST_ENTRY *entry = first->Flink; entry != first; entry = entry->Flink) 1852 { 1853 ++list_count; 1854 mod = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 1855 base = mod->DllBase; 1856 node = root; 1857 mod2 = NULL; 1858 while (1) 1859 { 1860 ok( !!node, "got NULL.\n" ); 1861 if (!node) break; 1862 mod2 = CONTAINING_RECORD(node, LDR_DATA_TABLE_ENTRY, BaseAddressIndexNode); 1863 if (base == (char *)mod2->DllBase) break; 1864 if (base < (char *)mod2->DllBase) node = node->Left; 1865 else node = node->Right; 1866 } 1867 ok( base == (char *)mod2->DllBase, "module %s not found.\n", debugstr_w(mod->BaseDllName.Buffer) ); 1868 } 1869 ok( tree_count == list_count, "count mismatch %u, %u.\n", tree_count, list_count ); 1870} 1871 1872static ULONG hash_basename( const UNICODE_STRING *basename ) 1873{ 1874 NTSTATUS status; 1875 ULONG hash; 1876 1877 status = pRtlHashUnicodeString( basename, TRUE, HASH_STRING_ALGORITHM_DEFAULT, &hash ); 1878 ok( !status, "got %#lx.\n", status ); 1879 return hash & 31; 1880} 1881 1882static void test_hash_links(void) 1883{ 1884 LIST_ENTRY *hash_map, *entry, *entry2, *mark, *root; 1885 LDR_DATA_TABLE_ENTRY *module; 1886 const WCHAR *modname; 1887 BOOL found; 1888 1889 /* Hash links structure is the same on older Windows loader but hashing algorithm is different. */ 1890 if (is_old_loader_struct()) return; 1891 1892 root = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList; 1893 module = CONTAINING_RECORD(root->Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 1894 hash_map = module->HashLinks.Blink - hash_basename( &module->BaseDllName ); 1895 1896 for (entry = root->Flink; entry != root; entry = entry->Flink) 1897 { 1898 module = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 1899 modname = module->BaseDllName.Buffer; 1900 mark = &hash_map[hash_basename( &module->BaseDllName )]; 1901 found = FALSE; 1902 for (entry2 = mark->Flink; entry2 != mark; entry2 = entry2->Flink) 1903 { 1904 module = CONTAINING_RECORD(entry2, LDR_DATA_TABLE_ENTRY, HashLinks); 1905 if ((found = !lstrcmpiW( module->BaseDllName.Buffer, modname ))) break; 1906 } 1907 ok( found, "Could not find %s.\n", debugstr_w(modname) ); 1908 } 1909} 1910 1911START_TEST(module) 1912{ 1913 WCHAR filenameW[MAX_PATH]; 1914 1915 /* Test if we can use GetModuleFileNameW */ 1916 1917 SetLastError(0xdeadbeef); 1918 GetModuleFileNameW(NULL, filenameW, MAX_PATH); 1919 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 1920 { 1921 win_skip("GetModuleFileNameW not existing on this platform, skipping W-calls\n"); 1922 is_unicode_enabled = FALSE; 1923 } 1924 1925 init_pointers(); 1926 1927 testGetModuleFileName(NULL); 1928 testGetModuleFileName("kernel32.dll"); 1929 testGetModuleFileName_Wrong(); 1930 1931 testGetDllDirectory(); 1932 1933 testLoadLibraryA(); 1934 testNestedLoadLibraryA(); 1935 testLoadLibraryA_Wrong(); 1936 testGetProcAddress_Wrong(); 1937 testLoadLibraryEx(); 1938 test_LoadLibraryEx_search_flags(); 1939 testGetModuleHandleEx(); 1940 testK32GetModuleInformation(); 1941 test_AddDllDirectory(); 1942 test_SetDefaultDllDirectories(); 1943 test_LdrGetDllHandleEx(); 1944 test_LdrGetDllFullName(); 1945 test_apisets(); 1946 test_ddag_node(); 1947 test_tls_links(); 1948 test_base_address_index_tree(); 1949 test_hash_links(); 1950}