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
24 #include "wine/test.h"
31 #define HAS_TRAIL_SLASH_A(string) (string[lstrlenA(string)-1]=='\\')
33 #define LONGFILE "Long File test.path"
34 #define SHORTFILE "pathtest.pth"
35 #define SHORTDIR "shortdir"
36 #define LONGDIR "Long Directory"
37 #define NONFILE_SHORT "noexist.pth"
38 #define NONFILE_LONG "NonExistent File"
39 #define NONDIR_SHORT "notadir"
40 #define NONDIR_LONG "NonExistent Directory"
42 #define NOT_A_VALID_DRIVE '@'
44 /* the following characters don't work well with GetFullPathNameA
45 in Win98. I don't know if this is a FAT thing, or if it is an OS thing
46 but I don't test these characters now.
47 NOTE: Win2k allows GetFullPathNameA to work with them though
50 static const CHAR funny_chars[]="!@#$%^&*()=+{}[],?'`";
51 static const CHAR is_char_ok[] ="11111110111111111011";
53 static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR,LPSTR,DWORD);
54 static DWORD (WINAPI *pGetLongPathNameW)(LPWSTR,LPWSTR,DWORD);
56 /* Present in Win2003+ */
57 static BOOL (WINAPI *pNeedCurrentDirectoryForExePathA)(LPCSTR);
58 static BOOL (WINAPI *pNeedCurrentDirectoryForExePathW)(LPCWSTR);
60 static DWORD (WINAPI *pSearchPathA)(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*);
61 static DWORD (WINAPI *pSearchPathW)(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,LPWSTR,LPWSTR*);
63 /* a structure to deal with wine todos somewhat cleanly */
73 /* function that tests GetFullPathNameA, GetShortPathNameA,GetLongPathNameA */
74 /* NOTE: the passfail structure is used to allow customizable todo checking
75 for wine. It is not very pretty, but it sure beats duplicating this
76 function lots of times
78 static void test_ValidPathA(const CHAR *curdir, const CHAR *subdir, const CHAR *filename,
79 CHAR *shortstr, SLpassfail *passfail, const CHAR *errstr)
81 CHAR tmpstr[MAX_PATH],
82 fullpath[MAX_PATH], /*full path to the file (not short/long) */
83 subpath[MAX_PATH], /*relative path to the file */
84 fullpathshort[MAX_PATH], /*absolute path to the file (short format) */
85 fullpathlong[MAX_PATH], /*absolute path to the file (long format) */
86 curdirshort[MAX_PATH], /*absolute path to the current dir (short) */
87 curdirlong[MAX_PATH]; /*absolute path to the current dir (long) */
88 LPSTR strptr; /*ptr to the filename portion of the path */
90 /* if passfail is NULL, we can perform all checks within this function,
91 otherwise, we will return the relevant data in the passfail struct, so
92 we must initialize it first
95 passfail->shortlen=-1;passfail->s2llen=-1;passfail->longlen=-1;
96 passfail->shorterror=0;passfail->s2lerror=0;passfail->longerror=0;
98 /* GetLongPathNameA is only supported on Win2k+ and Win98+ */
99 if(pGetLongPathNameA) {
100 ok((len=pGetLongPathNameA(curdir,curdirlong,MAX_PATH)),
101 "%s: GetLongPathNameA failed\n",errstr);
102 /*GetLongPathNameA can return a trailing '\\' but shouldn't do so here */
103 ok(! HAS_TRAIL_SLASH_A(curdirlong),
104 "%s: GetLongPathNameA should not have a trailing \\\n",errstr);
106 ok((len=GetShortPathNameA(curdir,curdirshort,MAX_PATH)),
107 "%s: GetShortPathNameA failed\n",errstr);
108 /*GetShortPathNameA can return a trailing '\\' but shouldn't do so here */
109 ok(! HAS_TRAIL_SLASH_A(curdirshort),
110 "%s: GetShortPathNameA should not have a trailing \\\n",errstr);
111 /* build relative and absolute paths from inputs */
112 if(lstrlenA(subdir)) {
113 sprintf(subpath,"%s\\%s",subdir,filename);
115 lstrcpyA(subpath,filename);
117 sprintf(fullpath,"%s\\%s",curdir,subpath);
118 sprintf(fullpathshort,"%s\\%s",curdirshort,subpath);
119 sprintf(fullpathlong,"%s\\%s",curdirlong,subpath);
120 /* Test GetFullPathNameA functionality */
121 len=GetFullPathNameA(subpath,MAX_PATH,tmpstr,&strptr);
122 ok(len, "GetFullPathNameA failed for: '%s'\n",subpath);
123 if(HAS_TRAIL_SLASH_A(subpath)) {
125 "%s: GetFullPathNameA should not return a filename ptr\n",errstr);
126 ok(lstrcmpiA(fullpath,tmpstr)==0,
127 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
128 errstr,tmpstr,fullpath);
130 ok(lstrcmpiA(strptr,filename)==0,
131 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
132 errstr,strptr,filename);
133 ok(lstrcmpiA(fullpath,tmpstr)==0,
134 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
135 errstr,tmpstr,fullpath);
137 /* Test GetShortPathNameA functionality */
139 len=GetShortPathNameA(fullpathshort,shortstr,MAX_PATH);
141 ok(len, "%s: GetShortPathNameA failed\n",errstr);
143 passfail->shortlen=len;
144 passfail->shorterror=GetLastError();
146 /* Test GetLongPathNameA functionality
147 We test both conversion from GetFullPathNameA and from GetShortPathNameA
149 if(pGetLongPathNameA) {
152 len=pGetLongPathNameA(shortstr,tmpstr,MAX_PATH);
155 "%s: GetLongPathNameA failed during Short->Long conversion\n", errstr);
156 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
157 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
158 errstr,tmpstr,fullpathlong);
160 passfail->s2llen=len;
161 passfail->s2lerror=GetLastError();
165 len=pGetLongPathNameA(fullpath,tmpstr,MAX_PATH);
167 ok(len, "%s: GetLongPathNameA failed\n",errstr);
168 if(HAS_TRAIL_SLASH_A(fullpath)) {
169 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
170 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
171 errstr,tmpstr,fullpathlong);
173 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
174 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
175 errstr,tmpstr,fullpathlong);
178 passfail->longlen=len;
179 passfail->longerror=GetLastError();
184 /* split path into leading directory, and 8.3 filename */
185 static void test_SplitShortPathA(CHAR *path,CHAR *dir,CHAR *eight,CHAR *three) {
190 ext=len; fil=len; done=0; error=0;
191 /* walk backwards over path looking for '.' or '\\' separators */
192 for(i=len-1;(i>=0) && (!done);i--) {
194 if(ext!=len) error=1; else ext=i;
195 else if(path[i]=='\\') {
204 /* Check that we didn't find a trailing '\\' or multiple '.' */
205 ok(!error,"Illegal file found in 8.3 path '%s'\n",path);
206 /* Separate dir, root, and extension */
207 if(ext!=len) lstrcpyA(three,path+ext+1); else lstrcpyA(three,"");
209 lstrcpynA(eight,path+fil+1,ext-fil);
210 lstrcpynA(dir,path,fil+1);
212 lstrcpynA(eight,path,ext+1);
215 /* Validate that root and extension really are 8.3 */
216 ok(lstrlenA(eight)<=8 && lstrlenA(three)<=3,
217 "GetShortPathNAmeA did not return an 8.3 path\n");
220 /* Check that GetShortPathNameA returns a valid 8.3 path */
221 static void test_LongtoShortA(CHAR *teststr,const CHAR *goodstr,
222 const CHAR *ext,const CHAR *errstr) {
223 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
225 test_SplitShortPathA(teststr,dir,eight,three);
226 ok(lstrcmpiA(dir,goodstr)==0,
227 "GetShortPathNameA returned '%s' instead of '%s'\n",dir,goodstr);
228 ok(lstrcmpiA(three,ext)==0,
229 "GetShortPathNameA returned '%s' with incorrect extension\n",three);
232 /* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
233 characters in the filename.
234 'valid' indicates whether this would be an allowed filename
235 'todo' indicates that wine doesn't get this right yet.
236 NOTE: We always call this routine with a nonexistent filename, so
237 Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
240 static void test_FunnyChars(CHAR *curdir,CHAR *curdir_short,CHAR *filename, INT valid,CHAR *errstr)
242 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
245 test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
247 sprintf(tmpstr1,"%s\\%s",curdir_short,filename);
248 ok((passfail.shortlen==0 &&
249 (passfail.shorterror==ERROR_FILE_NOT_FOUND || passfail.shorterror==ERROR_PATH_NOT_FOUND || !passfail.shorterror)) ||
250 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
251 "%s: GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
252 errstr,passfail.shortlen,passfail.shorterror,tmpstr);
254 ok(passfail.shortlen==0 &&
255 (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),
256 "%s: GetShortPathA should have failed len=%d, error=%d\n",
257 errstr,passfail.shortlen,passfail.shorterror);
259 if(pGetLongPathNameA) {
260 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
262 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
263 "%s: GetLongPathA returned %d and not %d\n",
264 errstr,passfail.longerror,ERROR_FILE_NOT_FOUND);
266 ok(passfail.longerror==ERROR_INVALID_NAME ||
267 passfail.longerror==ERROR_FILE_NOT_FOUND,
268 "%s: GetLongPathA returned %d and not %d or %d'\n",
269 errstr, passfail.longerror,ERROR_INVALID_NAME,ERROR_FILE_NOT_FOUND);
274 /* Routine to test that SetCurrentDirectory behaves as expected. */
275 static void test_setdir(CHAR *olddir,CHAR *newdir,
276 CHAR *cmprstr, INT pass, const CHAR *errstr)
278 CHAR tmppath[MAX_PATH], *dirptr;
279 DWORD val,len,chklen;
281 val=SetCurrentDirectoryA(newdir);
282 len=GetCurrentDirectoryA(MAX_PATH,tmppath);
283 /* if 'pass' then the SetDirectoryA was supposed to pass */
285 dirptr=(cmprstr==NULL) ? newdir : cmprstr;
286 chklen=lstrlenA(dirptr);
287 ok(val,"%s: SetCurrentDirectoryA failed\n",errstr);
289 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
291 ok(lstrcmpiA(dirptr,tmppath)==0,
292 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
294 ok(SetCurrentDirectoryA(olddir),
295 "%s: Couldn't set directory to it's original value\n",errstr);
297 /* else thest that it fails correctly */
298 chklen=lstrlenA(olddir);
300 "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr);
302 "%s: SetCurrentDirectory changed the directory, though it failed\n",
304 ok(lstrcmpiA(olddir,tmppath)==0,
305 "%s: SetCurrentDirectory changed the directory, though it failed\n",
309 static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
311 CHAR tmppath[MAX_PATH], /*path to TEMP */
314 invalid_dir[MAX_PATH];
316 DWORD len,len1,drives;
322 *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
324 /* Get the current drive letter */
325 if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
326 *curDrive = tmpstr[0];
328 trace( "Unable to discover current drive, some tests will not be conducted.\n");
330 /* Test GetTempPathA */
331 len=GetTempPathA(MAX_PATH,tmppath);
332 ok(len!=0 && len < MAX_PATH,"GetTempPathA failed\n");
333 ok(HAS_TRAIL_SLASH_A(tmppath),
334 "GetTempPathA returned a path that did not end in '\\'\n");
335 lstrcpyA(tmpstr,"aaaaaaaa");
336 len1=GetTempPathA(len,tmpstr);
337 ok(len1==len+1 || broken(len1 == len), /* WinME */
338 "GetTempPathA should return string length %d instead of %d\n",len+1,len1);
340 /* Test GetTmpFileNameA */
341 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
342 sprintf(tmpstr,"pat%.4x.tmp",id & 0xffff);
343 sprintf(tmpstr1,"pat%x.tmp",id & 0xffff);
344 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
345 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
346 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
347 newdir,tmpstr,tmpstr1,id);
348 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
350 id=GetTempFileNameA(tmppath,NULL,0,newdir);
351 /* Windows 95, 98 return 0==id, while Windows 2000, XP return 0!=id */
354 sprintf(tmpstr,"%.4x.tmp",id & 0xffff);
355 sprintf(tmpstr1,"%x.tmp",id & 0xffff);
356 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
357 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
358 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
359 newdir,tmpstr,tmpstr1,id);
360 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
363 for(unique=0;unique<3;unique++) {
364 /* Nonexistent path */
365 sprintf(invalid_dir, "%s\\%s",tmppath,"non_existent_dir_1jwj3y32nb3");
366 SetLastError(0xdeadbeef);
367 ok(!GetTempFileNameA(invalid_dir,"tfn",unique,newdir),"GetTempFileNameA should have failed\n");
368 ok(GetLastError()==ERROR_DIRECTORY || broken(GetLastError()==ERROR_PATH_NOT_FOUND)/*win98*/,
369 "got %d, expected ERROR_DIRECTORY\n", GetLastError());
371 /* Check return value for unique !=0 */
373 ok((GetTempFileNameA(tmppath,"tfn",unique,newdir) == unique),"GetTempFileNameA unexpectedly failed\n");
374 /* if unique != 0, the actual temp files are not created: */
375 ok(!DeleteFileA(newdir) && GetLastError() == ERROR_FILE_NOT_FOUND,"Deleted a file that shouldn't exist!\n");
379 /* Find first valid drive letter that is neither newdir[0] nor curDrive */
380 drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
381 if( *curDrive != NOT_A_VALID_DRIVE)
382 drives &= ~(1<<(*curDrive-'A'));
384 for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
386 trace( "Could not find alternative drive, some tests will not be conducted.\n");
388 /* Do some CreateDirectoryA tests */
389 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
390 really understand how they work.
391 More formal tests should be done along with CreateFile tests
393 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
394 ok(CreateDirectoryA(newdir,NULL)==0,
395 "CreateDirectoryA succeeded even though a file of the same name exists\n");
396 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
397 ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
398 /* Create some files to test other functions. Note, we will test CreateFileA
401 sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
402 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
403 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
404 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
405 sprintf(tmpstr,"%c:", *curDrive);
406 bRes = CreateDirectoryA(tmpstr,NULL);
407 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
408 GetLastError() == ERROR_ALREADY_EXISTS),
409 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
410 sprintf(tmpstr,"%c:\\", *curDrive);
411 bRes = CreateDirectoryA(tmpstr,NULL);
412 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
413 GetLastError() == ERROR_ALREADY_EXISTS),
414 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
415 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
416 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
417 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
418 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
419 ok(CloseHandle(hndl),"CloseHandle failed\n");
420 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
421 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
422 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
423 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
424 ok(CloseHandle(hndl),"CloseHandle failed\n");
425 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
426 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
427 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
428 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
429 ok(CloseHandle(hndl),"CloseHandle failed\n");
430 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
431 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
432 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
433 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
434 ok(CloseHandle(hndl),"CloseHandle failed\n");
437 /* Test GetCurrentDirectory & SetCurrentDirectory */
438 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
440 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
443 /* Save the original directory, so that we can return to it at the end
446 len=GetCurrentDirectoryA(MAX_PATH,origdir);
447 ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
448 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
449 buffer size is too small to hold the current directory
451 lstrcpyA(tmpstr,"aaaaaaa");
452 len1=GetCurrentDirectoryA(len,tmpstr);
453 ok(len1==len+1, "GetCurrentDirectoryA returned %d instead of %d\n",len1,len+1);
454 ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
455 "GetCurrentDirectoryA should not have modified the buffer\n");
457 buffer = HeapAlloc( GetProcessHeap(), 0, 2 * 65536 );
458 SetLastError( 0xdeadbeef );
459 strcpy( buffer, "foo" );
460 len = GetCurrentDirectoryA( 32767, buffer );
461 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
462 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
463 SetLastError( 0xdeadbeef );
464 strcpy( buffer, "foo" );
465 len = GetCurrentDirectoryA( 32768, buffer );
466 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
467 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
468 SetLastError( 0xdeadbeef );
469 strcpy( buffer, "foo" );
470 len = GetCurrentDirectoryA( 65535, buffer );
471 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4, win2k, xp */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
472 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
473 SetLastError( 0xdeadbeef );
474 strcpy( buffer, "foo" );
475 len = GetCurrentDirectoryA( 65536, buffer );
476 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4 */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
477 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
478 SetLastError( 0xdeadbeef );
479 strcpy( buffer, "foo" );
480 len = GetCurrentDirectoryA( 2 * 65536, buffer );
481 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4 */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
482 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
483 HeapFree( GetProcessHeap(), 0, buffer );
485 /* Check for crash prevention on swapped args. Crashes all but Win9x.
489 SetLastError( 0xdeadbeef );
490 len = GetCurrentDirectoryA( 42, (LPSTR)(MAX_PATH + 42) );
491 ok( len == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
492 "GetCurrentDirectoryA failed to fail %u err %u\n", len, GetLastError() );
495 /* SetCurrentDirectoryA shouldn't care whether the string has a
498 sprintf(tmpstr,"%s\\",newdir);
499 test_setdir(origdir,tmpstr,newdir,1,"check 1");
500 test_setdir(origdir,newdir,NULL,1,"check 2");
501 /* Set the directory to the working area. We just tested that this works,
502 so why check it again.
504 SetCurrentDirectoryA(newdir);
505 /* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
506 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
507 test_setdir(newdir,tmpstr,NULL,0,"check 3");
508 /* Check that SetCurrentDirectory fails for a nonexistent lond directory */
509 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
510 test_setdir(newdir,tmpstr,NULL,0,"check 4");
511 /* Check that SetCurrentDirectory passes with a long directory */
512 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
513 test_setdir(newdir,tmpstr,NULL,1,"check 5");
514 /* Check that SetCurrentDirectory passes with a short relative directory */
515 sprintf(tmpstr,"%s",SHORTDIR);
516 sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
517 test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
518 /* starting with a '.' */
519 sprintf(tmpstr,".\\%s",SHORTDIR);
520 test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
521 /* Check that SetCurrentDirectory passes with a short relative directory */
522 sprintf(tmpstr,"%s",LONGDIR);
523 sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
524 test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
525 /* starting with a '.' */
526 sprintf(tmpstr,".\\%s",LONGDIR);
527 test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
528 /* change to root without a trailing backslash. The function call succeeds
529 but the directory is not changed.
531 sprintf(tmpstr, "%c:", newdir[0]);
532 test_setdir(newdir,tmpstr,newdir,1,"check 10");
533 /* works however with a trailing backslash */
534 sprintf(tmpstr, "%c:\\", newdir[0]);
535 test_setdir(newdir,tmpstr,NULL,1,"check 11");
538 /* Cleanup the mess we made while executing these tests */
539 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
541 CHAR tmpstr[MAX_PATH];
542 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
543 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
544 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
545 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
546 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
547 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
548 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
549 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
550 sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
551 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
552 sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
553 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
554 ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
555 ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
558 /* test that short path name functions work regardless of case */
559 static void test_ShortPathCase(const char *tmpdir, const char *dirname,
560 const char *filename)
562 char buf[MAX_PATH], shortbuf[MAX_PATH];
566 snprintf(buf,sizeof(buf),"%s\\%s\\%s",tmpdir,dirname,filename);
567 GetShortPathNameA(buf,shortbuf,sizeof(shortbuf));
568 hndl = CreateFileA(shortbuf,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
569 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed (%d)\n",GetLastError());
571 /* Now for the real test */
572 for(i=0;i<strlen(shortbuf);i++)
574 shortbuf[i] = tolower(shortbuf[i]);
575 hndl = CreateFileA(shortbuf,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
576 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed (%d)\n",GetLastError());
580 /* This routine will test Get(Full|Short|Long)PathNameA */
581 static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
583 CHAR curdir_short[MAX_PATH],
584 longdir_short[MAX_PATH];
585 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH],tmpstr2[MAX_PATH];
586 LPSTR strptr; /*ptr to the filename portion of the path */
589 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
592 /* Get the short form of the current directory */
593 ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
594 "GetShortPathNameA failed\n");
595 ok(!HAS_TRAIL_SLASH_A(curdir_short),
596 "GetShortPathNameA should not have a trailing \\\n");
597 /* Get the short form of the absolute-path to LONGDIR */
598 sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
599 ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
600 "GetShortPathNameA failed\n");
601 ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
602 "GetShortPathNameA should not have a trailing \\\n");
604 if (pGetLongPathNameA) {
606 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
607 rc1=(*pGetLongPathNameA)(tmpstr,NULL,0);
608 rc2=(*pGetLongPathNameA)(curdir,NULL,0);
609 ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
610 "GetLongPathNameA: wrong return code, %d instead of %d\n",
611 rc1, lstrlenA(tmpstr)+1);
613 sprintf(dir,"%c:",curDrive);
614 rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
615 ok(strcmp(dir,tmpstr)==0,
616 "GetLongPathNameA: returned '%s' instead of '%s' (rc=%d)\n",
620 /* Check the cases where both file and directory exist first */
621 /* Start with a 8.3 directory, 8.3 filename */
622 test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
623 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
624 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
625 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
626 /* Now try a 8.3 directory, long file name */
627 test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
628 sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
629 test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
630 /* Next is a long directory, 8.3 file */
631 test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
632 sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
633 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
634 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
635 /*Lastly a long directory, long file */
636 test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
637 test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
639 /* Now check all of the invalid file w/ valid directory combinations */
640 /* Start with a 8.3 directory, 8.3 filename */
641 test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
642 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
643 ok((passfail.shortlen==0 &&
644 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
645 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
646 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
647 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
648 passfail.shortlen,passfail.shorterror,tmpstr);
649 if(pGetLongPathNameA) {
650 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
651 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
652 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
654 /* Now try a 8.3 directory, long file name */
655 test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
656 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
657 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
658 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
659 !passfail.shorterror,
660 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
661 if(pGetLongPathNameA) {
662 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
663 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
664 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
666 /* Next is a long directory, 8.3 file */
667 test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
668 sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
669 GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
670 strcat(tmpstr1,"\\" NONFILE_SHORT);
671 ok((passfail.shortlen==0 &&
672 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
673 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
674 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
675 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
676 passfail.shortlen,passfail.shorterror,tmpstr);
677 if(pGetLongPathNameA) {
678 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
679 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
680 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
682 /*Lastly a long directory, long file */
683 test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
684 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
685 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
686 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
687 !passfail.shorterror,
688 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
689 if(pGetLongPathNameA) {
690 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
691 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
692 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
694 /* Now try again with directories that don't exist */
695 /* 8.3 directory, 8.3 filename */
696 test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
697 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
698 ok((passfail.shortlen==0 &&
699 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
700 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
701 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
702 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
703 passfail.shortlen,passfail.shorterror,tmpstr);
704 if(pGetLongPathNameA) {
705 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
706 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
707 passfail.longerror==ERROR_FILE_NOT_FOUND,
708 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
711 /* Now try a 8.3 directory, long file name */
712 test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
713 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
714 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
715 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
716 !passfail.shorterror,
717 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
718 passfail.shorterror);
719 if(pGetLongPathNameA) {
720 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
721 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
722 passfail.longerror==ERROR_FILE_NOT_FOUND,
723 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
726 /* Next is a long directory, 8.3 file */
727 test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
728 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
729 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
730 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
731 !passfail.shorterror,
732 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
733 passfail.shorterror);
734 if(pGetLongPathNameA) {
735 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
736 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
737 passfail.longerror==ERROR_FILE_NOT_FOUND,
738 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
741 /*Lastly a long directory, long file */
742 test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
743 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
744 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
745 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
746 !passfail.shorterror,
747 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
748 passfail.shorterror);
749 if(pGetLongPathNameA) {
750 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
751 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
752 passfail.longerror==ERROR_FILE_NOT_FOUND,
753 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
756 /* Next try directories ending with '\\' */
757 /* Existing Directories */
758 sprintf(tmpstr,"%s\\",SHORTDIR);
759 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
760 sprintf(tmpstr,"%s\\",LONGDIR);
761 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
762 /* Nonexistent directories */
763 sprintf(tmpstr,"%s\\",NONDIR_SHORT);
764 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
765 sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
766 ok((passfail.shortlen==0 &&
767 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
768 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
769 (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
770 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
771 passfail.shortlen,passfail.shorterror,tmpstr);
772 if(pGetLongPathNameA) {
773 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
774 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
775 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
778 sprintf(tmpstr,"%s\\",NONDIR_LONG);
779 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
780 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
781 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
782 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
783 !passfail.shorterror,
784 "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
785 passfail.shorterror);
786 if(pGetLongPathNameA) {
787 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
788 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
789 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
792 /* Test GetFullPathNameA with drive letters */
793 if( curDrive != NOT_A_VALID_DRIVE) {
794 sprintf(tmpstr,"%c:",curdir[0]);
795 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
796 "GetFullPathNameA(%c:) failed\n", curdir[0]);
797 GetCurrentDirectoryA(MAX_PATH,tmpstr);
798 sprintf(tmpstr1,"%s\\",tmpstr);
799 ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
800 "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
801 curdir[0],tmpstr2,tmpstr,tmpstr1);
803 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
804 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
805 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
806 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
807 ok(lstrcmpiA(SHORTFILE,strptr)==0,
808 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
810 /* Without a leading slash, insert the current directory if on the current drive */
811 sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
812 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
813 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
814 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
815 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
816 ok(lstrcmpiA(SHORTFILE,strptr)==0,
817 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
818 /* Otherwise insert the missing leading slash */
819 if( otherDrive != NOT_A_VALID_DRIVE) {
820 /* FIXME: this test assumes that current directory on other drive is root */
821 sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
822 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
823 sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
824 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
825 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
826 ok(lstrcmpiA(SHORTFILE,strptr)==0,
827 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
829 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
831 if( curDrive != NOT_A_VALID_DRIVE) {
832 sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
833 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
834 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
835 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
836 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
837 ok(lstrcmpiA(SHORTFILE,strptr)==0,
838 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
841 sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
842 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
843 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
844 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
845 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
846 ok(lstrcmpiA(SHORTFILE,strptr)==0,
847 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
848 /* Windows will insert a drive letter in front of an absolute UNIX path */
849 sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
850 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
851 sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
852 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
853 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
854 /* This passes in Wine because it still contains the pointer from the previous test */
855 ok(lstrcmpiA(SHORTFILE,strptr)==0,
856 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
858 /* Now try some relative paths */
859 ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
860 test_SplitShortPathA(tmpstr,dir,eight,three);
861 if(pGetLongPathNameA) {
862 ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
863 ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
864 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
866 sprintf(tmpstr,".\\%s",LONGDIR);
867 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
868 test_SplitShortPathA(tmpstr1,dir,eight,three);
869 ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
870 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
871 if(pGetLongPathNameA) {
872 ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
874 ok(lstrcmpiA(tmpstr1,tmpstr)==0,
875 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
877 /* Check out Get*PathNameA on some funny characters */
878 for(i=0;i<lstrlenA(funny_chars);i++) {
880 valid=(is_char_ok[i]=='0') ? 0 : 1;
881 sprintf(tmpstr1,"check%d-1",i);
882 sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
883 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
884 sprintf(tmpstr1,"check%d-2",i);
885 sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
886 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
887 sprintf(tmpstr1,"check%d-3",i);
888 sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
889 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
890 sprintf(tmpstr1,"check%d-4",i);
891 sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
892 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
893 sprintf(tmpstr1,"check%d-5",i);
894 sprintf(tmpstr,"Long %c File",funny_chars[i]);
895 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
896 sprintf(tmpstr1,"check%d-6",i);
897 sprintf(tmpstr,"%c Long File",funny_chars[i]);
898 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
899 sprintf(tmpstr1,"check%d-7",i);
900 sprintf(tmpstr,"Long File %c",funny_chars[i]);
901 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
903 /* Now try it on mixed case short names */
904 test_ShortPathCase(curdir,SHORTDIR,LONGFILE);
905 test_ShortPathCase(curdir,LONGDIR,SHORTFILE);
906 test_ShortPathCase(curdir,LONGDIR,LONGFILE);
909 static void test_GetTempPathA(char* tmp_dir)
911 DWORD len, len_with_null;
914 len_with_null = strlen(tmp_dir) + 1;
916 lstrcpyA(buf, "foo");
917 len = GetTempPathA(MAX_PATH, buf);
918 ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
919 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
920 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
922 /* Some versions of Windows touch the buffer, some don't so we don't
923 * test that. Also, NT sometimes exaggerates the required buffer size
924 * so we cannot test for an exact match. Finally, the
925 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
926 * For instance in some cases Win98 returns len_with_null - 1 instead
929 len = GetTempPathA(1, buf);
930 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
932 len = GetTempPathA(0, NULL);
933 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
935 /* The call above gave us the buffer size that Windows thinks is needed
936 * so the next call should work
938 lstrcpyA(buf, "foo");
939 len = GetTempPathA(len, buf);
940 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
941 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
944 static void test_GetTempPathW(char* tmp_dir)
946 DWORD len, len_with_null;
948 WCHAR tmp_dirW[MAX_PATH];
949 static const WCHAR fooW[] = {'f','o','o',0};
951 MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
952 len_with_null = lstrlenW(tmp_dirW) + 1;
954 /* This one is different from ANSI version: ANSI version doesn't
955 * touch the buffer, unicode version usually truncates the buffer
956 * to zero size. NT still exaggerates the required buffer size
957 * sometimes so we cannot test for an exact match. Finally, the
958 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
959 * For instance on NT4 it will sometimes return a path without the
960 * trailing '\\' and sometimes return an error.
964 len = GetTempPathW(MAX_PATH, buf);
965 if (len == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
967 win_skip("GetTempPathW is not available\n");
970 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
971 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
974 len = GetTempPathW(1, buf);
975 ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
976 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
978 len = GetTempPathW(0, NULL);
979 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
982 len = GetTempPathW(len, buf);
983 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
984 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
987 static void test_GetTempPath(void)
989 char save_TMP[MAX_PATH];
990 char windir[MAX_PATH];
993 if (!GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP))) save_TMP[0] = 0;
995 /* test default configuration */
996 trace("TMP=%s\n", save_TMP);
999 strcpy(buf,save_TMP);
1000 if (buf[strlen(buf)-1]!='\\')
1002 test_GetTempPathA(buf);
1003 test_GetTempPathW(buf);
1006 /* TMP=C:\WINDOWS */
1007 GetWindowsDirectoryA(windir, sizeof(windir));
1008 SetEnvironmentVariableA("TMP", windir);
1009 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1010 trace("TMP=%s\n", buf);
1011 strcat(windir,"\\");
1012 test_GetTempPathA(windir);
1013 test_GetTempPathW(windir);
1016 GetWindowsDirectoryA(windir, sizeof(windir));
1018 SetEnvironmentVariableA("TMP", windir);
1019 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1020 trace("TMP=%s\n", buf);
1021 test_GetTempPathA(windir);
1022 test_GetTempPathW(windir);
1024 /* TMP=C: i.e. use current working directory of the specified drive */
1025 GetWindowsDirectoryA(windir, sizeof(windir));
1026 SetCurrentDirectoryA(windir);
1028 SetEnvironmentVariableA("TMP", windir);
1029 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1030 trace("TMP=%s\n", buf);
1031 GetWindowsDirectoryA(windir, sizeof(windir));
1032 strcat(windir,"\\");
1033 test_GetTempPathA(windir);
1034 test_GetTempPathW(windir);
1036 SetEnvironmentVariableA("TMP", save_TMP);
1039 static void test_GetLongPathNameA(void)
1041 DWORD length, explength, hostsize;
1042 char tempfile[MAX_PATH];
1043 char longpath[MAX_PATH];
1044 char unc_prefix[MAX_PATH];
1045 char unc_short[MAX_PATH], unc_long[MAX_PATH];
1046 char temppath[MAX_PATH], temppath2[MAX_PATH];
1049 if (!pGetLongPathNameA)
1052 GetTempPathA(MAX_PATH, tempfile);
1053 lstrcatA(tempfile, "longfilename.longext");
1055 file = CreateFileA(tempfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1058 /* Test a normal path with a small buffer size */
1059 memset(temppath, 0, MAX_PATH);
1060 length = pGetLongPathNameA(tempfile, temppath, 4);
1061 /* We have a failure so length should be the minimum plus the terminating '0' */
1062 ok(length >= lstrlen(tempfile) + 1, "Wrong length\n");
1063 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1065 /* Some UNC syntax tests */
1067 memset(temppath, 0, MAX_PATH);
1068 memset(temppath2, 0, MAX_PATH);
1069 lstrcpyA(temppath2, "\\\\?\\");
1070 lstrcatA(temppath2, tempfile);
1071 explength = length + 4;
1073 SetLastError(0xdeadbeef);
1074 length = pGetLongPathNameA(temppath2, NULL, 0);
1075 if (length == 0 && GetLastError() == ERROR_BAD_NET_NAME)
1077 win_skip("UNC syntax tests don't work on Win98/WinMe\n");
1078 DeleteFileA(tempfile);
1081 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1083 length = pGetLongPathNameA(temppath2, NULL, MAX_PATH);
1084 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1086 length = pGetLongPathNameA(temppath2, temppath, 4);
1087 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1088 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1090 /* Now an UNC path with the computername */
1091 lstrcpyA(unc_prefix, "\\\\");
1092 hostsize = sizeof(unc_prefix) - 2;
1093 GetComputerName(unc_prefix + 2, &hostsize);
1094 lstrcatA(unc_prefix, "\\");
1096 /* Create a short syntax for the whole unc path */
1097 memset(unc_short, 0, MAX_PATH);
1098 GetShortPathNameA(tempfile, temppath, MAX_PATH);
1099 lstrcpyA(unc_short, unc_prefix);
1100 unc_short[lstrlenA(unc_short)] = temppath[0];
1101 lstrcatA(unc_short, "$\\");
1102 lstrcatA(unc_short, strchr(temppath, '\\') + 1);
1104 /* Create a long syntax for reference */
1105 memset(longpath, 0, MAX_PATH);
1106 pGetLongPathNameA(tempfile, temppath, MAX_PATH);
1107 lstrcpyA(longpath, unc_prefix);
1108 longpath[lstrlenA(longpath)] = temppath[0];
1109 lstrcatA(longpath, "$\\");
1110 lstrcatA(longpath, strchr(temppath, '\\') + 1);
1113 SetLastError(0xdeadbeef);
1114 length = pGetLongPathNameA(unc_short, NULL, 0);
1115 if (length == 0 && GetLastError() == ERROR_BAD_NETPATH)
1117 /* Seen on Window XP Home */
1118 win_skip("UNC with computername is not supported\n");
1119 DeleteFileA(tempfile);
1122 explength = lstrlenA(longpath) + 1;
1124 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1126 length = pGetLongPathNameA(unc_short, NULL, MAX_PATH);
1128 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1130 memset(unc_long, 0, MAX_PATH);
1131 length = pGetLongPathNameA(unc_short, unc_long, lstrlenA(unc_short));
1132 /* length will include terminating '0' on failure */
1134 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1135 ok(unc_long[0] == 0, "Buffer should not have been touched\n");
1137 memset(unc_long, 0, MAX_PATH);
1138 length = pGetLongPathNameA(unc_short, unc_long, length);
1139 /* length doesn't include terminating '0' on success */
1143 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1144 ok(!lstrcmpiA(unc_long, longpath), "Expected (%s), got (%s)\n", longpath, unc_long);
1147 DeleteFileA(tempfile);
1150 static void test_GetLongPathNameW(void)
1152 DWORD length, expanded;
1155 WCHAR empty[MAX_PATH];
1156 WCHAR tempdir[MAX_PATH], name[200];
1157 WCHAR dirpath[4 + MAX_PATH + 200]; /* To ease removal */
1158 WCHAR shortpath[4 + MAX_PATH + 200 + 1 + 200];
1159 static const WCHAR prefix[] = { '\\','\\','?','\\', 0};
1160 static const WCHAR backslash[] = { '\\', 0};
1161 static const WCHAR letterX[] = { 'X', 0};
1163 if (!pGetLongPathNameW)
1166 SetLastError(0xdeadbeef);
1167 length = pGetLongPathNameW(NULL,NULL,0);
1168 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1170 win_skip("GetLongPathNameW is not implemented\n");
1173 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1174 ok(GetLastError()==ERROR_INVALID_PARAMETER,"GetLastError returned %d but expected ERROR_INVALID_PARAMETER\n",GetLastError());
1176 SetLastError(0xdeadbeef);
1178 length = pGetLongPathNameW(empty,NULL,0);
1179 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1180 ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
1182 /* Create a long path name. The path needs to exist for these tests to
1183 * succeed so we need the "\\?\" prefix when creating directories and
1187 while (lstrlenW(name) < (sizeof(name)/sizeof(WCHAR) - 1))
1188 lstrcatW(name, letterX);
1190 GetTempPathW(MAX_PATH, tempdir);
1192 lstrcpyW(shortpath, prefix);
1193 lstrcatW(shortpath, tempdir);
1194 lstrcatW(shortpath, name);
1195 lstrcpyW(dirpath, shortpath);
1196 ret = CreateDirectoryW(shortpath, NULL);
1197 ok(ret, "Could not create the temporary directory : %d\n", GetLastError());
1198 lstrcatW(shortpath, backslash);
1199 lstrcatW(shortpath, name);
1201 /* Path does not exist yet and we know it overruns MAX_PATH */
1204 SetLastError(0xdeadbeef);
1205 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1206 ok(length == 0, "Expected 0, got %d\n", length);
1208 ok(GetLastError() == ERROR_PATH_NOT_FOUND,
1209 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1211 SetLastError(0xdeadbeef);
1212 length = pGetLongPathNameW(shortpath, NULL, 0);
1215 ok(length == 0, "Expected 0, got %d\n", length);
1216 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
1217 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1220 file = CreateFileW(shortpath, GENERIC_READ|GENERIC_WRITE, 0, NULL,
1221 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1222 ok(file != INVALID_HANDLE_VALUE,
1223 "Could not create the temporary file : %d.\n", GetLastError());
1229 SetLastError(0xdeadbeef);
1230 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1233 ok(length == 0, "Expected 0, got %d\n", length);
1234 ok(GetLastError() == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1237 expanded = 4 + (pGetLongPathNameW(tempdir, NULL, 0) - 1) + lstrlenW(name) + 1 + lstrlenW(name) + 1;
1238 SetLastError(0xdeadbeef);
1239 length = pGetLongPathNameW(shortpath, NULL, 0);
1240 ok(length == expanded, "Expected %d, got %d\n", expanded, length);
1242 /* NULL buffer with length crashes on Windows */
1244 length = pGetLongPathNameW(shortpath, NULL, 20);
1246 ok(DeleteFileW(shortpath), "Could not delete temporary file\n");
1247 ok(RemoveDirectoryW(dirpath), "Could not delete temporary directory\n");
1250 static void test_GetShortPathNameW(void)
1252 WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
1253 WCHAR path[MAX_PATH];
1254 WCHAR short_path[MAX_PATH];
1258 WCHAR name[] = { 't', 'e', 's', 't', 0 };
1259 WCHAR backSlash[] = { '\\', 0 };
1261 SetLastError(0xdeadbeef);
1262 GetTempPathW( MAX_PATH, path );
1263 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1265 win_skip("GetTempPathW is not implemented\n");
1269 lstrcatW( path, test_path );
1270 lstrcatW( path, backSlash );
1271 ret = CreateDirectoryW( path, NULL );
1272 ok( ret, "Directory was not created. LastError = %d\n", GetLastError() );
1274 /* Starting a main part of test */
1275 length = GetShortPathNameW( path, short_path, 0 );
1276 ok( length, "GetShortPathNameW returned 0.\n" );
1277 ret = GetShortPathNameW( path, short_path, length );
1278 ok( ret, "GetShortPathNameW returned 0.\n" );
1279 lstrcatW( short_path, name );
1280 file = CreateFileW( short_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1281 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
1284 CloseHandle( file );
1285 ret = DeleteFileW( short_path );
1286 ok( ret, "Cannot delete file.\n" );
1287 ret = RemoveDirectoryW( path );
1288 ok( ret, "Cannot delete directory.\n" );
1291 static void test_GetSystemDirectory(void)
1293 CHAR buffer[MAX_PATH + 4];
1297 SetLastError(0xdeadbeef);
1298 res = GetSystemDirectory(NULL, 0);
1299 /* res includes the terminating Zero */
1300 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1304 /* this crashes on XP */
1305 if (0) res = GetSystemDirectory(NULL, total);
1307 SetLastError(0xdeadbeef);
1308 res = GetSystemDirectory(NULL, total-1);
1309 /* 95+NT: total (includes the terminating Zero)
1310 98+ME: 0 with ERROR_INVALID_PARAMETER */
1311 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1312 "returned %d with %d (expected '%d' or: '0' with "
1313 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1315 if (total > MAX_PATH) return;
1318 SetLastError(0xdeadbeef);
1319 res = GetSystemDirectory(buffer, total);
1320 /* res does not include the terminating Zero */
1321 ok( (res == (total-1)) && (buffer[0]),
1322 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1323 res, GetLastError(), buffer, total-1);
1326 SetLastError(0xdeadbeef);
1327 res = GetSystemDirectory(buffer, total + 1);
1328 /* res does not include the terminating Zero */
1329 ok( (res == (total-1)) && (buffer[0]),
1330 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1331 res, GetLastError(), buffer, total-1);
1333 memset(buffer, '#', total + 1);
1334 buffer[total + 2] = '\0';
1335 SetLastError(0xdeadbeef);
1336 res = GetSystemDirectory(buffer, total-1);
1337 /* res includes the terminating Zero) */
1338 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1339 res, GetLastError(), buffer, total);
1341 memset(buffer, '#', total + 1);
1342 buffer[total + 2] = '\0';
1343 SetLastError(0xdeadbeef);
1344 res = GetSystemDirectory(buffer, total-2);
1345 /* res includes the terminating Zero) */
1346 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1347 res, GetLastError(), buffer, total);
1350 static void test_GetWindowsDirectory(void)
1352 CHAR buffer[MAX_PATH + 4];
1356 SetLastError(0xdeadbeef);
1357 res = GetWindowsDirectory(NULL, 0);
1358 /* res includes the terminating Zero */
1359 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1362 /* this crashes on XP */
1363 if (0) res = GetWindowsDirectory(NULL, total);
1365 SetLastError(0xdeadbeef);
1366 res = GetWindowsDirectory(NULL, total-1);
1367 /* 95+NT: total (includes the terminating Zero)
1368 98+ME: 0 with ERROR_INVALID_PARAMETER */
1369 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1370 "returned %d with %d (expected '%d' or: '0' with "
1371 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1373 if (total > MAX_PATH) return;
1376 SetLastError(0xdeadbeef);
1377 res = GetWindowsDirectory(buffer, total);
1378 /* res does not include the terminating Zero */
1379 ok( (res == (total-1)) && (buffer[0]),
1380 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1381 res, GetLastError(), buffer, total-1);
1384 SetLastError(0xdeadbeef);
1385 res = GetWindowsDirectory(buffer, total + 1);
1386 /* res does not include the terminating Zero */
1387 ok( (res == (total-1)) && (buffer[0]),
1388 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1389 res, GetLastError(), buffer, total-1);
1391 memset(buffer, '#', total + 1);
1392 buffer[total + 2] = '\0';
1393 SetLastError(0xdeadbeef);
1394 res = GetWindowsDirectory(buffer, total-1);
1395 /* res includes the terminating Zero) */
1396 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1397 res, GetLastError(), buffer, total);
1399 memset(buffer, '#', total + 1);
1400 buffer[total + 2] = '\0';
1401 SetLastError(0xdeadbeef);
1402 res = GetWindowsDirectory(buffer, total-2);
1403 /* res includes the terminating Zero) */
1404 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1405 res, GetLastError(), buffer, total);
1408 static void test_NeedCurrentDirectoryForExePathA(void)
1410 if (!pNeedCurrentDirectoryForExePathA)
1412 win_skip("NeedCurrentDirectoryForExePathA is not available\n");
1416 /* Crashes in Windows */
1418 ok(pNeedCurrentDirectoryForExePathA(NULL), "returned FALSE for NULL\n");
1420 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1421 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1422 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1423 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1425 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1426 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1427 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1428 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1431 static void test_NeedCurrentDirectoryForExePathW(void)
1433 const WCHAR thispath[] = {'.', 0};
1434 const WCHAR fullpath[] = {'c', ':', '\\', 0};
1435 const WCHAR cmdname[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1437 if (!pNeedCurrentDirectoryForExePathW)
1439 win_skip("NeedCurrentDirectoryForExePathW is not available\n");
1443 /* Crashes in Windows */
1445 ok(pNeedCurrentDirectoryForExePathW(NULL), "returned FALSE for NULL\n");
1447 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1448 ok(pNeedCurrentDirectoryForExePathW(thispath), "returned FALSE for \".\"\n");
1449 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1450 ok(pNeedCurrentDirectoryForExePathW(cmdname), "returned FALSE for \"cmd.exe\"\n");
1452 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1453 ok(!pNeedCurrentDirectoryForExePathW(thispath), "returned TRUE for \".\"\n");
1454 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1455 ok(!pNeedCurrentDirectoryForExePathW(cmdname), "returned TRUE for \"cmd.exe\"\n");
1458 /* Call various path/file name retrieving APIs and check the case of
1459 * the returned drive letter. Some apps (for instance Adobe Photoshop CS3
1460 * installer) depend on the drive letter being in upper case.
1462 static void test_drive_letter_case(void)
1467 #define is_upper_case_letter(a) ((a) >= 'A' && (a) <= 'Z')
1469 memset(buf, 0, sizeof(buf));
1470 SetLastError(0xdeadbeef);
1471 ret = GetWindowsDirectory(buf, sizeof(buf));
1472 ok(ret, "GetWindowsDirectory error %u\n", GetLastError());
1473 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1474 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1475 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1477 /* re-use the buffer returned by GetFullPathName */
1479 SetLastError(0xdeadbeef);
1480 ret = GetFullPathName(buf + 2, sizeof(buf), buf, NULL);
1481 ok(ret, "GetFullPathName error %u\n", GetLastError());
1482 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1483 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1484 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1486 memset(buf, 0, sizeof(buf));
1487 SetLastError(0xdeadbeef);
1488 ret = GetSystemDirectory(buf, sizeof(buf));
1489 ok(ret, "GetSystemDirectory error %u\n", GetLastError());
1490 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1491 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1492 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1494 memset(buf, 0, sizeof(buf));
1495 SetLastError(0xdeadbeef);
1496 ret = GetCurrentDirectory(sizeof(buf), buf);
1497 ok(ret, "GetCurrentDirectory error %u\n", GetLastError());
1498 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1499 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1500 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1502 /* TEMP is an environment variable, so it can't be tested for case-sensitivity */
1503 memset(buf, 0, sizeof(buf));
1504 SetLastError(0xdeadbeef);
1505 ret = GetTempPath(sizeof(buf), buf);
1506 ok(ret, "GetTempPath error %u\n", GetLastError());
1507 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1510 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1511 ok(buf[strlen(buf)-1] == '\\', "Temporary path (%s) doesn't end in a slash\n", buf);
1514 memset(buf, 0, sizeof(buf));
1515 SetLastError(0xdeadbeef);
1516 ret = GetFullPathName(".", sizeof(buf), buf, NULL);
1517 ok(ret, "GetFullPathName error %u\n", GetLastError());
1518 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1519 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1520 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1522 /* re-use the buffer returned by GetFullPathName */
1523 SetLastError(0xdeadbeef);
1524 ret = GetShortPathName(buf, buf, sizeof(buf));
1525 ok(ret, "GetShortPathName error %u\n", GetLastError());
1526 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1527 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1528 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1530 if (pGetLongPathNameA)
1532 /* re-use the buffer returned by GetShortPathName */
1533 SetLastError(0xdeadbeef);
1534 ret = pGetLongPathNameA(buf, buf, sizeof(buf));
1535 ok(ret, "GetLongPathNameA error %u\n", GetLastError());
1536 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1537 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1538 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1540 #undef is_upper_case_letter
1543 static void test_SearchPathA(void)
1545 CHAR pathA[MAX_PATH], fileA[] = "", buffA[MAX_PATH];
1551 win_skip("SearchPathA isn't available\n");
1555 GetWindowsDirectoryA(pathA, sizeof(pathA)/sizeof(CHAR));
1558 SetLastError(0xdeadbeef);
1559 ret = pSearchPathA(pathA, NULL, NULL, sizeof(buffA)/sizeof(CHAR), buffA, &ptrA);
1560 ok(ret == 0, "Expected failure, got %d\n", ret);
1561 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1562 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1564 /* empty filename */
1565 SetLastError(0xdeadbeef);
1566 ret = pSearchPathA(pathA, fileA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, &ptrA);
1567 ok(ret == 0, "Expected failure, got %d\n", ret);
1568 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1569 broken(GetLastError() == ERROR_FILE_NOT_FOUND) /* win9x */,
1570 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1573 static void test_SearchPathW(void)
1575 WCHAR pathW[MAX_PATH], fileW[] = { 0 }, buffW[MAX_PATH];
1581 win_skip("SearchPathW isn't available\n");
1585 /* SearchPathW is a stub on win9x and doesn't return sane error,
1586 so quess if it's implemented indirectly */
1587 SetLastError(0xdeadbeef);
1588 GetWindowsDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR));
1589 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1591 win_skip("SearchPathW not implemented\n");
1597 /* NULL filename, crashes on nt4 */
1598 SetLastError(0xdeadbeef);
1599 ret = pSearchPathW(pathW, NULL, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW);
1600 ok(ret == 0, "Expected failure, got %d\n", ret);
1601 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1602 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1605 /* empty filename */
1606 SetLastError(0xdeadbeef);
1607 ret = pSearchPathW(pathW, fileW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW);
1608 ok(ret == 0, "Expected failure, got %d\n", ret);
1609 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1610 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1613 static void test_GetFullPathNameA(void)
1615 char output[MAX_PATH], *filepart;
1626 } invalid_parameters[] =
1628 {NULL, 0, NULL, NULL, 1},
1629 {NULL, MAX_PATH, NULL, NULL, 1},
1630 {NULL, MAX_PATH, output, NULL, 1},
1631 {NULL, MAX_PATH, output, &filepart, 1},
1632 {"", 0, NULL, NULL},
1633 {"", MAX_PATH, NULL, NULL},
1634 {"", MAX_PATH, output, NULL},
1635 {"", MAX_PATH, output, &filepart},
1638 SetLastError(0xdeadbeef);
1639 ret = GetFullPathNameW(NULL, 0, NULL, NULL);
1640 is_win9x = !ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED;
1643 win_skip("Skipping some tests that cause GetFullPathNameA to crash on Win9x\n");
1645 for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
1647 if (is_win9x && invalid_parameters[i].win9x_crash)
1650 SetLastError(0xdeadbeef);
1651 strcpy(output, "deadbeef");
1652 filepart = (char *)0xdeadbeef;
1653 ret = GetFullPathNameA(invalid_parameters[i].name,
1654 invalid_parameters[i].len,
1655 invalid_parameters[i].buffer,
1656 invalid_parameters[i].lastpart);
1657 ok(!ret, "[%d] Expected GetFullPathNameA to return 0, got %u\n", i, ret);
1658 ok(!strcmp(output, "deadbeef"), "[%d] Expected the output buffer to be unchanged, got \"%s\"\n", i, output);
1659 ok(filepart == (char *)0xdeadbeef, "[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
1660 ok(GetLastError() == 0xdeadbeef ||
1661 GetLastError() == ERROR_BAD_PATHNAME || /* Win9x */
1662 GetLastError() == ERROR_INVALID_NAME, /* Win7 */
1663 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
1668 static void test_GetFullPathNameW(void)
1670 static const WCHAR emptyW[] = {0};
1671 static const WCHAR deadbeefW[] = {'d','e','a','d','b','e','e','f',0};
1673 WCHAR output[MAX_PATH], *filepart;
1684 } invalid_parameters[] =
1686 {NULL, 0, NULL, NULL},
1687 {NULL, 0, NULL, &filepart, 1},
1688 {NULL, MAX_PATH, NULL, NULL},
1689 {NULL, MAX_PATH, output, NULL},
1690 {NULL, MAX_PATH, output, &filepart, 1},
1691 {emptyW, 0, NULL, NULL},
1692 {emptyW, 0, NULL, &filepart, 1},
1693 {emptyW, MAX_PATH, NULL, NULL},
1694 {emptyW, MAX_PATH, output, NULL},
1695 {emptyW, MAX_PATH, output, &filepart, 1},
1698 SetLastError(0xdeadbeef);
1699 ret = GetFullPathNameW(NULL, 0, NULL, NULL);
1700 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1702 win_skip("GetFullPathNameW is not available\n");
1706 for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
1708 SetLastError(0xdeadbeef);
1709 lstrcpyW(output, deadbeefW);
1710 filepart = (WCHAR *)0xdeadbeef;
1711 ret = GetFullPathNameW(invalid_parameters[i].name,
1712 invalid_parameters[i].len,
1713 invalid_parameters[i].buffer,
1714 invalid_parameters[i].lastpart);
1715 ok(!ret, "[%d] Expected GetFullPathNameW to return 0, got %u\n", i, ret);
1716 ok(!lstrcmpW(output, deadbeefW), "[%d] Expected the output buffer to be unchanged, got %s\n", i, wine_dbgstr_w(output));
1717 ok(filepart == (WCHAR *)0xdeadbeef ||
1718 (invalid_parameters[i].win7_expect && filepart == NULL),
1719 "[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
1720 ok(GetLastError() == 0xdeadbeef ||
1721 GetLastError() == ERROR_INVALID_NAME, /* Win7 */
1722 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
1727 static void init_pointers(void)
1729 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
1731 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hKernel32, #f))
1732 MAKEFUNC(GetLongPathNameA);
1733 MAKEFUNC(GetLongPathNameW);
1734 MAKEFUNC(NeedCurrentDirectoryForExePathA);
1735 MAKEFUNC(NeedCurrentDirectoryForExePathW);
1736 MAKEFUNC(SearchPathA);
1737 MAKEFUNC(SearchPathW);
1743 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
1747 /* Report only once */
1748 if (!pGetLongPathNameA)
1749 win_skip("GetLongPathNameA is not available\n");
1750 if (!pGetLongPathNameW)
1751 win_skip("GetLongPathNameW is not available\n");
1753 test_InitPathA(curdir, &curDrive, &otherDrive);
1754 test_CurrentDirectoryA(origdir,curdir);
1755 test_PathNameA(curdir, curDrive, otherDrive);
1756 test_CleanupPathA(origdir,curdir);
1758 test_GetLongPathNameA();
1759 test_GetLongPathNameW();
1760 test_GetShortPathNameW();
1761 test_GetSystemDirectory();
1762 test_GetWindowsDirectory();
1763 test_NeedCurrentDirectoryForExePathA();
1764 test_NeedCurrentDirectoryForExePathW();
1765 test_drive_letter_case();
1768 test_GetFullPathNameA();
1769 test_GetFullPathNameW();