From: Paul Gofman <pgofman@codeweavers.com> --- dlls/kernel32/tests/loader.c | 49 ++++++++++++------- dlls/kernel32/tests/module.c | 95 +++++++++++++++++++++++++++++++++++- 2 files changed, 125 insertions(+), 19 deletions(-) diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c index 1f74d7aa901..4112c3674cd 100644 --- a/dlls/kernel32/tests/loader.c +++ b/dlls/kernel32/tests/loader.c @@ -58,7 +58,7 @@ static NTSTATUS (WINAPI *pNtAllocateVirtualMemory)(HANDLE, PVOID *, ULONG_PTR, S static NTSTATUS (WINAPI *pNtFreeVirtualMemory)(HANDLE, PVOID *, SIZE_T *, ULONG); static NTSTATUS (WINAPI *pLdrLockLoaderLock)(ULONG, ULONG *, ULONG_PTR *); static NTSTATUS (WINAPI *pLdrUnlockLoaderLock)(ULONG, ULONG_PTR); -static NTSTATUS (WINAPI *pLdrLoadDll)(LPCWSTR,DWORD,const UNICODE_STRING *,HMODULE*); +static NTSTATUS (WINAPI *pLdrLoadDll)(LPCWSTR,DWORD *,const UNICODE_STRING *,HMODULE*); static NTSTATUS (WINAPI *pLdrUnloadDll)(HMODULE); static void (WINAPI *pRtlInitUnicodeString)(PUNICODE_STRING,LPCWSTR); static void (WINAPI *pRtlAcquirePebLock)(void); @@ -2112,8 +2112,8 @@ static DWORD WINAPI tls_thread_fn(void* tlsidx_v) static void test_import_resolution(void) { - char temp_path[MAX_PATH]; - char dll_name[MAX_PATH]; + WCHAR temp_path[MAX_PATH]; + WCHAR dll_name[MAX_PATH]; DWORD dummy; void *expect, *tmp; char *str; @@ -2122,6 +2122,7 @@ static void test_import_resolution(void) HMODULE mod, mod2; NTSTATUS status; LARGE_INTEGER offset; + UNICODE_STRING name; struct imports { IMAGE_IMPORT_DESCRIPTOR descr[2]; @@ -2177,7 +2178,7 @@ static void test_import_resolution(void) static const UCHAR entry_point_code[] = { 0x00 }; #endif - for (test = 0; test < 7; test++) + for (test = 0; test < 8; test++) { #define DATA_RVA(ptr) (page_size + ((char *)(ptr) - (char *)&data)) #ifdef _WIN64 @@ -2246,10 +2247,10 @@ static void test_import_resolution(void) nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = data.rel.reloc.SizeOfBlock; nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = DATA_RVA(&data.rel); - GetTempPathA(MAX_PATH, temp_path); - GetTempFileNameA(temp_path, "ldr", 0, dll_name); + GetTempPathW(MAX_PATH, temp_path); + GetTempFileNameW(temp_path, L"ldr", 0, dll_name); - hfile = CreateFileA(dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0); + hfile = CreateFileW(dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0); ok( hfile != INVALID_HANDLE_VALUE, "creation failed\n" ); memset( §ion, 0, sizeof(section) ); @@ -2273,7 +2274,7 @@ static void test_import_resolution(void) switch (test) { case 0: /* normal load */ - mod = LoadLibraryA( dll_name ); + mod = LoadLibraryW( dll_name ); ok( mod != NULL, "failed to load err %lu\n", GetLastError() ); if (!mod) break; ptr = (struct imports *)((char *)mod + page_size); @@ -2287,26 +2288,38 @@ static void test_import_resolution(void) check_tls_index(mod, ptr->tls_index != 9999); FreeLibrary( mod ); break; + case 7: case 1: /* load with DONT_RESOLVE_DLL_REFERENCES doesn't resolve imports */ - mod = LoadLibraryExA( dll_name, 0, DONT_RESOLVE_DLL_REFERENCES ); + if (test == 7) + { + DWORD load_flags = LDR_DONT_RESOLVE_REFS; + + pRtlInitUnicodeString( &name, dll_name ); + status = pLdrLoadDll( NULL, &load_flags, &name, &mod ); + ok( !status, "got %#lx.\n", status ); + } + else + { + mod = LoadLibraryExW( dll_name, 0, DONT_RESOLVE_DLL_REFERENCES ); + } ok( mod != NULL, "failed to load err %lu\n", GetLastError() ); if (!mod) break; ptr = (struct imports *)((char *)mod + page_size); - ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n", + todo_wine_if (test == 7) ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n", (void *)ptr->thunks[0].u1.Function, data.module, data.function.name ); - ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index ); + todo_wine_if (test == 7) ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index ); - mod2 = LoadLibraryA( dll_name ); + mod2 = LoadLibraryW( dll_name ); ok( mod2 == mod, "loaded twice %p / %p\n", mod, mod2 ); - ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n", + todo_wine_if (test == 7) ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n", (void *)ptr->thunks[0].u1.Function, data.module, data.function.name ); - ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index ); + todo_wine_if (test == 7) ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index ); check_tls_index(mod, ptr->tls_index != 9999); FreeLibrary( mod2 ); FreeLibrary( mod ); break; case 2: /* load without IMAGE_FILE_DLL doesn't resolve imports */ - mod = LoadLibraryA( dll_name ); + mod = LoadLibraryW( dll_name ); ok( mod != NULL, "failed to load err %lu\n", GetLastError() ); if (!mod) break; ptr = (struct imports *)((char *)mod + page_size); @@ -2317,7 +2330,7 @@ static void test_import_resolution(void) FreeLibrary( mod ); break; case 3: /* load with tls init function */ - mod = LoadLibraryA( dll_name ); + mod = LoadLibraryW( dll_name ); ok( mod != NULL, "failed to load err %lu\n", GetLastError() ); if (!mod) break; ptr = (struct imports *)((char *)mod + page_size); @@ -2345,7 +2358,7 @@ static void test_import_resolution(void) case 4: /* map with ntdll */ case 5: /* map with ntdll, without IMAGE_FILE_DLL */ case 6: /* map with ntdll, without IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE */ - hfile = CreateFileA(dll_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + hfile = CreateFileW(dll_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); ok( hfile != INVALID_HANDLE_VALUE, "CreateFile failed err %lu\n", GetLastError() ); mapping = CreateFileMappingA( hfile, NULL, SEC_IMAGE | PAGE_READONLY, 0, 0, NULL ); CloseHandle( hfile ); @@ -2397,7 +2410,7 @@ static void test_import_resolution(void) if (tmp) VirtualFree( tmp, 0, MEM_RELEASE ); break; } - DeleteFileA( dll_name ); + DeleteFileW( dll_name ); winetest_pop_context(); #undef DATA_RVA } diff --git a/dlls/kernel32/tests/module.c b/dlls/kernel32/tests/module.c index f26c412f748..9f008d0bda8 100644 --- a/dlls/kernel32/tests/module.c +++ b/dlls/kernel32/tests/module.c @@ -44,6 +44,8 @@ static NTSTATUS (WINAPI *pLdrSetDllDirectory)(UNICODE_STRING*); static NTSTATUS (WINAPI *pLdrGetDllHandle)( LPCWSTR load_path, ULONG flags, const UNICODE_STRING *name, HMODULE *base ); static NTSTATUS (WINAPI *pLdrGetDllHandleEx)( ULONG flags, LPCWSTR load_path, ULONG *dll_characteristics, const UNICODE_STRING *name, HMODULE *base ); +static NTSTATUS (WINAPI *pLdrGetDllPath)(LPCWSTR,ULONG,LPWSTR*,LPWSTR*); +static NTSTATUS (WINAPI *pLdrLoadDll)(LPCWSTR,DWORD *,const UNICODE_STRING *,HMODULE*); static NTSTATUS (WINAPI *pLdrGetDllFullName)( HMODULE module, UNICODE_STRING *name ); static BOOL (WINAPI *pIsApiSetImplemented)(LPCSTR); @@ -519,9 +521,13 @@ static void test_LoadLibraryEx_search_flags(void) { { 1, 1, 2 }, 0, 2 }, }; char *p, path[MAX_PATH], buf[MAX_PATH], curdir[MAX_PATH]; - WCHAR bufW[MAX_PATH]; + WCHAR bufW[MAX_PATH], pathW[MAX_PATH]; DLL_DIRECTORY_COOKIE cookies[4]; + WCHAR *load_path, *dummy; unsigned int i, j, k; + UNICODE_STRING name; + DWORD load_flags; + NTSTATUS status; BOOL ret; HMODULE mod; @@ -550,6 +556,12 @@ static void test_LoadLibraryEx_search_flags(void) ok( mod != NULL, "LoadLibrary failed err %lu\n", GetLastError() ); FreeLibrary( mod ); + RtlInitUnicodeString( &name, L"1\\winetestdll.dll" ); + status = pLdrLoadDll( NULL, NULL, &name, &mod ); + ok( !status, "got %#lx.\n", status ); + ok( !!mod, "got NULL.\n" ); + FreeLibrary( mod ); + SetLastError( 0xdeadbeef ); sprintf( path, "%c:1\\winetestdll.dll", buf[0] ); mod = LoadLibraryA( path ); @@ -563,10 +575,46 @@ static void test_LoadLibraryEx_search_flags(void) ok( !mod, "LoadLibrary succeeded\n" ); ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %lu\n", GetLastError() ); + RtlInitUnicodeString( &name, L"1\\winetestdll.dll" ); + mod = (void *)0xdeadbeef; + status = pLdrLoadDll( (void *)(ULONG_PTR)(LOAD_LIBRARY_SEARCH_SYSTEM32 | 1), NULL, &name, &mod ); + ok( status == STATUS_DLL_NOT_FOUND, "got %#lx.\n", status ); + todo_wine ok( mod == (HMODULE)0xdeadbeef, "got %p.\n", mod ); + + load_flags = LOAD_LIBRARY_SEARCH_SYSTEM32; + mod = (void *)0xdeadbeef; + if (0) + { + /* crashes on Windows. */ + pLdrLoadDll( NULL, (void *)(ULONG_PTR)load_flags, &name, &mod ); + } + status = pLdrLoadDll( NULL, &load_flags, &name, &mod ); + ok( !status, "got %#lx.\n", status ); + FreeLibrary( mod ); + + status = pLdrGetDllPath( name.Buffer, LOAD_LIBRARY_SEARCH_SYSTEM32, &load_path, &dummy ); + ok( !status, "got %#lx.\n", status ); + mod = (void *)0xdeadbeef; + status = pLdrLoadDll( load_path, NULL, &name, &mod ); + ok( status == STATUS_DLL_NOT_FOUND, "got %#lx.\n", status ); + todo_wine ok( mod == (HMODULE)0xdeadbeef, "got %p.\n", mod ); + RtlReleasePath( load_path ); + + mod = (void *)0xdeadbeef; + status = pLdrLoadDll( L".", NULL, &name, &mod ); + ok( !status, "got %#lx.\n", status ); + FreeLibrary( mod ); + SetLastError( 0xdeadbeef ); mod = LoadLibraryExA( path, 0, LOAD_LIBRARY_SEARCH_SYSTEM32 ); ok( mod != NULL, "LoadLibrary failed err %lu\n", GetLastError() ); FreeLibrary( mod ); + + MultiByteToWideChar( CP_ACP, 0, path, -1, pathW, ARRAY_SIZE(pathW) ); + RtlInitUnicodeString( &name, pathW ); + status = pLdrLoadDll( (void *)(LOAD_LIBRARY_SEARCH_SYSTEM32 | 1), NULL, &name, &mod ); + ok( !status, "got %#lx.\n", status ); + FreeLibrary( mod ); } strcpy( p, "\\1" ); @@ -614,6 +662,12 @@ static void test_LoadLibraryEx_search_flags(void) ok( !mod, "LoadLibrary succeeded\n" ); ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); + RtlInitUnicodeString( &name, L"winetestdll.dll" ); + mod = (void *)0xdeadbeef; + status = pLdrLoadDll( (void *)(LOAD_LIBRARY_SEARCH_SYSTEM32 | LOAD_WITH_ALTERED_SEARCH_PATH | 1), NULL, &name, &mod ); + ok( status == STATUS_INVALID_PARAMETER, "got %#lx.\n", status ); + ok( mod == (HMODULE)0xdeadbeef, "got %p.\n", mod ); + SetLastError( 0xdeadbeef ); mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_WITH_ALTERED_SEARCH_PATH ); ok( !mod, "LoadLibrary succeeded\n" ); @@ -673,6 +727,12 @@ static void test_LoadLibraryEx_search_flags(void) ok( !mod, "LoadLibrary succeeded\n" ); ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); + RtlInitUnicodeString( &name, L"foo\\winetestdll.dll" ); + mod = (void *)0xdeadbeef; + status = pLdrLoadDll( (void *)(LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | 1), NULL, &name, &mod ); + ok( status == STATUS_INVALID_PARAMETER, "got %#lx.\n", status ); + ok( mod == (HMODULE)0xdeadbeef, "got %p.\n", mod ); + SetLastError( 0xdeadbeef ); mod = LoadLibraryExA( "\\windows\\winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR ); ok( !mod, "LoadLibrary succeeded\n" ); @@ -716,6 +776,37 @@ static void test_LoadLibraryEx_search_flags(void) } FreeLibrary( mod ); + mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_USER_DIRS ); + if (tests[j].expect) + { + ok( mod != NULL, "%u: LoadLibrary failed err %lu\n", j, GetLastError() ); + GetModuleFileNameA( mod, path, MAX_PATH ); + sprintf( p, "\\%u\\winetestdll.dll", tests[j].expect ); + ok( !lstrcmpiA( path, buf ), "%u: wrong module %s expected %s\n", j, path, buf ); + } + else + { + ok( !mod, "%u: LoadLibrary succeeded\n", j ); + ok( GetLastError() == ERROR_MOD_NOT_FOUND || broken(GetLastError() == ERROR_NOT_ENOUGH_MEMORY), + "%u: wrong error %lu\n", j, GetLastError() ); + } + FreeLibrary( mod ); + + mod = NULL; + RtlInitUnicodeString( &name, L"winetestdll.dll" ); + status = pLdrLoadDll( (void *)(ULONG_PTR)(LOAD_LIBRARY_SEARCH_USER_DIRS | 1), NULL, &name, &mod ); + if (tests[j].expect) + { + ok( !status, "got %#lx.\n", status ); + ok( !!mod, "got NULL.\n" ); + } + else + { + ok( status == STATUS_DLL_NOT_FOUND, "got %#lx.\n", status ); + ok( !mod, "got %p.\n", mod ); + } + FreeLibrary( mod ); + for (k = 0; tests[j].add_dirs[k]; k++) pRemoveDllDirectory( cookies[k] ); } @@ -968,6 +1059,8 @@ static void init_pointers(void) MAKEFUNC(LdrSetDllDirectory); MAKEFUNC(LdrGetDllHandle); MAKEFUNC(LdrGetDllHandleEx); + MAKEFUNC(LdrGetDllPath); + MAKEFUNC(LdrLoadDll); MAKEFUNC(LdrGetDllFullName); MAKEFUNC(RtlHashUnicodeString); mod = GetModuleHandleA( "kernelbase.dll" ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9888