mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / kernel32 / tests / path.c
blobf49af6d5bfe3133c64fa09ba68a6a08702f7c113
1 /*
2 * Unit test suite for various Path and Directory Functions
4 * Copyright 2002 Geoffrey Hausheer
5 * Copyright 2006 Detlef Riekenberg
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <assert.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winternl.h"
30 #include "winuser.h"
31 #include "winerror.h"
32 #include "winnls.h"
33 #include "wine/test.h"
35 #define HAS_TRAIL_SLASH_A(string) (string[lstrlenA(string)-1]=='\\')
37 #define LONGFILE "Long File test.path"
38 #define SHORTFILE "pathtest.pth"
39 #define SHORTDIR "shortdir"
40 #define LONGDIR "Long Directory"
41 #define NONFILE_SHORT "noexist.pth"
42 #define NONFILE_LONG "NonExistent File"
43 #define NONDIR_SHORT "notadir"
44 #define NONDIR_LONG "NonExistent Directory"
46 #define NOT_A_VALID_DRIVE '@'
48 #ifdef __i386__
49 #define ARCH "x86"
50 #elif defined __x86_64__
51 #define ARCH "amd64"
52 #elif defined __arm__
53 #define ARCH "arm"
54 #elif defined __aarch64__
55 #define ARCH "arm64"
56 #else
57 #define ARCH "none"
58 #endif
60 /* the following characters don't work well with GetFullPathNameA
61 in Win98. I don't know if this is a FAT thing, or if it is an OS thing
62 but I don't test these characters now.
63 NOTE: Win2k allows GetFullPathNameA to work with them though
64 |<>"
66 static const CHAR funny_chars[]="!@#$%^&*()=+{}[],?'`";
67 static const CHAR is_char_ok[] ="11111110111111111011";
69 /* Present in Win2003+ */
70 static BOOL (WINAPI *pNeedCurrentDirectoryForExePathA)(LPCSTR);
71 static BOOL (WINAPI *pNeedCurrentDirectoryForExePathW)(LPCWSTR);
73 static DLL_DIRECTORY_COOKIE (WINAPI *pAddDllDirectory)(const WCHAR*);
74 static BOOL (WINAPI *pRemoveDllDirectory)(DLL_DIRECTORY_COOKIE);
75 static BOOL (WINAPI *pSetSearchPathMode)(DWORD);
76 static BOOL (WINAPI *pSetDllDirectoryW)(LPCWSTR);
77 static BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD);
78 static NTSTATUS (WINAPI *pRtlGetExePath)(LPCWSTR,LPWSTR*);
79 static NTSTATUS (WINAPI *pRtlGetSearchPath)(LPWSTR*);
80 static void (WINAPI *pRtlReleasePath)(LPWSTR);
81 static NTSTATUS (WINAPI *pLdrGetDllPath)(LPCWSTR,ULONG,LPWSTR*,LPWSTR*);
83 static BOOL (WINAPI *pCheckNameLegalDOS8Dot3W)(const WCHAR *, char *, DWORD, BOOL *, BOOL *);
84 static BOOL (WINAPI *pCheckNameLegalDOS8Dot3A)(const char *, char *, DWORD, BOOL *, BOOL *);
86 /* a structure to deal with wine todos somewhat cleanly */
87 typedef struct {
88 DWORD shortlen;
89 DWORD shorterror;
90 DWORD s2llen;
91 DWORD s2lerror;
92 DWORD longlen;
93 DWORD longerror;
94 } SLpassfail;
96 /* function that tests GetFullPathNameA, GetShortPathNameA,GetLongPathNameA */
97 /* NOTE: the passfail structure is used to allow customizable todo checking
98 for wine. It is not very pretty, but it sure beats duplicating this
99 function lots of times
101 static void test_ValidPathA(const CHAR *curdir, const CHAR *subdir, const CHAR *filename,
102 CHAR *shortstr, SLpassfail *passfail, const CHAR *errstr)
104 CHAR tmpstr[MAX_PATH],
105 fullpath[MAX_PATH + 1], /*full path to the file (not short/long) */
106 subpath[MAX_PATH], /*relative path to the file */
107 fullpathshort[2 * MAX_PATH], /*absolute path to the file (short format) */
108 fullpathlong[2 * MAX_PATH], /*absolute path to the file (long format) */
109 curdirshort[MAX_PATH], /*absolute path to the current dir (short) */
110 curdirlong[MAX_PATH]; /*absolute path to the current dir (long) */
111 LPSTR strptr; /*ptr to the filename portion of the path */
112 DWORD len;
113 /* if passfail is NULL, we can perform all checks within this function,
114 otherwise, we will return the relevant data in the passfail struct, so
115 we must initialize it first
117 if(passfail!=NULL) {
118 passfail->shortlen=-1;passfail->s2llen=-1;passfail->longlen=-1;
119 passfail->shorterror=0;passfail->s2lerror=0;passfail->longerror=0;
122 ok((len = GetLongPathNameA(curdir,curdirlong,MAX_PATH)), "%s: GetLongPathNameA failed\n", errstr);
123 /*GetLongPathNameA can return a trailing '\\' but shouldn't do so here */
124 ok(!HAS_TRAIL_SLASH_A(curdirlong), "%s: GetLongPathNameA should not have a trailing \\\n", errstr);
126 ok((len=GetShortPathNameA(curdir,curdirshort,MAX_PATH)),
127 "%s: GetShortPathNameA failed\n",errstr);
128 /*GetShortPathNameA can return a trailing '\\' but shouldn't do so here */
129 ok(! HAS_TRAIL_SLASH_A(curdirshort),
130 "%s: GetShortPathNameA should not have a trailing \\\n",errstr);
131 /* build relative and absolute paths from inputs */
132 if(*subdir) {
133 sprintf(subpath,"%s\\%s",subdir,filename);
134 } else {
135 lstrcpyA(subpath,filename);
137 sprintf(fullpath,"%s\\%s",curdir,subpath);
138 sprintf(fullpathshort,"%s\\%s",curdirshort,subpath);
139 sprintf(fullpathlong,"%s\\%s",curdirlong,subpath);
140 /* Test GetFullPathNameA functionality */
141 len=GetFullPathNameA(subpath,MAX_PATH,tmpstr,&strptr);
142 ok(len, "GetFullPathNameA failed for: '%s'\n",subpath);
143 if(HAS_TRAIL_SLASH_A(subpath)) {
144 ok(strptr==NULL,
145 "%s: GetFullPathNameA should not return a filename ptr\n",errstr);
146 ok(lstrcmpiA(fullpath,tmpstr)==0,
147 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
148 errstr,tmpstr,fullpath);
149 } else {
150 ok(lstrcmpiA(strptr,filename)==0,
151 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
152 errstr,strptr,filename);
153 ok(lstrcmpiA(fullpath,tmpstr)==0,
154 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
155 errstr,tmpstr,fullpath);
157 /* Test GetShortPathNameA functionality */
158 SetLastError(0);
159 len=GetShortPathNameA(fullpathshort,shortstr,MAX_PATH);
160 if(passfail==NULL) {
161 ok(len, "%s: GetShortPathNameA failed\n",errstr);
162 } else {
163 passfail->shortlen=len;
164 passfail->shorterror=GetLastError();
167 /* Test GetLongPathNameA functionality, both conversion from GetFullPathNameA and from GetShortPathNameA */
168 if (len)
170 SetLastError(0);
171 len = GetLongPathNameA(shortstr, tmpstr, MAX_PATH);
172 if (!passfail)
174 ok(len, "%s: GetLongPathNameA failed during Short->Long conversion\n", errstr);
175 ok(!lstrcmpiA(fullpathlong, tmpstr), "%s: GetLongPathNameA returned '%s' instead of '%s'\n", errstr,
176 tmpstr, fullpathlong);
178 else
180 passfail->s2llen = len;
181 passfail->s2lerror = GetLastError();
185 SetLastError(0);
186 len = GetLongPathNameA(fullpath, tmpstr, MAX_PATH);
187 if (!passfail)
189 ok(len, "%s: GetLongPathNameA failed\n",errstr);
190 ok(!lstrcmpiA(fullpathlong, tmpstr), "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
191 errstr, tmpstr, fullpathlong);
193 else
195 passfail->longlen = len;
196 passfail->longerror = GetLastError();
200 /* split path into leading directory, and 8.3 filename */
201 static void test_SplitShortPathA(CHAR *path,CHAR *dir,CHAR *eight,CHAR *three) {
202 BOOL done = FALSE, error = FALSE;
203 int ext,fil;
204 int len,i;
205 len=lstrlenA(path);
206 ext=len;
207 fil=len;
208 /* walk backwards over path looking for '.' or '\\' separators */
209 for(i=len-1;(i>=0) && (!done);i--) {
210 if(path[i]=='.')
211 if(ext!=len) error=TRUE; else ext=i;
212 else if(path[i]=='\\') {
213 if(i==len-1) {
214 error=TRUE;
215 } else {
216 fil=i;
217 done=TRUE;
221 /* Check that we didn't find a trailing '\\' or multiple '.' */
222 ok(!error,"Illegal file found in 8.3 path '%s'\n",path);
223 /* Separate dir, root, and extension */
224 if(ext!=len) lstrcpyA(three,path+ext+1); else lstrcpyA(three,"");
225 if(fil!=len) {
226 lstrcpynA(eight,path+fil+1,ext-fil);
227 lstrcpynA(dir,path,fil+1);
228 } else {
229 lstrcpynA(eight,path,ext+1);
230 lstrcpyA(dir,"");
232 /* Validate that root and extension really are 8.3 */
233 ok(lstrlenA(eight)<=8 && lstrlenA(three)<=3,
234 "GetShortPathNAmeA did not return an 8.3 path\n");
237 /* Check that GetShortPathNameA returns a valid 8.3 path */
238 static void test_LongtoShortA(CHAR *teststr,const CHAR *goodstr,
239 const CHAR *ext,const CHAR *errstr) {
240 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
242 test_SplitShortPathA(teststr,dir,eight,three);
243 ok(lstrcmpiA(dir,goodstr)==0,
244 "GetShortPathNameA returned '%s' instead of '%s'\n",dir,goodstr);
245 ok(lstrcmpiA(three,ext)==0,
246 "GetShortPathNameA returned '%s' with incorrect extension\n",three);
249 /* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
250 characters in the filename.
251 'valid' indicates whether this would be an allowed filename
252 'todo' indicates that wine doesn't get this right yet.
253 NOTE: We always call this routine with a nonexistent filename, so
254 Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
255 should.
257 static void test_FunnyChars(CHAR *curdir,CHAR *curdir_short,CHAR *filename, INT valid,CHAR *errstr)
259 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
260 SLpassfail passfail;
262 test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
263 if(valid) {
264 sprintf(tmpstr1,"%s\\%s",curdir_short,filename);
265 ok((passfail.shortlen==0 &&
266 (passfail.shorterror==ERROR_FILE_NOT_FOUND || passfail.shorterror==ERROR_PATH_NOT_FOUND || !passfail.shorterror)) ||
267 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
268 "%s: GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
269 errstr,passfail.shortlen,passfail.shorterror,tmpstr);
270 } else {
271 ok(passfail.shortlen==0 &&
272 (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),
273 "%s: GetShortPathA should have failed len=%d, error=%d\n",
274 errstr,passfail.shortlen,passfail.shorterror);
277 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
278 if (valid)
280 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "%s: GetLongPathA unexpected error %d.\n", errstr,
281 passfail.longerror);
283 else
285 ok(passfail.longerror == ERROR_INVALID_NAME || passfail.longerror == ERROR_FILE_NOT_FOUND,
286 "%s: GetLongPathA unexpected error %d.\n", errstr, passfail.longerror);
290 /* Routine to test that SetCurrentDirectory behaves as expected. */
291 static void test_setdir(CHAR *olddir,CHAR *newdir,
292 CHAR *cmprstr, INT pass, const CHAR *errstr)
294 CHAR tmppath[MAX_PATH], *dirptr;
295 DWORD val,len,chklen;
297 val=SetCurrentDirectoryA(newdir);
298 len=GetCurrentDirectoryA(MAX_PATH,tmppath);
299 /* if 'pass' then the SetDirectoryA was supposed to pass */
300 if(pass) {
301 dirptr=(cmprstr==NULL) ? newdir : cmprstr;
302 chklen=lstrlenA(dirptr);
303 ok(val,"%s: SetCurrentDirectoryA failed\n",errstr);
304 ok(len==chklen,
305 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
306 errstr);
307 ok(lstrcmpiA(dirptr,tmppath)==0,
308 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
309 errstr);
310 ok(SetCurrentDirectoryA(olddir),
311 "%s: Couldn't set directory to its original value\n",errstr);
312 } else {
313 /* else test that it fails correctly */
314 chklen=lstrlenA(olddir);
315 ok(val==0,
316 "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr);
317 ok(len==chklen,
318 "%s: SetCurrentDirectory changed the directory, though it failed\n",
319 errstr);
320 ok(lstrcmpiA(olddir,tmppath)==0,
321 "%s: SetCurrentDirectory changed the directory, though it failed\n",
322 errstr);
325 static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
327 CHAR tmppath[MAX_PATH], /*path to TEMP */
328 tmpstr[MAX_PATH],
329 tmpstr1[MAX_PATH],
330 invalid_dir[MAX_PATH + 29];
332 DWORD len,len1,drives;
333 INT id;
334 HANDLE hndl;
335 BOOL bRes;
336 UINT unique;
338 *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
340 /* Get the current drive letter */
341 if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
342 *curDrive = tmpstr[0];
343 else
344 trace( "Unable to discover current drive, some tests will not be conducted.\n");
346 /* Test GetTempPathA */
347 len=GetTempPathA(MAX_PATH,tmppath);
348 ok(len!=0 && len < MAX_PATH,"GetTempPathA failed\n");
349 ok(HAS_TRAIL_SLASH_A(tmppath),
350 "GetTempPathA returned a path that did not end in '\\'\n");
351 lstrcpyA(tmpstr,"aaaaaaaa");
352 len1=GetTempPathA(len,tmpstr);
353 ok(len1==len+1 || broken(len1 == len), /* WinME */
354 "GetTempPathA should return string length %d instead of %d\n",len+1,len1);
356 /* Test GetTmpFileNameA */
357 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
358 sprintf(tmpstr,"pat%.4x.tmp",id & 0xffff);
359 sprintf(tmpstr1,"pat%x.tmp",id & 0xffff);
360 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
361 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
362 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
363 newdir,tmpstr,tmpstr1,id);
364 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
366 id=GetTempFileNameA(tmppath,NULL,0,newdir);
367 /* Windows 95, 98 return 0==id, while Windows 2000, XP return 0!=id */
368 if (id)
370 sprintf(tmpstr,"%.4x.tmp",id & 0xffff);
371 sprintf(tmpstr1,"%x.tmp",id & 0xffff);
372 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
373 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
374 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
375 newdir,tmpstr,tmpstr1,id);
376 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
379 for(unique=0;unique<3;unique++) {
380 /* Nonexistent path */
381 sprintf(invalid_dir, "%s\\%s",tmppath,"non_existent_dir_1jwj3y32nb3");
382 SetLastError(0xdeadbeef);
383 ok(!GetTempFileNameA(invalid_dir,"tfn",unique,newdir),"GetTempFileNameA should have failed\n");
384 ok(GetLastError()==ERROR_DIRECTORY || broken(GetLastError()==ERROR_PATH_NOT_FOUND)/*win98*/,
385 "got %d, expected ERROR_DIRECTORY\n", GetLastError());
387 /* Check return value for unique !=0 */
388 if(unique) {
389 ok((GetTempFileNameA(tmppath,"tfn",unique,newdir) == unique),"GetTempFileNameA unexpectedly failed\n");
390 /* if unique != 0, the actual temp files are not created: */
391 ok(!DeleteFileA(newdir) && GetLastError() == ERROR_FILE_NOT_FOUND,"Deleted a file that shouldn't exist!\n");
395 /* Find first valid drive letter that is neither newdir[0] nor curDrive */
396 drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
397 if( *curDrive != NOT_A_VALID_DRIVE)
398 drives &= ~(1<<(*curDrive-'A'));
399 if( drives)
400 for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
401 else
402 trace( "Could not find alternative drive, some tests will not be conducted.\n");
404 /* Do some CreateDirectoryA tests */
405 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
406 really understand how they work.
407 More formal tests should be done along with CreateFile tests
409 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
410 ok(CreateDirectoryA(newdir,NULL)==0,
411 "CreateDirectoryA succeeded even though a file of the same name exists\n");
412 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
413 ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
414 /* Create some files to test other functions. Note, we will test CreateFileA
415 at some later point
417 sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
418 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
419 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
420 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
421 sprintf(tmpstr,"%c:", *curDrive);
422 bRes = CreateDirectoryA(tmpstr,NULL);
423 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
424 GetLastError() == ERROR_ALREADY_EXISTS),
425 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
426 sprintf(tmpstr,"%c:\\", *curDrive);
427 bRes = CreateDirectoryA(tmpstr,NULL);
428 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
429 GetLastError() == ERROR_ALREADY_EXISTS),
430 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
431 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
432 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
433 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
434 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
435 ok(CloseHandle(hndl),"CloseHandle failed\n");
436 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
437 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
438 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
439 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
440 ok(CloseHandle(hndl),"CloseHandle failed\n");
441 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
442 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
443 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
444 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
445 ok(CloseHandle(hndl),"CloseHandle failed\n");
446 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
447 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
448 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
449 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
450 ok(CloseHandle(hndl),"CloseHandle failed\n");
453 /* Test GetCurrentDirectory & SetCurrentDirectory */
454 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
456 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
457 char *buffer;
458 DWORD len,len1;
459 /* Save the original directory, so that we can return to it at the end
460 of the test
462 len=GetCurrentDirectoryA(MAX_PATH,origdir);
463 ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
464 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
465 buffer size is too small to hold the current directory
467 lstrcpyA(tmpstr,"aaaaaaa");
468 len1=GetCurrentDirectoryA(len,tmpstr);
469 ok(len1==len+1, "GetCurrentDirectoryA returned %d instead of %d\n",len1,len+1);
470 ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
471 "GetCurrentDirectoryA should not have modified the buffer\n");
473 buffer = HeapAlloc( GetProcessHeap(), 0, 2 * 65536 );
474 SetLastError( 0xdeadbeef );
475 strcpy( buffer, "foo" );
476 len = GetCurrentDirectoryA( 32767, buffer );
477 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
478 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
479 SetLastError( 0xdeadbeef );
480 strcpy( buffer, "foo" );
481 len = GetCurrentDirectoryA( 32768, buffer );
482 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
483 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
484 SetLastError( 0xdeadbeef );
485 strcpy( buffer, "foo" );
486 len = GetCurrentDirectoryA( 65535, buffer );
487 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4, win2k, xp */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
488 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
489 SetLastError( 0xdeadbeef );
490 strcpy( buffer, "foo" );
491 len = GetCurrentDirectoryA( 65536, buffer );
492 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4 */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
493 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
494 SetLastError( 0xdeadbeef );
495 strcpy( buffer, "foo" );
496 len = GetCurrentDirectoryA( 2 * 65536, buffer );
497 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4 */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
498 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
499 HeapFree( GetProcessHeap(), 0, buffer );
501 /* Check for crash prevention on swapped args. Crashes all but Win9x.
503 if (0)
505 GetCurrentDirectoryA( 42, (LPSTR)(MAX_PATH + 42) );
508 /* SetCurrentDirectoryA shouldn't care whether the string has a
509 trailing '\\' or not
511 sprintf(tmpstr,"%s\\",newdir);
512 test_setdir(origdir,tmpstr,newdir,1,"check 1");
513 test_setdir(origdir,newdir,NULL,1,"check 2");
514 /* Set the directory to the working area. We just tested that this works,
515 so why check it again.
517 SetCurrentDirectoryA(newdir);
518 /* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
519 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
520 test_setdir(newdir,tmpstr,NULL,0,"check 3");
521 /* Check that SetCurrentDirectory fails for a nonexistent long directory */
522 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
523 test_setdir(newdir,tmpstr,NULL,0,"check 4");
524 /* Check that SetCurrentDirectory passes with a long directory */
525 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
526 test_setdir(newdir,tmpstr,NULL,1,"check 5");
527 /* Check that SetCurrentDirectory passes with a short relative directory */
528 sprintf(tmpstr,"%s",SHORTDIR);
529 sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
530 test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
531 /* starting with a '.' */
532 sprintf(tmpstr,".\\%s",SHORTDIR);
533 test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
534 /* Check that SetCurrentDirectory passes with a short relative directory */
535 sprintf(tmpstr,"%s",LONGDIR);
536 sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
537 test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
538 /* starting with a '.' */
539 sprintf(tmpstr,".\\%s",LONGDIR);
540 test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
541 /* change to root without a trailing backslash. The function call succeeds
542 but the directory is not changed.
544 sprintf(tmpstr, "%c:", newdir[0]);
545 test_setdir(newdir,tmpstr,newdir,1,"check 10");
546 /* works however with a trailing backslash */
547 sprintf(tmpstr, "%c:\\", newdir[0]);
548 test_setdir(newdir,tmpstr,NULL,1,"check 11");
551 /* Cleanup the mess we made while executing these tests */
552 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
554 CHAR tmpstr[MAX_PATH + 35];
555 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
556 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
557 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
558 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
559 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
560 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
561 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
562 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
563 sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
564 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
565 sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
566 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
567 ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
568 ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
571 /* test that short path name functions work regardless of case */
572 static void test_ShortPathCase(const char *tmpdir, const char *dirname,
573 const char *filename)
575 char buf[MAX_PATH], shortbuf[MAX_PATH];
576 HANDLE hndl;
577 size_t i;
579 assert(strlen(tmpdir) + strlen(dirname) + strlen(filename) + 2 < sizeof(buf));
580 sprintf(buf,"%s\\%s\\%s",tmpdir,dirname,filename);
581 GetShortPathNameA(buf,shortbuf,sizeof(shortbuf));
582 hndl = CreateFileA(shortbuf,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
583 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed (%d)\n",GetLastError());
584 CloseHandle(hndl);
585 /* Now for the real test */
586 for(i=0;i<strlen(shortbuf);i++)
587 if (i % 2)
588 shortbuf[i] = tolower(shortbuf[i]);
589 hndl = CreateFileA(shortbuf,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
590 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed (%d)\n",GetLastError());
591 CloseHandle(hndl);
594 /* This routine will test Get(Full|Short|Long)PathNameA */
595 static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
597 CHAR curdir_short[MAX_PATH],
598 longdir_short[MAX_PATH];
599 CHAR tmpstr[MAX_PATH + 15],tmpstr1[MAX_PATH + 22],tmpstr2[2 * MAX_PATH + 15];
600 LPSTR strptr; /*ptr to the filename portion of the path */
601 DWORD len;
602 INT i;
603 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
604 SLpassfail passfail;
605 DWORD rc1, rc2;
607 /* Get the short form of the current directory */
608 ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
609 "GetShortPathNameA failed\n");
610 ok(!HAS_TRAIL_SLASH_A(curdir_short),
611 "GetShortPathNameA should not have a trailing \\\n");
612 /* Get the short form of the absolute-path to LONGDIR */
613 sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
614 ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
615 "GetShortPathNameA failed\n");
616 ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
617 "GetShortPathNameA should not have a trailing \\\n");
619 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
620 rc1 = GetLongPathNameA(tmpstr, NULL, 0);
621 rc2 = GetLongPathNameA(curdir, NULL, 0);
622 ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
623 "GetLongPathNameA: wrong return code, %d instead of %d\n",
624 rc1, lstrlenA(tmpstr)+1);
626 sprintf(dir,"%c:",curDrive);
627 rc1= GetLongPathNameA(dir, tmpstr, sizeof(tmpstr));
628 ok(!strcmp(dir,tmpstr), "GetLongPathNameA: returned '%s' instead of '%s' (rc=%d)\n",
629 tmpstr, dir, rc1);
631 /* Check the cases where both file and directory exist first */
632 /* Start with a 8.3 directory, 8.3 filename */
633 test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
634 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
635 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
636 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
637 /* Now try a 8.3 directory, long file name */
638 test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
639 sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
640 test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
641 /* Next is a long directory, 8.3 file */
642 test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
643 sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
644 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
645 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
646 /*Lastly a long directory, long file */
647 test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
648 test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
650 /* Now check all of the invalid file w/ valid directory combinations */
651 /* Start with a 8.3 directory, 8.3 filename */
652 test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
653 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
654 ok((passfail.shortlen==0 &&
655 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
656 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
657 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
658 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
659 passfail.shortlen,passfail.shorterror,tmpstr);
661 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
662 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "Unexpected error %d.\n", passfail.longerror);
664 /* Now try a 8.3 directory, long file name */
665 test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
666 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
667 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
668 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
669 !passfail.shorterror,
670 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
671 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
672 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "Unexpected error %d.\n", passfail.longerror);
674 /* Next is a long directory, 8.3 file */
675 test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
676 sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
677 GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
678 strcat(tmpstr1,"\\" NONFILE_SHORT);
679 ok((passfail.shortlen==0 &&
680 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
681 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
682 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
683 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
684 passfail.shortlen,passfail.shorterror,tmpstr);
685 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
686 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "Unexpected error %d.\n", passfail.longerror);
688 /*Lastly a long directory, long file */
689 test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
690 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
691 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
692 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
693 !passfail.shorterror,
694 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
695 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
696 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "Unexpected error %d.\n", passfail.longerror);
698 /* Now try again with directories that don't exist */
699 /* 8.3 directory, 8.3 filename */
700 test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
701 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
702 ok((passfail.shortlen==0 &&
703 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
704 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
705 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
706 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
707 passfail.shortlen,passfail.shorterror,tmpstr);
708 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
709 ok(passfail.longerror == ERROR_PATH_NOT_FOUND || passfail.longerror == ERROR_FILE_NOT_FOUND,
710 "Unexpected error %d.\n", passfail.longerror);
712 /* Now try a 8.3 directory, long file name */
713 test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
714 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
715 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
716 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
717 !passfail.shorterror,
718 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
719 passfail.shorterror);
720 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
721 ok(passfail.longerror == ERROR_PATH_NOT_FOUND || passfail.longerror == ERROR_FILE_NOT_FOUND,
722 "Unexpected error %d.\n", passfail.longerror);
724 /* Next is a long directory, 8.3 file */
725 test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
726 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
727 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
728 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
729 !passfail.shorterror,
730 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
731 passfail.shorterror);
732 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
733 ok(passfail.longerror == ERROR_PATH_NOT_FOUND || passfail.longerror == ERROR_FILE_NOT_FOUND,
734 "Unexpected error %d.\n", passfail.longerror);
736 /*Lastly a long directory, long file */
737 test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
738 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
739 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
740 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
741 !passfail.shorterror,
742 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
743 passfail.shorterror);
744 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
745 ok(passfail.longerror == ERROR_PATH_NOT_FOUND || passfail.longerror == ERROR_FILE_NOT_FOUND,
746 "Unexpected error %d.\n", passfail.longerror);
748 /* Next try directories ending with '\\' */
749 /* Existing Directories */
750 sprintf(tmpstr,"%s\\",SHORTDIR);
751 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
752 sprintf(tmpstr,"%s\\",LONGDIR);
753 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
754 /* Nonexistent directories */
755 sprintf(tmpstr,"%s\\",NONDIR_SHORT);
756 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
757 sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
758 ok((passfail.shortlen==0 &&
759 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
760 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
761 (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
762 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
763 passfail.shortlen,passfail.shorterror,tmpstr);
764 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
765 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "Unexpected error %d.\n", passfail.longerror);
767 sprintf(tmpstr,"%s\\",NONDIR_LONG);
768 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
769 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
770 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
771 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
772 !passfail.shorterror,
773 "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
774 passfail.shorterror);
775 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
776 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "Unexpected error %d.\n", passfail.longerror);
778 /* Test GetFullPathNameA with drive letters */
779 if( curDrive != NOT_A_VALID_DRIVE) {
780 sprintf(tmpstr,"%c:",curdir[0]);
781 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
782 "GetFullPathNameA(%c:) failed\n", curdir[0]);
783 GetCurrentDirectoryA(MAX_PATH,tmpstr);
784 sprintf(tmpstr1,"%s\\",tmpstr);
785 ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
786 "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
787 curdir[0],tmpstr2,tmpstr,tmpstr1);
789 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
790 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
791 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
792 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
793 ok(lstrcmpiA(SHORTFILE,strptr)==0,
794 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
796 /* Without a leading slash, insert the current directory if on the current drive */
797 sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
798 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
799 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
800 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
801 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
802 ok(lstrcmpiA(SHORTFILE,strptr)==0,
803 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
804 /* Otherwise insert the missing leading slash */
805 if( otherDrive != NOT_A_VALID_DRIVE) {
806 /* FIXME: this test assumes that current directory on other drive is root */
807 sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
808 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
809 sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
810 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
811 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
812 ok(lstrcmpiA(SHORTFILE,strptr)==0,
813 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
815 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
816 So test for them. */
817 if( curDrive != NOT_A_VALID_DRIVE) {
818 sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
819 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
820 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
821 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
822 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
823 ok(lstrcmpiA(SHORTFILE,strptr)==0,
824 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
826 /* Don't Starve relies on GetLongPathName returning the passed in filename,
827 even if the actual file on disk has a different case or separator */
828 len = lstrlenA(LONGDIR) + 1;
829 sprintf(tmpstr,"%s/%s",LONGDIR,LONGFILE);
830 ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
831 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
832 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
833 tmpstr[len] = tolower(tmpstr[len]);
834 ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
835 ok(lstrcmpA(tmpstr,tmpstr1)==0,
836 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
837 sprintf(tmpstr,"%s/%s",SHORTDIR,SHORTFILE);
838 ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
839 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
840 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
841 len = lstrlenA(SHORTDIR) + 1;
842 tmpstr[len] = toupper(tmpstr[len]);
843 ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
844 ok(lstrcmpiA(tmpstr,tmpstr1)==0 && lstrcmpA(tmpstr,tmpstr1) != 0,
845 "GetLongPathNameA returned '%s' instead of '%s/%s'\n",tmpstr1,SHORTDIR,SHORTFILE);
847 sprintf(tmpstr,"%s/%s",SHORTDIR,SHORTFILE);
848 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
849 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
850 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
852 /**/
853 sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
854 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
855 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
856 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
857 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
858 ok(lstrcmpiA(SHORTFILE,strptr)==0,
859 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
860 /* Windows will insert a drive letter in front of an absolute UNIX path */
861 sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
862 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
863 sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
864 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
865 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
866 /* This passes in Wine because it still contains the pointer from the previous test */
867 ok(lstrcmpiA(SHORTFILE,strptr)==0,
868 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
870 /* Now try some relative paths */
871 ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
872 test_SplitShortPathA(tmpstr,dir,eight,three);
873 ok(GetLongPathNameA(tmpstr, tmpstr1, MAX_PATH), "GetLongPathNameA failed\n");
874 ok(!lstrcmpiA(tmpstr1, LONGDIR), "GetLongPathNameA returned '%s' instead of '%s'\n", tmpstr1, LONGDIR);
876 sprintf(tmpstr,".\\%s",LONGDIR);
877 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
878 test_SplitShortPathA(tmpstr1,dir,eight,three);
879 ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
880 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
881 ok(GetLongPathNameA(tmpstr1, tmpstr1, MAX_PATH), "GetLongPathNameA failed %s\n", tmpstr);
882 ok(!lstrcmpiA(tmpstr1, tmpstr), "GetLongPathNameA returned '%s' instead of '%s'\n", tmpstr1, tmpstr);
884 /* Check out Get*PathNameA on some funny characters */
885 for(i=0;i<lstrlenA(funny_chars);i++) {
886 INT valid;
887 valid=(is_char_ok[i]=='0') ? 0 : 1;
888 sprintf(tmpstr1,"check%d-1",i);
889 sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
890 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
891 sprintf(tmpstr1,"check%d-2",i);
892 sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
893 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
894 sprintf(tmpstr1,"check%d-3",i);
895 sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
896 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
897 sprintf(tmpstr1,"check%d-4",i);
898 sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
899 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
900 sprintf(tmpstr1,"check%d-5",i);
901 sprintf(tmpstr,"Long %c File",funny_chars[i]);
902 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
903 sprintf(tmpstr1,"check%d-6",i);
904 sprintf(tmpstr,"%c Long File",funny_chars[i]);
905 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
906 sprintf(tmpstr1,"check%d-7",i);
907 sprintf(tmpstr,"Long File %c",funny_chars[i]);
908 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
910 /* Now try it on mixed case short names */
911 test_ShortPathCase(curdir,SHORTDIR,LONGFILE);
912 test_ShortPathCase(curdir,LONGDIR,SHORTFILE);
913 test_ShortPathCase(curdir,LONGDIR,LONGFILE);
915 /* test double delimiters */
916 sprintf(tmpstr,"%s\\\\%s", SHORTDIR,SHORTFILE);
917 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
918 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
919 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
920 sprintf(tmpstr,".\\\\%s\\\\%s", SHORTDIR,SHORTFILE);
921 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
922 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
923 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
925 sprintf(tmpstr,"%s\\\\%s",LONGDIR,LONGFILE);
926 ok(GetLongPathNameA(tmpstr, tmpstr1, MAX_PATH), "GetLongPathNameA failed\n");
927 ok(!lstrcmpiA(tmpstr,tmpstr1), "GetLongPathNameA returned '%s' instead of '%s'\n", tmpstr1, tmpstr);
929 sprintf(tmpstr,".\\\\%s\\\\%s",LONGDIR,LONGFILE);
930 ok(GetLongPathNameA(tmpstr, tmpstr1, MAX_PATH), "GetLongPathNameA failed\n");
931 ok(!lstrcmpiA(tmpstr,tmpstr1), "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
934 static void test_GetTempPathA(char* tmp_dir)
936 DWORD len, slen, len_with_null;
937 char buf[MAX_PATH];
939 len_with_null = strlen(tmp_dir) + 1;
941 lstrcpyA(buf, "foo");
942 len = GetTempPathA(MAX_PATH, buf);
943 ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
944 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
945 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
947 /* Some versions of Windows touch the buffer, some don't so we don't
948 * test that. Also, NT sometimes exaggerates the required buffer size
949 * so we cannot test for an exact match. Finally, the
950 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
951 * For instance in some cases Win98 returns len_with_null - 1 instead
952 * of len_with_null.
954 len = GetTempPathA(1, buf);
955 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
957 len = GetTempPathA(0, NULL);
958 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
960 /* The call above gave us the buffer size that Windows thinks is needed
961 * so the next call should work
963 lstrcpyA(buf, "foo");
964 len = GetTempPathA(len, buf);
965 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
966 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
968 memset(buf, 'a', sizeof(buf));
969 len = GetTempPathA(sizeof(buf), buf);
970 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
971 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
972 /* The rest of the buffer remains untouched */
973 slen = len + 1;
974 for(len++; len < sizeof(buf); len++)
975 ok(buf[len] == 'a', "expected 'a' at [%d], got 0x%x\n", len, buf[len]);
977 /* When the buffer is not long enough it remains untouched */
978 memset(buf, 'a', sizeof(buf));
979 len = GetTempPathA(slen / 2, buf);
980 ok(len == slen || broken(len == slen + 1) /* read the big comment above */ ,
981 "expected %d, got %d\n", slen, len);
982 for(len = 0; len < ARRAY_SIZE(buf); len++)
983 ok(buf[len] == 'a', "expected 'a' at [%d], got 0x%x\n", len, buf[len]);
986 static void test_GetTempPathW(char* tmp_dir)
988 DWORD len, slen, len_with_null;
989 WCHAR buf[MAX_PATH], *long_buf;
990 WCHAR tmp_dirW[MAX_PATH];
991 static const WCHAR fooW[] = {'f','o','o',0};
993 MultiByteToWideChar(CP_ACP, 0, tmp_dir, -1, tmp_dirW, ARRAY_SIZE(tmp_dirW));
994 len_with_null = lstrlenW(tmp_dirW) + 1;
996 /* This one is different from ANSI version: ANSI version doesn't
997 * touch the buffer, unicode version usually truncates the buffer
998 * to zero size. NT still exaggerates the required buffer size
999 * sometimes so we cannot test for an exact match. Finally, the
1000 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
1001 * For instance on NT4 it will sometimes return a path without the
1002 * trailing '\\' and sometimes return an error.
1005 lstrcpyW(buf, fooW);
1006 len = GetTempPathW(MAX_PATH, buf);
1007 if (len == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1009 win_skip("GetTempPathW is not available\n");
1010 return;
1012 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
1013 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
1015 lstrcpyW(buf, fooW);
1016 len = GetTempPathW(1, buf);
1017 ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
1018 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
1020 len = GetTempPathW(0, NULL);
1021 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
1023 lstrcpyW(buf, fooW);
1024 len = GetTempPathW(len, buf);
1025 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
1026 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
1028 for(len = 0; len < ARRAY_SIZE(buf); len++)
1029 buf[len] = 'a';
1030 len = GetTempPathW(len, buf);
1031 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
1032 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
1033 /* The rest of the buffer must be zeroed */
1034 slen = len + 1;
1035 for(len++; len < ARRAY_SIZE(buf); len++)
1036 ok(buf[len] == '\0', "expected NULL at [%d], got 0x%x\n", len, buf[len]);
1038 /* When the buffer is not long enough the length passed is zeroed */
1039 for(len = 0; len < ARRAY_SIZE(buf); len++)
1040 buf[len] = 'a';
1041 len = GetTempPathW(slen / 2, buf);
1042 ok(len == slen || broken(len == slen + 1) /* read the big comment above */ ,
1043 "expected %d, got %d\n", slen, len);
1046 /* In Windows 8 when TMP var points to a drive only (like C:) instead of a
1047 * full directory the behavior changes. It will start filling the path but
1048 * will later truncate the buffer before returning. So the generic test
1049 * below will fail for this Windows 8 corner case.
1051 char tmp_var[64];
1052 DWORD version = GetVersion();
1053 GetEnvironmentVariableA("TMP", tmp_var, sizeof(tmp_var));
1054 if (strlen(tmp_var) == 2 && version >= 0x00060002)
1055 return;
1058 for(len = 0; len < slen / 2; len++)
1059 ok(buf[len] == '\0', "expected NULL at [%d], got 0x%x\n", len, buf[len]);
1060 for(; len < ARRAY_SIZE(buf); len++)
1061 ok(buf[len] == 'a', "expected 'a' at [%d], got 0x%x\n", len, buf[len]);
1063 /* bogus application from bug 38220 passes the count value in sizeof(buffer)
1064 * instead the correct count of WCHAR, this test catches this case. */
1065 slen = 65534;
1066 long_buf = HeapAlloc(GetProcessHeap(), 0, slen * sizeof(WCHAR));
1067 if (!long_buf)
1069 skip("Could not allocate memory for the test\n");
1070 return;
1072 for(len = 0; len < slen; len++)
1073 long_buf[len] = 0xCC;
1074 len = GetTempPathW(slen, long_buf);
1075 ok(lstrcmpiW(long_buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
1076 ok(len == lstrlenW(long_buf), "returned length should be equal to the length of string\n");
1077 /* the remaining buffer must be zeroed up to different values in different OS versions.
1078 * <= XP - 32766
1079 * > XP - 32767
1080 * to simplify testing we will test only until XP.
1082 for(; len < 32767; len++)
1083 ok(long_buf[len] == '\0', "expected NULL at [%d], got 0x%x\n", len, long_buf[len]);
1084 /* we will know skip the test that is in the middle of the OS difference by
1085 * incrementing len and then resume the test for the untouched part. */
1086 for(len++; len < slen; len++)
1087 ok(long_buf[len] == 0xcc, "expected 0xcc at [%d], got 0x%x\n", len, long_buf[len]);
1089 HeapFree(GetProcessHeap(), 0, long_buf);
1092 static void test_GetTempPath(void)
1094 char save_TMP[MAX_PATH];
1095 char windir[MAX_PATH];
1096 char buf[MAX_PATH];
1097 WCHAR curdir[MAX_PATH];
1099 if (!GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP))) save_TMP[0] = 0;
1101 /* test default configuration */
1102 trace("TMP=%s\n", save_TMP);
1103 if (save_TMP[0])
1105 strcpy(buf,save_TMP);
1106 if (buf[strlen(buf)-1]!='\\')
1107 strcat(buf,"\\");
1108 test_GetTempPathA(buf);
1109 test_GetTempPathW(buf);
1112 /* TMP=C:\WINDOWS */
1113 GetWindowsDirectoryA(windir, sizeof(windir));
1114 SetEnvironmentVariableA("TMP", windir);
1115 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1116 trace("TMP=%s\n", buf);
1117 strcat(windir,"\\");
1118 test_GetTempPathA(windir);
1119 test_GetTempPathW(windir);
1121 /* TMP=C:\ */
1122 GetWindowsDirectoryA(windir, sizeof(windir));
1123 windir[3] = 0;
1124 SetEnvironmentVariableA("TMP", windir);
1125 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1126 trace("TMP=%s\n", buf);
1127 test_GetTempPathA(windir);
1128 test_GetTempPathW(windir);
1130 GetCurrentDirectoryW(MAX_PATH, curdir);
1131 /* TMP=C: i.e. use current working directory of the specified drive */
1132 GetWindowsDirectoryA(windir, sizeof(windir));
1133 SetCurrentDirectoryA(windir);
1134 windir[2] = 0;
1135 SetEnvironmentVariableA("TMP", windir);
1136 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1137 trace("TMP=%s\n", buf);
1138 GetWindowsDirectoryA(windir, sizeof(windir));
1139 strcat(windir,"\\");
1140 test_GetTempPathA(windir);
1141 test_GetTempPathW(windir);
1143 SetEnvironmentVariableA("TMP", save_TMP);
1144 SetCurrentDirectoryW(curdir);
1147 static void test_GetLongPathNameA(void)
1149 DWORD length, explength, hostsize;
1150 char tempfile[MAX_PATH], *name;
1151 char longpath[MAX_PATH];
1152 char unc_prefix[MAX_PATH];
1153 char unc_short[MAX_PATH], unc_long[MAX_PATH];
1154 char temppath[MAX_PATH], temppath2[MAX_PATH];
1155 HANDLE file;
1157 GetTempPathA(MAX_PATH, tempfile);
1158 name = tempfile + strlen(tempfile);
1160 strcpy(name, "*");
1161 SetLastError(0xdeadbeef);
1162 length = GetLongPathNameA(tempfile, temppath, MAX_PATH);
1163 ok(!length, "GetLongPathNameA should fail\n");
1164 ok(GetLastError() == ERROR_INVALID_NAME, "wrong error %d\n", GetLastError());
1166 strcpy(name, "longfilename.longext");
1168 file = CreateFileA(tempfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1169 CloseHandle(file);
1171 /* Test a normal path with a small buffer size */
1172 memset(temppath, 0, MAX_PATH);
1173 length = GetLongPathNameA(tempfile, temppath, 4);
1174 /* We have a failure so length should be the minimum plus the terminating '0' */
1175 ok(length >= strlen(tempfile) + 1, "Wrong length\n");
1176 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1178 /* Some UNC syntax tests */
1180 memset(temppath, 0, MAX_PATH);
1181 memset(temppath2, 0, MAX_PATH);
1182 lstrcpyA(temppath2, "\\\\?\\");
1183 lstrcatA(temppath2, tempfile);
1184 explength = length + 4;
1186 SetLastError(0xdeadbeef);
1187 length = GetLongPathNameA(temppath2, NULL, 0);
1188 if (length == 0 && GetLastError() == ERROR_BAD_NET_NAME)
1190 win_skip("UNC syntax tests don't work on Win98/WinMe\n");
1191 DeleteFileA(tempfile);
1192 return;
1194 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1196 length = GetLongPathNameA(temppath2, NULL, MAX_PATH);
1197 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1199 length = GetLongPathNameA(temppath2, temppath, 4);
1200 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1201 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1203 /* Now an UNC path with the computername */
1204 lstrcpyA(unc_prefix, "\\\\");
1205 hostsize = sizeof(unc_prefix) - 2;
1206 GetComputerNameA(unc_prefix + 2, &hostsize);
1207 lstrcatA(unc_prefix, "\\");
1209 /* Create a short syntax for the whole unc path */
1210 memset(unc_short, 0, MAX_PATH);
1211 GetShortPathNameA(tempfile, temppath, MAX_PATH);
1212 lstrcpyA(unc_short, unc_prefix);
1213 unc_short[lstrlenA(unc_short)] = temppath[0];
1214 lstrcatA(unc_short, "$\\");
1215 lstrcatA(unc_short, strchr(temppath, '\\') + 1);
1217 /* Create a long syntax for reference */
1218 memset(longpath, 0, MAX_PATH);
1219 GetLongPathNameA(tempfile, temppath, MAX_PATH);
1220 lstrcpyA(longpath, unc_prefix);
1221 longpath[lstrlenA(longpath)] = temppath[0];
1222 lstrcatA(longpath, "$\\");
1223 lstrcatA(longpath, strchr(temppath, '\\') + 1);
1225 /* NULL test */
1226 SetLastError(0xdeadbeef);
1227 length = GetLongPathNameA(unc_short, NULL, 0);
1228 if (length == 0 && GetLastError() == ERROR_BAD_NETPATH)
1230 /* Seen on Window XP Home */
1231 win_skip("UNC with computername is not supported\n");
1232 DeleteFileA(tempfile);
1233 return;
1235 explength = lstrlenA(longpath) + 1;
1236 todo_wine
1237 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1239 length = GetLongPathNameA(unc_short, NULL, MAX_PATH);
1240 todo_wine
1241 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1243 memset(unc_long, 0, MAX_PATH);
1244 length = GetLongPathNameA(unc_short, unc_long, lstrlenA(unc_short));
1245 /* length will include terminating '0' on failure */
1246 todo_wine
1247 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1248 ok(unc_long[0] == 0, "Buffer should not have been touched\n");
1250 memset(unc_long, 0, MAX_PATH);
1251 length = GetLongPathNameA(unc_short, unc_long, length);
1252 /* length doesn't include terminating '0' on success */
1253 explength--;
1254 todo_wine
1256 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1257 ok(!lstrcmpiA(unc_long, longpath), "Expected (%s), got (%s)\n", longpath, unc_long);
1260 DeleteFileA(tempfile);
1263 static void test_GetLongPathNameW(void)
1265 DWORD length, expanded;
1266 BOOL ret;
1267 HANDLE file;
1268 WCHAR empty[MAX_PATH];
1269 WCHAR tempdir[MAX_PATH], name[200];
1270 WCHAR dirpath[4 + MAX_PATH + 200]; /* To ease removal */
1271 WCHAR shortpath[4 + MAX_PATH + 200 + 1 + 200];
1272 static const WCHAR prefix[] = { '\\','\\','?','\\', 0};
1273 static const WCHAR backslash[] = { '\\', 0};
1274 static const WCHAR letterX[] = { 'X', 0};
1276 SetLastError(0xdeadbeef);
1277 length = GetLongPathNameW(NULL,NULL,0);
1278 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1280 win_skip("GetLongPathNameW is not implemented\n");
1281 return;
1283 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1284 ok(GetLastError()==ERROR_INVALID_PARAMETER,"GetLastError returned %d but expected ERROR_INVALID_PARAMETER\n",GetLastError());
1286 SetLastError(0xdeadbeef);
1287 empty[0]=0;
1288 length = GetLongPathNameW(empty,NULL,0);
1289 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1290 ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
1292 /* Create a long path name. The path needs to exist for these tests to
1293 * succeed so we need the "\\?\" prefix when creating directories and
1294 * files.
1296 name[0] = 0;
1297 while (lstrlenW(name) < (ARRAY_SIZE(name) - 1))
1298 lstrcatW(name, letterX);
1300 GetTempPathW(MAX_PATH, tempdir);
1302 lstrcpyW(shortpath, prefix);
1303 lstrcatW(shortpath, tempdir);
1304 lstrcatW(shortpath, name);
1305 lstrcpyW(dirpath, shortpath);
1306 ret = CreateDirectoryW(shortpath, NULL);
1307 ok(ret, "Could not create the temporary directory : %d\n", GetLastError());
1308 lstrcatW(shortpath, backslash);
1309 lstrcatW(shortpath, name);
1311 /* Path does not exist yet and we know it overruns MAX_PATH */
1313 /* No prefix */
1314 SetLastError(0xdeadbeef);
1315 length = GetLongPathNameW(shortpath + 4, NULL, 0);
1316 ok(length == 0, "Expected 0, got %d\n", length);
1317 todo_wine
1318 ok(GetLastError() == ERROR_PATH_NOT_FOUND,
1319 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1320 /* With prefix */
1321 SetLastError(0xdeadbeef);
1322 length = GetLongPathNameW(shortpath, NULL, 0);
1323 todo_wine
1325 ok(length == 0, "Expected 0, got %d\n", length);
1326 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
1327 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1330 file = CreateFileW(shortpath, GENERIC_READ|GENERIC_WRITE, 0, NULL,
1331 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1332 ok(file != INVALID_HANDLE_VALUE,
1333 "Could not create the temporary file : %d.\n", GetLastError());
1334 CloseHandle(file);
1336 /* Path exists */
1338 /* No prefix */
1339 SetLastError(0xdeadbeef);
1340 length = GetLongPathNameW(shortpath + 4, NULL, 0);
1341 todo_wine
1343 ok(length == 0, "Expected 0, got %d\n", length);
1344 ok(GetLastError() == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1346 /* With prefix */
1347 expanded = 4 + (GetLongPathNameW(tempdir, NULL, 0) - 1) + lstrlenW(name) + 1 + lstrlenW(name) + 1;
1348 SetLastError(0xdeadbeef);
1349 length = GetLongPathNameW(shortpath, NULL, 0);
1350 ok(length == expanded, "Expected %d, got %d\n", expanded, length);
1352 /* NULL buffer with length crashes on Windows */
1353 if (0)
1354 GetLongPathNameW(shortpath, NULL, 20);
1356 ok(DeleteFileW(shortpath), "Could not delete temporary file\n");
1357 ok(RemoveDirectoryW(dirpath), "Could not delete temporary directory\n");
1360 static void test_GetShortPathNameW(void)
1362 static const WCHAR extended_prefix[] = {'\\','\\','?','\\',0};
1363 static const WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
1364 static const WCHAR name[] = { 't', 'e', 's', 't', 0 };
1365 static const WCHAR backSlash[] = { '\\', 0 };
1366 static const WCHAR a_bcdeW[] = {'a','.','b','c','d','e',0};
1367 static const WCHAR wildW[] = { '*',0 };
1368 WCHAR path[MAX_PATH], tmppath[MAX_PATH], *ptr;
1369 WCHAR short_path[MAX_PATH];
1370 DWORD length;
1371 HANDLE file;
1372 int ret;
1374 SetLastError(0xdeadbeef);
1375 GetTempPathW( MAX_PATH, tmppath );
1376 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1378 win_skip("GetTempPathW is not implemented\n");
1379 return;
1382 lstrcpyW( path, tmppath );
1383 lstrcatW( path, test_path );
1384 lstrcatW( path, backSlash );
1385 ret = CreateDirectoryW( path, NULL );
1386 ok( ret, "Directory was not created. LastError = %d\n", GetLastError() );
1388 /* Starting a main part of test */
1390 /* extended path \\?\C:\path\ */
1391 lstrcpyW( path, extended_prefix );
1392 lstrcatW( path, tmppath );
1393 lstrcatW( path, test_path );
1394 lstrcatW( path, backSlash );
1395 short_path[0] = 0;
1396 length = GetShortPathNameW( path, short_path, ARRAY_SIZE( short_path ));
1397 ok( length, "GetShortPathNameW returned 0.\n" );
1399 lstrcpyW( path, tmppath );
1400 lstrcatW( path, test_path );
1401 lstrcatW( path, backSlash );
1402 length = GetShortPathNameW( path, short_path, 0 );
1403 ok( length, "GetShortPathNameW returned 0.\n" );
1404 ret = GetShortPathNameW( path, short_path, length );
1405 ok( ret && ret == length-1, "GetShortPathNameW returned 0.\n" );
1407 lstrcatW( short_path, name );
1409 /* GetShortPathName for a non-existent short file name should fail */
1410 SetLastError(0xdeadbeef);
1411 length = GetShortPathNameW( short_path, path, 0 );
1412 ok(!length, "GetShortPathNameW should fail\n");
1413 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
1415 file = CreateFileW( short_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1416 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
1417 CloseHandle( file );
1418 ret = DeleteFileW( short_path );
1419 ok( ret, "Cannot delete file.\n" );
1421 ptr = path + lstrlenW(path);
1422 lstrcpyW( ptr, a_bcdeW);
1423 file = CreateFileW( path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1424 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
1425 CloseHandle( file );
1427 length = GetShortPathNameW( path, short_path, ARRAY_SIZE( short_path ));
1428 ok( length, "GetShortPathNameW failed: %u.\n", GetLastError() );
1430 lstrcpyW(ptr, wildW);
1431 SetLastError(0xdeadbeef);
1432 length = GetShortPathNameW( path, short_path, ARRAY_SIZE( short_path ) );
1433 ok(!length, "GetShortPathNameW should fail\n");
1434 ok(GetLastError() == ERROR_INVALID_NAME, "wrong error %d\n", GetLastError());
1436 lstrcpyW(ptr, a_bcdeW);
1437 ret = DeleteFileW( path );
1438 ok( ret, "Cannot delete file.\n" );
1439 *ptr = 0;
1441 /* End test */
1442 ret = RemoveDirectoryW( path );
1443 ok( ret, "Cannot delete directory.\n" );
1446 static void test_GetSystemDirectory(void)
1448 CHAR buffer[MAX_PATH + 4];
1449 DWORD res;
1450 DWORD total;
1452 SetLastError(0xdeadbeef);
1453 res = GetSystemDirectoryA(NULL, 0);
1454 /* res includes the terminating Zero */
1455 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1457 total = res;
1459 /* this crashes on XP */
1460 if (0)
1461 GetSystemDirectoryA(NULL, total);
1463 SetLastError(0xdeadbeef);
1464 res = GetSystemDirectoryA(NULL, total-1);
1465 /* 95+NT: total (includes the terminating Zero)
1466 98+ME: 0 with ERROR_INVALID_PARAMETER */
1467 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1468 "returned %d with %d (expected '%d' or: '0' with "
1469 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1471 if (total > MAX_PATH) return;
1473 buffer[0] = '\0';
1474 SetLastError(0xdeadbeef);
1475 res = GetSystemDirectoryA(buffer, total);
1476 /* res does not include the terminating Zero */
1477 ok( (res == (total-1)) && (buffer[0]),
1478 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1479 res, GetLastError(), buffer, total-1);
1481 buffer[0] = '\0';
1482 SetLastError(0xdeadbeef);
1483 res = GetSystemDirectoryA(buffer, total + 1);
1484 /* res does not include the terminating Zero */
1485 ok( (res == (total-1)) && (buffer[0]),
1486 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1487 res, GetLastError(), buffer, total-1);
1489 memset(buffer, '#', total + 1);
1490 buffer[total + 2] = '\0';
1491 SetLastError(0xdeadbeef);
1492 res = GetSystemDirectoryA(buffer, total-1);
1493 /* res includes the terminating Zero) */
1494 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1495 res, GetLastError(), buffer, total);
1497 memset(buffer, '#', total + 1);
1498 buffer[total + 2] = '\0';
1499 SetLastError(0xdeadbeef);
1500 res = GetSystemDirectoryA(buffer, total-2);
1501 /* res includes the terminating Zero) */
1502 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1503 res, GetLastError(), buffer, total);
1506 static void test_GetWindowsDirectory(void)
1508 CHAR buffer[MAX_PATH + 4];
1509 DWORD res;
1510 DWORD total;
1512 SetLastError(0xdeadbeef);
1513 res = GetWindowsDirectoryA(NULL, 0);
1514 /* res includes the terminating Zero */
1515 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1517 total = res;
1518 /* this crashes on XP */
1519 if (0)
1520 GetWindowsDirectoryA(NULL, total);
1522 SetLastError(0xdeadbeef);
1523 res = GetWindowsDirectoryA(NULL, total-1);
1524 /* 95+NT: total (includes the terminating Zero)
1525 98+ME: 0 with ERROR_INVALID_PARAMETER */
1526 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1527 "returned %d with %d (expected '%d' or: '0' with "
1528 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1530 if (total > MAX_PATH) return;
1532 buffer[0] = '\0';
1533 SetLastError(0xdeadbeef);
1534 res = GetWindowsDirectoryA(buffer, total);
1535 /* res does not include the terminating Zero */
1536 ok( (res == (total-1)) && (buffer[0]),
1537 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1538 res, GetLastError(), buffer, total-1);
1540 buffer[0] = '\0';
1541 SetLastError(0xdeadbeef);
1542 res = GetWindowsDirectoryA(buffer, total + 1);
1543 /* res does not include the terminating Zero */
1544 ok( (res == (total-1)) && (buffer[0]),
1545 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1546 res, GetLastError(), buffer, total-1);
1548 memset(buffer, '#', total + 1);
1549 buffer[total + 2] = '\0';
1550 SetLastError(0xdeadbeef);
1551 res = GetWindowsDirectoryA(buffer, total-1);
1552 /* res includes the terminating Zero) */
1553 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1554 res, GetLastError(), buffer, total);
1556 memset(buffer, '#', total + 1);
1557 buffer[total + 2] = '\0';
1558 SetLastError(0xdeadbeef);
1559 res = GetWindowsDirectoryA(buffer, total-2);
1560 /* res includes the terminating Zero) */
1561 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1562 res, GetLastError(), buffer, total);
1565 static void test_NeedCurrentDirectoryForExePathA(void)
1567 if (!pNeedCurrentDirectoryForExePathA)
1569 win_skip("NeedCurrentDirectoryForExePathA is not available\n");
1570 return;
1573 /* Crashes in Windows */
1574 if (0)
1575 pNeedCurrentDirectoryForExePathA(NULL);
1577 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1578 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1579 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1580 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1582 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1583 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1584 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1585 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1588 static void test_NeedCurrentDirectoryForExePathW(void)
1590 const WCHAR thispath[] = {'.', 0};
1591 const WCHAR fullpath[] = {'c', ':', '\\', 0};
1592 const WCHAR cmdname[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1594 if (!pNeedCurrentDirectoryForExePathW)
1596 win_skip("NeedCurrentDirectoryForExePathW is not available\n");
1597 return;
1600 /* Crashes in Windows */
1601 if (0)
1602 pNeedCurrentDirectoryForExePathW(NULL);
1604 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1605 ok(pNeedCurrentDirectoryForExePathW(thispath), "returned FALSE for \".\"\n");
1606 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1607 ok(pNeedCurrentDirectoryForExePathW(cmdname), "returned FALSE for \"cmd.exe\"\n");
1609 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1610 ok(!pNeedCurrentDirectoryForExePathW(thispath), "returned TRUE for \".\"\n");
1611 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1612 ok(!pNeedCurrentDirectoryForExePathW(cmdname), "returned TRUE for \"cmd.exe\"\n");
1615 /* Call various path/file name retrieving APIs and check the case of
1616 * the returned drive letter. Some apps (for instance Adobe Photoshop CS3
1617 * installer) depend on the drive letter being in upper case.
1619 static void test_drive_letter_case(void)
1621 UINT ret;
1622 char buf[MAX_PATH];
1624 #define is_upper_case_letter(a) ((a) >= 'A' && (a) <= 'Z')
1626 memset(buf, 0, sizeof(buf));
1627 SetLastError(0xdeadbeef);
1628 ret = GetWindowsDirectoryA(buf, sizeof(buf));
1629 ok(ret, "GetWindowsDirectory error %u\n", GetLastError());
1630 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1631 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1632 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1634 /* re-use the buffer returned by GetFullPathName */
1635 buf[2] = '/';
1636 SetLastError(0xdeadbeef);
1637 ret = GetFullPathNameA(buf + 2, sizeof(buf), buf, NULL);
1638 ok(ret, "GetFullPathName error %u\n", GetLastError());
1639 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1640 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1641 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1643 memset(buf, 0, sizeof(buf));
1644 SetLastError(0xdeadbeef);
1645 ret = GetSystemDirectoryA(buf, sizeof(buf));
1646 ok(ret, "GetSystemDirectory error %u\n", GetLastError());
1647 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1648 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1649 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1651 memset(buf, 0, sizeof(buf));
1652 SetLastError(0xdeadbeef);
1653 ret = GetCurrentDirectoryA(sizeof(buf), buf);
1654 ok(ret, "GetCurrentDirectory error %u\n", GetLastError());
1655 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1656 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1657 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1659 /* TEMP is an environment variable, so it can't be tested for case-sensitivity */
1660 memset(buf, 0, sizeof(buf));
1661 SetLastError(0xdeadbeef);
1662 ret = GetTempPathA(sizeof(buf), buf);
1663 ok(ret, "GetTempPath error %u\n", GetLastError());
1664 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1665 if (buf[0])
1667 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1668 ok(buf[strlen(buf)-1] == '\\', "Temporary path (%s) doesn't end in a slash\n", buf);
1671 memset(buf, 0, sizeof(buf));
1672 SetLastError(0xdeadbeef);
1673 ret = GetFullPathNameA(".", sizeof(buf), buf, NULL);
1674 ok(ret, "GetFullPathName error %u\n", GetLastError());
1675 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1676 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1677 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1679 /* re-use the buffer returned by GetFullPathName */
1680 SetLastError(0xdeadbeef);
1681 ret = GetShortPathNameA(buf, buf, sizeof(buf));
1682 ok(ret, "GetShortPathName error %u\n", GetLastError());
1683 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1684 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1685 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1687 /* re-use the buffer returned by GetShortPathName */
1688 SetLastError(0xdeadbeef);
1689 ret = GetLongPathNameA(buf, buf, sizeof(buf));
1690 ok(ret, "GetLongPathNameA error %u\n", GetLastError());
1691 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1692 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1693 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1694 #undef is_upper_case_letter
1697 static const char manifest_dep[] =
1698 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1699 "<assemblyIdentity version=\"1.2.3.4\" name=\"testdep1\" type=\"win32\" processorArchitecture=\"" ARCH "\"/>"
1700 " <file name=\"testdep.dll\" />"
1701 " <file name=\"ole32\" />"
1702 " <file name=\"kernel32.dll\" />"
1703 "</assembly>";
1705 static const char manifest_main[] =
1706 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1707 "<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
1708 "<dependency>"
1709 " <dependentAssembly>"
1710 " <assemblyIdentity type=\"win32\" name=\"testdep1\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH "\" />"
1711 " </dependentAssembly>"
1712 "</dependency>"
1713 "</assembly>";
1715 static void create_manifest_file(const char *filename, const char *manifest)
1717 WCHAR path[MAX_PATH], manifest_path[MAX_PATH];
1718 HANDLE file;
1719 DWORD size;
1721 MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH );
1723 GetTempPathW(ARRAY_SIZE(manifest_path), manifest_path);
1724 lstrcatW(manifest_path, path);
1726 file = CreateFileW(manifest_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1727 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
1728 WriteFile(file, manifest, strlen(manifest), &size, NULL);
1729 CloseHandle(file);
1732 static void delete_manifest_file(const char *filename)
1734 CHAR path[MAX_PATH];
1736 GetTempPathA(sizeof(path), path);
1737 strcat(path, filename);
1738 DeleteFileA(path);
1741 static HANDLE test_create(const char *file)
1743 WCHAR path[MAX_PATH], manifest_path[MAX_PATH];
1744 ACTCTXW actctx;
1745 HANDLE handle;
1747 MultiByteToWideChar(CP_ACP, 0, file, -1, path, MAX_PATH);
1748 GetTempPathW(ARRAY_SIZE(manifest_path), manifest_path);
1749 lstrcatW(manifest_path, path);
1751 memset(&actctx, 0, sizeof(ACTCTXW));
1752 actctx.cbSize = sizeof(ACTCTXW);
1753 actctx.lpSource = manifest_path;
1755 handle = CreateActCtxW(&actctx);
1756 ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError());
1758 ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize);
1759 ok(actctx.dwFlags == 0, "dwFlags=%d\n", actctx.dwFlags);
1760 ok(actctx.lpSource == manifest_path, "lpSource=%p\n", actctx.lpSource);
1761 ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
1762 ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId);
1763 ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
1764 ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName);
1765 ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName);
1766 ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule);
1768 return handle;
1771 static void test_SearchPathA(void)
1773 static const CHAR testdepA[] = "testdep.dll";
1774 static const CHAR testdeprelA[] = "./testdep.dll";
1775 static const CHAR kernel32A[] = "kernel32.dll";
1776 static const CHAR fileA[] = "";
1777 CHAR pathA[MAX_PATH + 13], buffA[MAX_PATH], path2A[MAX_PATH], path3A[MAX_PATH + 13], curdirA[MAX_PATH];
1778 CHAR tmpdirA[MAX_PATH], *ptrA = NULL;
1779 ULONG_PTR cookie;
1780 HANDLE handle;
1781 BOOL bret;
1782 DWORD ret;
1784 GetWindowsDirectoryA(pathA, ARRAY_SIZE(pathA));
1786 /* NULL filename */
1787 SetLastError(0xdeadbeef);
1788 ret = SearchPathA(pathA, NULL, NULL, ARRAY_SIZE(buffA), buffA, &ptrA);
1789 ok(ret == 0, "Expected failure, got %d\n", ret);
1790 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1791 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1793 /* empty filename */
1794 SetLastError(0xdeadbeef);
1795 ret = SearchPathA(pathA, fileA, NULL, ARRAY_SIZE(buffA), buffA, &ptrA);
1796 ok(ret == 0, "Expected failure, got %d\n", ret);
1797 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1798 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1800 GetTempPathA(ARRAY_SIZE(pathA), pathA);
1801 strcpy(path2A, pathA);
1802 strcat(path2A, "testfile.ext.ext2");
1804 handle = CreateFileA(path2A, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
1805 ok(handle != INVALID_HANDLE_VALUE, "Failed to create test file.\n");
1806 CloseHandle(handle);
1808 buffA[0] = 0;
1809 ret = SearchPathA(pathA, "testfile.ext", NULL, ARRAY_SIZE(buffA), buffA, NULL);
1810 ok(!ret, "Unexpected return value %u.\n", ret);
1812 buffA[0] = 0;
1813 ret = SearchPathA(pathA, "testfile.ext", ".ext2", ARRAY_SIZE(buffA), buffA, NULL);
1814 ok(!ret, "Unexpected return value %u.\n", ret);
1816 buffA[0] = 0;
1817 ret = SearchPathA(pathA, "testfile.ext.ext2", NULL, ARRAY_SIZE(buffA), buffA, NULL);
1818 ok(ret && ret == strlen(path2A), "got %d\n", ret);
1820 DeleteFileA(path2A);
1822 GetWindowsDirectoryA(pathA, ARRAY_SIZE(pathA));
1824 create_manifest_file("testdep1.manifest", manifest_dep);
1825 create_manifest_file("main.manifest", manifest_main);
1827 handle = test_create("main.manifest");
1828 delete_manifest_file("testdep1.manifest");
1829 delete_manifest_file("main.manifest");
1831 /* search fails without active context */
1832 ret = SearchPathA(NULL, testdepA, NULL, ARRAY_SIZE(buffA), buffA, NULL);
1833 ok(ret == 0, "got %d\n", ret);
1835 ret = SearchPathA(NULL, kernel32A, NULL, ARRAY_SIZE(path2A), path2A, NULL);
1836 ok(ret && ret == strlen(path2A), "got %d\n", ret);
1838 ret = ActivateActCtx(handle, &cookie);
1839 ok(ret, "failed to activate context, %u\n", GetLastError());
1841 /* works when activated */
1842 ret = SearchPathA(NULL, testdepA, NULL, ARRAY_SIZE(buffA), buffA, NULL);
1843 ok(ret && ret == strlen(buffA), "got %d\n", ret);
1845 ret = SearchPathA(NULL, "testdep.dll", ".ext", ARRAY_SIZE(buffA), buffA, NULL);
1846 ok(ret && ret == strlen(buffA), "got %d\n", ret);
1848 ret = SearchPathA(NULL, "testdep", ".dll", ARRAY_SIZE(buffA), buffA, NULL);
1849 ok(ret && ret == strlen(buffA), "got %d\n", ret);
1851 ret = SearchPathA(NULL, "testdep", ".ext", ARRAY_SIZE(buffA), buffA, NULL);
1852 ok(!ret, "got %d\n", ret);
1854 /* name contains path */
1855 ret = SearchPathA(NULL, testdeprelA, NULL, ARRAY_SIZE(buffA), buffA, NULL);
1856 ok(!ret, "got %d\n", ret);
1858 /* fails with specified path that doesn't contain this file */
1859 ret = SearchPathA(pathA, testdepA, NULL, ARRAY_SIZE(buffA), buffA, NULL);
1860 ok(!ret, "got %d\n", ret);
1862 /* path is redirected for wellknown names too */
1863 ret = SearchPathA(NULL, kernel32A, NULL, ARRAY_SIZE(buffA), buffA, NULL);
1864 ok(ret && ret == strlen(buffA), "got %d\n", ret);
1865 ok(strcmp(buffA, path2A), "got wrong path %s, %s\n", buffA, path2A);
1867 ret = DeactivateActCtx(0, cookie);
1868 ok(ret, "failed to deactivate context, %u\n", GetLastError());
1869 ReleaseActCtx(handle);
1871 /* test the search path priority of the working directory */
1872 GetTempPathA(sizeof(tmpdirA), tmpdirA);
1873 ret = GetCurrentDirectoryA(MAX_PATH, curdirA);
1874 ok(ret, "failed to obtain working directory.\n");
1875 sprintf(pathA, "%s\\%s", tmpdirA, kernel32A);
1876 ret = SearchPathA(NULL, kernel32A, NULL, ARRAY_SIZE(path2A), path2A, NULL);
1877 ok(ret && ret == strlen(path2A), "got %d\n", ret);
1878 bret = CopyFileA(path2A, pathA, FALSE);
1879 ok(bret != 0, "failed to copy test executable to temp directory, %u\n", GetLastError());
1880 GetModuleFileNameA( GetModuleHandleA(0), path3A, sizeof(path3A) );
1881 strcpy( strrchr( path3A, '\\' ) + 1, kernel32A );
1882 bret = CopyFileA(path2A, path3A, FALSE);
1883 ok(bret != 0, "failed to copy test executable to launch directory, %u\n", GetLastError());
1884 bret = SetCurrentDirectoryA(tmpdirA);
1885 ok(bret, "failed to change working directory\n");
1886 ret = SearchPathA(NULL, kernel32A, ".exe", sizeof(buffA), buffA, NULL);
1887 ok(ret && ret == strlen(buffA), "got %d\n", ret);
1888 ok(strcmp(buffA, path3A) == 0, "expected %s, got %s\n", path3A, buffA);
1889 bret = SetCurrentDirectoryA(curdirA);
1890 ok(bret, "failed to reset working directory\n");
1891 DeleteFileA(path3A);
1892 DeleteFileA(pathA);
1895 static void test_SearchPathW(void)
1897 static const WCHAR fileext2W[] = {'t','e','s','t','f','i','l','e','.','e','x','t','.','e','x','t','2',0};
1898 static const WCHAR fileextW[] = {'t','e','s','t','f','i','l','e','.','e','x','t',0};
1899 static const WCHAR testdeprelW[] = {'.','/','t','e','s','t','d','e','p','.','d','l','l',0};
1900 static const WCHAR testdepW[] = {'t','e','s','t','d','e','p','.','d','l','l',0};
1901 static const WCHAR testdep1W[] = {'t','e','s','t','d','e','p',0};
1902 static const WCHAR kernel32dllW[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
1903 static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2',0};
1904 static const WCHAR ole32W[] = {'o','l','e','3','2',0};
1905 static const WCHAR ext2W[] = {'.','e','x','t','2',0};
1906 static const WCHAR extW[] = {'.','e','x','t',0};
1907 static const WCHAR dllW[] = {'.','d','l','l',0};
1908 static const WCHAR fileW[] = { 0 };
1909 WCHAR pathW[MAX_PATH], buffW[MAX_PATH], path2W[MAX_PATH];
1910 WCHAR *ptrW = NULL;
1911 ULONG_PTR cookie;
1912 HANDLE handle;
1913 DWORD ret;
1915 if (0)
1917 /* NULL filename, crashes on nt4 */
1918 SearchPathW(pathW, NULL, NULL, ARRAY_SIZE(buffW), buffW, &ptrW);
1921 GetWindowsDirectoryW(pathW, ARRAY_SIZE(pathW));
1923 /* empty filename */
1924 SetLastError(0xdeadbeef);
1925 ret = SearchPathW(pathW, fileW, NULL, ARRAY_SIZE(buffW), buffW, &ptrW);
1926 ok(ret == 0, "Expected failure, got %d\n", ret);
1927 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1928 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1930 GetTempPathW(ARRAY_SIZE(pathW), pathW);
1931 lstrcpyW(path2W, pathW);
1932 lstrcatW(path2W, fileext2W);
1934 handle = CreateFileW(path2W, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
1935 ok(handle != INVALID_HANDLE_VALUE, "Failed to create test file.\n");
1936 CloseHandle(handle);
1938 buffW[0] = 0;
1939 ret = SearchPathW(pathW, fileextW, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1940 ok(!ret, "Unexpected return value %u.\n", ret);
1942 buffW[0] = 0;
1943 ret = SearchPathW(pathW, fileextW, ext2W, ARRAY_SIZE(buffW), buffW, NULL);
1944 ok(!ret, "Unexpected return value %u.\n", ret);
1946 buffW[0] = 0;
1947 ret = SearchPathW(pathW, fileext2W, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1948 ok(ret && ret == lstrlenW(path2W), "got %d\n", ret);
1950 DeleteFileW(path2W);
1952 GetWindowsDirectoryW(pathW, ARRAY_SIZE(pathW));
1954 create_manifest_file("testdep1.manifest", manifest_dep);
1955 create_manifest_file("main.manifest", manifest_main);
1957 handle = test_create("main.manifest");
1958 delete_manifest_file("testdep1.manifest");
1959 delete_manifest_file("main.manifest");
1961 /* search fails without active context */
1962 ret = SearchPathW(NULL, testdepW, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1963 ok(ret == 0, "got %d\n", ret);
1965 ret = SearchPathW(NULL, kernel32dllW, NULL, ARRAY_SIZE(path2W), path2W, NULL);
1966 ok(ret && ret == lstrlenW(path2W), "got %d\n", ret);
1968 /* full path, name without 'dll' extension */
1969 GetSystemDirectoryW(pathW, ARRAY_SIZE(pathW));
1970 ret = SearchPathW(pathW, kernel32W, NULL, ARRAY_SIZE(path2W), path2W, NULL);
1971 ok(ret == 0, "got %d\n", ret);
1973 GetWindowsDirectoryW(pathW, ARRAY_SIZE(pathW));
1975 ret = ActivateActCtx(handle, &cookie);
1976 ok(ret, "failed to activate context, %u\n", GetLastError());
1978 /* works when activated */
1979 ret = SearchPathW(NULL, testdepW, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1980 ok(ret && ret == lstrlenW(buffW), "got %d\n", ret);
1982 ret = SearchPathW(NULL, testdepW, extW, ARRAY_SIZE(buffW), buffW, NULL);
1983 ok(ret && ret == lstrlenW(buffW), "got %d\n", ret);
1985 ret = SearchPathW(NULL, testdep1W, dllW, ARRAY_SIZE(buffW), buffW, NULL);
1986 ok(ret && ret == lstrlenW(buffW), "got %d\n", ret);
1988 ret = SearchPathW(NULL, testdep1W, extW, ARRAY_SIZE(buffW), buffW, NULL);
1989 ok(!ret, "got %d\n", ret);
1991 /* name contains path */
1992 ret = SearchPathW(NULL, testdeprelW, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1993 ok(!ret, "got %d\n", ret);
1995 /* fails with specified path that doesn't contain this file */
1996 ret = SearchPathW(pathW, testdepW, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1997 ok(!ret, "got %d\n", ret);
1999 /* path is redirected for wellknown names too, meaning it takes precedence over normal search order */
2000 ret = SearchPathW(NULL, kernel32dllW, NULL, ARRAY_SIZE(buffW), buffW, NULL);
2001 ok(ret && ret == lstrlenW(buffW), "got %d\n", ret);
2002 ok(lstrcmpW(buffW, path2W), "got wrong path %s, %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(path2W));
2004 /* path is built using on manifest file name */
2005 ret = SearchPathW(NULL, ole32W, NULL, ARRAY_SIZE(buffW), buffW, NULL);
2006 ok(ret && ret == lstrlenW(buffW), "got %d\n", ret);
2008 ret = DeactivateActCtx(0, cookie);
2009 ok(ret, "failed to deactivate context, %u\n", GetLastError());
2010 ReleaseActCtx(handle);
2013 static void test_GetFullPathNameA(void)
2015 char output[MAX_PATH], *filepart;
2016 DWORD ret;
2017 int i;
2018 UINT acp;
2020 const struct
2022 LPCSTR name;
2023 DWORD len;
2024 LPSTR buffer;
2025 LPSTR *lastpart;
2026 } invalid_parameters[] =
2028 {NULL, 0, NULL, NULL},
2029 {NULL, MAX_PATH, NULL, NULL},
2030 {NULL, MAX_PATH, output, NULL},
2031 {NULL, MAX_PATH, output, &filepart},
2032 {"", 0, NULL, NULL},
2033 {"", MAX_PATH, NULL, NULL},
2034 {"", MAX_PATH, output, NULL},
2035 {"", MAX_PATH, output, &filepart},
2038 for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++)
2040 SetLastError(0xdeadbeef);
2041 strcpy(output, "deadbeef");
2042 filepart = (char *)0xdeadbeef;
2043 ret = GetFullPathNameA(invalid_parameters[i].name,
2044 invalid_parameters[i].len,
2045 invalid_parameters[i].buffer,
2046 invalid_parameters[i].lastpart);
2047 ok(!ret, "[%d] Expected GetFullPathNameA to return 0, got %u\n", i, ret);
2048 ok(!strcmp(output, "deadbeef"), "[%d] Expected the output buffer to be unchanged, got \"%s\"\n", i, output);
2049 ok(filepart == (char *)0xdeadbeef, "[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
2050 ok(GetLastError() == 0xdeadbeef ||
2051 GetLastError() == ERROR_INVALID_NAME, /* Win7 */
2052 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
2053 i, GetLastError());
2056 acp = GetACP();
2057 if (acp != 932)
2058 skip("Skipping DBCS(Japanese) GetFullPathNameA test in this codepage (%d)\n", acp);
2059 else {
2060 const struct dbcs_case {
2061 const char *input;
2062 const char *expected;
2063 } testset[] = {
2064 { "c:\\a\\\x95\x5c\x97\xa0.txt", "\x95\x5c\x97\xa0.txt" },
2065 { "c:\\\x83\x8f\x83\x43\x83\x93\\wine.c", "wine.c" },
2066 { "c:\\demo\\\x97\xa0\x95\x5c", "\x97\xa0\x95\x5c" }
2068 for (i = 0; i < ARRAY_SIZE(testset); i++) {
2069 ret = GetFullPathNameA(testset[i].input, sizeof(output),
2070 output, &filepart);
2071 ok(ret, "[%d] GetFullPathName error %u\n", i, GetLastError());
2072 ok(!lstrcmpA(filepart, testset[i].expected),
2073 "[%d] expected %s got %s\n", i, testset[i].expected, filepart);
2078 static void test_GetFullPathNameW(void)
2080 static const WCHAR emptyW[] = {0};
2081 static const WCHAR deadbeefW[] = {'d','e','a','d','b','e','e','f',0};
2083 WCHAR output[MAX_PATH], *filepart;
2084 DWORD ret;
2085 int i;
2087 const struct
2089 LPCWSTR name;
2090 DWORD len;
2091 LPWSTR buffer;
2092 LPWSTR *lastpart;
2093 int win7_expect;
2094 } invalid_parameters[] =
2096 {NULL, 0, NULL, NULL},
2097 {NULL, 0, NULL, &filepart, 1},
2098 {NULL, MAX_PATH, NULL, NULL},
2099 {NULL, MAX_PATH, output, NULL},
2100 {NULL, MAX_PATH, output, &filepart, 1},
2101 {emptyW, 0, NULL, NULL},
2102 {emptyW, 0, NULL, &filepart, 1},
2103 {emptyW, MAX_PATH, NULL, NULL},
2104 {emptyW, MAX_PATH, output, NULL},
2105 {emptyW, MAX_PATH, output, &filepart, 1},
2108 SetLastError(0xdeadbeef);
2109 ret = GetFullPathNameW(NULL, 0, NULL, NULL);
2110 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2112 win_skip("GetFullPathNameW is not available\n");
2113 return;
2116 for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++)
2118 SetLastError(0xdeadbeef);
2119 lstrcpyW(output, deadbeefW);
2120 filepart = (WCHAR *)0xdeadbeef;
2121 ret = GetFullPathNameW(invalid_parameters[i].name,
2122 invalid_parameters[i].len,
2123 invalid_parameters[i].buffer,
2124 invalid_parameters[i].lastpart);
2125 ok(!ret, "[%d] Expected GetFullPathNameW to return 0, got %u\n", i, ret);
2126 ok(!lstrcmpW(output, deadbeefW), "[%d] Expected the output buffer to be unchanged, got %s\n", i, wine_dbgstr_w(output));
2127 ok(filepart == (WCHAR *)0xdeadbeef ||
2128 (invalid_parameters[i].win7_expect && filepart == NULL),
2129 "[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
2130 ok(GetLastError() == 0xdeadbeef ||
2131 GetLastError() == ERROR_INVALID_NAME, /* Win7 */
2132 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
2133 i, GetLastError());
2137 static void init_pointers(void)
2139 HMODULE mod = GetModuleHandleA("kernel32.dll");
2141 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(mod, #f))
2142 MAKEFUNC(NeedCurrentDirectoryForExePathA);
2143 MAKEFUNC(NeedCurrentDirectoryForExePathW);
2144 MAKEFUNC(SetSearchPathMode);
2145 MAKEFUNC(AddDllDirectory);
2146 MAKEFUNC(RemoveDllDirectory);
2147 MAKEFUNC(SetDllDirectoryW);
2148 MAKEFUNC(SetDefaultDllDirectories);
2149 MAKEFUNC(CheckNameLegalDOS8Dot3W);
2150 MAKEFUNC(CheckNameLegalDOS8Dot3A);
2151 mod = GetModuleHandleA("ntdll.dll");
2152 MAKEFUNC(LdrGetDllPath);
2153 MAKEFUNC(RtlGetExePath);
2154 MAKEFUNC(RtlGetSearchPath);
2155 MAKEFUNC(RtlReleasePath);
2156 #undef MAKEFUNC
2159 static void test_relative_path(void)
2161 char path[MAX_PATH], buf[MAX_PATH];
2162 HANDLE file;
2163 int ret;
2164 WCHAR curdir[MAX_PATH];
2166 GetCurrentDirectoryW(MAX_PATH, curdir);
2167 GetTempPathA(MAX_PATH, path);
2168 ret = SetCurrentDirectoryA(path);
2169 ok(ret, "SetCurrentDirectory error %d\n", GetLastError());
2171 ret = CreateDirectoryA("foo", NULL);
2172 ok(ret, "CreateDirectory error %d\n", GetLastError());
2173 file = CreateFileA("foo\\file", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
2174 ok(file != INVALID_HANDLE_VALUE, "failed to create temp file\n");
2175 CloseHandle(file);
2176 ret = CreateDirectoryA("bar", NULL);
2177 ok(ret, "CreateDirectory error %d\n", GetLastError());
2178 ret = SetCurrentDirectoryA("bar");
2179 ok(ret, "SetCurrentDirectory error %d\n", GetLastError());
2181 ret = GetFileAttributesA("..\\foo\\file");
2182 ok(ret != INVALID_FILE_ATTRIBUTES, "GetFileAttributes error %d\n", GetLastError());
2184 strcpy(buf, "deadbeef");
2185 ret = GetLongPathNameA(".", buf, MAX_PATH);
2186 ok(ret, "GetLongPathName error %d\n", GetLastError());
2187 ok(!strcmp(buf, "."), "expected ., got %s\n", buf);
2188 strcpy(buf, "deadbeef");
2189 ret = GetShortPathNameA(".", buf, MAX_PATH);
2190 ok(ret, "GetShortPathName error %d\n", GetLastError());
2191 ok(!strcmp(buf, "."), "expected ., got %s\n", buf);
2193 strcpy(buf, "deadbeef");
2194 ret = GetLongPathNameA("..", buf, MAX_PATH);
2195 ok(ret, "GetLongPathName error %d\n", GetLastError());
2196 ok(!strcmp(buf, ".."), "expected .., got %s\n", buf);
2197 strcpy(buf, "deadbeef");
2198 ret = GetShortPathNameA("..", buf, MAX_PATH);
2199 ok(ret, "GetShortPathName error %d\n", GetLastError());
2200 ok(!strcmp(buf, ".."), "expected .., got %s\n", buf);
2202 strcpy(buf, "deadbeef");
2203 ret = GetLongPathNameA("..\\foo\\file", buf, MAX_PATH);
2204 ok(ret, "GetLongPathName error %d\n", GetLastError());
2205 ok(!strcmp(buf, "..\\foo\\file"), "expected ..\\foo\\file, got %s\n", buf);
2206 strcpy(buf, "deadbeef");
2207 ret = GetShortPathNameA("..\\foo\\file", buf, MAX_PATH);
2208 ok(ret, "GetShortPathName error %d\n", GetLastError());
2209 ok(!strcmp(buf, "..\\foo\\file"), "expected ..\\foo\\file, got %s\n", buf);
2211 strcpy(buf, "deadbeef");
2212 ret = GetLongPathNameA(".\\..\\foo\\file", buf, MAX_PATH);
2213 ok(ret, "GetLongPathName error %d\n", GetLastError());
2214 ok(!strcmp(buf, ".\\..\\foo\\file"), "expected .\\..\\foo\\file, got %s\n", buf);
2215 strcpy(buf, "deadbeef");
2216 ret = GetShortPathNameA(".\\..\\foo\\file", buf, MAX_PATH);
2217 ok(ret, "GetShortPathName error %d\n", GetLastError());
2218 ok(!strcmp(buf, ".\\..\\foo\\file"), "expected .\\..\\foo\\file, got %s\n", buf);
2220 /* test double delimiters */
2221 strcpy(buf, "deadbeef");
2222 ret = GetLongPathNameA("..\\\\foo\\file", buf, MAX_PATH);
2223 ok(ret, "GetLongPathName error %d\n", GetLastError());
2224 ok(!strcmp(buf, "..\\\\foo\\file"), "expected ..\\\\foo\\file, got %s\n", buf);
2225 strcpy(buf, "deadbeef");
2226 ret = GetShortPathNameA("..\\\\foo\\file", buf, MAX_PATH);
2227 ok(ret, "GetShortPathName error %d\n", GetLastError());
2228 ok(!strcmp(buf, "..\\\\foo\\file"), "expected ..\\\\foo\\file, got %s\n", buf);
2230 SetCurrentDirectoryA("..");
2231 DeleteFileA("foo\\file");
2232 RemoveDirectoryA("foo");
2233 RemoveDirectoryA("bar");
2234 SetCurrentDirectoryW(curdir);
2237 static void test_CheckNameLegalDOS8Dot3(void)
2239 static const WCHAR has_driveW[] = {'C',':','\\','a','.','t','x','t',0};
2240 static const WCHAR has_pathW[] = {'b','\\','a','.','t','x','t',0};
2241 static const WCHAR too_longW[] = {'a','l','o','n','g','f','i','l','e','n','a','m','e','.','t','x','t',0};
2242 static const WCHAR twodotsW[] = {'t','e','s','t','.','e','s','t','.','t','x','t',0};
2243 static const WCHAR longextW[] = {'t','e','s','t','.','t','x','t','t','x','t',0};
2244 static const WCHAR emptyW[] = {0};
2245 static const WCHAR funnycharsW[] = {'!','#','$','%','&','\'','(',')','.','-','@','^',0};
2246 static const WCHAR length8W[] = {'t','e','s','t','t','e','s','t','.','t','x','t',0};
2247 static const WCHAR length1W[] = {'t',0};
2248 static const WCHAR withspaceW[] = {'t','e','s','t',' ','e','s','t','.','t','x','t',0};
2250 static const struct {
2251 const WCHAR *name;
2252 BOOL should_be_legal, has_space;
2253 } cases[] = {
2254 {has_driveW, FALSE, FALSE},
2255 {has_pathW, FALSE, FALSE},
2256 {too_longW, FALSE, FALSE},
2257 {twodotsW, FALSE, FALSE},
2258 {longextW, FALSE, FALSE},
2259 {emptyW, TRUE /* ! */, FALSE},
2260 {funnycharsW, TRUE, FALSE},
2261 {length8W, TRUE, FALSE},
2262 {length1W, TRUE, FALSE},
2263 {withspaceW, TRUE, TRUE},
2266 BOOL br, is_legal, has_space;
2267 char astr[64];
2268 DWORD i;
2270 if(!pCheckNameLegalDOS8Dot3W){
2271 win_skip("Missing CheckNameLegalDOS8Dot3, skipping tests\n");
2272 return;
2275 br = pCheckNameLegalDOS8Dot3W(NULL, NULL, 0, NULL, &is_legal);
2276 ok(br == FALSE, "CheckNameLegalDOS8Dot3W should have failed\n");
2278 br = pCheckNameLegalDOS8Dot3A(NULL, NULL, 0, NULL, &is_legal);
2279 ok(br == FALSE, "CheckNameLegalDOS8Dot3A should have failed\n");
2281 br = pCheckNameLegalDOS8Dot3W(length8W, NULL, 0, NULL, NULL);
2282 ok(br == FALSE, "CheckNameLegalDOS8Dot3W should have failed\n");
2284 br = pCheckNameLegalDOS8Dot3A("testtest.txt", NULL, 0, NULL, NULL);
2285 ok(br == FALSE, "CheckNameLegalDOS8Dot3A should have failed\n");
2287 for(i = 0; i < ARRAY_SIZE(cases); ++i){
2288 br = pCheckNameLegalDOS8Dot3W(cases[i].name, NULL, 0, &has_space, &is_legal);
2289 ok(br == TRUE, "CheckNameLegalDOS8Dot3W failed for %s\n", wine_dbgstr_w(cases[i].name));
2290 ok(is_legal == cases[i].should_be_legal, "Got wrong legality for %s\n", wine_dbgstr_w(cases[i].name));
2291 if(is_legal)
2292 ok(has_space == cases[i].has_space, "Got wrong space for %s\n", wine_dbgstr_w(cases[i].name));
2294 WideCharToMultiByte(CP_ACP, 0, cases[i].name, -1, astr, sizeof(astr), NULL, NULL);
2296 br = pCheckNameLegalDOS8Dot3A(astr, NULL, 0, &has_space, &is_legal);
2297 ok(br == TRUE, "CheckNameLegalDOS8Dot3W failed for %s\n", astr);
2298 ok(is_legal == cases[i].should_be_legal, "Got wrong legality for %s\n", astr);
2299 if(is_legal)
2300 ok(has_space == cases[i].has_space, "Got wrong space for %s\n", wine_dbgstr_w(cases[i].name));
2304 static void test_SetSearchPathMode(void)
2306 BOOL ret;
2307 char orig[MAX_PATH], buf[MAX_PATH], dir[MAX_PATH], expect[MAX_PATH];
2308 HANDLE handle;
2310 if (!pSetSearchPathMode)
2312 win_skip( "SetSearchPathMode isn't available\n" );
2313 return;
2315 GetCurrentDirectoryA( MAX_PATH, orig );
2316 GetTempPathA( MAX_PATH, buf );
2317 GetTempFileNameA( buf, "path", 0, dir );
2318 DeleteFileA( dir );
2319 CreateDirectoryA( dir, NULL );
2320 ret = SetCurrentDirectoryA( dir );
2321 ok( ret, "failed to switch to %s\n", dir );
2322 if (!ret)
2324 RemoveDirectoryA( dir );
2325 return;
2328 handle = CreateFileA( "kernel32.dll", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2329 CloseHandle( handle );
2331 SetLastError( 0xdeadbeef );
2332 ret = pSetSearchPathMode( 0 );
2333 ok( !ret, "SetSearchPathMode succeeded\n" );
2334 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
2336 SetLastError( 0xdeadbeef );
2337 ret = pSetSearchPathMode( 0x80 );
2338 ok( !ret, "SetSearchPathMode succeeded\n" );
2339 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
2341 SetLastError( 0xdeadbeef );
2342 ret = pSetSearchPathMode( BASE_SEARCH_PATH_PERMANENT );
2343 ok( !ret, "SetSearchPathMode succeeded\n" );
2344 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
2346 SetLastError( 0xdeadbeef );
2347 ret = SearchPathA( NULL, "kernel32.dll", NULL, MAX_PATH, buf, NULL );
2348 ok( ret, "SearchPathA failed err %u\n", GetLastError() );
2349 GetCurrentDirectoryA( MAX_PATH, expect );
2350 strcat( expect, "\\kernel32.dll" );
2351 ok( !lstrcmpiA( buf, expect ), "found %s expected %s\n", buf, expect );
2353 SetLastError( 0xdeadbeef );
2354 ret = pSetSearchPathMode( BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE );
2355 ok( ret, "SetSearchPathMode failed err %u\n", GetLastError() );
2357 SetLastError( 0xdeadbeef );
2358 ret = SearchPathA( NULL, "kernel32.dll", NULL, MAX_PATH, buf, NULL );
2359 ok( ret, "SearchPathA failed err %u\n", GetLastError() );
2360 GetSystemDirectoryA( expect, MAX_PATH );
2361 strcat( expect, "\\kernel32.dll" );
2362 ok( !lstrcmpiA( buf, expect ), "found %s expected %s\n", buf, expect );
2364 SetLastError( 0xdeadbeef );
2365 ret = pSetSearchPathMode( BASE_SEARCH_PATH_DISABLE_SAFE_SEARCHMODE );
2366 ok( ret, "SetSearchPathMode failed err %u\n", GetLastError() );
2368 SetLastError( 0xdeadbeef );
2369 ret = SearchPathA( NULL, "kernel32.dll", NULL, MAX_PATH, buf, NULL );
2370 ok( ret, "SearchPathA failed err %u\n", GetLastError() );
2371 GetCurrentDirectoryA( MAX_PATH, expect );
2372 strcat( expect, "\\kernel32.dll" );
2373 ok( !lstrcmpiA( buf, expect ), "found %s expected %s\n", buf, expect );
2375 SetLastError( 0xdeadbeef );
2376 ret = pSetSearchPathMode( BASE_SEARCH_PATH_DISABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT );
2377 ok( !ret, "SetSearchPathMode succeeded\n" );
2378 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
2380 SetLastError( 0xdeadbeef );
2381 ret = pSetSearchPathMode( BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT );
2382 ok( ret, "SetSearchPathMode failed err %u\n", GetLastError() );
2384 SetLastError( 0xdeadbeef );
2385 ret = pSetSearchPathMode( BASE_SEARCH_PATH_DISABLE_SAFE_SEARCHMODE );
2386 ok( !ret, "SetSearchPathMode succeeded\n" );
2387 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
2389 SetLastError( 0xdeadbeef );
2390 ret = pSetSearchPathMode( BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE );
2391 ok( !ret, "SetSearchPathMode succeeded\n" );
2392 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
2394 SetLastError( 0xdeadbeef );
2395 ret = pSetSearchPathMode( BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT );
2396 ok( ret, "SetSearchPathMode failed err %u\n", GetLastError() );
2398 SetLastError( 0xdeadbeef );
2399 ret = SearchPathA( NULL, "kernel32.dll", NULL, MAX_PATH, buf, NULL );
2400 ok( ret, "SearchPathA failed err %u\n", GetLastError() );
2401 GetSystemDirectoryA( expect, MAX_PATH );
2402 strcat( expect, "\\kernel32.dll" );
2403 ok( !lstrcmpiA( buf, expect ), "found %s expected %s\n", buf, expect );
2405 DeleteFileA( "kernel32.dll" );
2406 SetCurrentDirectoryA( orig );
2407 RemoveDirectoryA( dir );
2410 static const WCHAR pathW[] = {'P','A','T','H',0};
2412 static void build_search_path( WCHAR *buffer, UINT size, const WCHAR *dlldir, BOOL safe )
2414 WCHAR *p;
2415 GetModuleFileNameW( NULL, buffer, size );
2416 if (!(p = wcsrchr( buffer, '\\' ))) return;
2417 *p++ = ';';
2418 if (dlldir)
2420 lstrcpyW( p, dlldir );
2421 p += lstrlenW( p );
2422 if (*dlldir) *p++ = ';';
2424 else if (!safe)
2426 *p++ = '.';
2427 *p++ = ';';
2429 GetSystemDirectoryW( p, buffer + size - p );
2430 p = buffer + lstrlenW(buffer);
2431 *p++ = ';';
2432 GetSystemDirectoryW( p, buffer + size - p );
2433 p = buffer + lstrlenW(buffer) - 2; /* remove "32" */
2434 *p++ = ';';
2435 GetWindowsDirectoryW( p, buffer + size - p );
2436 p = buffer + lstrlenW(buffer);
2437 *p++ = ';';
2438 if (!dlldir && safe)
2440 *p++ = '.';
2441 *p++ = ';';
2443 GetEnvironmentVariableW( pathW, p, buffer + size - p );
2446 static BOOL path_equal( const WCHAR *path1, const WCHAR *path2 )
2448 for (;;)
2450 while (*path1 && towlower(*path1) == towlower(*path2)) { path1++; path2++; }
2451 if (*path1 && *path1 != '\\' && *path1 != ';') return FALSE;
2452 while (*path1 && (*path1 == '\\' || *path1 == ';')) path1++;
2453 while (*path2 && (*path2 == '\\' || *path2 == ';')) path2++;
2454 if (!*path1 || !*path2) return !*path1 && !*path2;
2458 static void test_RtlGetSearchPath(void)
2460 NTSTATUS ret;
2461 WCHAR *path;
2462 WCHAR buffer[2048], old_path[2048], dlldir[4];
2464 if (!pRtlGetSearchPath)
2466 win_skip( "RtlGetSearchPath isn't available\n" );
2467 return;
2470 GetEnvironmentVariableW( pathW, old_path, ARRAY_SIZE(old_path) );
2471 GetWindowsDirectoryW( buffer, ARRAY_SIZE(buffer) );
2472 lstrcpynW( dlldir, buffer, ARRAY_SIZE(dlldir) );
2474 build_search_path( buffer, ARRAY_SIZE(buffer), NULL, TRUE );
2475 path = (WCHAR *)0xdeadbeef;
2476 ret = pRtlGetSearchPath( &path );
2477 ok( !ret, "RtlGetSearchPath failed %x\n", ret );
2478 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2479 pRtlReleasePath( path );
2481 SetEnvironmentVariableA( "PATH", "foo" );
2482 build_search_path( buffer, ARRAY_SIZE(buffer), NULL, TRUE );
2483 path = (WCHAR *)0xdeadbeef;
2484 ret = pRtlGetSearchPath( &path );
2485 ok( !ret, "RtlGetSearchPath failed %x\n", ret );
2486 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2487 pRtlReleasePath( path );
2489 if (pSetDllDirectoryW)
2491 ok( pSetDllDirectoryW( dlldir ), "SetDllDirectoryW failed\n" );
2492 build_search_path( buffer, ARRAY_SIZE(buffer), NULL, TRUE );
2493 path = (WCHAR *)0xdeadbeef;
2494 ret = pRtlGetSearchPath( &path );
2495 ok( !ret, "RtlGetSearchPath failed %x\n", ret );
2496 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2497 pRtlReleasePath( path );
2498 pSetDllDirectoryW( NULL );
2501 SetEnvironmentVariableW( pathW, old_path );
2504 static void test_RtlGetExePath(void)
2506 static const WCHAR fooW[] = {'\\','f','o','o',0};
2507 static const WCHAR emptyW[1];
2508 NTSTATUS ret;
2509 WCHAR *path;
2510 WCHAR buffer[2048], old_path[2048], dlldir[4];
2512 if (!pRtlGetExePath)
2514 win_skip( "RtlGetExePath isn't available\n" );
2515 return;
2518 GetEnvironmentVariableW( pathW, old_path, ARRAY_SIZE(old_path) );
2519 GetWindowsDirectoryW( buffer, ARRAY_SIZE(buffer) );
2520 lstrcpynW( dlldir, buffer, ARRAY_SIZE(dlldir) );
2521 SetEnvironmentVariableA( "NoDefaultCurrentDirectoryInExePath", NULL );
2523 build_search_path( buffer, ARRAY_SIZE(buffer), NULL, FALSE );
2524 path = (WCHAR *)0xdeadbeef;
2525 ret = pRtlGetExePath( fooW, &path );
2526 ok( !ret, "RtlGetExePath failed %x\n", ret );
2527 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2528 pRtlReleasePath( path );
2530 build_search_path( buffer, ARRAY_SIZE(buffer), NULL, FALSE );
2531 path = (WCHAR *)0xdeadbeef;
2532 ret = pRtlGetExePath( fooW + 1, &path );
2533 ok( !ret, "RtlGetExePath failed %x\n", ret );
2534 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2535 pRtlReleasePath( path );
2537 SetEnvironmentVariableA( "NoDefaultCurrentDirectoryInExePath", "yes" );
2539 build_search_path( buffer, ARRAY_SIZE(buffer), NULL, FALSE );
2540 path = (WCHAR *)0xdeadbeef;
2541 ret = pRtlGetExePath( fooW, &path );
2542 ok( !ret, "RtlGetExePath failed %x\n", ret );
2543 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2544 pRtlReleasePath( path );
2546 build_search_path( buffer, ARRAY_SIZE(buffer), emptyW, TRUE );
2547 path = (WCHAR *)0xdeadbeef;
2548 ret = pRtlGetExePath( fooW + 1, &path );
2549 ok( !ret, "RtlGetExePath failed %x\n", ret );
2550 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2551 pRtlReleasePath( path );
2553 SetEnvironmentVariableA( "PATH", "foo" );
2554 build_search_path( buffer, ARRAY_SIZE(buffer), NULL, FALSE );
2555 path = (WCHAR *)0xdeadbeef;
2556 ret = pRtlGetExePath( fooW, &path );
2557 ok( !ret, "RtlGetExePath failed %x\n", ret );
2558 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2559 pRtlReleasePath( path );
2561 if (pSetDllDirectoryW)
2563 ok( pSetDllDirectoryW( dlldir ), "SetDllDirectoryW failed\n" );
2564 build_search_path( buffer, ARRAY_SIZE(buffer), NULL, FALSE );
2565 path = (WCHAR *)0xdeadbeef;
2566 ret = pRtlGetExePath( fooW, &path );
2567 ok( !ret, "RtlGetExePath failed %x\n", ret );
2568 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2569 pRtlReleasePath( path );
2570 pSetDllDirectoryW( NULL );
2573 SetEnvironmentVariableW( pathW, old_path );
2576 static void test_LdrGetDllPath(void)
2578 static const WCHAR fooW[] = {'f','o','o',0};
2579 NTSTATUS ret;
2580 WCHAR *path, *unknown_ptr, *p;
2581 WCHAR buffer[2048], old_path[2048], dlldir[4];
2583 if (!pLdrGetDllPath)
2585 win_skip( "LdrGetDllPath isn't available\n" );
2586 return;
2588 GetEnvironmentVariableW( pathW, old_path, ARRAY_SIZE(old_path) );
2589 GetWindowsDirectoryW( buffer, ARRAY_SIZE(buffer) );
2590 lstrcpynW( dlldir, buffer, ARRAY_SIZE(dlldir) );
2592 build_search_path( buffer, ARRAY_SIZE(buffer), NULL, TRUE );
2594 path = unknown_ptr = (WCHAR *)0xdeadbeef;
2595 ret = pLdrGetDllPath( 0, 0, &path, &unknown_ptr );
2596 ok( !ret, "LdrGetDllPath failed %x\n", ret );
2597 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2598 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2599 pRtlReleasePath( path );
2601 SetEnvironmentVariableA( "PATH", "foo" );
2602 build_search_path( buffer, ARRAY_SIZE(buffer), NULL, TRUE );
2603 ret = pLdrGetDllPath( 0, 0, &path, &unknown_ptr );
2604 ok( !ret, "LdrGetDllPath failed %x\n", ret );
2605 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2606 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2607 pRtlReleasePath( path );
2609 if (pSetDllDirectoryW)
2611 ok( pSetDllDirectoryW( dlldir ), "SetDllDirectoryW failed\n" );
2612 build_search_path( buffer, ARRAY_SIZE(buffer), dlldir, TRUE );
2613 ret = pLdrGetDllPath( 0, 0, &path, &unknown_ptr );
2614 ok( !ret, "LdrGetDllPath failed %x\n", ret );
2615 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2616 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2617 pRtlReleasePath( path );
2618 pSetDllDirectoryW( NULL );
2621 ret = pLdrGetDllPath( 0, LOAD_LIBRARY_SEARCH_SYSTEM32, &path, &unknown_ptr );
2622 ok( !ret, "LdrGetDllPath failed %x\n", ret );
2623 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2624 GetSystemDirectoryW( buffer, ARRAY_SIZE(buffer) );
2625 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2626 pRtlReleasePath( path );
2628 ret = pLdrGetDllPath( 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR, &path, &unknown_ptr );
2629 ok( !ret, "LdrGetDllPath failed %x\n", ret );
2630 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2631 GetModuleFileNameW( NULL, buffer, ARRAY_SIZE(buffer) );
2632 if ((p = wcsrchr( buffer, '\\' ))) *p = 0;
2633 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2634 pRtlReleasePath( path );
2636 ret = pLdrGetDllPath( fooW, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, &path, &unknown_ptr );
2637 ok( ret == STATUS_INVALID_PARAMETER, "LdrGetDllPath failed %x\n", ret );
2639 lstrcpyW( buffer, L"\\\\?\\" );
2640 lstrcatW( buffer, dlldir );
2641 p = buffer + lstrlenW(buffer);
2642 *p++ = '\\';
2643 lstrcpyW( p, fooW );
2644 ret = pLdrGetDllPath( buffer, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, &path, &unknown_ptr );
2645 ok( !ret, "LdrGetDllPath failed %x\n", ret );
2646 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2647 ok( !memcmp( path, L"\\\\?\\", 4 * sizeof(WCHAR) ) && path_equal( path + 4, dlldir ),
2648 "got %s expected \\\\?\\%s\n", wine_dbgstr_w(path), wine_dbgstr_w(dlldir));
2649 pRtlReleasePath( path );
2651 ret = pLdrGetDllPath( L"\\\\?\\c:\\test.dll", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, &path, &unknown_ptr );
2652 ok( !ret, "LdrGetDllPath failed %x\n", ret );
2653 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2654 ok( !lstrcmpW( path, L"\\\\?\\c:" ), "got %s expected \\\\?\\c:\n", wine_dbgstr_w(path));
2655 pRtlReleasePath( path );
2657 lstrcpyW( buffer, dlldir );
2658 p = buffer + lstrlenW(buffer);
2659 *p++ = '\\';
2660 lstrcpyW( p, fooW );
2661 ret = pLdrGetDllPath( buffer, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, &path, &unknown_ptr );
2662 ok( !ret, "LdrGetDllPath failed %x\n", ret );
2663 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2664 ok( path_equal( path, dlldir ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(dlldir));
2665 pRtlReleasePath( path );
2667 if (pAddDllDirectory)
2669 DLL_DIRECTORY_COOKIE cookie = pAddDllDirectory( dlldir );
2670 ok( !!cookie, "AddDllDirectory failed\n" );
2671 ret = pLdrGetDllPath( 0, LOAD_LIBRARY_SEARCH_USER_DIRS, &path, &unknown_ptr );
2672 ok( !ret, "LdrGetDllPath failed %x\n", ret );
2673 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2674 ok( path_equal( path, dlldir ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(dlldir));
2675 pRtlReleasePath( path );
2676 pRemoveDllDirectory( cookie );
2679 if (pSetDefaultDllDirectories)
2681 pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_SYSTEM32 );
2682 ret = pLdrGetDllPath( 0, 0, &path, &unknown_ptr );
2683 ok( !ret, "LdrGetDllPath failed %x\n", ret );
2684 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2685 GetSystemDirectoryW( buffer, ARRAY_SIZE(buffer) );
2686 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2687 pRtlReleasePath( path );
2688 pSetDefaultDllDirectories( 0 );
2691 SetEnvironmentVariableW( pathW, old_path );
2694 START_TEST(path)
2696 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
2698 init_pointers();
2700 test_relative_path();
2701 test_InitPathA(curdir, &curDrive, &otherDrive);
2702 test_CurrentDirectoryA(origdir,curdir);
2703 test_PathNameA(curdir, curDrive, otherDrive);
2704 test_CleanupPathA(origdir,curdir);
2705 test_GetTempPath();
2706 test_GetLongPathNameA();
2707 test_GetLongPathNameW();
2708 test_GetShortPathNameW();
2709 test_GetSystemDirectory();
2710 test_GetWindowsDirectory();
2711 test_NeedCurrentDirectoryForExePathA();
2712 test_NeedCurrentDirectoryForExePathW();
2713 test_drive_letter_case();
2714 test_SearchPathA();
2715 test_SearchPathW();
2716 test_GetFullPathNameA();
2717 test_GetFullPathNameW();
2718 test_CheckNameLegalDOS8Dot3();
2719 test_SetSearchPathMode();
2720 test_RtlGetSearchPath();
2721 test_RtlGetExePath();
2722 test_LdrGetDllPath();