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 "precomp.h"
22 
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 DLL_DIRECTORY_COOKIE (WINAPI *pAddDllDirectory)(const WCHAR*);
29 static BOOL (WINAPI *pRemoveDllDirectory)(DLL_DIRECTORY_COOKIE);
30 static BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD);
31 static BOOL (WINAPI *pGetModuleHandleExA)(DWORD,LPCSTR,HMODULE*);
32 static BOOL (WINAPI *pGetModuleHandleExW)(DWORD,LPCWSTR,HMODULE*);
33 static BOOL (WINAPI *pK32GetModuleInformation)(HANDLE process, HMODULE module,
34                                                MODULEINFO *modinfo, DWORD cb);
35 
36 static BOOL is_unicode_enabled = TRUE;
37 
38 static BOOL cmpStrAW(const char* a, const WCHAR* b, DWORD lenA, DWORD lenB)
39 {
40     WCHAR       aw[1024];
41 
42     DWORD len = MultiByteToWideChar( AreFileApisANSI() ? CP_ACP : CP_OEMCP, 0,
43                                      a, lenA, aw, sizeof(aw) / sizeof(aw[0]) );
44     if (len != lenB) return FALSE;
45     return memcmp(aw, b, len * sizeof(WCHAR)) == 0;
46 }
47 
48 static const struct
49 {
50     IMAGE_DOS_HEADER dos;
51     IMAGE_NT_HEADERS nt;
52     IMAGE_SECTION_HEADER section;
53 } dll_image =
54 {
55     { IMAGE_DOS_SIGNATURE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 }, 0, 0, { 0 },
56       sizeof(IMAGE_DOS_HEADER) },
57     {
58         IMAGE_NT_SIGNATURE, /* Signature */
59         {
60 #if defined __i386__
61             IMAGE_FILE_MACHINE_I386, /* Machine */
62 #elif defined __x86_64__
63             IMAGE_FILE_MACHINE_AMD64, /* Machine */
64 #elif defined __powerpc__
65             IMAGE_FILE_MACHINE_POWERPC, /* Machine */
66 #elif defined __arm__
67             IMAGE_FILE_MACHINE_ARMNT, /* Machine */
68 #elif defined __aarch64__
69             IMAGE_FILE_MACHINE_ARM64, /* Machine */
70 #else
71 # error You must specify the machine type
72 #endif
73             1, /* NumberOfSections */
74             0, /* TimeDateStamp */
75             0, /* PointerToSymbolTable */
76             0, /* NumberOfSymbols */
77             sizeof(IMAGE_OPTIONAL_HEADER), /* SizeOfOptionalHeader */
78             IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL /* Characteristics */
79         },
80         { IMAGE_NT_OPTIONAL_HDR_MAGIC, /* Magic */
81           1, /* MajorLinkerVersion */
82           0, /* MinorLinkerVersion */
83           0, /* SizeOfCode */
84           0, /* SizeOfInitializedData */
85           0, /* SizeOfUninitializedData */
86           0, /* AddressOfEntryPoint */
87           0x1000, /* BaseOfCode */
88 #ifndef _WIN64
89           0, /* BaseOfData */
90 #endif
91           0x10000000, /* ImageBase */
92           0x1000, /* SectionAlignment */
93           0x1000, /* FileAlignment */
94           4, /* MajorOperatingSystemVersion */
95           0, /* MinorOperatingSystemVersion */
96           1, /* MajorImageVersion */
97           0, /* MinorImageVersion */
98           4, /* MajorSubsystemVersion */
99           0, /* MinorSubsystemVersion */
100           0, /* Win32VersionValue */
101           0x2000, /* SizeOfImage */
102           sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS), /* SizeOfHeaders */
103           0, /* CheckSum */
104           IMAGE_SUBSYSTEM_WINDOWS_CUI, /* Subsystem */
105           0, /* DllCharacteristics */
106           0, /* SizeOfStackReserve */
107           0, /* SizeOfStackCommit */
108           0, /* SizeOfHeapReserve */
109           0, /* SizeOfHeapCommit */
110           0, /* LoaderFlags */
111           0, /* NumberOfRvaAndSizes */
112           { { 0 } } /* DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] */
113         }
114     },
115     { ".rodata", { 0 }, 0x1000, 0x1000, 0, 0, 0, 0, 0,
116       IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ }
117 };
118 
119 static void create_test_dll( const char *name )
120 {
121     DWORD dummy;
122     HANDLE handle = CreateFileA( name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0 );
123 
124     ok( handle != INVALID_HANDLE_VALUE, "failed to create file err %u\n", GetLastError() );
125     WriteFile( handle, &dll_image, sizeof(dll_image), &dummy, NULL );
126     SetFilePointer( handle, dll_image.nt.OptionalHeader.SizeOfImage, NULL, FILE_BEGIN );
127     SetEndOfFile( handle );
128     CloseHandle( handle );
129 }
130 
131 static void testGetModuleFileName(const char* name)
132 {
133     HMODULE     hMod;
134     char        bufA[MAX_PATH];
135     WCHAR       bufW[MAX_PATH];
136     DWORD       len1A, len1W = 0, len2A, len2W = 0;
137 
138     hMod = (name) ? GetModuleHandleA(name) : NULL;
139 
140     /* first test, with enough space in buffer */
141     memset(bufA, '-', sizeof(bufA));
142     SetLastError(0xdeadbeef);
143     len1A = GetModuleFileNameA(hMod, bufA, sizeof(bufA));
144     ok(GetLastError() == ERROR_SUCCESS ||
145        broken(GetLastError() == 0xdeadbeef), /* <= XP SP3 */
146        "LastError was not reset: %u\n", GetLastError());
147     ok(len1A > 0, "Getting module filename for handle %p\n", hMod);
148 
149     if (is_unicode_enabled)
150     {
151         memset(bufW, '-', sizeof(bufW));
152         SetLastError(0xdeadbeef);
153         len1W = GetModuleFileNameW(hMod, bufW, sizeof(bufW) / sizeof(WCHAR));
154         ok(GetLastError() == ERROR_SUCCESS ||
155            broken(GetLastError() == 0xdeadbeef), /* <= XP SP3 */
156            "LastError was not reset: %u\n", GetLastError());
157         ok(len1W > 0, "Getting module filename for handle %p\n", hMod);
158     }
159 
160     ok(len1A == strlen(bufA), "Unexpected length of GetModuleFilenameA (%d/%d)\n", len1A, lstrlenA(bufA));
161 
162     if (is_unicode_enabled)
163     {
164         ok(len1W == lstrlenW(bufW), "Unexpected length of GetModuleFilenameW (%d/%d)\n", len1W, lstrlenW(bufW));
165         ok(cmpStrAW(bufA, bufW, len1A, len1W), "Comparing GetModuleFilenameAW results\n");
166     }
167 
168     /* second test with a buffer too small */
169     memset(bufA, '-', sizeof(bufA));
170     len2A = GetModuleFileNameA(hMod, bufA, len1A / 2);
171     ok(len2A > 0, "Getting module filename for handle %p\n", hMod);
172 
173     if (is_unicode_enabled)
174     {
175         memset(bufW, '-', sizeof(bufW));
176         len2W = GetModuleFileNameW(hMod, bufW, len1W / 2);
177         ok(len2W > 0, "Getting module filename for handle %p\n", hMod);
178         ok(cmpStrAW(bufA, bufW, len2A, len2W), "Comparing GetModuleFilenameAW results with buffer too small\n" );
179         ok(len1W / 2 == len2W, "Correct length in GetModuleFilenameW with buffer too small (%d/%d)\n", len1W / 2, len2W);
180     }
181 
182     ok(len1A / 2 == len2A ||
183        len1A / 2 == len2A + 1, /* Win9x */
184        "Correct length in GetModuleFilenameA with buffer too small (%d/%d)\n", len1A / 2, len2A);
185 }
186 
187 static void testGetModuleFileName_Wrong(void)
188 {
189     char        bufA[MAX_PATH];
190     WCHAR       bufW[MAX_PATH];
191 
192     /* test wrong handle */
193     if (is_unicode_enabled)
194     {
195         bufW[0] = '*';
196         ok(GetModuleFileNameW((void*)0xffffffff, bufW, sizeof(bufW) / sizeof(WCHAR)) == 0, "Unexpected success in module handle\n");
197         ok(bufW[0] == '*', "When failing, buffer shouldn't be written to\n");
198     }
199 
200     bufA[0] = '*';
201     ok(GetModuleFileNameA((void*)0xffffffff, bufA, sizeof(bufA)) == 0, "Unexpected success in module handle\n");
202     ok(bufA[0] == '*' ||
203        bufA[0] == 0 /* Win9x */,
204        "When failing, buffer shouldn't be written to\n");
205 }
206 
207 static void testLoadLibraryA(void)
208 {
209     HMODULE hModule, hModule1;
210     FARPROC fp;
211 
212     SetLastError(0xdeadbeef);
213     hModule = LoadLibraryA("kernel32.dll");
214     ok( hModule != NULL, "kernel32.dll should be loadable\n");
215     ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %d\n", GetLastError());
216 
217     fp = GetProcAddress(hModule, "CreateFileA");
218     ok( fp != NULL, "CreateFileA should be there\n");
219     ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %d\n", GetLastError());
220 
221     SetLastError(0xdeadbeef);
222     hModule1 = LoadLibraryA("kernel32   ");
223     /* Only winNT does this */
224     if (GetLastError() != ERROR_DLL_NOT_FOUND)
225     {
226         ok( hModule1 != NULL, "\"kernel32   \" should be loadable\n");
227         ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %d\n", GetLastError());
228         ok( hModule == hModule1, "Loaded wrong module\n");
229         FreeLibrary(hModule1);
230     }
231     FreeLibrary(hModule);
232 }
233 
234 static void testNestedLoadLibraryA(void)
235 {
236     static const char dllname[] = "shell32.dll";
237     char path1[MAX_PATH], path2[MAX_PATH];
238     HMODULE hModule1, hModule2, hModule3;
239 
240     /* This is not really a Windows conformance test, but more a Wine
241      * regression test. Wine's builtin dlls can be loaded from multiple paths,
242      * and this test tries to make sure that Wine does not get confused and
243      * really unloads the Unix .so file at the right time. Failure to do so
244      * will result in the dll being unloadable.
245      * This test must be done with a dll that can be unloaded, which means:
246      * - it must not already be loaded
247      * - it must not have a 16-bit counterpart
248      */
249     GetWindowsDirectoryA(path1, sizeof(path1));
250     strcat(path1, "\\system\\");
251     strcat(path1, dllname);
252     hModule1 = LoadLibraryA(path1);
253     if (!hModule1)
254     {
255         /* We must be on Windows NT, so we cannot test */
256         return;
257     }
258 
259     GetWindowsDirectoryA(path2, sizeof(path2));
260     strcat(path2, "\\system32\\");
261     strcat(path2, dllname);
262     hModule2 = LoadLibraryA(path2);
263     if (!hModule2)
264     {
265         /* We must be on Windows 9x, so we cannot test */
266         ok(FreeLibrary(hModule1), "FreeLibrary() failed\n");
267         return;
268     }
269 
270     /* The first LoadLibrary() call may have registered the dll under the
271      * system32 path. So load it, again, under the '...\system\...' path so
272      * Wine does not immediately notice that it is already loaded.
273      */
274     hModule3 = LoadLibraryA(path1);
275     ok(hModule3 != NULL, "LoadLibrary(%s) failed\n", path1);
276 
277     /* Now fully unload the dll */
278     ok(FreeLibrary(hModule3), "FreeLibrary() failed\n");
279     ok(FreeLibrary(hModule2), "FreeLibrary() failed\n");
280     ok(FreeLibrary(hModule1), "FreeLibrary() failed\n");
281     ok(GetModuleHandleA(dllname) == NULL, "%s was not fully unloaded\n", dllname);
282 
283     /* Try to load the dll again, if refcounting is ok, this should work */
284     hModule1 = LoadLibraryA(path1);
285     ok(hModule1 != NULL, "LoadLibrary(%s) failed\n", path1);
286     if (hModule1 != NULL)
287         ok(FreeLibrary(hModule1), "FreeLibrary() failed\n");
288 }
289 
290 static void testLoadLibraryA_Wrong(void)
291 {
292     HMODULE hModule;
293 
294     /* Try to load a nonexistent dll */
295     SetLastError(0xdeadbeef);
296     hModule = LoadLibraryA("non_ex_pv.dll");
297     ok( !hModule, "non_ex_pv.dll should be not loadable\n");
298     ok( GetLastError() == ERROR_MOD_NOT_FOUND || GetLastError() == ERROR_DLL_NOT_FOUND,
299         "Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND (win9x), got %d\n", GetLastError());
300 
301     /* Just in case */
302     FreeLibrary(hModule);
303 }
304 
305 static void testGetProcAddress_Wrong(void)
306 {
307     FARPROC fp;
308 
309     SetLastError(0xdeadbeef);
310     fp = GetProcAddress(NULL, "non_ex_call");
311     ok( !fp, "non_ex_call should not be found\n");
312     ok( GetLastError() == ERROR_PROC_NOT_FOUND || GetLastError() == ERROR_INVALID_HANDLE,
313         "Expected ERROR_PROC_NOT_FOUND or ERROR_INVALID_HANDLE(win9x), got %d\n", GetLastError());
314 
315     SetLastError(0xdeadbeef);
316     fp = GetProcAddress((HMODULE)0xdeadbeef, "non_ex_call");
317     ok( !fp, "non_ex_call should not be found\n");
318     ok( GetLastError() == ERROR_MOD_NOT_FOUND || GetLastError() == ERROR_INVALID_HANDLE,
319         "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_HANDLE(win9x), got %d\n", GetLastError());
320 }
321 
322 static void testLoadLibraryEx(void)
323 {
324     CHAR path[MAX_PATH];
325     HMODULE hmodule;
326     HANDLE hfile;
327     BOOL ret;
328 
329     hfile = CreateFileA("testfile.dll", GENERIC_READ | GENERIC_WRITE,
330                         FILE_SHARE_READ | FILE_SHARE_WRITE,
331                         NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
332     ok(hfile != INVALID_HANDLE_VALUE, "Expected a valid file handle\n");
333 
334     /* NULL lpFileName */
335     if (is_unicode_enabled)
336     {
337         SetLastError(0xdeadbeef);
338         hmodule = LoadLibraryExA(NULL, NULL, 0);
339         ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
340         ok(GetLastError() == ERROR_MOD_NOT_FOUND ||
341            GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
342            "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n",
343            GetLastError());
344     }
345     else
346         win_skip("NULL filename crashes on WinMe\n");
347 
348     /* empty lpFileName */
349     SetLastError(0xdeadbeef);
350     hmodule = LoadLibraryExA("", NULL, 0);
351     ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
352     ok(GetLastError() == ERROR_MOD_NOT_FOUND ||
353        GetLastError() == ERROR_DLL_NOT_FOUND /* win9x */ ||
354        GetLastError() == ERROR_INVALID_PARAMETER /* win8 */,
355        "Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND, got %d\n",
356        GetLastError());
357 
358     /* hFile is non-NULL */
359     SetLastError(0xdeadbeef);
360     hmodule = LoadLibraryExA("testfile.dll", hfile, 0);
361     ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
362     todo_wine
363     {
364         ok(GetLastError() == ERROR_SHARING_VIOLATION ||
365            GetLastError() == ERROR_INVALID_PARAMETER || /* win2k3 */
366            GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */
367            "Unexpected last error, got %d\n", GetLastError());
368     }
369 
370     SetLastError(0xdeadbeef);
371     hmodule = LoadLibraryExA("testfile.dll", (HANDLE)0xdeadbeef, 0);
372     ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
373     todo_wine
374     {
375         ok(GetLastError() == ERROR_SHARING_VIOLATION ||
376            GetLastError() == ERROR_INVALID_PARAMETER || /* win2k3 */
377            GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */
378            "Unexpected last error, got %d\n", GetLastError());
379     }
380 
381     /* try to open a file that is locked */
382     SetLastError(0xdeadbeef);
383     hmodule = LoadLibraryExA("testfile.dll", NULL, 0);
384     ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
385     todo_wine
386     {
387         ok(GetLastError() == ERROR_SHARING_VIOLATION ||
388            GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */
389            "Expected ERROR_SHARING_VIOLATION or ERROR_FILE_NOT_FOUND, got %d\n",
390            GetLastError());
391     }
392 
393     /* lpFileName does not matter */
394     if (is_unicode_enabled)
395     {
396         SetLastError(0xdeadbeef);
397         hmodule = LoadLibraryExA(NULL, hfile, 0);
398         ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
399         ok(GetLastError() == ERROR_MOD_NOT_FOUND ||
400            GetLastError() == ERROR_INVALID_PARAMETER, /* win2k3 */
401            "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n",
402            GetLastError());
403     }
404 
405     CloseHandle(hfile);
406 
407     /* load empty file */
408     SetLastError(0xdeadbeef);
409     hmodule = LoadLibraryExA("testfile.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
410     ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
411     todo_wine
412     {
413         ok(GetLastError() == ERROR_FILE_INVALID ||
414            GetLastError() == ERROR_BAD_FORMAT, /* win9x */
415            "Expected ERROR_FILE_INVALID or ERROR_BAD_FORMAT, got %d\n",
416            GetLastError());
417     }
418 
419     DeleteFileA("testfile.dll");
420 
421     GetSystemDirectoryA(path, MAX_PATH);
422     if (path[lstrlenA(path) - 1] != '\\')
423         lstrcatA(path, "\\");
424     lstrcatA(path, "kernel32.dll");
425 
426     /* load kernel32.dll with an absolute path */
427     SetLastError(0xdeadbeef);
428     hmodule = LoadLibraryExA(path, NULL, LOAD_LIBRARY_AS_DATAFILE);
429     ok(hmodule != 0, "Expected valid module handle\n");
430     ok(GetLastError() == 0xdeadbeef ||
431        GetLastError() == ERROR_SUCCESS, /* win9x */
432        "Expected 0xdeadbeef or ERROR_SUCCESS, got %d\n", GetLastError());
433 
434     /* try invalid file handle */
435     SetLastError(0xdeadbeef);
436     hmodule = LoadLibraryExA(path, (HANDLE)0xdeadbeef, 0);
437     if (!hmodule)  /* succeeds on xp and older */
438         ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
439 
440     FreeLibrary(hmodule);
441 
442     /* load kernel32.dll with no path */
443     SetLastError(0xdeadbeef);
444     hmodule = LoadLibraryExA("kernel32.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
445     ok(hmodule != 0, "Expected valid module handle\n");
446     ok(GetLastError() == 0xdeadbeef ||
447        GetLastError() == ERROR_SUCCESS, /* win9x */
448        "Expected 0xdeadbeef or ERROR_SUCCESS, got %d\n", GetLastError());
449 
450     FreeLibrary(hmodule);
451 
452     GetCurrentDirectoryA(MAX_PATH, path);
453     if (path[lstrlenA(path) - 1] != '\\')
454         lstrcatA(path, "\\");
455     lstrcatA(path, "kernel32.dll");
456 
457     /* load kernel32.dll with an absolute path that does not exist */
458     SetLastError(0xdeadbeef);
459     hmodule = LoadLibraryExA(path, NULL, LOAD_LIBRARY_AS_DATAFILE);
460     todo_wine
461     {
462         ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
463     }
464     ok(GetLastError() == ERROR_FILE_NOT_FOUND ||
465        broken(GetLastError() == ERROR_INVALID_HANDLE),  /* nt4 */
466        "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
467 
468     /* Free the loaded dll when it's the first time this dll is loaded
469        in process - First time should pass, second fail */
470     SetLastError(0xdeadbeef);
471     hmodule = LoadLibraryExA("comctl32.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
472     ok(hmodule != 0, "Expected valid module handle\n");
473 
474     SetLastError(0xdeadbeef);
475     ret = FreeLibrary(hmodule);
476     ok(ret, "Expected to be able to free the module, failed with %d\n", GetLastError());
477     SetLastError(0xdeadbeef);
478     ret = FreeLibrary(hmodule);
479     ok(!ret, "Unexpected ability to free the module, failed with %d\n", GetLastError());
480 
481     /* load with full path, name without extension */
482     GetSystemDirectoryA(path, MAX_PATH);
483     if (path[lstrlenA(path) - 1] != '\\')
484         lstrcatA(path, "\\");
485     lstrcatA(path, "kernel32");
486     hmodule = LoadLibraryExA(path, NULL, 0);
487     ok(hmodule != NULL, "got %p\n", hmodule);
488     FreeLibrary(hmodule);
489 
490     /* same with alterate search path */
491     hmodule = LoadLibraryExA(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
492     ok(hmodule != NULL, "got %p\n", hmodule);
493     FreeLibrary(hmodule);
494 }
495 
496 static void test_LoadLibraryEx_search_flags(void)
497 {
498     static const struct
499     {
500         int add_dirs[4];
501         int dll_dir;
502         int expect;
503     } tests[] =
504     {
505         { { 1, 2, 3 }, 4, 3 }, /* 0 */
506         { { 1, 3, 2 }, 4, 2 },
507         { { 3, 1 },    4, 1 },
508         { { 5, 6 },    4, 4 },
509         { { 5, 2 },    4, 2 },
510         { { 0 },       4, 4 }, /* 5 */
511         { { 0 },       0, 0 },
512         { { 6, 5 },    5, 0 },
513         { { 1, 1, 2 }, 0, 2 },
514     };
515     char *p, path[MAX_PATH], buf[MAX_PATH];
516     WCHAR bufW[MAX_PATH];
517     DLL_DIRECTORY_COOKIE cookies[4];
518     unsigned int i, j, k;
519     BOOL ret;
520     HMODULE mod;
521 
522     if (!pAddDllDirectory || !pSetDllDirectoryA) return;
523 
524     GetTempPathA( sizeof(path), path );
525     GetTempFileNameA( path, "tmp", 0, buf );
526     DeleteFileA( buf );
527     ret = CreateDirectoryA( buf, NULL );
528     ok( ret, "CreateDirectory failed err %u\n", GetLastError() );
529     p = buf + strlen( buf );
530     for (i = 1; i <= 6; i++)
531     {
532         sprintf( p, "\\%u", i );
533         ret = CreateDirectoryA( buf, NULL );
534         ok( ret, "CreateDirectory failed err %u\n", GetLastError() );
535         if (i >= 5) continue;  /* dirs 5 and 6 are left empty */
536         sprintf( p, "\\%u\\winetestdll.dll", i );
537         create_test_dll( buf );
538     }
539     SetLastError( 0xdeadbeef );
540     mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR );
541     ok( !mod, "LoadLibrary succeeded\n" );
542     ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %u\n", GetLastError() );
543 
544     SetLastError( 0xdeadbeef );
545     mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_USER_DIRS );
546     ok( !mod, "LoadLibrary succeeded\n" );
547     ok( GetLastError() == ERROR_MOD_NOT_FOUND || broken(GetLastError() == ERROR_NOT_ENOUGH_MEMORY),
548         "wrong error %u\n", GetLastError() );
549 
550     SetLastError( 0xdeadbeef );
551     mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_SYSTEM32 );
552     ok( !mod, "LoadLibrary succeeded\n" );
553     ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %u\n", GetLastError() );
554 
555     SetLastError( 0xdeadbeef );
556     mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR );
557     ok( !mod, "LoadLibrary succeeded\n" );
558     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
559 
560     SetLastError( 0xdeadbeef );
561     mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32 );
562     ok( !mod, "LoadLibrary succeeded\n" );
563     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
564 
565     SetLastError( 0xdeadbeef );
566     mod = LoadLibraryExA( "foo\\winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR );
567     ok( !mod, "LoadLibrary succeeded\n" );
568     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
569 
570     SetLastError( 0xdeadbeef );
571     mod = LoadLibraryExA( "\\windows\\winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR );
572     ok( !mod, "LoadLibrary succeeded\n" );
573     ok( GetLastError() == ERROR_MOD_NOT_FOUND, "wrong error %u\n", GetLastError() );
574 
575     for (j = 0; j < sizeof(tests) / sizeof(tests[0]); j++)
576     {
577         for (k = 0; tests[j].add_dirs[k]; k++)
578         {
579             sprintf( p, "\\%u", tests[j].add_dirs[k] );
580             MultiByteToWideChar( CP_ACP, 0, buf, -1, bufW, MAX_PATH );
581             cookies[k] = pAddDllDirectory( bufW );
582             ok( cookies[k] != NULL, "failed to add %s\n", buf );
583         }
584         if (tests[j].dll_dir)
585         {
586             sprintf( p, "\\%u", tests[j].dll_dir );
587             pSetDllDirectoryA( buf );
588         }
589         else pSetDllDirectoryA( NULL );
590 
591         SetLastError( 0xdeadbeef );
592         mod = LoadLibraryExA( "winetestdll.dll", 0, LOAD_LIBRARY_SEARCH_USER_DIRS );
593         if (tests[j].expect)
594         {
595             ok( mod != NULL, "%u: LoadLibrary failed err %u\n", j, GetLastError() );
596             GetModuleFileNameA( mod, path, MAX_PATH );
597             sprintf( p, "\\%u\\winetestdll.dll", tests[j].expect );
598             ok( !lstrcmpiA( path, buf ), "%u: wrong module %s expected %s\n", j, path, buf );
599         }
600         else
601         {
602             ok( !mod, "%u: LoadLibrary succeeded\n", j );
603             ok( GetLastError() == ERROR_MOD_NOT_FOUND || broken(GetLastError() == ERROR_NOT_ENOUGH_MEMORY),
604                 "%u: wrong error %u\n", j, GetLastError() );
605         }
606         FreeLibrary( mod );
607 
608         for (k = 0; tests[j].add_dirs[k]; k++) pRemoveDllDirectory( cookies[k] );
609     }
610 
611     for (i = 1; i <= 6; i++)
612     {
613         sprintf( p, "\\%u\\winetestdll.dll", i );
614         DeleteFileA( buf );
615         sprintf( p, "\\%u", i );
616         RemoveDirectoryA( buf );
617     }
618     *p = 0;
619     RemoveDirectoryA( buf );
620 }
621 
622 static void testGetDllDirectory(void)
623 {
624     CHAR bufferA[MAX_PATH];
625     WCHAR bufferW[MAX_PATH];
626     DWORD length, ret;
627     int i;
628     static const char *dll_directories[] =
629     {
630         "",
631         "C:\\Some\\Path",
632         "C:\\Some\\Path\\",
633         "Q:\\A\\Long\\Path with spaces that\\probably\\doesn't exist!",
634     };
635     const int test_count = sizeof(dll_directories) / sizeof(dll_directories[0]);
636 
637     if (!pGetDllDirectoryA || !pGetDllDirectoryW)
638     {
639         win_skip("GetDllDirectory not available\n");
640         return;
641     }
642     if (!pSetDllDirectoryA)
643     {
644         win_skip("SetDllDirectoryA not available\n");
645         return;
646     }
647 
648     for (i = 0; i < test_count; i++)
649     {
650         length = strlen(dll_directories[i]);
651         if (!pSetDllDirectoryA(dll_directories[i]))
652         {
653             skip("i=%d, SetDllDirectoryA failed\n", i);
654             continue;
655         }
656 
657         /* no buffer, determine length */
658         ret = pGetDllDirectoryA(0, NULL);
659         ok(ret == length + 1, "Expected %u, got %u\n", length + 1, ret);
660 
661         ret = pGetDllDirectoryW(0, NULL);
662         ok(ret == length + 1, "Expected %u, got %u\n", length + 1, ret);
663 
664         /* buffer of exactly the right size */
665         bufferA[length] = 'A';
666         bufferA[length + 1] = 'A';
667         ret = pGetDllDirectoryA(length + 1, bufferA);
668         ok(ret == length || broken(ret + 1 == length) /* win8 */,
669            "i=%d, Expected %u(+1), got %u\n", i, length, ret);
670         ok(bufferA[length + 1] == 'A', "i=%d, Buffer overflow\n", i);
671         ok(strcmp(bufferA, dll_directories[i]) == 0, "i=%d, Wrong path returned: '%s'\n", i, bufferA);
672 
673         bufferW[length] = 'A';
674         bufferW[length + 1] = 'A';
675         ret = pGetDllDirectoryW(length + 1, bufferW);
676         ok(ret == length, "i=%d, Expected %u, got %u\n", i, length, ret);
677         ok(bufferW[length + 1] == 'A', "i=%d, Buffer overflow\n", i);
678         ok(cmpStrAW(dll_directories[i], bufferW, length, length),
679            "i=%d, Wrong path returned: %s\n", i, wine_dbgstr_w(bufferW));
680 
681         /* Zero size buffer. The buffer may or may not be terminated depending
682          * on the Windows version and whether the A or W API is called. */
683         bufferA[0] = 'A';
684         ret = pGetDllDirectoryA(0, bufferA);
685         ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
686 
687         bufferW[0] = 'A';
688         ret = pGetDllDirectoryW(0, bufferW);
689         ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
690         ok(bufferW[0] == 0 || /* XP, 2003 */
691            broken(bufferW[0] == 'A'), "i=%d, Buffer overflow\n", i);
692 
693         /* buffer just one too short */
694         bufferA[0] = 'A';
695         ret = pGetDllDirectoryA(length, bufferA);
696         ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
697         if (length != 0)
698             ok(bufferA[0] == 0, "i=%d, Buffer not null terminated\n", i);
699 
700         bufferW[0] = 'A';
701         ret = pGetDllDirectoryW(length, bufferW);
702         ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
703         ok(bufferW[0] == 0 || /* XP, 2003 */
704            broken(bufferW[0] == 'A'), "i=%d, Buffer overflow\n", i);
705 
706         if (0)
707         {
708             /* crashes on win8 */
709             /* no buffer, but too short length */
710             ret = pGetDllDirectoryA(length, NULL);
711             ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
712 
713             ret = pGetDllDirectoryW(length, NULL);
714             ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
715         }
716     }
717 
718     /* unset whatever we did so following tests won't be affected */
719     pSetDllDirectoryA(NULL);
720 }
721 
722 static void init_pointers(void)
723 {
724     HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
725 
726 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hKernel32, #f))
727     MAKEFUNC(GetDllDirectoryA);
728     MAKEFUNC(GetDllDirectoryW);
729     MAKEFUNC(SetDllDirectoryA);
730     MAKEFUNC(AddDllDirectory);
731     MAKEFUNC(RemoveDllDirectory);
732     MAKEFUNC(SetDefaultDllDirectories);
733     MAKEFUNC(GetModuleHandleExA);
734     MAKEFUNC(GetModuleHandleExW);
735     MAKEFUNC(K32GetModuleInformation);
736 #undef MAKEFUNC
737 
738     /* not all Windows versions export this in kernel32 */
739     if (!pK32GetModuleInformation)
740     {
741         HMODULE hPsapi = LoadLibraryA("psapi.dll");
742         if (hPsapi)
743         {
744             pK32GetModuleInformation = (void *)GetProcAddress(hPsapi, "GetModuleInformation");
745             if (!pK32GetModuleInformation) FreeLibrary(hPsapi);
746         }
747     }
748 
749 }
750 
751 static void testGetModuleHandleEx(void)
752 {
753     static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2',0};
754     static const WCHAR nosuchmodW[] = {'n','o','s','u','c','h','m','o','d',0};
755     BOOL ret;
756     DWORD error;
757     HMODULE mod, mod_kernel32;
758 
759     if (!pGetModuleHandleExA || !pGetModuleHandleExW)
760     {
761         win_skip( "GetModuleHandleEx not available\n" );
762         return;
763     }
764 
765     SetLastError( 0xdeadbeef );
766     ret = pGetModuleHandleExA( 0, NULL, NULL );
767     error = GetLastError();
768     ok( !ret, "unexpected success\n" );
769     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
770 
771     SetLastError( 0xdeadbeef );
772     ret = pGetModuleHandleExA( 0, "kernel32", NULL );
773     error = GetLastError();
774     ok( !ret, "unexpected success\n" );
775     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
776 
777     SetLastError( 0xdeadbeef );
778     mod = (HMODULE)0xdeadbeef;
779     ret = pGetModuleHandleExA( 0, "kernel32", &mod );
780     ok( ret, "unexpected failure %u\n", GetLastError() );
781     ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod );
782     FreeLibrary( mod );
783 
784     SetLastError( 0xdeadbeef );
785     mod = (HMODULE)0xdeadbeef;
786     ret = pGetModuleHandleExA( 0, "nosuchmod", &mod );
787     error = GetLastError();
788     ok( !ret, "unexpected success\n" );
789     ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
790     ok( mod == NULL, "got %p\n", mod );
791 
792     SetLastError( 0xdeadbeef );
793     ret = pGetModuleHandleExW( 0, NULL, NULL );
794     error = GetLastError();
795     ok( !ret, "unexpected success\n" );
796     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
797 
798     SetLastError( 0xdeadbeef );
799     ret = pGetModuleHandleExW( 0, kernel32W, NULL );
800     error = GetLastError();
801     ok( !ret, "unexpected success\n" );
802     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
803 
804     SetLastError( 0xdeadbeef );
805     mod = (HMODULE)0xdeadbeef;
806     ret = pGetModuleHandleExW( 0, kernel32W, &mod );
807     ok( ret, "unexpected failure %u\n", GetLastError() );
808     ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod );
809     FreeLibrary( mod );
810 
811     SetLastError( 0xdeadbeef );
812     mod = (HMODULE)0xdeadbeef;
813     ret = pGetModuleHandleExW( 0, nosuchmodW, &mod );
814     error = GetLastError();
815     ok( !ret, "unexpected success\n" );
816     ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
817     ok( mod == NULL, "got %p\n", mod );
818 
819     SetLastError( 0xdeadbeef );
820     ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL );
821     error = GetLastError();
822     ok( !ret, "unexpected success\n" );
823     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
824 
825     SetLastError( 0xdeadbeef );
826     ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", NULL );
827     error = GetLastError();
828     ok( !ret, "unexpected success\n" );
829     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
830 
831     SetLastError( 0xdeadbeef );
832     mod = (HMODULE)0xdeadbeef;
833     ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", &mod );
834     ok( ret, "unexpected failure %u\n", GetLastError() );
835     ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod );
836 
837     SetLastError( 0xdeadbeef );
838     mod = (HMODULE)0xdeadbeef;
839     ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "nosuchmod", &mod );
840     error = GetLastError();
841     ok( !ret, "unexpected success\n" );
842     ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
843     ok( mod == NULL, "got %p\n", mod );
844 
845     SetLastError( 0xdeadbeef );
846     ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL );
847     error = GetLastError();
848     ok( !ret, "unexpected success\n" );
849     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
850 
851     SetLastError( 0xdeadbeef );
852     ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, NULL );
853     error = GetLastError();
854     ok( !ret, "unexpected success\n" );
855     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
856 
857     SetLastError( 0xdeadbeef );
858     mod = (HMODULE)0xdeadbeef;
859     ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, &mod );
860     ok( ret, "unexpected failure %u\n", GetLastError() );
861     ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod );
862 
863     SetLastError( 0xdeadbeef );
864     mod = (HMODULE)0xdeadbeef;
865     ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, nosuchmodW, &mod );
866     error = GetLastError();
867     ok( !ret, "unexpected success\n" );
868     ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
869     ok( mod == NULL, "got %p\n", mod );
870 
871     mod_kernel32 = LoadLibraryA( "kernel32" );
872 
873     SetLastError( 0xdeadbeef );
874     ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL );
875     error = GetLastError();
876     ok( !ret, "unexpected success\n" );
877     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
878 
879     SetLastError( 0xdeadbeef );
880     ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, NULL );
881     error = GetLastError();
882     ok( !ret, "unexpected success\n" );
883     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
884 
885     SetLastError( 0xdeadbeef );
886     mod = (HMODULE)0xdeadbeef;
887     ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, &mod );
888     ok( ret, "unexpected failure %u\n", GetLastError() );
889     ok( mod == mod_kernel32, "got %p\n", mod );
890     FreeLibrary( mod );
891 
892     SetLastError( 0xdeadbeef );
893     mod = (HMODULE)0xdeadbeef;
894     ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)0xbeefdead, &mod );
895     error = GetLastError();
896     ok( !ret, "unexpected success\n" );
897     ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
898     ok( mod == NULL, "got %p\n", mod );
899 
900     SetLastError( 0xdeadbeef );
901     ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL );
902     error = GetLastError();
903     ok( !ret, "unexpected success\n" );
904     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
905 
906     SetLastError( 0xdeadbeef );
907     ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, NULL );
908     error = GetLastError();
909     ok( !ret, "unexpected success\n" );
910     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
911 
912     SetLastError( 0xdeadbeef );
913     mod = (HMODULE)0xdeadbeef;
914     ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, &mod );
915     ok( ret, "unexpected failure %u\n", GetLastError() );
916     ok( mod == mod_kernel32, "got %p\n", mod );
917     FreeLibrary( mod );
918 
919     SetLastError( 0xdeadbeef );
920     mod = (HMODULE)0xdeadbeef;
921     ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)0xbeefdead, &mod );
922     error = GetLastError();
923     ok( !ret, "unexpected success\n" );
924     ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
925     ok( mod == NULL, "got %p\n", mod );
926 
927     FreeLibrary( mod_kernel32 );
928 }
929 
930 static void testK32GetModuleInformation(void)
931 {
932     MODULEINFO info;
933     HMODULE mod;
934     BOOL ret;
935 
936     if (!pK32GetModuleInformation)
937     {
938         win_skip("K32GetModuleInformation not available\n");
939         return;
940     }
941 
942     mod = GetModuleHandleA(NULL);
943     memset(&info, 0xAA, sizeof(info));
944     ret = pK32GetModuleInformation(GetCurrentProcess(), mod, &info, sizeof(info));
945     ok(ret, "K32GetModuleInformation failed for main module\n");
946     ok(info.lpBaseOfDll == mod, "Wrong info.lpBaseOfDll = %p, expected %p\n", info.lpBaseOfDll, mod);
947     ok(info.EntryPoint != NULL, "Expected nonzero entrypoint\n");
948 
949     mod = GetModuleHandleA("kernel32.dll");
950     memset(&info, 0xAA, sizeof(info));
951     ret = pK32GetModuleInformation(GetCurrentProcess(), mod, &info, sizeof(info));
952     ok(ret, "K32GetModuleInformation failed for kernel32 module\n");
953     ok(info.lpBaseOfDll == mod, "Wrong info.lpBaseOfDll = %p, expected %p\n", info.lpBaseOfDll, mod);
954     ok(info.EntryPoint != NULL, "Expected nonzero entrypoint\n");
955 }
956 
957 static void test_AddDllDirectory(void)
958 {
959     static const WCHAR tmpW[] = {'t','m','p',0};
960     static const WCHAR dotW[] = {'.','\\','.',0};
961     static const WCHAR rootW[] = {'\\',0};
962     WCHAR path[MAX_PATH], buf[MAX_PATH];
963     DLL_DIRECTORY_COOKIE cookie;
964     BOOL ret;
965 
966     if (!pAddDllDirectory || !pRemoveDllDirectory)
967     {
968         win_skip( "AddDllDirectory not available\n" );
969         return;
970     }
971 
972     buf[0] = '\0';
973     GetTempPathW( sizeof(path)/sizeof(path[0]), path );
974     GetTempFileNameW( path, tmpW, 0, buf );
975     SetLastError( 0xdeadbeef );
976     cookie = pAddDllDirectory( buf );
977     ok( cookie != NULL, "AddDllDirectory failed err %u\n", GetLastError() );
978     SetLastError( 0xdeadbeef );
979     ret = pRemoveDllDirectory( cookie );
980     ok( ret, "RemoveDllDirectory failed err %u\n", GetLastError() );
981 
982     DeleteFileW( buf );
983     SetLastError( 0xdeadbeef );
984     cookie = pAddDllDirectory( buf );
985     ok( !cookie, "AddDllDirectory succeeded\n" );
986     ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError() );
987     cookie = pAddDllDirectory( dotW );
988     ok( !cookie, "AddDllDirectory succeeded\n" );
989     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
990     cookie = pAddDllDirectory( rootW );
991     ok( cookie != NULL, "AddDllDirectory failed err %u\n", GetLastError() );
992     SetLastError( 0xdeadbeef );
993     ret = pRemoveDllDirectory( cookie );
994     ok( ret, "RemoveDllDirectory failed err %u\n", GetLastError() );
995     GetWindowsDirectoryW( buf, MAX_PATH );
996     lstrcpyW( buf + 2, tmpW );
997     cookie = pAddDllDirectory( buf );
998     ok( !cookie, "AddDllDirectory succeeded\n" );
999     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1000 }
1001 
1002 static void test_SetDefaultDllDirectories(void)
1003 {
1004     HMODULE mod;
1005     BOOL ret;
1006 
1007     if (!pSetDefaultDllDirectories)
1008     {
1009         win_skip( "SetDefaultDllDirectories not available\n" );
1010         return;
1011     }
1012 
1013     mod = LoadLibraryA( "authz.dll" );
1014     ok( mod != NULL, "loading authz failed\n" );
1015     FreeLibrary( mod );
1016     ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_USER_DIRS );
1017     ok( ret, "SetDefaultDllDirectories failed err %u\n", GetLastError() );
1018     mod = LoadLibraryA( "authz.dll" );
1019     todo_wine ok( !mod, "loading authz succeeded\n" );
1020     FreeLibrary( mod );
1021     ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_SYSTEM32 );
1022     ok( ret, "SetDefaultDllDirectories failed err %u\n", GetLastError() );
1023     mod = LoadLibraryA( "authz.dll" );
1024     ok( mod != NULL, "loading authz failed\n" );
1025     FreeLibrary( mod );
1026     mod = LoadLibraryExA( "authz.dll", 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR );
1027     todo_wine ok( !mod, "loading authz succeeded\n" );
1028     FreeLibrary( mod );
1029     ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_APPLICATION_DIR );
1030     ok( ret, "SetDefaultDllDirectories failed err %u\n", GetLastError() );
1031     mod = LoadLibraryA( "authz.dll" );
1032     todo_wine ok( !mod, "loading authz succeeded\n" );
1033     FreeLibrary( mod );
1034     ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_DEFAULT_DIRS );
1035     ok( ret, "SetDefaultDllDirectories failed err %u\n", GetLastError() );
1036     mod = LoadLibraryA( "authz.dll" );
1037     ok( mod != NULL, "loading authz failed\n" );
1038     FreeLibrary( mod );
1039 
1040     SetLastError( 0xdeadbeef );
1041     ret = pSetDefaultDllDirectories( 0 );
1042     ok( !ret, "SetDefaultDllDirectories succeeded\n" );
1043     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1044 
1045     SetLastError( 0xdeadbeef );
1046     ret = pSetDefaultDllDirectories( 3 );
1047     ok( !ret, "SetDefaultDllDirectories succeeded\n" );
1048     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1049 
1050     SetLastError( 0xdeadbeef );
1051     ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_APPLICATION_DIR | 0x8000 );
1052     ok( !ret, "SetDefaultDllDirectories succeeded\n" );
1053     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1054 
1055     SetLastError( 0xdeadbeef );
1056     ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR );
1057     ok( !ret || broken(ret) /* win7 */, "SetDefaultDllDirectories succeeded\n" );
1058     if (!ret) ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1059 
1060     SetLastError( 0xdeadbeef );
1061     ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_USER_DIRS );
1062     ok( !ret || broken(ret) /* win7 */, "SetDefaultDllDirectories succeeded\n" );
1063     if (!ret) ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1064 
1065     /* restore some sane defaults */
1066     pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_DEFAULT_DIRS );
1067 }
1068 
1069 START_TEST(module)
1070 {
1071     WCHAR filenameW[MAX_PATH];
1072 
1073     /* Test if we can use GetModuleFileNameW */
1074 
1075     SetLastError(0xdeadbeef);
1076     GetModuleFileNameW(NULL, filenameW, MAX_PATH);
1077     if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1078     {
1079         win_skip("GetModuleFileNameW not existing on this platform, skipping W-calls\n");
1080         is_unicode_enabled = FALSE;
1081     }
1082 
1083     init_pointers();
1084 
1085     testGetModuleFileName(NULL);
1086     testGetModuleFileName("kernel32.dll");
1087     testGetModuleFileName_Wrong();
1088 
1089     testGetDllDirectory();
1090 
1091     testLoadLibraryA();
1092     testNestedLoadLibraryA();
1093     testLoadLibraryA_Wrong();
1094     testGetProcAddress_Wrong();
1095     testLoadLibraryEx();
1096     test_LoadLibraryEx_search_flags();
1097     testGetModuleHandleEx();
1098     testK32GetModuleInformation();
1099     test_AddDllDirectory();
1100     test_SetDefaultDllDirectories();
1101 }
1102