[INETCOMM_WINETEST] Sync with Wine Staging 2.2. CORE-12823
[reactos.git] / rostests / winetests / kernel32 / module.c
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 "wine/test.h"
22 #include <windows.h>
23 #include <psapi.h>
24
25 static DWORD (WINAPI *pGetDllDirectoryA)(DWORD,LPSTR);
26 static DWORD (WINAPI *pGetDllDirectoryW)(DWORD,LPWSTR);
27 static BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR);
28 static BOOL (WINAPI *pGetModuleHandleExA)(DWORD,LPCSTR,HMODULE*);
29 static BOOL (WINAPI *pGetModuleHandleExW)(DWORD,LPCWSTR,HMODULE*);
30 static BOOL (WINAPI *pK32GetModuleInformation)(HANDLE process, HMODULE module,
31 MODULEINFO *modinfo, DWORD cb);
32
33 static BOOL is_unicode_enabled = TRUE;
34
35 static BOOL cmpStrAW(const char* a, const WCHAR* b, DWORD lenA, DWORD lenB)
36 {
37 WCHAR aw[1024];
38
39 DWORD len = MultiByteToWideChar( AreFileApisANSI() ? CP_ACP : CP_OEMCP, 0,
40 a, lenA, aw, sizeof(aw) / sizeof(aw[0]) );
41 if (len != lenB) return FALSE;
42 return memcmp(aw, b, len * sizeof(WCHAR)) == 0;
43 }
44
45 static void testGetModuleFileName(const char* name)
46 {
47 HMODULE hMod;
48 char bufA[MAX_PATH];
49 WCHAR bufW[MAX_PATH];
50 DWORD len1A, len1W = 0, len2A, len2W = 0;
51
52 hMod = (name) ? GetModuleHandleA(name) : NULL;
53
54 /* first test, with enough space in buffer */
55 memset(bufA, '-', sizeof(bufA));
56 SetLastError(0xdeadbeef);
57 len1A = GetModuleFileNameA(hMod, bufA, sizeof(bufA));
58 ok(GetLastError() == ERROR_SUCCESS ||
59 broken(GetLastError() == 0xdeadbeef), /* <= XP SP3 */
60 "LastError was not reset: %u\n", GetLastError());
61 ok(len1A > 0, "Getting module filename for handle %p\n", hMod);
62
63 if (is_unicode_enabled)
64 {
65 memset(bufW, '-', sizeof(bufW));
66 SetLastError(0xdeadbeef);
67 len1W = GetModuleFileNameW(hMod, bufW, sizeof(bufW) / sizeof(WCHAR));
68 ok(GetLastError() == ERROR_SUCCESS ||
69 broken(GetLastError() == 0xdeadbeef), /* <= XP SP3 */
70 "LastError was not reset: %u\n", GetLastError());
71 ok(len1W > 0, "Getting module filename for handle %p\n", hMod);
72 }
73
74 ok(len1A == strlen(bufA), "Unexpected length of GetModuleFilenameA (%d/%d)\n", len1A, lstrlenA(bufA));
75
76 if (is_unicode_enabled)
77 {
78 ok(len1W == lstrlenW(bufW), "Unexpected length of GetModuleFilenameW (%d/%d)\n", len1W, lstrlenW(bufW));
79 ok(cmpStrAW(bufA, bufW, len1A, len1W), "Comparing GetModuleFilenameAW results\n");
80 }
81
82 /* second test with a buffer too small */
83 memset(bufA, '-', sizeof(bufA));
84 len2A = GetModuleFileNameA(hMod, bufA, len1A / 2);
85 ok(len2A > 0, "Getting module filename for handle %p\n", hMod);
86
87 if (is_unicode_enabled)
88 {
89 memset(bufW, '-', sizeof(bufW));
90 len2W = GetModuleFileNameW(hMod, bufW, len1W / 2);
91 ok(len2W > 0, "Getting module filename for handle %p\n", hMod);
92 ok(cmpStrAW(bufA, bufW, len2A, len2W), "Comparing GetModuleFilenameAW results with buffer too small\n" );
93 ok(len1W / 2 == len2W, "Correct length in GetModuleFilenameW with buffer too small (%d/%d)\n", len1W / 2, len2W);
94 }
95
96 ok(len1A / 2 == len2A ||
97 len1A / 2 == len2A + 1, /* Win9x */
98 "Correct length in GetModuleFilenameA with buffer too small (%d/%d)\n", len1A / 2, len2A);
99 }
100
101 static void testGetModuleFileName_Wrong(void)
102 {
103 char bufA[MAX_PATH];
104 WCHAR bufW[MAX_PATH];
105
106 /* test wrong handle */
107 if (is_unicode_enabled)
108 {
109 bufW[0] = '*';
110 ok(GetModuleFileNameW((void*)0xffffffff, bufW, sizeof(bufW) / sizeof(WCHAR)) == 0, "Unexpected success in module handle\n");
111 ok(bufW[0] == '*', "When failing, buffer shouldn't be written to\n");
112 }
113
114 bufA[0] = '*';
115 ok(GetModuleFileNameA((void*)0xffffffff, bufA, sizeof(bufA)) == 0, "Unexpected success in module handle\n");
116 ok(bufA[0] == '*' ||
117 bufA[0] == 0 /* Win9x */,
118 "When failing, buffer shouldn't be written to\n");
119 }
120
121 static void testLoadLibraryA(void)
122 {
123 HMODULE hModule, hModule1;
124 FARPROC fp;
125
126 SetLastError(0xdeadbeef);
127 hModule = LoadLibraryA("kernel32.dll");
128 ok( hModule != NULL, "kernel32.dll should be loadable\n");
129 ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %d\n", GetLastError());
130
131 fp = GetProcAddress(hModule, "CreateFileA");
132 ok( fp != NULL, "CreateFileA should be there\n");
133 ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %d\n", GetLastError());
134
135 SetLastError(0xdeadbeef);
136 hModule1 = LoadLibraryA("kernel32 ");
137 /* Only winNT does this */
138 if (GetLastError() != ERROR_DLL_NOT_FOUND)
139 {
140 ok( hModule1 != NULL, "\"kernel32 \" should be loadable\n");
141 ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %d\n", GetLastError());
142 ok( hModule == hModule1, "Loaded wrong module\n");
143 FreeLibrary(hModule1);
144 }
145 FreeLibrary(hModule);
146 }
147
148 static void testNestedLoadLibraryA(void)
149 {
150 static const char dllname[] = "shell32.dll";
151 char path1[MAX_PATH], path2[MAX_PATH];
152 HMODULE hModule1, hModule2, hModule3;
153
154 /* This is not really a Windows conformance test, but more a Wine
155 * regression test. Wine's builtin dlls can be loaded from multiple paths,
156 * and this test tries to make sure that Wine does not get confused and
157 * really unloads the Unix .so file at the right time. Failure to do so
158 * will result in the dll being unloadable.
159 * This test must be done with a dll that can be unloaded, which means:
160 * - it must not already be loaded
161 * - it must not have a 16-bit counterpart
162 */
163 GetWindowsDirectoryA(path1, sizeof(path1));
164 strcat(path1, "\\system\\");
165 strcat(path1, dllname);
166 hModule1 = LoadLibraryA(path1);
167 if (!hModule1)
168 {
169 /* We must be on Windows NT, so we cannot test */
170 return;
171 }
172
173 GetWindowsDirectoryA(path2, sizeof(path2));
174 strcat(path2, "\\system32\\");
175 strcat(path2, dllname);
176 hModule2 = LoadLibraryA(path2);
177 if (!hModule2)
178 {
179 /* We must be on Windows 9x, so we cannot test */
180 ok(FreeLibrary(hModule1), "FreeLibrary() failed\n");
181 return;
182 }
183
184 /* The first LoadLibrary() call may have registered the dll under the
185 * system32 path. So load it, again, under the '...\system\...' path so
186 * Wine does not immediately notice that it is already loaded.
187 */
188 hModule3 = LoadLibraryA(path1);
189 ok(hModule3 != NULL, "LoadLibrary(%s) failed\n", path1);
190
191 /* Now fully unload the dll */
192 ok(FreeLibrary(hModule3), "FreeLibrary() failed\n");
193 ok(FreeLibrary(hModule2), "FreeLibrary() failed\n");
194 ok(FreeLibrary(hModule1), "FreeLibrary() failed\n");
195 ok(GetModuleHandleA(dllname) == NULL, "%s was not fully unloaded\n", dllname);
196
197 /* Try to load the dll again, if refcounting is ok, this should work */
198 hModule1 = LoadLibraryA(path1);
199 ok(hModule1 != NULL, "LoadLibrary(%s) failed\n", path1);
200 if (hModule1 != NULL)
201 ok(FreeLibrary(hModule1), "FreeLibrary() failed\n");
202 }
203
204 static void testLoadLibraryA_Wrong(void)
205 {
206 HMODULE hModule;
207
208 /* Try to load a nonexistent dll */
209 SetLastError(0xdeadbeef);
210 hModule = LoadLibraryA("non_ex_pv.dll");
211 ok( !hModule, "non_ex_pv.dll should be not loadable\n");
212 ok( GetLastError() == ERROR_MOD_NOT_FOUND || GetLastError() == ERROR_DLL_NOT_FOUND,
213 "Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND (win9x), got %d\n", GetLastError());
214
215 /* Just in case */
216 FreeLibrary(hModule);
217 }
218
219 static void testGetProcAddress_Wrong(void)
220 {
221 FARPROC fp;
222
223 SetLastError(0xdeadbeef);
224 fp = GetProcAddress(NULL, "non_ex_call");
225 ok( !fp, "non_ex_call should not be found\n");
226 ok( GetLastError() == ERROR_PROC_NOT_FOUND || GetLastError() == ERROR_INVALID_HANDLE,
227 "Expected ERROR_PROC_NOT_FOUND or ERROR_INVALID_HANDLE(win9x), got %d\n", GetLastError());
228
229 SetLastError(0xdeadbeef);
230 fp = GetProcAddress((HMODULE)0xdeadbeef, "non_ex_call");
231 ok( !fp, "non_ex_call should not be found\n");
232 ok( GetLastError() == ERROR_MOD_NOT_FOUND || GetLastError() == ERROR_INVALID_HANDLE,
233 "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_HANDLE(win9x), got %d\n", GetLastError());
234 }
235
236 static void testLoadLibraryEx(void)
237 {
238 CHAR path[MAX_PATH];
239 HMODULE hmodule;
240 HANDLE hfile;
241 BOOL ret;
242
243 hfile = CreateFileA("testfile.dll", GENERIC_READ | GENERIC_WRITE,
244 FILE_SHARE_READ | FILE_SHARE_WRITE,
245 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
246 ok(hfile != INVALID_HANDLE_VALUE, "Expected a valid file handle\n");
247
248 /* NULL lpFileName */
249 if (is_unicode_enabled)
250 {
251 SetLastError(0xdeadbeef);
252 hmodule = LoadLibraryExA(NULL, NULL, 0);
253 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
254 ok(GetLastError() == ERROR_MOD_NOT_FOUND ||
255 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
256 "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n",
257 GetLastError());
258 }
259 else
260 win_skip("NULL filename crashes on WinMe\n");
261
262 /* empty lpFileName */
263 SetLastError(0xdeadbeef);
264 hmodule = LoadLibraryExA("", NULL, 0);
265 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
266 ok(GetLastError() == ERROR_MOD_NOT_FOUND ||
267 GetLastError() == ERROR_DLL_NOT_FOUND /* win9x */ ||
268 GetLastError() == ERROR_INVALID_PARAMETER /* win8 */,
269 "Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND, got %d\n",
270 GetLastError());
271
272 /* hFile is non-NULL */
273 SetLastError(0xdeadbeef);
274 hmodule = LoadLibraryExA("testfile.dll", hfile, 0);
275 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
276 todo_wine
277 {
278 ok(GetLastError() == ERROR_SHARING_VIOLATION ||
279 GetLastError() == ERROR_INVALID_PARAMETER || /* win2k3 */
280 GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */
281 "Unexpected last error, got %d\n", GetLastError());
282 }
283
284 SetLastError(0xdeadbeef);
285 hmodule = LoadLibraryExA("testfile.dll", (HANDLE)0xdeadbeef, 0);
286 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
287 todo_wine
288 {
289 ok(GetLastError() == ERROR_SHARING_VIOLATION ||
290 GetLastError() == ERROR_INVALID_PARAMETER || /* win2k3 */
291 GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */
292 "Unexpected last error, got %d\n", GetLastError());
293 }
294
295 /* try to open a file that is locked */
296 SetLastError(0xdeadbeef);
297 hmodule = LoadLibraryExA("testfile.dll", NULL, 0);
298 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
299 todo_wine
300 {
301 ok(GetLastError() == ERROR_SHARING_VIOLATION ||
302 GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */
303 "Expected ERROR_SHARING_VIOLATION or ERROR_FILE_NOT_FOUND, got %d\n",
304 GetLastError());
305 }
306
307 /* lpFileName does not matter */
308 if (is_unicode_enabled)
309 {
310 SetLastError(0xdeadbeef);
311 hmodule = LoadLibraryExA(NULL, hfile, 0);
312 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
313 ok(GetLastError() == ERROR_MOD_NOT_FOUND ||
314 GetLastError() == ERROR_INVALID_PARAMETER, /* win2k3 */
315 "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n",
316 GetLastError());
317 }
318
319 CloseHandle(hfile);
320
321 /* load empty file */
322 SetLastError(0xdeadbeef);
323 hmodule = LoadLibraryExA("testfile.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
324 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
325 todo_wine
326 {
327 ok(GetLastError() == ERROR_FILE_INVALID ||
328 GetLastError() == ERROR_BAD_FORMAT, /* win9x */
329 "Expected ERROR_FILE_INVALID or ERROR_BAD_FORMAT, got %d\n",
330 GetLastError());
331 }
332
333 DeleteFileA("testfile.dll");
334
335 GetSystemDirectoryA(path, MAX_PATH);
336 if (path[lstrlenA(path) - 1] != '\\')
337 lstrcatA(path, "\\");
338 lstrcatA(path, "kernel32.dll");
339
340 /* load kernel32.dll with an absolute path */
341 SetLastError(0xdeadbeef);
342 hmodule = LoadLibraryExA(path, NULL, LOAD_LIBRARY_AS_DATAFILE);
343 ok(hmodule != 0, "Expected valid module handle\n");
344 ok(GetLastError() == 0xdeadbeef ||
345 GetLastError() == ERROR_SUCCESS, /* win9x */
346 "Expected 0xdeadbeef or ERROR_SUCCESS, got %d\n", GetLastError());
347
348 /* try invalid file handle */
349 SetLastError(0xdeadbeef);
350 hmodule = LoadLibraryExA(path, (HANDLE)0xdeadbeef, 0);
351 if (!hmodule) /* succeeds on xp and older */
352 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
353
354 FreeLibrary(hmodule);
355
356 /* load kernel32.dll with no path */
357 SetLastError(0xdeadbeef);
358 hmodule = LoadLibraryExA("kernel32.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
359 ok(hmodule != 0, "Expected valid module handle\n");
360 ok(GetLastError() == 0xdeadbeef ||
361 GetLastError() == ERROR_SUCCESS, /* win9x */
362 "Expected 0xdeadbeef or ERROR_SUCCESS, got %d\n", GetLastError());
363
364 FreeLibrary(hmodule);
365
366 GetCurrentDirectoryA(MAX_PATH, path);
367 if (path[lstrlenA(path) - 1] != '\\')
368 lstrcatA(path, "\\");
369 lstrcatA(path, "kernel32.dll");
370
371 /* load kernel32.dll with an absolute path that does not exist */
372 SetLastError(0xdeadbeef);
373 hmodule = LoadLibraryExA(path, NULL, LOAD_LIBRARY_AS_DATAFILE);
374 todo_wine
375 {
376 ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
377 }
378 ok(GetLastError() == ERROR_FILE_NOT_FOUND ||
379 broken(GetLastError() == ERROR_INVALID_HANDLE), /* nt4 */
380 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
381
382 /* Free the loaded dll when it's the first time this dll is loaded
383 in process - First time should pass, second fail */
384 SetLastError(0xdeadbeef);
385 hmodule = LoadLibraryExA("comctl32.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
386 ok(hmodule != 0, "Expected valid module handle\n");
387
388 SetLastError(0xdeadbeef);
389 ret = FreeLibrary(hmodule);
390 ok(ret, "Expected to be able to free the module, failed with %d\n", GetLastError());
391 SetLastError(0xdeadbeef);
392 ret = FreeLibrary(hmodule);
393 ok(!ret, "Unexpected ability to free the module, failed with %d\n", GetLastError());
394
395 /* load with full path, name without extension */
396 GetSystemDirectoryA(path, MAX_PATH);
397 if (path[lstrlenA(path) - 1] != '\\')
398 lstrcatA(path, "\\");
399 lstrcatA(path, "kernel32");
400 hmodule = LoadLibraryExA(path, NULL, 0);
401 ok(hmodule != NULL, "got %p\n", hmodule);
402 FreeLibrary(hmodule);
403
404 /* same with alterate search path */
405 hmodule = LoadLibraryExA(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
406 ok(hmodule != NULL, "got %p\n", hmodule);
407 FreeLibrary(hmodule);
408 }
409
410 static void testGetDllDirectory(void)
411 {
412 CHAR bufferA[MAX_PATH];
413 WCHAR bufferW[MAX_PATH];
414 DWORD length, ret;
415 int i;
416 static const char *dll_directories[] =
417 {
418 "",
419 "C:\\Some\\Path",
420 "C:\\Some\\Path\\",
421 "Q:\\A\\Long\\Path with spaces that\\probably\\doesn't exist!",
422 };
423 const int test_count = sizeof(dll_directories) / sizeof(dll_directories[0]);
424
425 if (!pGetDllDirectoryA || !pGetDllDirectoryW)
426 {
427 win_skip("GetDllDirectory not available\n");
428 return;
429 }
430 if (!pSetDllDirectoryA)
431 {
432 win_skip("SetDllDirectoryA not available\n");
433 return;
434 }
435
436 for (i = 0; i < test_count; i++)
437 {
438 length = strlen(dll_directories[i]);
439 if (!pSetDllDirectoryA(dll_directories[i]))
440 {
441 skip("i=%d, SetDllDirectoryA failed\n", i);
442 continue;
443 }
444
445 /* no buffer, determine length */
446 ret = pGetDllDirectoryA(0, NULL);
447 ok(ret == length + 1, "Expected %u, got %u\n", length + 1, ret);
448
449 ret = pGetDllDirectoryW(0, NULL);
450 ok(ret == length + 1, "Expected %u, got %u\n", length + 1, ret);
451
452 /* buffer of exactly the right size */
453 bufferA[length] = 'A';
454 bufferA[length + 1] = 'A';
455 ret = pGetDllDirectoryA(length + 1, bufferA);
456 ok(ret == length || broken(ret + 1 == length) /* win8 */,
457 "i=%d, Expected %u(+1), got %u\n", i, length, ret);
458 ok(bufferA[length + 1] == 'A', "i=%d, Buffer overflow\n", i);
459 ok(strcmp(bufferA, dll_directories[i]) == 0, "i=%d, Wrong path returned: '%s'\n", i, bufferA);
460
461 bufferW[length] = 'A';
462 bufferW[length + 1] = 'A';
463 ret = pGetDllDirectoryW(length + 1, bufferW);
464 ok(ret == length, "i=%d, Expected %u, got %u\n", i, length, ret);
465 ok(bufferW[length + 1] == 'A', "i=%d, Buffer overflow\n", i);
466 ok(cmpStrAW(dll_directories[i], bufferW, length, length),
467 "i=%d, Wrong path returned: %s\n", i, wine_dbgstr_w(bufferW));
468
469 /* Zero size buffer. The buffer may or may not be terminated depending
470 * on the Windows version and whether the A or W API is called. */
471 bufferA[0] = 'A';
472 ret = pGetDllDirectoryA(0, bufferA);
473 ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
474
475 bufferW[0] = 'A';
476 ret = pGetDllDirectoryW(0, bufferW);
477 ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
478 ok(bufferW[0] == 0 || /* XP, 2003 */
479 broken(bufferW[0] == 'A'), "i=%d, Buffer overflow\n", i);
480
481 /* buffer just one too short */
482 bufferA[0] = 'A';
483 ret = pGetDllDirectoryA(length, bufferA);
484 ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
485 if (length != 0)
486 ok(bufferA[0] == 0, "i=%d, Buffer not null terminated\n", i);
487
488 bufferW[0] = 'A';
489 ret = pGetDllDirectoryW(length, bufferW);
490 ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
491 ok(bufferW[0] == 0 || /* XP, 2003 */
492 broken(bufferW[0] == 'A'), "i=%d, Buffer overflow\n", i);
493
494 if (0)
495 {
496 /* crashes on win8 */
497 /* no buffer, but too short length */
498 ret = pGetDllDirectoryA(length, NULL);
499 ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
500
501 ret = pGetDllDirectoryW(length, NULL);
502 ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
503 }
504 }
505
506 /* unset whatever we did so following tests won't be affected */
507 pSetDllDirectoryA(NULL);
508 }
509
510 static void init_pointers(void)
511 {
512 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
513
514 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hKernel32, #f))
515 MAKEFUNC(GetDllDirectoryA);
516 MAKEFUNC(GetDllDirectoryW);
517 MAKEFUNC(SetDllDirectoryA);
518 MAKEFUNC(GetModuleHandleExA);
519 MAKEFUNC(GetModuleHandleExW);
520 MAKEFUNC(K32GetModuleInformation);
521 #undef MAKEFUNC
522
523 /* not all Windows versions export this in kernel32 */
524 if (!pK32GetModuleInformation)
525 {
526 HMODULE hPsapi = LoadLibraryA("psapi.dll");
527 if (hPsapi)
528 {
529 pK32GetModuleInformation = (void *)GetProcAddress(hPsapi, "GetModuleInformation");
530 if (!pK32GetModuleInformation) FreeLibrary(hPsapi);
531 }
532 }
533
534 }
535
536 static void testGetModuleHandleEx(void)
537 {
538 static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2',0};
539 static const WCHAR nosuchmodW[] = {'n','o','s','u','c','h','m','o','d',0};
540 BOOL ret;
541 DWORD error;
542 HMODULE mod, mod_kernel32;
543
544 if (!pGetModuleHandleExA || !pGetModuleHandleExW)
545 {
546 win_skip( "GetModuleHandleEx not available\n" );
547 return;
548 }
549
550 SetLastError( 0xdeadbeef );
551 ret = pGetModuleHandleExA( 0, NULL, NULL );
552 error = GetLastError();
553 ok( !ret, "unexpected success\n" );
554 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
555
556 SetLastError( 0xdeadbeef );
557 ret = pGetModuleHandleExA( 0, "kernel32", NULL );
558 error = GetLastError();
559 ok( !ret, "unexpected success\n" );
560 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
561
562 SetLastError( 0xdeadbeef );
563 mod = (HMODULE)0xdeadbeef;
564 ret = pGetModuleHandleExA( 0, "kernel32", &mod );
565 ok( ret, "unexpected failure %u\n", GetLastError() );
566 ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod );
567 FreeLibrary( mod );
568
569 SetLastError( 0xdeadbeef );
570 mod = (HMODULE)0xdeadbeef;
571 ret = pGetModuleHandleExA( 0, "nosuchmod", &mod );
572 error = GetLastError();
573 ok( !ret, "unexpected success\n" );
574 ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
575 ok( mod == NULL, "got %p\n", mod );
576
577 SetLastError( 0xdeadbeef );
578 ret = pGetModuleHandleExW( 0, NULL, NULL );
579 error = GetLastError();
580 ok( !ret, "unexpected success\n" );
581 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
582
583 SetLastError( 0xdeadbeef );
584 ret = pGetModuleHandleExW( 0, kernel32W, NULL );
585 error = GetLastError();
586 ok( !ret, "unexpected success\n" );
587 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
588
589 SetLastError( 0xdeadbeef );
590 mod = (HMODULE)0xdeadbeef;
591 ret = pGetModuleHandleExW( 0, kernel32W, &mod );
592 ok( ret, "unexpected failure %u\n", GetLastError() );
593 ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod );
594 FreeLibrary( mod );
595
596 SetLastError( 0xdeadbeef );
597 mod = (HMODULE)0xdeadbeef;
598 ret = pGetModuleHandleExW( 0, nosuchmodW, &mod );
599 error = GetLastError();
600 ok( !ret, "unexpected success\n" );
601 ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
602 ok( mod == NULL, "got %p\n", mod );
603
604 SetLastError( 0xdeadbeef );
605 ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL );
606 error = GetLastError();
607 ok( !ret, "unexpected success\n" );
608 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
609
610 SetLastError( 0xdeadbeef );
611 ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", NULL );
612 error = GetLastError();
613 ok( !ret, "unexpected success\n" );
614 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
615
616 SetLastError( 0xdeadbeef );
617 mod = (HMODULE)0xdeadbeef;
618 ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", &mod );
619 ok( ret, "unexpected failure %u\n", GetLastError() );
620 ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod );
621
622 SetLastError( 0xdeadbeef );
623 mod = (HMODULE)0xdeadbeef;
624 ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "nosuchmod", &mod );
625 error = GetLastError();
626 ok( !ret, "unexpected success\n" );
627 ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
628 ok( mod == NULL, "got %p\n", mod );
629
630 SetLastError( 0xdeadbeef );
631 ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL );
632 error = GetLastError();
633 ok( !ret, "unexpected success\n" );
634 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
635
636 SetLastError( 0xdeadbeef );
637 ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, NULL );
638 error = GetLastError();
639 ok( !ret, "unexpected success\n" );
640 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
641
642 SetLastError( 0xdeadbeef );
643 mod = (HMODULE)0xdeadbeef;
644 ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, &mod );
645 ok( ret, "unexpected failure %u\n", GetLastError() );
646 ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod );
647
648 SetLastError( 0xdeadbeef );
649 mod = (HMODULE)0xdeadbeef;
650 ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, nosuchmodW, &mod );
651 error = GetLastError();
652 ok( !ret, "unexpected success\n" );
653 ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
654 ok( mod == NULL, "got %p\n", mod );
655
656 mod_kernel32 = LoadLibraryA( "kernel32" );
657
658 SetLastError( 0xdeadbeef );
659 ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL );
660 error = GetLastError();
661 ok( !ret, "unexpected success\n" );
662 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
663
664 SetLastError( 0xdeadbeef );
665 ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, NULL );
666 error = GetLastError();
667 ok( !ret, "unexpected success\n" );
668 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
669
670 SetLastError( 0xdeadbeef );
671 mod = (HMODULE)0xdeadbeef;
672 ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, &mod );
673 ok( ret, "unexpected failure %u\n", GetLastError() );
674 ok( mod == mod_kernel32, "got %p\n", mod );
675 FreeLibrary( mod );
676
677 SetLastError( 0xdeadbeef );
678 mod = (HMODULE)0xdeadbeef;
679 ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)0xbeefdead, &mod );
680 error = GetLastError();
681 ok( !ret, "unexpected success\n" );
682 ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
683 ok( mod == NULL, "got %p\n", mod );
684
685 SetLastError( 0xdeadbeef );
686 ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL );
687 error = GetLastError();
688 ok( !ret, "unexpected success\n" );
689 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
690
691 SetLastError( 0xdeadbeef );
692 ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, NULL );
693 error = GetLastError();
694 ok( !ret, "unexpected success\n" );
695 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
696
697 SetLastError( 0xdeadbeef );
698 mod = (HMODULE)0xdeadbeef;
699 ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, &mod );
700 ok( ret, "unexpected failure %u\n", GetLastError() );
701 ok( mod == mod_kernel32, "got %p\n", mod );
702 FreeLibrary( mod );
703
704 SetLastError( 0xdeadbeef );
705 mod = (HMODULE)0xdeadbeef;
706 ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)0xbeefdead, &mod );
707 error = GetLastError();
708 ok( !ret, "unexpected success\n" );
709 ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
710 ok( mod == NULL, "got %p\n", mod );
711
712 FreeLibrary( mod_kernel32 );
713 }
714
715 static void testK32GetModuleInformation(void)
716 {
717 MODULEINFO info;
718 HMODULE mod;
719 BOOL ret;
720
721 if (!pK32GetModuleInformation)
722 {
723 win_skip("K32GetModuleInformation not available\n");
724 return;
725 }
726
727 mod = GetModuleHandleA(NULL);
728 memset(&info, 0xAA, sizeof(info));
729 ret = pK32GetModuleInformation(GetCurrentProcess(), mod, &info, sizeof(info));
730 ok(ret, "K32GetModuleInformation failed for main module\n");
731 ok(info.lpBaseOfDll == mod, "Wrong info.lpBaseOfDll = %p, expected %p\n", info.lpBaseOfDll, mod);
732 ok(info.EntryPoint != NULL, "Expected nonzero entrypoint\n");
733
734 mod = GetModuleHandleA("kernel32.dll");
735 memset(&info, 0xAA, sizeof(info));
736 ret = pK32GetModuleInformation(GetCurrentProcess(), mod, &info, sizeof(info));
737 ok(ret, "K32GetModuleInformation failed for kernel32 module\n");
738 ok(info.lpBaseOfDll == mod, "Wrong info.lpBaseOfDll = %p, expected %p\n", info.lpBaseOfDll, mod);
739 ok(info.EntryPoint != NULL, "Expected nonzero entrypoint\n");
740 }
741
742 START_TEST(module)
743 {
744 WCHAR filenameW[MAX_PATH];
745
746 /* Test if we can use GetModuleFileNameW */
747
748 SetLastError(0xdeadbeef);
749 GetModuleFileNameW(NULL, filenameW, MAX_PATH);
750 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
751 {
752 win_skip("GetModuleFileNameW not existing on this platform, skipping W-calls\n");
753 is_unicode_enabled = FALSE;
754 }
755
756 init_pointers();
757
758 testGetModuleFileName(NULL);
759 testGetModuleFileName("kernel32.dll");
760 testGetModuleFileName_Wrong();
761
762 testGetDllDirectory();
763
764 testLoadLibraryA();
765 testNestedLoadLibraryA();
766 testLoadLibraryA_Wrong();
767 testGetProcAddress_Wrong();
768 testLoadLibraryEx();
769 testGetModuleHandleEx();
770 testK32GetModuleInformation();
771 }