2 * Unit tests for module/DLL/library API
4 * Copyright (c) 2004 Eric Pouech
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.
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.
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
21 #include "wine/test.h"
24 static BOOL is_unicode_enabled = TRUE;
26 static BOOL cmpStrAW(const char* a, const WCHAR* b, DWORD lenA, DWORD lenB)
30 DWORD len = MultiByteToWideChar( AreFileApisANSI() ? CP_ACP : CP_OEMCP, 0,
31 a, lenA, aw, sizeof(aw) / sizeof(aw[0]) );
32 if (len != lenB) return FALSE;
33 return memcmp(aw, b, len * sizeof(WCHAR)) == 0;
36 static void testGetModuleFileName(const char* name)
41 DWORD len1A, len1W = 0, len2A, len2W = 0;
43 hMod = (name) ? GetModuleHandle(name) : NULL;
45 /* first test, with enough space in buffer */
46 memset(bufA, '-', sizeof(bufA));
47 SetLastError(0xdeadbeef);
48 len1A = GetModuleFileNameA(hMod, bufA, sizeof(bufA));
49 ok(GetLastError() == ERROR_SUCCESS ||
50 broken(GetLastError() == 0xdeadbeef), /* <= XP SP3 */
51 "LastError was not reset: %u\n", GetLastError());
52 ok(len1A > 0, "Getting module filename for handle %p\n", hMod);
54 if (is_unicode_enabled)
56 memset(bufW, '-', sizeof(bufW));
57 SetLastError(0xdeadbeef);
58 len1W = GetModuleFileNameW(hMod, bufW, sizeof(bufW) / sizeof(WCHAR));
59 ok(GetLastError() == ERROR_SUCCESS ||
60 broken(GetLastError() == 0xdeadbeef), /* <= XP SP3 */
61 "LastError was not reset: %u\n", GetLastError());
62 ok(len1W > 0, "Getting module filename for handle %p\n", hMod);
65 ok(len1A == strlen(bufA), "Unexpected length of GetModuleFilenameA (%d/%d)\n", len1A, lstrlenA(bufA));
67 if (is_unicode_enabled)
69 ok(len1W == lstrlenW(bufW), "Unexpected length of GetModuleFilenameW (%d/%d)\n", len1W, lstrlenW(bufW));
70 ok(cmpStrAW(bufA, bufW, len1A, len1W), "Comparing GetModuleFilenameAW results\n");
73 /* second test with a buffer too small */
74 memset(bufA, '-', sizeof(bufA));
75 len2A = GetModuleFileNameA(hMod, bufA, len1A / 2);
76 ok(len2A > 0, "Getting module filename for handle %p\n", hMod);
78 if (is_unicode_enabled)
80 memset(bufW, '-', sizeof(bufW));
81 len2W = GetModuleFileNameW(hMod, bufW, len1W / 2);
82 ok(len2W > 0, "Getting module filename for handle %p\n", hMod);
83 ok(cmpStrAW(bufA, bufW, len2A, len2W), "Comparing GetModuleFilenameAW results with buffer too small\n" );
84 ok(len1W / 2 == len2W, "Correct length in GetModuleFilenameW with buffer too small (%d/%d)\n", len1W / 2, len2W);
87 ok(len1A / 2 == len2A ||
88 len1A / 2 == len2A + 1, /* Win9x */
89 "Correct length in GetModuleFilenameA with buffer too small (%d/%d)\n", len1A / 2, len2A);
92 static void testGetModuleFileName_Wrong(void)
97 /* test wrong handle */
98 if (is_unicode_enabled)
101 ok(GetModuleFileNameW((void*)0xffffffff, bufW, sizeof(bufW) / sizeof(WCHAR)) == 0, "Unexpected success in module handle\n");
102 ok(bufW[0] == '*', "When failing, buffer shouldn't be written to\n");
106 ok(GetModuleFileNameA((void*)0xffffffff, bufA, sizeof(bufA)) == 0, "Unexpected success in module handle\n");
108 bufA[0] == 0 /* Win9x */,
109 "When failing, buffer shouldn't be written to\n");
112 static void testLoadLibraryA(void)
114 HMODULE hModule, hModule1;
117 SetLastError(0xdeadbeef);
118 hModule = LoadLibraryA("kernel32.dll");
119 ok( hModule != NULL, "kernel32.dll should be loadable\n");
120 ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %d\n", GetLastError());
122 fp = GetProcAddress(hModule, "CreateFileA");
123 ok( fp != NULL, "CreateFileA should be there\n");
124 ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %d\n", GetLastError());
126 SetLastError(0xdeadbeef);
127 hModule1 = LoadLibraryA("kernel32 ");
128 /* Only winNT does this */
129 if (GetLastError() != ERROR_DLL_NOT_FOUND)
131 ok( hModule1 != NULL, "\"kernel32 \" should be loadable\n");
132 ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %d\n", GetLastError());
133 ok( hModule == hModule1, "Loaded wrong module\n");
134 FreeLibrary(hModule1);
136 FreeLibrary(hModule);
139 static void testNestedLoadLibraryA(void)
141 static const char dllname[] = "shell32.dll";
142 char path1[MAX_PATH], path2[MAX_PATH];
143 HMODULE hModule1, hModule2, hModule3;
145 /* This is not really a Windows conformance test, but more a Wine
146 * regression test. Wine's builtin dlls can be loaded from multiple paths,
147 * and this test tries to make sure that Wine does not get confused and
148 * really unloads the Unix .so file at the right time. Failure to do so
149 * will result in the dll being unloadable.
150 * This test must be done with a dll that can be unloaded, which means:
151 * - it must not already be loaded
152 * - it must not have a 16-bit counterpart
154 GetWindowsDirectory(path1, sizeof(path1));
155 strcat(path1, "\\system\\");
156 strcat(path1, dllname);
157 hModule1 = LoadLibraryA(path1);
160 /* We must be on Windows NT, so we cannot test */
164 GetWindowsDirectory(path2, sizeof(path2));
165 strcat(path2, "\\system32\\");
166 strcat(path2, dllname);
167 hModule2 = LoadLibraryA(path2);
170 /* We must be on Windows 9x, so we cannot test */
171 ok(FreeLibrary(hModule1), "FreeLibrary() failed\n");
175 /* The first LoadLibrary() call may have registered the dll under the
176 * system32 path. So load it, again, under the '...\system\...' path so
177 * Wine does not immediately notice that it is already loaded.
179 hModule3 = LoadLibraryA(path1);
180 ok(hModule3 != NULL, "LoadLibrary(%s) failed\n", path1);
182 /* Now fully unload the dll */
183 ok(FreeLibrary(hModule3), "FreeLibrary() failed\n");
184 ok(FreeLibrary(hModule2), "FreeLibrary() failed\n");
185 ok(FreeLibrary(hModule1), "FreeLibrary() failed\n");
186 ok(GetModuleHandle(dllname) == NULL, "%s was not fully unloaded\n", dllname);
188 /* Try to load the dll again, if refcounting is ok, this should work */
189 hModule1 = LoadLibraryA(path1);
190 ok(hModule1 != NULL, "LoadLibrary(%s) failed\n", path1);
191 if (hModule1 != NULL)
192 ok(FreeLibrary(hModule1), "FreeLibrary() failed\n");
195 static void testLoadLibraryA_Wrong(void)
199 /* Try to load a nonexistent dll */
200 SetLastError(0xdeadbeef);
201 hModule = LoadLibraryA("non_ex_pv.dll");
202 ok( !hModule, "non_ex_pv.dll should be not loadable\n");
203 ok( GetLastError() == ERROR_MOD_NOT_FOUND || GetLastError() == ERROR_DLL_NOT_FOUND,
204 "Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND (win9x), got %d\n", GetLastError());
207 FreeLibrary(hModule);
210 static void testGetProcAddress_Wrong(void)
214 SetLastError(0xdeadbeef);
215 fp = GetProcAddress(NULL, "non_ex_call");
216 ok( !fp, "non_ex_call should not be found\n");
217 ok( GetLastError() == ERROR_PROC_NOT_FOUND || GetLastError() == ERROR_INVALID_HANDLE,
218 "Expected ERROR_PROC_NOT_FOUND or ERROR_INVALID_HANDLE(win9x), got %d\n", GetLastError());
220 SetLastError(0xdeadbeef);
221 fp = GetProcAddress((HMODULE)0xdeadbeef, "non_ex_call");
222 ok( !fp, "non_ex_call should not be found\n");
223 ok( GetLastError() == ERROR_MOD_NOT_FOUND || GetLastError() == ERROR_INVALID_HANDLE,
224 "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_HANDLE(win9x), got %d\n", GetLastError());
227 static void testLoadLibraryEx(void)
234 hfile = CreateFileA("testfile.dll", GENERIC_READ | GENERIC_WRITE,
235 FILE_SHARE_READ | FILE_SHARE_WRITE,
236 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
237 ok(hfile != INVALID_HANDLE_VALUE, "Expected a valid file handle\n");
239 /* NULL lpFileName */
240 if (is_unicode_enabled)
242 SetLastError(0xdeadbeef);
243 hmodule = LoadLibraryExA(NULL, NULL, 0);
244 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
245 ok(GetLastError() == ERROR_MOD_NOT_FOUND ||
246 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
247 "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n",
251 win_skip("NULL filename crashes on WinMe\n");
253 /* empty lpFileName */
254 SetLastError(0xdeadbeef);
255 hmodule = LoadLibraryExA("", NULL, 0);
256 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
257 ok(GetLastError() == ERROR_MOD_NOT_FOUND ||
258 GetLastError() == ERROR_DLL_NOT_FOUND, /* win9x */
259 "Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND, got %d\n",
262 /* hFile is non-NULL */
263 SetLastError(0xdeadbeef);
264 hmodule = LoadLibraryExA("testfile.dll", hfile, 0);
265 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
268 ok(GetLastError() == ERROR_SHARING_VIOLATION ||
269 GetLastError() == ERROR_INVALID_PARAMETER || /* win2k3 */
270 GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */
271 "Unexpected last error, got %d\n", GetLastError());
274 SetLastError(0xdeadbeef);
275 hmodule = LoadLibraryExA("testfile.dll", (HANDLE)0xdeadbeef, 0);
276 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
279 ok(GetLastError() == ERROR_SHARING_VIOLATION ||
280 GetLastError() == ERROR_INVALID_PARAMETER || /* win2k3 */
281 GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */
282 "Unexpected last error, got %d\n", GetLastError());
285 /* try to open a file that is locked */
286 SetLastError(0xdeadbeef);
287 hmodule = LoadLibraryExA("testfile.dll", NULL, 0);
288 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
291 ok(GetLastError() == ERROR_SHARING_VIOLATION ||
292 GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */
293 "Expected ERROR_SHARING_VIOLATION or ERROR_FILE_NOT_FOUND, got %d\n",
297 /* lpFileName does not matter */
298 if (is_unicode_enabled)
300 SetLastError(0xdeadbeef);
301 hmodule = LoadLibraryExA(NULL, hfile, 0);
302 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
303 ok(GetLastError() == ERROR_MOD_NOT_FOUND ||
304 GetLastError() == ERROR_INVALID_PARAMETER, /* win2k3 */
305 "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n",
311 /* load empty file */
312 SetLastError(0xdeadbeef);
313 hmodule = LoadLibraryExA("testfile.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
314 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
317 ok(GetLastError() == ERROR_FILE_INVALID ||
318 GetLastError() == ERROR_BAD_FORMAT, /* win9x */
319 "Expected ERROR_FILE_INVALID or ERROR_BAD_FORMAT, got %d\n",
323 DeleteFileA("testfile.dll");
325 GetSystemDirectoryA(path, MAX_PATH);
326 if (path[lstrlenA(path) - 1] != '\\')
327 lstrcatA(path, "\\");
328 lstrcatA(path, "kernel32.dll");
330 /* load kernel32.dll with an absolute path */
331 SetLastError(0xdeadbeef);
332 hmodule = LoadLibraryExA(path, NULL, LOAD_LIBRARY_AS_DATAFILE);
333 ok(hmodule != 0, "Expected valid module handle\n");
334 ok(GetLastError() == 0xdeadbeef ||
335 GetLastError() == ERROR_SUCCESS, /* win9x */
336 "Expected 0xdeadbeef or ERROR_SUCCESS, got %d\n", GetLastError());
338 /* try invalid file handle */
339 SetLastError(0xdeadbeef);
340 hmodule = LoadLibraryExA(path, (HANDLE)0xdeadbeef, 0);
341 if (!hmodule) /* succeeds on xp and older */
342 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
344 CloseHandle(hmodule);
346 /* load kernel32.dll with no path */
347 SetLastError(0xdeadbeef);
348 hmodule = LoadLibraryExA("kernel32.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
349 ok(hmodule != 0, "Expected valid module handle\n");
350 ok(GetLastError() == 0xdeadbeef ||
351 GetLastError() == ERROR_SUCCESS, /* win9x */
352 "Expected 0xdeadbeef or ERROR_SUCCESS, got %d\n", GetLastError());
354 CloseHandle(hmodule);
356 GetCurrentDirectoryA(MAX_PATH, path);
357 if (path[lstrlenA(path) - 1] != '\\')
358 lstrcatA(path, "\\");
359 lstrcatA(path, "kernel32.dll");
361 /* load kernel32.dll with an absolute path that does not exist */
362 SetLastError(0xdeadbeef);
363 hmodule = LoadLibraryExA(path, NULL, LOAD_LIBRARY_AS_DATAFILE);
366 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
368 ok(GetLastError() == ERROR_FILE_NOT_FOUND ||
369 broken(GetLastError() == ERROR_INVALID_HANDLE), /* nt4 */
370 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
372 /* Free the loaded dll when its the first time this dll is loaded
373 in process - First time should pass, second fail */
374 SetLastError(0xdeadbeef);
375 hmodule = LoadLibraryExA("comctl32.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
376 ok(hmodule != 0, "Expected valid module handle\n");
378 SetLastError(0xdeadbeef);
379 ret = FreeLibrary(hmodule);
380 ok(ret, "Expected to be able to free the module, failed with %d\n", GetLastError());
381 SetLastError(0xdeadbeef);
382 ret = FreeLibrary(hmodule);
383 ok(!ret, "Unexpected ability to free the module, failed with %d\n", GetLastError());
385 CloseHandle(hmodule);
391 WCHAR filenameW[MAX_PATH];
393 /* Test if we can use GetModuleFileNameW */
395 SetLastError(0xdeadbeef);
396 GetModuleFileNameW(NULL, filenameW, MAX_PATH);
397 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
399 win_skip("GetModuleFileNameW not existing on this platform, skipping W-calls\n");
400 is_unicode_enabled = FALSE;
403 testGetModuleFileName(NULL);
404 testGetModuleFileName("kernel32.dll");
405 testGetModuleFileName_Wrong();
408 testNestedLoadLibraryA();
409 testLoadLibraryA_Wrong();
410 testGetProcAddress_Wrong();