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 /* Non-existent path */
365 sprintf(invalid_dir, "%s\%s",tmppath,"non_existent_dir_1jwj3y32nb3");
366 SetLastError(0xdeadbeef);
368 ok(!GetTempFileNameA(invalid_dir,"tfn",unique,newdir),"GetTempFileNameA should have failed\n");
370 ok(GetLastError()==ERROR_DIRECTORY || broken(GetLastError()==ERROR_PATH_NOT_FOUND)/*win98*/,
371 "got %d, expected ERROR_DIRECTORY\n", GetLastError());
373 /* Check return value for unique !=0 */
375 ok((GetTempFileNameA(tmppath,"tfn",unique,newdir) == unique),"GetTempFileNameA unexpectedly failed\n");
376 /* if unique != 0, the actual temp files are not created: */
377 ok(!DeleteFileA(newdir) && GetLastError() == ERROR_FILE_NOT_FOUND,"Deleted a file that shouldn't exist!\n");
381 /* Find first valid drive letter that is neither newdir[0] nor curDrive */
382 drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
383 if( *curDrive != NOT_A_VALID_DRIVE)
384 drives &= ~(1<<(*curDrive-'A'));
386 for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
388 trace( "Could not find alternative drive, some tests will not be conducted.\n");
390 /* Do some CreateDirectoryA tests */
391 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
392 really understand how they work.
393 More formal tests should be done along with CreateFile tests
395 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
396 ok(CreateDirectoryA(newdir,NULL)==0,
397 "CreateDirectoryA succeeded even though a file of the same name exists\n");
398 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
399 ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
400 /* Create some files to test other functions. Note, we will test CreateFileA
403 sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
404 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
405 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
406 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
407 sprintf(tmpstr,"%c:", *curDrive);
408 bRes = CreateDirectoryA(tmpstr,NULL);
409 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
410 GetLastError() == ERROR_ALREADY_EXISTS),
411 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
412 sprintf(tmpstr,"%c:\\", *curDrive);
413 bRes = CreateDirectoryA(tmpstr,NULL);
414 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
415 GetLastError() == ERROR_ALREADY_EXISTS),
416 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
417 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
418 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
419 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
420 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
421 ok(CloseHandle(hndl),"CloseHandle failed\n");
422 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
423 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
424 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
425 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
426 ok(CloseHandle(hndl),"CloseHandle failed\n");
427 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
428 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
429 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
430 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
431 ok(CloseHandle(hndl),"CloseHandle failed\n");
432 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
433 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
434 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
435 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
436 ok(CloseHandle(hndl),"CloseHandle failed\n");
439 /* Test GetCurrentDirectory & SetCurrentDirectory */
440 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
442 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
445 /* Save the original directory, so that we can return to it at the end
448 len=GetCurrentDirectoryA(MAX_PATH,origdir);
449 ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
450 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
451 buffer size is too small to hold the current directory
453 lstrcpyA(tmpstr,"aaaaaaa");
454 len1=GetCurrentDirectoryA(len,tmpstr);
455 ok(len1==len+1, "GetCurrentDirectoryA returned %d instead of %d\n",len1,len+1);
456 ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
457 "GetCurrentDirectoryA should not have modified the buffer\n");
459 buffer = HeapAlloc( GetProcessHeap(), 0, 2 * 65536 );
460 SetLastError( 0xdeadbeef );
461 strcpy( buffer, "foo" );
462 len = GetCurrentDirectoryA( 32767, buffer );
463 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
464 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
465 SetLastError( 0xdeadbeef );
466 strcpy( buffer, "foo" );
467 len = GetCurrentDirectoryA( 32768, buffer );
468 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
469 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
470 SetLastError( 0xdeadbeef );
471 strcpy( buffer, "foo" );
472 len = GetCurrentDirectoryA( 65535, buffer );
473 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4, win2k, xp */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
474 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
475 SetLastError( 0xdeadbeef );
476 strcpy( buffer, "foo" );
477 len = GetCurrentDirectoryA( 65536, buffer );
478 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4 */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
479 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
480 SetLastError( 0xdeadbeef );
481 strcpy( buffer, "foo" );
482 len = GetCurrentDirectoryA( 2 * 65536, buffer );
483 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4 */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
484 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
485 HeapFree( GetProcessHeap(), 0, buffer );
487 /* Check for crash prevention on swapped args. Crashes all but Win9x.
491 SetLastError( 0xdeadbeef );
492 len = GetCurrentDirectoryA( 42, (LPSTR)(MAX_PATH + 42) );
493 ok( len == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
494 "GetCurrentDirectoryA failed to fail %u err %u\n", len, GetLastError() );
497 /* SetCurrentDirectoryA shouldn't care whether the string has a
500 sprintf(tmpstr,"%s\\",newdir);
501 test_setdir(origdir,tmpstr,newdir,1,"check 1");
502 test_setdir(origdir,newdir,NULL,1,"check 2");
503 /* Set the directory to the working area. We just tested that this works,
504 so why check it again.
506 SetCurrentDirectoryA(newdir);
507 /* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
508 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
509 test_setdir(newdir,tmpstr,NULL,0,"check 3");
510 /* Check that SetCurrentDirectory fails for a nonexistent lond directory */
511 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
512 test_setdir(newdir,tmpstr,NULL,0,"check 4");
513 /* Check that SetCurrentDirectory passes with a long directory */
514 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
515 test_setdir(newdir,tmpstr,NULL,1,"check 5");
516 /* Check that SetCurrentDirectory passes with a short relative directory */
517 sprintf(tmpstr,"%s",SHORTDIR);
518 sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
519 test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
520 /* starting with a '.' */
521 sprintf(tmpstr,".\\%s",SHORTDIR);
522 test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
523 /* Check that SetCurrentDirectory passes with a short relative directory */
524 sprintf(tmpstr,"%s",LONGDIR);
525 sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
526 test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
527 /* starting with a '.' */
528 sprintf(tmpstr,".\\%s",LONGDIR);
529 test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
530 /* change to root without a trailing backslash. The function call succeeds
531 but the directory is not changed.
533 sprintf(tmpstr, "%c:", newdir[0]);
534 test_setdir(newdir,tmpstr,newdir,1,"check 10");
535 /* works however with a trailing backslash */
536 sprintf(tmpstr, "%c:\\", newdir[0]);
537 test_setdir(newdir,tmpstr,NULL,1,"check 11");
540 /* Cleanup the mess we made while executing these tests */
541 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
543 CHAR tmpstr[MAX_PATH];
544 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
545 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
546 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
547 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
548 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
549 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
550 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
551 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
552 sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
553 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
554 sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
555 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
556 ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
557 ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
560 /* This routine will test Get(Full|Short|Long)PathNameA */
561 static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
563 CHAR curdir_short[MAX_PATH],
564 longdir_short[MAX_PATH];
565 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH],tmpstr2[MAX_PATH];
566 LPSTR strptr; /*ptr to the filename portion of the path */
569 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
572 /* Get the short form of the current directory */
573 ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
574 "GetShortPathNameA failed\n");
575 ok(!HAS_TRAIL_SLASH_A(curdir_short),
576 "GetShortPathNameA should not have a trailing \\\n");
577 /* Get the short form of the absolute-path to LONGDIR */
578 sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
579 ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
580 "GetShortPathNameA failed\n");
581 ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
582 "GetShortPathNameA should not have a trailing \\\n");
584 if (pGetLongPathNameA) {
586 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
587 rc1=(*pGetLongPathNameA)(tmpstr,NULL,0);
588 rc2=(*pGetLongPathNameA)(curdir,NULL,0);
589 ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
590 "GetLongPathNameA: wrong return code, %d instead of %d\n",
591 rc1, lstrlenA(tmpstr)+1);
593 sprintf(dir,"%c:",curDrive);
594 rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
595 ok(strcmp(dir,tmpstr)==0,
596 "GetLongPathNameA: returned '%s' instead of '%s' (rc=%d)\n",
600 /* Check the cases where both file and directory exist first */
601 /* Start with a 8.3 directory, 8.3 filename */
602 test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
603 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
604 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
605 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
606 /* Now try a 8.3 directory, long file name */
607 test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
608 sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
609 test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
610 /* Next is a long directory, 8.3 file */
611 test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
612 sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
613 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
614 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
615 /*Lastly a long directory, long file */
616 test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
617 test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
619 /* Now check all of the invalid file w/ valid directory combinations */
620 /* Start with a 8.3 directory, 8.3 filename */
621 test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
622 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
623 ok((passfail.shortlen==0 &&
624 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
625 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
626 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
627 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
628 passfail.shortlen,passfail.shorterror,tmpstr);
629 if(pGetLongPathNameA) {
630 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
631 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
632 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
634 /* Now try a 8.3 directory, long file name */
635 test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
636 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
637 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
638 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
639 !passfail.shorterror,
640 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
641 if(pGetLongPathNameA) {
642 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
643 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
644 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
646 /* Next is a long directory, 8.3 file */
647 test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
648 sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
649 GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
650 strcat(tmpstr1,"\\" NONFILE_SHORT);
651 ok((passfail.shortlen==0 &&
652 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
653 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
654 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
655 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
656 passfail.shortlen,passfail.shorterror,tmpstr);
657 if(pGetLongPathNameA) {
658 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
659 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
660 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
662 /*Lastly a long directory, long file */
663 test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
664 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
665 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
666 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
667 !passfail.shorterror,
668 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
669 if(pGetLongPathNameA) {
670 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
671 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
672 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
674 /* Now try again with directories that don't exist */
675 /* 8.3 directory, 8.3 filename */
676 test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
677 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
678 ok((passfail.shortlen==0 &&
679 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
680 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
681 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
682 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
683 passfail.shortlen,passfail.shorterror,tmpstr);
684 if(pGetLongPathNameA) {
685 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
686 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
687 passfail.longerror==ERROR_FILE_NOT_FOUND,
688 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
691 /* Now try a 8.3 directory, long file name */
692 test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
693 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
694 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
695 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
696 !passfail.shorterror,
697 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
698 passfail.shorterror);
699 if(pGetLongPathNameA) {
700 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
701 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
702 passfail.longerror==ERROR_FILE_NOT_FOUND,
703 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
706 /* Next is a long directory, 8.3 file */
707 test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
708 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
709 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
710 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
711 !passfail.shorterror,
712 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
713 passfail.shorterror);
714 if(pGetLongPathNameA) {
715 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
716 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
717 passfail.longerror==ERROR_FILE_NOT_FOUND,
718 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
721 /*Lastly a long directory, long file */
722 test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
723 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
724 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
725 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
726 !passfail.shorterror,
727 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
728 passfail.shorterror);
729 if(pGetLongPathNameA) {
730 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
731 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
732 passfail.longerror==ERROR_FILE_NOT_FOUND,
733 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
736 /* Next try directories ending with '\\' */
737 /* Existing Directories */
738 sprintf(tmpstr,"%s\\",SHORTDIR);
739 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
740 sprintf(tmpstr,"%s\\",LONGDIR);
741 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
742 /* Nonexistent directories */
743 sprintf(tmpstr,"%s\\",NONDIR_SHORT);
744 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
745 sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
746 ok((passfail.shortlen==0 &&
747 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
748 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
749 (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
750 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
751 passfail.shortlen,passfail.shorterror,tmpstr);
752 if(pGetLongPathNameA) {
753 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
754 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
755 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
758 sprintf(tmpstr,"%s\\",NONDIR_LONG);
759 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
760 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
761 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
762 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
763 !passfail.shorterror,
764 "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
765 passfail.shorterror);
766 if(pGetLongPathNameA) {
767 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
768 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
769 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
772 /* Test GetFullPathNameA with drive letters */
773 if( curDrive != NOT_A_VALID_DRIVE) {
774 sprintf(tmpstr,"%c:",curdir[0]);
775 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
776 "GetFullPathNameA(%c:) failed\n", curdir[0]);
777 GetCurrentDirectoryA(MAX_PATH,tmpstr);
778 sprintf(tmpstr1,"%s\\",tmpstr);
779 ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
780 "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
781 curdir[0],tmpstr2,tmpstr,tmpstr1);
783 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
784 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
785 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
786 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
787 ok(lstrcmpiA(SHORTFILE,strptr)==0,
788 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
790 /* Without a leading slash, insert the current directory if on the current drive */
791 sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
792 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
793 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
794 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
795 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
796 ok(lstrcmpiA(SHORTFILE,strptr)==0,
797 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
798 /* Otherwise insert the missing leading slash */
799 if( otherDrive != NOT_A_VALID_DRIVE) {
800 /* FIXME: this test assumes that current directory on other drive is root */
801 sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
802 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
803 sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
804 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
805 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
806 ok(lstrcmpiA(SHORTFILE,strptr)==0,
807 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
809 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
811 if( curDrive != NOT_A_VALID_DRIVE) {
812 sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
813 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
814 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
815 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
816 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
817 ok(lstrcmpiA(SHORTFILE,strptr)==0,
818 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
821 sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
822 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
823 sprintf(tmpstr,"%s\\%s\\%s",curdir,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);
828 /* Windows will insert a drive letter in front of an absolute UNIX path */
829 sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
830 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
831 sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
832 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
833 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
834 /* This passes in Wine because it still contains the pointer from the previous test */
835 ok(lstrcmpiA(SHORTFILE,strptr)==0,
836 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
838 /* Now try some relative paths */
839 ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
840 test_SplitShortPathA(tmpstr,dir,eight,three);
841 if(pGetLongPathNameA) {
842 ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
843 ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
844 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
846 sprintf(tmpstr,".\\%s",LONGDIR);
847 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
848 test_SplitShortPathA(tmpstr1,dir,eight,three);
849 ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
850 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
851 if(pGetLongPathNameA) {
852 ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
854 ok(lstrcmpiA(tmpstr1,tmpstr)==0,
855 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
857 /* Check out Get*PathNameA on some funny characters */
858 for(i=0;i<lstrlenA(funny_chars);i++) {
860 valid=(is_char_ok[i]=='0') ? 0 : 1;
861 sprintf(tmpstr1,"check%d-1",i);
862 sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
863 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
864 sprintf(tmpstr1,"check%d-2",i);
865 sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
866 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
867 sprintf(tmpstr1,"check%d-3",i);
868 sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
869 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
870 sprintf(tmpstr1,"check%d-4",i);
871 sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
872 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
873 sprintf(tmpstr1,"check%d-5",i);
874 sprintf(tmpstr,"Long %c File",funny_chars[i]);
875 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
876 sprintf(tmpstr1,"check%d-6",i);
877 sprintf(tmpstr,"%c Long File",funny_chars[i]);
878 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
879 sprintf(tmpstr1,"check%d-7",i);
880 sprintf(tmpstr,"Long File %c",funny_chars[i]);
881 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
885 static void test_GetTempPathA(char* tmp_dir)
887 DWORD len, len_with_null;
890 len_with_null = strlen(tmp_dir) + 1;
892 lstrcpyA(buf, "foo");
893 len = GetTempPathA(MAX_PATH, buf);
894 ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
895 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
896 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
898 /* Some versions of Windows touch the buffer, some don't so we don't
899 * test that. Also, NT sometimes exaggerates the required buffer size
900 * so we cannot test for an exact match. Finally, the
901 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
902 * For instance in some cases Win98 returns len_with_null - 1 instead
905 len = GetTempPathA(1, buf);
906 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
908 len = GetTempPathA(0, NULL);
909 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
911 /* The call above gave us the buffer size that Windows thinks is needed
912 * so the next call should work
914 lstrcpyA(buf, "foo");
915 len = GetTempPathA(len, buf);
916 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
917 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
920 static void test_GetTempPathW(char* tmp_dir)
922 DWORD len, len_with_null;
924 WCHAR tmp_dirW[MAX_PATH];
925 static const WCHAR fooW[] = {'f','o','o',0};
927 MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
928 len_with_null = lstrlenW(tmp_dirW) + 1;
930 /* This one is different from ANSI version: ANSI version doesn't
931 * touch the buffer, unicode version usually truncates the buffer
932 * to zero size. NT still exaggerates the required buffer size
933 * sometimes so we cannot test for an exact match. Finally, the
934 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
935 * For instance on NT4 it will sometimes return a path without the
936 * trailing '\\' and sometimes return an error.
940 len = GetTempPathW(MAX_PATH, buf);
941 if (len == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
943 win_skip("GetTempPathW is not available\n");
946 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
947 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
950 len = GetTempPathW(1, buf);
951 ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
952 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
954 len = GetTempPathW(0, NULL);
955 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
958 len = GetTempPathW(len, buf);
959 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
960 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
963 static void test_GetTempPath(void)
965 char save_TMP[MAX_PATH];
966 char windir[MAX_PATH];
969 if (!GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP))) save_TMP[0] = 0;
971 /* test default configuration */
972 trace("TMP=%s\n", save_TMP);
975 strcpy(buf,save_TMP);
976 if (buf[strlen(buf)-1]!='\\')
978 test_GetTempPathA(buf);
979 test_GetTempPathW(buf);
983 GetWindowsDirectoryA(windir, sizeof(windir));
984 SetEnvironmentVariableA("TMP", windir);
985 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
986 trace("TMP=%s\n", buf);
988 test_GetTempPathA(windir);
989 test_GetTempPathW(windir);
992 GetWindowsDirectoryA(windir, sizeof(windir));
994 SetEnvironmentVariableA("TMP", windir);
995 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
996 trace("TMP=%s\n", buf);
997 test_GetTempPathA(windir);
998 test_GetTempPathW(windir);
1000 /* TMP=C: i.e. use current working directory of the specified drive */
1001 GetWindowsDirectoryA(windir, sizeof(windir));
1002 SetCurrentDirectoryA(windir);
1004 SetEnvironmentVariableA("TMP", windir);
1005 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1006 trace("TMP=%s\n", buf);
1007 GetWindowsDirectoryA(windir, sizeof(windir));
1008 strcat(windir,"\\");
1009 test_GetTempPathA(windir);
1010 test_GetTempPathW(windir);
1012 SetEnvironmentVariableA("TMP", save_TMP);
1015 static void test_GetLongPathNameA(void)
1017 DWORD length, explength, hostsize;
1018 char tempfile[MAX_PATH];
1019 char longpath[MAX_PATH];
1020 char unc_prefix[MAX_PATH];
1021 char unc_short[MAX_PATH], unc_long[MAX_PATH];
1022 char temppath[MAX_PATH], temppath2[MAX_PATH];
1025 if (!pGetLongPathNameA)
1028 GetTempPathA(MAX_PATH, tempfile);
1029 lstrcatA(tempfile, "longfilename.longext");
1031 file = CreateFileA(tempfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1034 /* Test a normal path with a small buffer size */
1035 memset(temppath, 0, MAX_PATH);
1036 length = pGetLongPathNameA(tempfile, temppath, 4);
1037 /* We have a failure so length should be the minimum plus the terminating '0' */
1038 ok(length >= lstrlen(tempfile) + 1, "Wrong length\n");
1039 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1041 /* Some UNC syntax tests */
1043 memset(temppath, 0, MAX_PATH);
1044 memset(temppath2, 0, MAX_PATH);
1045 lstrcpyA(temppath2, "\\\\?\\");
1046 lstrcatA(temppath2, tempfile);
1047 explength = length + 4;
1049 SetLastError(0xdeadbeef);
1050 length = pGetLongPathNameA(temppath2, NULL, 0);
1051 if (length == 0 && GetLastError() == ERROR_BAD_NET_NAME)
1053 win_skip("UNC syntax tests don't work on Win98/WinMe\n");
1054 DeleteFileA(tempfile);
1057 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1059 length = pGetLongPathNameA(temppath2, NULL, MAX_PATH);
1060 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1062 length = pGetLongPathNameA(temppath2, temppath, 4);
1063 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1064 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1066 /* Now an UNC path with the computername */
1067 lstrcpyA(unc_prefix, "\\\\");
1068 hostsize = sizeof(unc_prefix) - 2;
1069 GetComputerName(unc_prefix + 2, &hostsize);
1070 lstrcatA(unc_prefix, "\\");
1072 /* Create a short syntax for the whole unc path */
1073 memset(unc_short, 0, MAX_PATH);
1074 GetShortPathNameA(tempfile, temppath, MAX_PATH);
1075 lstrcpyA(unc_short, unc_prefix);
1076 unc_short[lstrlenA(unc_short)] = temppath[0];
1077 lstrcatA(unc_short, "$\\");
1078 lstrcatA(unc_short, strchr(temppath, '\\') + 1);
1080 /* Create a long syntax for reference */
1081 memset(longpath, 0, MAX_PATH);
1082 pGetLongPathNameA(tempfile, temppath, MAX_PATH);
1083 lstrcpyA(longpath, unc_prefix);
1084 longpath[lstrlenA(longpath)] = temppath[0];
1085 lstrcatA(longpath, "$\\");
1086 lstrcatA(longpath, strchr(temppath, '\\') + 1);
1089 SetLastError(0xdeadbeef);
1090 length = pGetLongPathNameA(unc_short, NULL, 0);
1091 if (length == 0 && GetLastError() == ERROR_BAD_NETPATH)
1093 /* Seen on Window XP Home */
1094 win_skip("UNC with computername is not supported\n");
1095 DeleteFileA(tempfile);
1098 explength = lstrlenA(longpath) + 1;
1100 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1102 length = pGetLongPathNameA(unc_short, NULL, MAX_PATH);
1104 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1106 memset(unc_long, 0, MAX_PATH);
1107 length = pGetLongPathNameA(unc_short, unc_long, lstrlenA(unc_short));
1108 /* length will include terminating '0' on failure */
1110 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1111 ok(unc_long[0] == 0, "Buffer should not have been touched\n");
1113 memset(unc_long, 0, MAX_PATH);
1114 length = pGetLongPathNameA(unc_short, unc_long, length);
1115 /* length doesn't include terminating '0' on success */
1119 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1120 ok(!lstrcmpiA(unc_long, longpath), "Expected (%s), got (%s)\n", longpath, unc_long);
1123 DeleteFileA(tempfile);
1126 static void test_GetLongPathNameW(void)
1128 DWORD length, expanded;
1131 WCHAR empty[MAX_PATH];
1132 WCHAR tempdir[MAX_PATH], name[200];
1133 WCHAR dirpath[4 + MAX_PATH + 200]; /* To ease removal */
1134 WCHAR shortpath[4 + MAX_PATH + 200 + 1 + 200];
1135 static const WCHAR prefix[] = { '\\','\\','?','\\', 0};
1136 static const WCHAR backslash[] = { '\\', 0};
1137 static const WCHAR letterX[] = { 'X', 0};
1139 if (!pGetLongPathNameW)
1142 SetLastError(0xdeadbeef);
1143 length = pGetLongPathNameW(NULL,NULL,0);
1144 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1146 win_skip("GetLongPathNameW is not implemented\n");
1149 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1150 ok(GetLastError()==ERROR_INVALID_PARAMETER,"GetLastError returned %d but expected ERROR_INVALID_PARAMETER\n",GetLastError());
1152 SetLastError(0xdeadbeef);
1154 length = pGetLongPathNameW(empty,NULL,0);
1155 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1156 ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
1158 /* Create a long path name. The path needs to exist for these tests to
1159 * succeed so we need the "\\?\" prefix when creating directories and
1163 while (lstrlenW(name) < (sizeof(name)/sizeof(WCHAR) - 1))
1164 lstrcatW(name, letterX);
1166 GetTempPathW(MAX_PATH, tempdir);
1168 lstrcpyW(shortpath, prefix);
1169 lstrcatW(shortpath, tempdir);
1170 lstrcatW(shortpath, name);
1171 lstrcpyW(dirpath, shortpath);
1172 ret = CreateDirectoryW(shortpath, NULL);
1173 ok(ret, "Could not create the temporary directory : %d\n", GetLastError());
1174 lstrcatW(shortpath, backslash);
1175 lstrcatW(shortpath, name);
1177 /* Path does not exist yet and we know it overruns MAX_PATH */
1180 SetLastError(0xdeadbeef);
1181 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1182 ok(length == 0, "Expected 0, got %d\n", length);
1184 ok(GetLastError() == ERROR_PATH_NOT_FOUND,
1185 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1187 SetLastError(0xdeadbeef);
1188 length = pGetLongPathNameW(shortpath, NULL, 0);
1191 ok(length == 0, "Expected 0, got %d\n", length);
1192 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
1193 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1196 file = CreateFileW(shortpath, GENERIC_READ|GENERIC_WRITE, 0, NULL,
1197 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1198 ok(file != INVALID_HANDLE_VALUE,
1199 "Could not create the temporary file : %d.\n", GetLastError());
1205 SetLastError(0xdeadbeef);
1206 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1209 ok(length == 0, "Expected 0, got %d\n", length);
1210 ok(GetLastError() == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1213 expanded = 4 + (pGetLongPathNameW(tempdir, NULL, 0) - 1) + lstrlenW(name) + 1 + lstrlenW(name) + 1;
1214 SetLastError(0xdeadbeef);
1215 length = pGetLongPathNameW(shortpath, NULL, 0);
1216 ok(length == expanded, "Expected %d, got %d\n", expanded, length);
1218 /* NULL buffer with length crashes on Windows */
1220 length = pGetLongPathNameW(shortpath, NULL, 20);
1222 ok(DeleteFileW(shortpath), "Could not delete temporary file\n");
1223 ok(RemoveDirectoryW(dirpath), "Could not delete temporary directory\n");
1226 static void test_GetShortPathNameW(void)
1228 WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
1229 WCHAR path[MAX_PATH];
1230 WCHAR short_path[MAX_PATH];
1234 WCHAR name[] = { 't', 'e', 's', 't', 0 };
1235 WCHAR backSlash[] = { '\\', 0 };
1237 SetLastError(0xdeadbeef);
1238 GetTempPathW( MAX_PATH, path );
1239 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1241 win_skip("GetTempPathW is not implemented\n");
1245 lstrcatW( path, test_path );
1246 lstrcatW( path, backSlash );
1247 ret = CreateDirectoryW( path, NULL );
1248 ok( ret, "Directory was not created. LastError = %d\n", GetLastError() );
1250 /* Starting a main part of test */
1251 length = GetShortPathNameW( path, short_path, 0 );
1252 ok( length, "GetShortPathNameW returned 0.\n" );
1253 ret = GetShortPathNameW( path, short_path, length );
1254 ok( ret, "GetShortPathNameW returned 0.\n" );
1255 lstrcatW( short_path, name );
1256 file = CreateFileW( short_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1257 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
1260 CloseHandle( file );
1261 ret = DeleteFileW( short_path );
1262 ok( ret, "Cannot delete file.\n" );
1263 ret = RemoveDirectoryW( path );
1264 ok( ret, "Cannot delete directory.\n" );
1267 static void test_GetSystemDirectory(void)
1269 CHAR buffer[MAX_PATH + 4];
1273 SetLastError(0xdeadbeef);
1274 res = GetSystemDirectory(NULL, 0);
1275 /* res includes the terminating Zero */
1276 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1280 /* this crashes on XP */
1281 if (0) res = GetSystemDirectory(NULL, total);
1283 SetLastError(0xdeadbeef);
1284 res = GetSystemDirectory(NULL, total-1);
1285 /* 95+NT: total (includes the terminating Zero)
1286 98+ME: 0 with ERROR_INVALID_PARAMETER */
1287 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1288 "returned %d with %d (expected '%d' or: '0' with "
1289 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1291 if (total > MAX_PATH) return;
1294 SetLastError(0xdeadbeef);
1295 res = GetSystemDirectory(buffer, total);
1296 /* res does not include the terminating Zero */
1297 ok( (res == (total-1)) && (buffer[0]),
1298 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1299 res, GetLastError(), buffer, total-1);
1302 SetLastError(0xdeadbeef);
1303 res = GetSystemDirectory(buffer, total + 1);
1304 /* res does not include the terminating Zero */
1305 ok( (res == (total-1)) && (buffer[0]),
1306 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1307 res, GetLastError(), buffer, total-1);
1309 memset(buffer, '#', total + 1);
1310 buffer[total + 2] = '\0';
1311 SetLastError(0xdeadbeef);
1312 res = GetSystemDirectory(buffer, total-1);
1313 /* res includes the terminating Zero) */
1314 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1315 res, GetLastError(), buffer, total);
1317 memset(buffer, '#', total + 1);
1318 buffer[total + 2] = '\0';
1319 SetLastError(0xdeadbeef);
1320 res = GetSystemDirectory(buffer, total-2);
1321 /* res includes the terminating Zero) */
1322 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1323 res, GetLastError(), buffer, total);
1326 static void test_GetWindowsDirectory(void)
1328 CHAR buffer[MAX_PATH + 4];
1332 SetLastError(0xdeadbeef);
1333 res = GetWindowsDirectory(NULL, 0);
1334 /* res includes the terminating Zero */
1335 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1338 /* this crashes on XP */
1339 if (0) res = GetWindowsDirectory(NULL, total);
1341 SetLastError(0xdeadbeef);
1342 res = GetWindowsDirectory(NULL, total-1);
1343 /* 95+NT: total (includes the terminating Zero)
1344 98+ME: 0 with ERROR_INVALID_PARAMETER */
1345 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1346 "returned %d with %d (expected '%d' or: '0' with "
1347 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1349 if (total > MAX_PATH) return;
1352 SetLastError(0xdeadbeef);
1353 res = GetWindowsDirectory(buffer, total);
1354 /* res does not include the terminating Zero */
1355 ok( (res == (total-1)) && (buffer[0]),
1356 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1357 res, GetLastError(), buffer, total-1);
1360 SetLastError(0xdeadbeef);
1361 res = GetWindowsDirectory(buffer, total + 1);
1362 /* res does not include the terminating Zero */
1363 ok( (res == (total-1)) && (buffer[0]),
1364 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1365 res, GetLastError(), buffer, total-1);
1367 memset(buffer, '#', total + 1);
1368 buffer[total + 2] = '\0';
1369 SetLastError(0xdeadbeef);
1370 res = GetWindowsDirectory(buffer, total-1);
1371 /* res includes the terminating Zero) */
1372 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1373 res, GetLastError(), buffer, total);
1375 memset(buffer, '#', total + 1);
1376 buffer[total + 2] = '\0';
1377 SetLastError(0xdeadbeef);
1378 res = GetWindowsDirectory(buffer, total-2);
1379 /* res includes the terminating Zero) */
1380 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1381 res, GetLastError(), buffer, total);
1384 static void test_NeedCurrentDirectoryForExePathA(void)
1386 if (!pNeedCurrentDirectoryForExePathA)
1388 win_skip("NeedCurrentDirectoryForExePathA is not available\n");
1392 /* Crashes in Windows */
1394 ok(pNeedCurrentDirectoryForExePathA(NULL), "returned FALSE for NULL\n");
1396 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1397 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1398 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1399 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1401 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1402 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1403 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1404 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1407 static void test_NeedCurrentDirectoryForExePathW(void)
1409 const WCHAR thispath[] = {'.', 0};
1410 const WCHAR fullpath[] = {'c', ':', '\\', 0};
1411 const WCHAR cmdname[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1413 if (!pNeedCurrentDirectoryForExePathW)
1415 win_skip("NeedCurrentDirectoryForExePathW is not available\n");
1419 /* Crashes in Windows */
1421 ok(pNeedCurrentDirectoryForExePathW(NULL), "returned FALSE for NULL\n");
1423 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1424 ok(pNeedCurrentDirectoryForExePathW(thispath), "returned FALSE for \".\"\n");
1425 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1426 ok(pNeedCurrentDirectoryForExePathW(cmdname), "returned FALSE for \"cmd.exe\"\n");
1428 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1429 ok(!pNeedCurrentDirectoryForExePathW(thispath), "returned TRUE for \".\"\n");
1430 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1431 ok(!pNeedCurrentDirectoryForExePathW(cmdname), "returned TRUE for \"cmd.exe\"\n");
1434 /* Call various path/file name retrieving APIs and check the case of
1435 * the returned drive letter. Some apps (for instance Adobe Photoshop CS3
1436 * installer) depend on the drive letter being in upper case.
1438 static void test_drive_letter_case(void)
1443 #define is_upper_case_letter(a) ((a) >= 'A' && (a) <= 'Z')
1445 memset(buf, 0, sizeof(buf));
1446 SetLastError(0xdeadbeef);
1447 ret = GetWindowsDirectory(buf, sizeof(buf));
1448 ok(ret, "GetWindowsDirectory error %u\n", GetLastError());
1449 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1450 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1451 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1453 /* re-use the buffer returned by GetFullPathName */
1455 SetLastError(0xdeadbeef);
1456 ret = GetFullPathName(buf + 2, sizeof(buf), buf, NULL);
1457 ok(ret, "GetFullPathName error %u\n", GetLastError());
1458 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1459 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1460 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1462 memset(buf, 0, sizeof(buf));
1463 SetLastError(0xdeadbeef);
1464 ret = GetSystemDirectory(buf, sizeof(buf));
1465 ok(ret, "GetSystemDirectory error %u\n", GetLastError());
1466 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1467 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1468 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1470 memset(buf, 0, sizeof(buf));
1471 SetLastError(0xdeadbeef);
1472 ret = GetCurrentDirectory(sizeof(buf), buf);
1473 ok(ret, "GetCurrentDirectory error %u\n", GetLastError());
1474 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1475 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1476 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1478 /* TEMP is an environment variable, so it can't be tested for case-sensitivity */
1479 memset(buf, 0, sizeof(buf));
1480 SetLastError(0xdeadbeef);
1481 ret = GetTempPath(sizeof(buf), buf);
1482 ok(ret, "GetTempPath error %u\n", GetLastError());
1483 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1486 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1487 ok(buf[strlen(buf)-1] == '\\', "Temporary path (%s) doesn't end in a slash\n", buf);
1490 memset(buf, 0, sizeof(buf));
1491 SetLastError(0xdeadbeef);
1492 ret = GetFullPathName(".", sizeof(buf), buf, NULL);
1493 ok(ret, "GetFullPathName error %u\n", GetLastError());
1494 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1495 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1496 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1498 /* re-use the buffer returned by GetFullPathName */
1499 SetLastError(0xdeadbeef);
1500 ret = GetShortPathName(buf, buf, sizeof(buf));
1501 ok(ret, "GetShortPathName error %u\n", GetLastError());
1502 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1503 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1504 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1506 if (pGetLongPathNameA)
1508 /* re-use the buffer returned by GetShortPathName */
1509 SetLastError(0xdeadbeef);
1510 ret = pGetLongPathNameA(buf, buf, sizeof(buf));
1511 ok(ret, "GetLongPathNameA error %u\n", GetLastError());
1512 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1513 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1514 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1516 #undef is_upper_case_letter
1519 static void test_SearchPathA(void)
1521 CHAR pathA[MAX_PATH], fileA[] = "", buffA[MAX_PATH];
1527 win_skip("SearchPathA isn't available\n");
1531 GetWindowsDirectoryA(pathA, sizeof(pathA)/sizeof(CHAR));
1534 SetLastError(0xdeadbeef);
1535 ret = pSearchPathA(pathA, NULL, NULL, sizeof(buffA)/sizeof(CHAR), buffA, &ptrA);
1536 ok(ret == 0, "Expected failure, got %d\n", ret);
1537 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1538 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1540 /* empty filename */
1541 SetLastError(0xdeadbeef);
1542 ret = pSearchPathA(pathA, fileA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, &ptrA);
1543 ok(ret == 0, "Expected failure, got %d\n", ret);
1544 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1545 broken(GetLastError() == ERROR_FILE_NOT_FOUND) /* win9x */,
1546 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1549 static void test_SearchPathW(void)
1551 WCHAR pathW[MAX_PATH], fileW[] = { 0 }, buffW[MAX_PATH];
1557 win_skip("SearchPathW isn't available\n");
1561 /* SearchPathW is a stub on win9x and doesn't return sane error,
1562 so quess if it's implemented indirectly */
1563 SetLastError(0xdeadbeef);
1564 GetWindowsDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR));
1565 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1567 win_skip("SearchPathW not implemented\n");
1573 /* NULL filename, crashes on nt4 */
1574 SetLastError(0xdeadbeef);
1575 ret = pSearchPathW(pathW, NULL, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW);
1576 ok(ret == 0, "Expected failure, got %d\n", ret);
1577 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1578 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1581 /* empty filename */
1582 SetLastError(0xdeadbeef);
1583 ret = pSearchPathW(pathW, fileW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW);
1584 ok(ret == 0, "Expected failure, got %d\n", ret);
1585 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1586 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1589 static void test_GetFullPathNameA(void)
1591 char output[MAX_PATH], *filepart;
1602 } invalid_parameters[] =
1604 {NULL, 0, NULL, NULL, 1},
1605 {NULL, MAX_PATH, NULL, NULL, 1},
1606 {NULL, MAX_PATH, output, NULL, 1},
1607 {NULL, MAX_PATH, output, &filepart, 1},
1608 {"", 0, NULL, NULL},
1609 {"", MAX_PATH, NULL, NULL},
1610 {"", MAX_PATH, output, NULL},
1611 {"", MAX_PATH, output, &filepart},
1614 SetLastError(0xdeadbeef);
1615 ret = GetFullPathNameW(NULL, 0, NULL, NULL);
1616 is_win9x = !ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED;
1619 win_skip("Skipping some tests that cause GetFullPathNameA to crash on Win9x\n");
1621 for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
1623 if (is_win9x && invalid_parameters[i].win9x_crash)
1626 SetLastError(0xdeadbeef);
1627 strcpy(output, "deadbeef");
1628 filepart = (char *)0xdeadbeef;
1629 ret = GetFullPathNameA(invalid_parameters[i].name,
1630 invalid_parameters[i].len,
1631 invalid_parameters[i].buffer,
1632 invalid_parameters[i].lastpart);
1633 ok(!ret, "[%d] Expected GetFullPathNameA to return 0, got %u\n", i, ret);
1634 ok(!strcmp(output, "deadbeef"), "[%d] Expected the output buffer to be unchanged, got \"%s\"\n", i, output);
1635 ok(filepart == (char *)0xdeadbeef, "[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
1636 ok(GetLastError() == 0xdeadbeef ||
1637 GetLastError() == ERROR_BAD_PATHNAME || /* Win9x */
1638 GetLastError() == ERROR_INVALID_NAME, /* Win7 */
1639 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
1644 static void test_GetFullPathNameW(void)
1646 static const WCHAR emptyW[] = {0};
1647 static const WCHAR deadbeefW[] = {'d','e','a','d','b','e','e','f',0};
1649 WCHAR output[MAX_PATH], *filepart;
1660 } invalid_parameters[] =
1662 {NULL, 0, NULL, NULL},
1663 {NULL, 0, NULL, &filepart, 1},
1664 {NULL, MAX_PATH, NULL, NULL},
1665 {NULL, MAX_PATH, output, NULL},
1666 {NULL, MAX_PATH, output, &filepart, 1},
1667 {emptyW, 0, NULL, NULL},
1668 {emptyW, 0, NULL, &filepart, 1},
1669 {emptyW, MAX_PATH, NULL, NULL},
1670 {emptyW, MAX_PATH, output, NULL},
1671 {emptyW, MAX_PATH, output, &filepart, 1},
1674 SetLastError(0xdeadbeef);
1675 ret = GetFullPathNameW(NULL, 0, NULL, NULL);
1676 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1678 win_skip("GetFullPathNameW is not available\n");
1682 for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
1684 SetLastError(0xdeadbeef);
1685 lstrcpyW(output, deadbeefW);
1686 filepart = (WCHAR *)0xdeadbeef;
1687 ret = GetFullPathNameW(invalid_parameters[i].name,
1688 invalid_parameters[i].len,
1689 invalid_parameters[i].buffer,
1690 invalid_parameters[i].lastpart);
1691 ok(!ret, "[%d] Expected GetFullPathNameW to return 0, got %u\n", i, ret);
1692 ok(!lstrcmpW(output, deadbeefW), "[%d] Expected the output buffer to be unchanged, got %s\n", i, wine_dbgstr_w(output));
1693 ok(filepart == (WCHAR *)0xdeadbeef ||
1694 (invalid_parameters[i].win7_expect && filepart == NULL),
1695 "[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
1696 ok(GetLastError() == 0xdeadbeef ||
1697 GetLastError() == ERROR_INVALID_NAME, /* Win7 */
1698 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
1703 static void init_pointers(void)
1705 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
1707 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hKernel32, #f))
1708 MAKEFUNC(GetLongPathNameA);
1709 MAKEFUNC(GetLongPathNameW);
1710 MAKEFUNC(NeedCurrentDirectoryForExePathA);
1711 MAKEFUNC(NeedCurrentDirectoryForExePathW);
1712 MAKEFUNC(SearchPathA);
1713 MAKEFUNC(SearchPathW);
1719 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
1723 /* Report only once */
1724 if (!pGetLongPathNameA)
1725 win_skip("GetLongPathNameA is not available\n");
1726 if (!pGetLongPathNameW)
1727 win_skip("GetLongPathNameW is not available\n");
1729 test_InitPathA(curdir, &curDrive, &otherDrive);
1730 test_CurrentDirectoryA(origdir,curdir);
1731 test_PathNameA(curdir, curDrive, otherDrive);
1732 test_CleanupPathA(origdir,curdir);
1734 test_GetLongPathNameA();
1735 test_GetLongPathNameW();
1736 test_GetShortPathNameW();
1737 test_GetSystemDirectory();
1738 test_GetWindowsDirectory();
1739 test_NeedCurrentDirectoryForExePathA();
1740 test_NeedCurrentDirectoryForExePathW();
1741 test_drive_letter_case();
1744 test_GetFullPathNameA();
1745 test_GetFullPathNameW();