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