Index: modules/rostests/winetests/kernel32/CMakeLists.txt =================================================================== --- modules/rostests/winetests/kernel32/CMakeLists.txt (revision 54747) +++ modules/rostests/winetests/kernel32/CMakeLists.txt (working copy) @@ -48,10 +48,10 @@ add_executable(kernel32_winetest ${SOURCE}) target_link_libraries(kernel32_winetest wine) set_module_type(kernel32_winetest win32cui) -add_importlibs(kernel32_winetest user32 advapi32 msvcrt kernel32 ntdll) +add_importlibs(kernel32_winetest user32 advapi32 shlwapi msvcrt kernel32 ntdll) if(NOT MSVC) add_target_compile_flags(kernel32_winetest "-Wno-format") allow_warnings(kernel32_winetest) endif() -add_cd_file(TARGET kernel32_winetest DESTINATION reactos/bin FOR all) \ No newline at end of file +add_cd_file(TARGET kernel32_winetest DESTINATION reactos/bin FOR all) Index: modules/rostests/winetests/kernel32/module.c =================================================================== --- modules/rostests/winetests/kernel32/module.c (revision 54747) +++ modules/rostests/winetests/kernel32/module.c (working copy) @@ -20,7 +20,13 @@ #include "wine/test.h" #include +#include +static DWORD (WINAPI *pGetDllDirectoryA)(DWORD,LPSTR); +static DWORD (WINAPI *pGetDllDirectoryW)(DWORD,LPWSTR); + +static BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR); + static BOOL is_unicode_enabled = TRUE; static BOOL cmpStrAW(const char* a, const WCHAR* b, DWORD lenA, DWORD lenB) @@ -44,14 +50,24 @@ /* first test, with enough space in buffer */ memset(bufA, '-', sizeof(bufA)); + SetLastError(0xdeadbeef); len1A = GetModuleFileNameA(hMod, bufA, sizeof(bufA)); + ok(GetLastError() == ERROR_SUCCESS || + broken(GetLastError() == 0xdeadbeef), /* <= XP SP3 */ + "LastError was not reset: %u\n", GetLastError()); ok(len1A > 0, "Getting module filename for handle %p\n", hMod); + ok(!PathIsRelativeA(bufA), "Got relative path: %s\n", bufA); if (is_unicode_enabled) { memset(bufW, '-', sizeof(bufW)); + SetLastError(0xdeadbeef); len1W = GetModuleFileNameW(hMod, bufW, sizeof(bufW) / sizeof(WCHAR)); + ok(GetLastError() == ERROR_SUCCESS || + broken(GetLastError() == 0xdeadbeef), /* <= XP SP3 */ + "LastError was not reset: %u\n", GetLastError()); ok(len1W > 0, "Getting module filename for handle %p\n", hMod); + ok(!PathIsRelativeW(bufW), "Got relative path: %s\n", wine_dbgstr_w(bufW)); } ok(len1A == strlen(bufA), "Unexpected length of GetModuleFilenameA (%d/%d)\n", len1A, lstrlenA(bufA)); @@ -378,6 +394,113 @@ } +static void testGetDllDirectory(void) +{ + CHAR bufferA[MAX_PATH]; + WCHAR bufferW[MAX_PATH]; + DWORD length, ret; + int i; + static const char *dll_directories[] = + { + "", + "C:\\Some\\Path", + "C:\\Some\\Path\\", + "Q:\\A\\Long\\Path with spaces that\\probably\\doesn't exist!", + }; + const int test_count = sizeof(dll_directories) / sizeof(dll_directories[0]); + + if (!pGetDllDirectoryA || !pGetDllDirectoryW) + { + win_skip("GetDllDirectory not available\n"); + return; + } + if (!pSetDllDirectoryA) + { + win_skip("SetDllDirectoryA not available\n"); + return; + } + + for (i = 0; i < test_count; i++) + { + length = strlen(dll_directories[i]); + if (!pSetDllDirectoryA(dll_directories[i])) + { + skip("i=%d, SetDllDirectoryA failed\n", i); + continue; + } + + /* no buffer, determine length */ + ret = pGetDllDirectoryA(0, NULL); + ok(ret == length + 1, "Expected %u, got %u\n", length + 1, ret); + + ret = pGetDllDirectoryW(0, NULL); + ok(ret == length + 1, "Expected %u, got %u\n", length + 1, ret); + + /* buffer of exactly the right size */ + bufferA[length] = 'A'; + bufferA[length + 1] = 'A'; + ret = pGetDllDirectoryA(length + 1, bufferA); + ok(ret == length, "i=%d, Expected %u, got %u\n", i, length, ret); + ok(bufferA[length + 1] == 'A', "i=%d, Buffer overflow\n", i); + ok(strcmp(bufferA, dll_directories[i]) == 0, "i=%d, Wrong path returned: '%s'\n", i, bufferA); + + bufferW[length] = 'A'; + bufferW[length + 1] = 'A'; + ret = pGetDllDirectoryW(length + 1, bufferW); + ok(ret == length, "i=%d, Expected %u, got %u\n", i, length, ret); + ok(bufferW[length + 1] == 'A', "i=%d, Buffer overflow\n", i); + ok(cmpStrAW(dll_directories[i], bufferW, length, length), + "i=%d, Wrong path returned: %s\n", i, wine_dbgstr_w(bufferW)); + + /* zero size buffer + * the A version always null-terminates the buffer, + * the W version doesn't do it on some platforms */ + bufferA[0] = 'A'; + ret = pGetDllDirectoryA(0, bufferA); + ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret); + ok(bufferA[0] == 0, "i=%d, Buffer not null terminated\n", i); + + bufferW[0] = 'A'; + ret = pGetDllDirectoryW(0, bufferW); + ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret); + ok(bufferW[0] == 0 || /* XP, 2003 */ + broken(bufferW[0] == 'A'), "i=%d, Buffer overflow\n", i); + + /* buffer just one too short */ + bufferA[0] = 'A'; + ret = pGetDllDirectoryA(length, bufferA); + ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret); + ok(bufferA[0] == 0, "i=%d, Buffer not null terminated\n", i); + + bufferW[0] = 'A'; + ret = pGetDllDirectoryW(length, bufferW); + ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret); + ok(bufferW[0] == 0 || /* XP, 2003 */ + broken(bufferW[0] == 'A'), "i=%d, Buffer overflow\n", i); + + /* no buffer, but too short length */ + ret = pGetDllDirectoryA(length, NULL); + ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret); + + ret = pGetDllDirectoryW(length, NULL); + ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret); + } + + /* unset whatever we did so following tests won't be affected */ + pSetDllDirectoryA(NULL); +} + +static void init_pointers(void) +{ + HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); + +#define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hKernel32, #f)) + MAKEFUNC(GetDllDirectoryA); + MAKEFUNC(GetDllDirectoryW); + MAKEFUNC(SetDllDirectoryA); +#undef MAKEFUNC +} + START_TEST(module) { WCHAR filenameW[MAX_PATH]; @@ -392,10 +515,14 @@ is_unicode_enabled = FALSE; } + init_pointers(); + testGetModuleFileName(NULL); testGetModuleFileName("kernel32.dll"); testGetModuleFileName_Wrong(); + testGetDllDirectory(); + testLoadLibraryA(); testNestedLoadLibraryA(); testLoadLibraryA_Wrong();