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 DWORD len,len1,drives;
319 *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
321 /* Get the current drive letter */
322 if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
323 *curDrive = tmpstr[0];
325 trace( "Unable to discover current drive, some tests will not be conducted.\n");
327 /* Test GetTempPathA */
328 len=GetTempPathA(MAX_PATH,tmppath);
329 ok(len!=0 && len < MAX_PATH,"GetTempPathA failed\n");
330 ok(HAS_TRAIL_SLASH_A(tmppath),
331 "GetTempPathA returned a path that did not end in '\\'\n");
332 lstrcpyA(tmpstr,"aaaaaaaa");
333 len1=GetTempPathA(len,tmpstr);
334 ok(len1==len+1 || broken(len1 == len), /* WinME */
335 "GetTempPathA should return string length %d instead of %d\n",len+1,len1);
337 /* Test GetTmpFileNameA
338 The only test we do here is whether GetTempFileNameA passes or not.
339 We do not thoroughly test this function yet (specifically, whether
340 it behaves correctly when 'unique' is non zero)
342 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
343 sprintf(tmpstr,"pat%.4x.tmp",id & 0xffff);
344 sprintf(tmpstr1,"pat%x.tmp",id & 0xffff);
345 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
346 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
347 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
348 newdir,tmpstr,tmpstr1,id);
349 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
351 id=GetTempFileNameA(tmppath,NULL,0,newdir);
352 /* Windows 95, 98 return 0==id, while Windows 2000, XP return 0!=id */
355 sprintf(tmpstr,"%.4x.tmp",id & 0xffff);
356 sprintf(tmpstr1,"%x.tmp",id & 0xffff);
357 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
358 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
359 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
360 newdir,tmpstr,tmpstr1,id);
361 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
364 /* Find first valid drive letter that is neither newdir[0] nor curDrive */
365 drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
366 if( *curDrive != NOT_A_VALID_DRIVE)
367 drives &= ~(1<<(*curDrive-'A'));
369 for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
371 trace( "Could not find alternative drive, some tests will not be conducted.\n");
373 /* Do some CreateDirectoryA tests */
374 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
375 really understand how they work.
376 More formal tests should be done along with CreateFile tests
378 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
379 ok(CreateDirectoryA(newdir,NULL)==0,
380 "CreateDirectoryA succeeded even though a file of the same name exists\n");
381 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
382 ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
383 /* Create some files to test other functions. Note, we will test CreateFileA
386 sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
387 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
388 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
389 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
390 sprintf(tmpstr,"%c:", *curDrive);
391 bRes = CreateDirectoryA(tmpstr,NULL);
392 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
393 GetLastError() == ERROR_ALREADY_EXISTS),
394 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
395 sprintf(tmpstr,"%c:\\", *curDrive);
396 bRes = CreateDirectoryA(tmpstr,NULL);
397 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
398 GetLastError() == ERROR_ALREADY_EXISTS),
399 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
400 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
401 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
402 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
403 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
404 ok(CloseHandle(hndl),"CloseHandle failed\n");
405 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
406 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
407 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
408 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
409 ok(CloseHandle(hndl),"CloseHandle failed\n");
410 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
411 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
412 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
413 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
414 ok(CloseHandle(hndl),"CloseHandle failed\n");
415 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
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");
422 /* Test GetCurrentDirectory & SetCurrentDirectory */
423 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
425 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
428 /* Save the original directory, so that we can return to it at the end
431 len=GetCurrentDirectoryA(MAX_PATH,origdir);
432 ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
433 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
434 buffer size is too small to hold the current directory
436 lstrcpyA(tmpstr,"aaaaaaa");
437 len1=GetCurrentDirectoryA(len,tmpstr);
438 ok(len1==len+1, "GetCurrentDirectoryA returned %d instead of %d\n",len1,len+1);
439 ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
440 "GetCurrentDirectoryA should not have modified the buffer\n");
442 buffer = HeapAlloc( GetProcessHeap(), 0, 2 * 65536 );
443 SetLastError( 0xdeadbeef );
444 strcpy( buffer, "foo" );
445 len = GetCurrentDirectoryA( 32767, buffer );
446 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
447 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
448 SetLastError( 0xdeadbeef );
449 strcpy( buffer, "foo" );
450 len = GetCurrentDirectoryA( 32768, buffer );
451 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
452 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
453 SetLastError( 0xdeadbeef );
454 strcpy( buffer, "foo" );
455 len = GetCurrentDirectoryA( 65535, buffer );
456 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4, win2k, xp */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
457 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
458 SetLastError( 0xdeadbeef );
459 strcpy( buffer, "foo" );
460 len = GetCurrentDirectoryA( 65536, buffer );
461 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4 */ "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( 2 * 65536, buffer );
466 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4 */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
467 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
468 HeapFree( GetProcessHeap(), 0, buffer );
470 /* SetCurrentDirectoryA shouldn't care whether the string has a
473 sprintf(tmpstr,"%s\\",newdir);
474 test_setdir(origdir,tmpstr,newdir,1,"check 1");
475 test_setdir(origdir,newdir,NULL,1,"check 2");
476 /* Set the directory to the working area. We just tested that this works,
477 so why check it again.
479 SetCurrentDirectoryA(newdir);
480 /* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
481 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
482 test_setdir(newdir,tmpstr,NULL,0,"check 3");
483 /* Check that SetCurrentDirectory fails for a nonexistent lond directory */
484 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
485 test_setdir(newdir,tmpstr,NULL,0,"check 4");
486 /* Check that SetCurrentDirectory passes with a long directory */
487 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
488 test_setdir(newdir,tmpstr,NULL,1,"check 5");
489 /* Check that SetCurrentDirectory passes with a short relative directory */
490 sprintf(tmpstr,"%s",SHORTDIR);
491 sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
492 test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
493 /* starting with a '.' */
494 sprintf(tmpstr,".\\%s",SHORTDIR);
495 test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
496 /* Check that SetCurrentDirectory passes with a short relative directory */
497 sprintf(tmpstr,"%s",LONGDIR);
498 sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
499 test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
500 /* starting with a '.' */
501 sprintf(tmpstr,".\\%s",LONGDIR);
502 test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
503 /* change to root without a trailing backslash. The function call succeeds
504 but the directory is not changed.
506 sprintf(tmpstr, "%c:", newdir[0]);
507 test_setdir(newdir,tmpstr,newdir,1,"check 10");
508 /* works however with a trailing backslash */
509 sprintf(tmpstr, "%c:\\", newdir[0]);
510 test_setdir(newdir,tmpstr,NULL,1,"check 11");
513 /* Cleanup the mess we made while executing these tests */
514 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
516 CHAR tmpstr[MAX_PATH];
517 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
518 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
519 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
520 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
521 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
522 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
523 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
524 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
525 sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
526 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
527 sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
528 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
529 ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
530 ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
533 /* This routine will test Get(Full|Short|Long)PathNameA */
534 static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
536 CHAR curdir_short[MAX_PATH],
537 longdir_short[MAX_PATH];
538 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH],tmpstr2[MAX_PATH];
539 LPSTR strptr; /*ptr to the filename portion of the path */
542 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
545 /* Get the short form of the current directory */
546 ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
547 "GetShortPathNameA failed\n");
548 ok(!HAS_TRAIL_SLASH_A(curdir_short),
549 "GetShortPathNameA should not have a trailing \\\n");
550 /* Get the short form of the absolute-path to LONGDIR */
551 sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
552 ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
553 "GetShortPathNameA failed\n");
554 ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
555 "GetShortPathNameA should not have a trailing \\\n");
557 if (pGetLongPathNameA) {
559 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
560 rc1=(*pGetLongPathNameA)(tmpstr,NULL,0);
561 rc2=(*pGetLongPathNameA)(curdir,NULL,0);
562 ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
563 "GetLongPathNameA: wrong return code, %d instead of %d\n",
564 rc1, lstrlenA(tmpstr)+1);
566 sprintf(dir,"%c:",curDrive);
567 rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
568 ok(strcmp(dir,tmpstr)==0,
569 "GetLongPathNameA: returned '%s' instead of '%s' (rc=%d)\n",
573 /* Check the cases where both file and directory exist first */
574 /* Start with a 8.3 directory, 8.3 filename */
575 test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
576 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
577 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
578 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
579 /* Now try a 8.3 directory, long file name */
580 test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
581 sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
582 test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
583 /* Next is a long directory, 8.3 file */
584 test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
585 sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
586 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
587 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
588 /*Lastly a long directory, long file */
589 test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
590 test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
592 /* Now check all of the invalid file w/ valid directory combinations */
593 /* Start with a 8.3 directory, 8.3 filename */
594 test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
595 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
596 ok((passfail.shortlen==0 &&
597 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
598 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
599 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
600 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
601 passfail.shortlen,passfail.shorterror,tmpstr);
602 if(pGetLongPathNameA) {
603 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
604 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
605 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
607 /* Now try a 8.3 directory, long file name */
608 test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
609 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
610 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
611 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
612 !passfail.shorterror,
613 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
614 if(pGetLongPathNameA) {
615 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
616 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
617 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
619 /* Next is a long directory, 8.3 file */
620 test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
621 sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
622 GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
623 strcat(tmpstr1,"\\" NONFILE_SHORT);
624 ok((passfail.shortlen==0 &&
625 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
626 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
627 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
628 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
629 passfail.shortlen,passfail.shorterror,tmpstr);
630 if(pGetLongPathNameA) {
631 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
632 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
633 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
635 /*Lastly a long directory, long file */
636 test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
637 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
638 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
639 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
640 !passfail.shorterror,
641 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
642 if(pGetLongPathNameA) {
643 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
644 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
645 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
647 /* Now try again with directories that don't exist */
648 /* 8.3 directory, 8.3 filename */
649 test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
650 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
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_PATH_NOT_FOUND ||
660 passfail.longerror==ERROR_FILE_NOT_FOUND,
661 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
664 /* Now try a 8.3 directory, long file name */
665 test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
666 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
667 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
668 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
669 !passfail.shorterror,
670 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
671 passfail.shorterror);
672 if(pGetLongPathNameA) {
673 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
674 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
675 passfail.longerror==ERROR_FILE_NOT_FOUND,
676 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
679 /* Next is a long directory, 8.3 file */
680 test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
681 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
682 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
683 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
684 !passfail.shorterror,
685 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
686 passfail.shorterror);
687 if(pGetLongPathNameA) {
688 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
689 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
690 passfail.longerror==ERROR_FILE_NOT_FOUND,
691 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
694 /*Lastly a long directory, long file */
695 test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
696 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
697 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
698 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
699 !passfail.shorterror,
700 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
701 passfail.shorterror);
702 if(pGetLongPathNameA) {
703 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
704 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
705 passfail.longerror==ERROR_FILE_NOT_FOUND,
706 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
709 /* Next try directories ending with '\\' */
710 /* Existing Directories */
711 sprintf(tmpstr,"%s\\",SHORTDIR);
712 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
713 sprintf(tmpstr,"%s\\",LONGDIR);
714 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
715 /* Nonexistent directories */
716 sprintf(tmpstr,"%s\\",NONDIR_SHORT);
717 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
718 sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
719 ok((passfail.shortlen==0 &&
720 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
721 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
722 (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
723 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
724 passfail.shortlen,passfail.shorterror,tmpstr);
725 if(pGetLongPathNameA) {
726 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
727 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
728 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
731 sprintf(tmpstr,"%s\\",NONDIR_LONG);
732 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
733 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
734 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
735 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
736 !passfail.shorterror,
737 "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
738 passfail.shorterror);
739 if(pGetLongPathNameA) {
740 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
741 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
742 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
745 /* Test GetFullPathNameA with drive letters */
746 if( curDrive != NOT_A_VALID_DRIVE) {
747 sprintf(tmpstr,"%c:",curdir[0]);
748 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
749 "GetFullPathNameA(%c:) failed\n", curdir[0]);
750 GetCurrentDirectoryA(MAX_PATH,tmpstr);
751 sprintf(tmpstr1,"%s\\",tmpstr);
752 ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
753 "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
754 curdir[0],tmpstr2,tmpstr,tmpstr1);
756 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
757 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
758 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
759 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
760 ok(lstrcmpiA(SHORTFILE,strptr)==0,
761 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
763 /* Without a leading slash, insert the current directory if on the current drive */
764 sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
765 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
766 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
767 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
768 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
769 ok(lstrcmpiA(SHORTFILE,strptr)==0,
770 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
771 /* Otherwise insert the missing leading slash */
772 if( otherDrive != NOT_A_VALID_DRIVE) {
773 /* FIXME: this test assumes that current directory on other drive is root */
774 sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
775 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
776 sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
777 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
778 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
779 ok(lstrcmpiA(SHORTFILE,strptr)==0,
780 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
782 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
784 if( curDrive != NOT_A_VALID_DRIVE) {
785 sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
786 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
787 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
788 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
789 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
790 ok(lstrcmpiA(SHORTFILE,strptr)==0,
791 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
794 sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
795 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
796 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
797 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
798 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
799 ok(lstrcmpiA(SHORTFILE,strptr)==0,
800 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
801 /* Windows will insert a drive letter in front of an absolute UNIX path */
802 sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
803 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
804 sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
805 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
806 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
807 /* This passes in Wine because it still contains the pointer from the previous test */
808 ok(lstrcmpiA(SHORTFILE,strptr)==0,
809 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
811 /* Now try some relative paths */
812 ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
813 test_SplitShortPathA(tmpstr,dir,eight,three);
814 if(pGetLongPathNameA) {
815 ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
816 ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
817 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
819 sprintf(tmpstr,".\\%s",LONGDIR);
820 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
821 test_SplitShortPathA(tmpstr1,dir,eight,three);
822 ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
823 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
824 if(pGetLongPathNameA) {
825 ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
827 ok(lstrcmpiA(tmpstr1,tmpstr)==0,
828 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
830 /* Check out Get*PathNameA on some funny characters */
831 for(i=0;i<lstrlenA(funny_chars);i++) {
833 valid=(is_char_ok[i]=='0') ? 0 : 1;
834 sprintf(tmpstr1,"check%d-1",i);
835 sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
836 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
837 sprintf(tmpstr1,"check%d-2",i);
838 sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
839 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
840 sprintf(tmpstr1,"check%d-3",i);
841 sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
842 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
843 sprintf(tmpstr1,"check%d-4",i);
844 sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
845 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
846 sprintf(tmpstr1,"check%d-5",i);
847 sprintf(tmpstr,"Long %c File",funny_chars[i]);
848 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
849 sprintf(tmpstr1,"check%d-6",i);
850 sprintf(tmpstr,"%c Long File",funny_chars[i]);
851 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
852 sprintf(tmpstr1,"check%d-7",i);
853 sprintf(tmpstr,"Long File %c",funny_chars[i]);
854 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
858 static void test_GetTempPathA(char* tmp_dir)
860 DWORD len, len_with_null;
863 len_with_null = strlen(tmp_dir) + 1;
865 lstrcpyA(buf, "foo");
866 len = GetTempPathA(MAX_PATH, buf);
867 ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
868 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
869 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
871 /* Some versions of Windows touch the buffer, some don't so we don't
872 * test that. Also, NT sometimes exaggerates the required buffer size
873 * so we cannot test for an exact match. Finally, the
874 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
875 * For instance in some cases Win98 returns len_with_null - 1 instead
878 len = GetTempPathA(1, buf);
879 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
881 len = GetTempPathA(0, NULL);
882 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
884 /* The call above gave us the buffer size that Windows thinks is needed
885 * so the next call should work
887 lstrcpyA(buf, "foo");
888 len = GetTempPathA(len, buf);
889 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
890 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
893 static void test_GetTempPathW(char* tmp_dir)
895 DWORD len, len_with_null;
897 WCHAR tmp_dirW[MAX_PATH];
898 static const WCHAR fooW[] = {'f','o','o',0};
900 MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
901 len_with_null = lstrlenW(tmp_dirW) + 1;
903 /* This one is different from ANSI version: ANSI version doesn't
904 * touch the buffer, unicode version usually truncates the buffer
905 * to zero size. NT still exaggerates the required buffer size
906 * sometimes so we cannot test for an exact match. Finally, the
907 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
908 * For instance on NT4 it will sometimes return a path without the
909 * trailing '\\' and sometimes return an error.
913 len = GetTempPathW(MAX_PATH, buf);
914 if (len == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
916 win_skip("GetTempPathW is not available\n");
919 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
920 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
923 len = GetTempPathW(1, buf);
924 ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
925 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
927 len = GetTempPathW(0, NULL);
928 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
931 len = GetTempPathW(len, buf);
932 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
933 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
936 static void test_GetTempPath(void)
938 char save_TMP[MAX_PATH];
939 char windir[MAX_PATH];
942 if (!GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP))) save_TMP[0] = 0;
944 /* test default configuration */
945 trace("TMP=%s\n", save_TMP);
948 strcpy(buf,save_TMP);
949 if (buf[strlen(buf)-1]!='\\')
951 test_GetTempPathA(buf);
952 test_GetTempPathW(buf);
956 GetWindowsDirectoryA(windir, sizeof(windir));
957 SetEnvironmentVariableA("TMP", windir);
958 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
959 trace("TMP=%s\n", buf);
961 test_GetTempPathA(windir);
962 test_GetTempPathW(windir);
965 GetWindowsDirectoryA(windir, sizeof(windir));
967 SetEnvironmentVariableA("TMP", windir);
968 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
969 trace("TMP=%s\n", buf);
970 test_GetTempPathA(windir);
971 test_GetTempPathW(windir);
973 /* TMP=C: i.e. use current working directory of the specified drive */
974 GetWindowsDirectoryA(windir, sizeof(windir));
975 SetCurrentDirectoryA(windir);
977 SetEnvironmentVariableA("TMP", windir);
978 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
979 trace("TMP=%s\n", buf);
980 GetWindowsDirectoryA(windir, sizeof(windir));
982 test_GetTempPathA(windir);
983 test_GetTempPathW(windir);
985 SetEnvironmentVariableA("TMP", save_TMP);
988 static void test_GetLongPathNameA(void)
990 DWORD length, explength, hostsize;
991 char tempfile[MAX_PATH];
992 char longpath[MAX_PATH];
993 char unc_prefix[MAX_PATH];
994 char unc_short[MAX_PATH], unc_long[MAX_PATH];
995 char temppath[MAX_PATH], temppath2[MAX_PATH];
998 if (!pGetLongPathNameA)
1001 GetTempPathA(MAX_PATH, tempfile);
1002 lstrcatA(tempfile, "longfilename.longext");
1004 file = CreateFileA(tempfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1007 /* Test a normal path with a small buffer size */
1008 memset(temppath, 0, MAX_PATH);
1009 length = pGetLongPathNameA(tempfile, temppath, 4);
1010 /* We have a failure so length should be the minumum plus the terminating '0' */
1011 ok(length >= lstrlen(tempfile) + 1, "Wrong length\n");
1012 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1014 /* Some UNC syntax tests */
1016 memset(temppath, 0, MAX_PATH);
1017 memset(temppath2, 0, MAX_PATH);
1018 lstrcpyA(temppath2, "\\\\?\\");
1019 lstrcatA(temppath2, tempfile);
1020 explength = length + 4;
1022 SetLastError(0xdeadbeef);
1023 length = pGetLongPathNameA(temppath2, NULL, 0);
1024 if (length == 0 && GetLastError() == ERROR_BAD_NET_NAME)
1026 win_skip("UNC syntax tests don't work on Win98/WinMe\n");
1027 DeleteFileA(tempfile);
1030 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1032 length = pGetLongPathNameA(temppath2, NULL, MAX_PATH);
1033 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1035 length = pGetLongPathNameA(temppath2, temppath, 4);
1036 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1037 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1039 /* Now an UNC path with the computername */
1040 lstrcpyA(unc_prefix, "\\\\");
1041 hostsize = sizeof(unc_prefix) - 2;
1042 GetComputerName(unc_prefix + 2, &hostsize);
1043 lstrcatA(unc_prefix, "\\");
1045 /* Create a short syntax for the whole unc path */
1046 memset(unc_short, 0, MAX_PATH);
1047 GetShortPathNameA(tempfile, temppath, MAX_PATH);
1048 lstrcpyA(unc_short, unc_prefix);
1049 unc_short[lstrlenA(unc_short)] = temppath[0];
1050 lstrcatA(unc_short, "$\\");
1051 lstrcatA(unc_short, strchr(temppath, '\\') + 1);
1053 /* Create a long syntax for reference */
1054 memset(longpath, 0, MAX_PATH);
1055 pGetLongPathNameA(tempfile, temppath, MAX_PATH);
1056 lstrcpyA(longpath, unc_prefix);
1057 longpath[lstrlenA(longpath)] = temppath[0];
1058 lstrcatA(longpath, "$\\");
1059 lstrcatA(longpath, strchr(temppath, '\\') + 1);
1062 SetLastError(0xdeadbeef);
1063 length = pGetLongPathNameA(unc_short, NULL, 0);
1064 if (length == 0 && GetLastError() == ERROR_BAD_NETPATH)
1066 /* Seen on Window XP Home */
1067 win_skip("UNC with computername is not supported\n");
1068 DeleteFileA(tempfile);
1071 explength = lstrlenA(longpath) + 1;
1073 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1075 length = pGetLongPathNameA(unc_short, NULL, MAX_PATH);
1077 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1079 memset(unc_long, 0, MAX_PATH);
1080 length = pGetLongPathNameA(unc_short, unc_long, lstrlenA(unc_short));
1081 /* length will include terminating '0' on failure */
1083 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1084 ok(unc_long[0] == 0, "Buffer should not have been touched\n");
1086 memset(unc_long, 0, MAX_PATH);
1087 length = pGetLongPathNameA(unc_short, unc_long, length);
1088 /* length doesn't include terminating '0' on success */
1092 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1093 ok(!lstrcmpiA(unc_long, longpath), "Expected (%s), got (%s)\n", longpath, unc_long);
1096 DeleteFileA(tempfile);
1099 static void test_GetLongPathNameW(void)
1101 DWORD length, expanded;
1104 WCHAR empty[MAX_PATH];
1105 WCHAR tempdir[MAX_PATH], name[200];
1106 WCHAR dirpath[4 + MAX_PATH + 200]; /* To ease removal */
1107 WCHAR shortpath[4 + MAX_PATH + 200 + 1 + 200];
1108 static const WCHAR prefix[] = { '\\','\\','?','\\', 0};
1109 static const WCHAR backslash[] = { '\\', 0};
1110 static const WCHAR letterX[] = { 'X', 0};
1112 if (!pGetLongPathNameW)
1115 SetLastError(0xdeadbeef);
1116 length = pGetLongPathNameW(NULL,NULL,0);
1117 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1119 win_skip("GetLongPathNameW is not implemented\n");
1122 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1123 ok(GetLastError()==ERROR_INVALID_PARAMETER,"GetLastError returned %d but expected ERROR_INVALID_PARAMETER\n",GetLastError());
1125 SetLastError(0xdeadbeef);
1127 length = pGetLongPathNameW(empty,NULL,0);
1128 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1129 ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
1131 /* Create a long path name. The path needs to exist for these tests to
1132 * succeed so we need the "\\?\" prefix when creating directories and
1136 while (lstrlenW(name) < (sizeof(name)/sizeof(WCHAR) - 1))
1137 lstrcatW(name, letterX);
1139 GetTempPathW(MAX_PATH, tempdir);
1141 lstrcpyW(shortpath, prefix);
1142 lstrcatW(shortpath, tempdir);
1143 lstrcatW(shortpath, name);
1144 lstrcpyW(dirpath, shortpath);
1145 ret = CreateDirectoryW(shortpath, NULL);
1146 ok(ret, "Could not create the temporary directory : %d\n", GetLastError());
1147 lstrcatW(shortpath, backslash);
1148 lstrcatW(shortpath, name);
1150 /* Path does not exist yet and we know it overruns MAX_PATH */
1153 SetLastError(0xdeadbeef);
1154 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1155 ok(length == 0, "Expected 0, got %d\n", length);
1157 ok(GetLastError() == ERROR_PATH_NOT_FOUND,
1158 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1160 SetLastError(0xdeadbeef);
1161 length = pGetLongPathNameW(shortpath, NULL, 0);
1164 ok(length == 0, "Expected 0, got %d\n", length);
1165 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
1166 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1169 file = CreateFileW(shortpath, GENERIC_READ|GENERIC_WRITE, 0, NULL,
1170 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1171 ok(file != INVALID_HANDLE_VALUE,
1172 "Could not create the temporary file : %d.\n", GetLastError());
1178 SetLastError(0xdeadbeef);
1179 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1182 ok(length == 0, "Expected 0, got %d\n", length);
1183 ok(GetLastError() == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1186 expanded = 4 + (pGetLongPathNameW(tempdir, NULL, 0) - 1) + lstrlenW(name) + 1 + lstrlenW(name) + 1;
1187 SetLastError(0xdeadbeef);
1188 length = pGetLongPathNameW(shortpath, NULL, 0);
1189 ok(length == expanded, "Expected %d, got %d\n", expanded, length);
1191 /* NULL buffer with length crashes on Windows */
1193 length = pGetLongPathNameW(shortpath, NULL, 20);
1195 ok(DeleteFileW(shortpath), "Could not delete temporary file\n");
1196 ok(RemoveDirectoryW(dirpath), "Could not delete temporary directory\n");
1199 static void test_GetShortPathNameW(void)
1201 WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
1202 WCHAR path[MAX_PATH];
1203 WCHAR short_path[MAX_PATH];
1207 WCHAR name[] = { 't', 'e', 's', 't', 0 };
1208 WCHAR backSlash[] = { '\\', 0 };
1210 SetLastError(0xdeadbeef);
1211 GetTempPathW( MAX_PATH, path );
1212 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1214 win_skip("GetTempPathW is not implemented\n");
1218 lstrcatW( path, test_path );
1219 lstrcatW( path, backSlash );
1220 ret = CreateDirectoryW( path, NULL );
1221 ok( ret, "Directory was not created. LastError = %d\n", GetLastError() );
1223 /* Starting a main part of test */
1224 length = GetShortPathNameW( path, short_path, 0 );
1225 ok( length, "GetShortPathNameW returned 0.\n" );
1226 ret = GetShortPathNameW( path, short_path, length );
1227 ok( ret, "GetShortPathNameW returned 0.\n" );
1228 lstrcatW( short_path, name );
1229 file = CreateFileW( short_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1230 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
1233 CloseHandle( file );
1234 ret = DeleteFileW( short_path );
1235 ok( ret, "Cannot delete file.\n" );
1236 ret = RemoveDirectoryW( path );
1237 ok( ret, "Cannot delete directory.\n" );
1240 static void test_GetSystemDirectory(void)
1242 CHAR buffer[MAX_PATH + 4];
1246 SetLastError(0xdeadbeef);
1247 res = GetSystemDirectory(NULL, 0);
1248 /* res includes the terminating Zero */
1249 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1253 /* this crashes on XP */
1254 if (0) res = GetSystemDirectory(NULL, total);
1256 SetLastError(0xdeadbeef);
1257 res = GetSystemDirectory(NULL, total-1);
1258 /* 95+NT: total (includes the terminating Zero)
1259 98+ME: 0 with ERROR_INVALID_PARAMETER */
1260 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1261 "returned %d with %d (expected '%d' or: '0' with "
1262 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1264 if (total > MAX_PATH) return;
1267 SetLastError(0xdeadbeef);
1268 res = GetSystemDirectory(buffer, total);
1269 /* res does not include the terminating Zero */
1270 ok( (res == (total-1)) && (buffer[0]),
1271 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1272 res, GetLastError(), buffer, total-1);
1275 SetLastError(0xdeadbeef);
1276 res = GetSystemDirectory(buffer, total + 1);
1277 /* res does not include the terminating Zero */
1278 ok( (res == (total-1)) && (buffer[0]),
1279 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1280 res, GetLastError(), buffer, total-1);
1282 memset(buffer, '#', total + 1);
1283 buffer[total + 2] = '\0';
1284 SetLastError(0xdeadbeef);
1285 res = GetSystemDirectory(buffer, total-1);
1286 /* res includes the terminating Zero) */
1287 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1288 res, GetLastError(), buffer, total);
1290 memset(buffer, '#', total + 1);
1291 buffer[total + 2] = '\0';
1292 SetLastError(0xdeadbeef);
1293 res = GetSystemDirectory(buffer, total-2);
1294 /* res includes the terminating Zero) */
1295 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1296 res, GetLastError(), buffer, total);
1299 static void test_GetWindowsDirectory(void)
1301 CHAR buffer[MAX_PATH + 4];
1305 SetLastError(0xdeadbeef);
1306 res = GetWindowsDirectory(NULL, 0);
1307 /* res includes the terminating Zero */
1308 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1311 /* this crashes on XP */
1312 if (0) res = GetWindowsDirectory(NULL, total);
1314 SetLastError(0xdeadbeef);
1315 res = GetWindowsDirectory(NULL, total-1);
1316 /* 95+NT: total (includes the terminating Zero)
1317 98+ME: 0 with ERROR_INVALID_PARAMETER */
1318 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1319 "returned %d with %d (expected '%d' or: '0' with "
1320 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1322 if (total > MAX_PATH) return;
1325 SetLastError(0xdeadbeef);
1326 res = GetWindowsDirectory(buffer, total);
1327 /* res does not include the terminating Zero */
1328 ok( (res == (total-1)) && (buffer[0]),
1329 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1330 res, GetLastError(), buffer, total-1);
1333 SetLastError(0xdeadbeef);
1334 res = GetWindowsDirectory(buffer, total + 1);
1335 /* res does not include the terminating Zero */
1336 ok( (res == (total-1)) && (buffer[0]),
1337 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1338 res, GetLastError(), buffer, total-1);
1340 memset(buffer, '#', total + 1);
1341 buffer[total + 2] = '\0';
1342 SetLastError(0xdeadbeef);
1343 res = GetWindowsDirectory(buffer, total-1);
1344 /* res includes the terminating Zero) */
1345 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1346 res, GetLastError(), buffer, total);
1348 memset(buffer, '#', total + 1);
1349 buffer[total + 2] = '\0';
1350 SetLastError(0xdeadbeef);
1351 res = GetWindowsDirectory(buffer, total-2);
1352 /* res includes the terminating Zero) */
1353 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1354 res, GetLastError(), buffer, total);
1357 static void test_NeedCurrentDirectoryForExePathA(void)
1359 if (!pNeedCurrentDirectoryForExePathA)
1361 win_skip("NeedCurrentDirectoryForExePathA is not available\n");
1365 /* Crashes in Windows */
1367 ok(pNeedCurrentDirectoryForExePathA(NULL), "returned FALSE for NULL\n");
1369 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1370 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1371 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1372 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1374 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1375 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1376 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1377 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1380 static void test_NeedCurrentDirectoryForExePathW(void)
1382 const WCHAR thispath[] = {'.', 0};
1383 const WCHAR fullpath[] = {'c', ':', '\\', 0};
1384 const WCHAR cmdname[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1386 if (!pNeedCurrentDirectoryForExePathW)
1388 win_skip("NeedCurrentDirectoryForExePathW is not available\n");
1392 /* Crashes in Windows */
1394 ok(pNeedCurrentDirectoryForExePathW(NULL), "returned FALSE for NULL\n");
1396 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1397 ok(pNeedCurrentDirectoryForExePathW(thispath), "returned FALSE for \".\"\n");
1398 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1399 ok(pNeedCurrentDirectoryForExePathW(cmdname), "returned FALSE for \"cmd.exe\"\n");
1401 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1402 ok(!pNeedCurrentDirectoryForExePathW(thispath), "returned TRUE for \".\"\n");
1403 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1404 ok(!pNeedCurrentDirectoryForExePathW(cmdname), "returned TRUE for \"cmd.exe\"\n");
1407 /* Call various path/file name retrieving APIs and check the case of
1408 * the returned drive letter. Some apps (for instance Adobe Photoshop CS3
1409 * installer) depend on the drive letter being in upper case.
1411 static void test_drive_letter_case(void)
1416 #define is_upper_case_letter(a) ((a) >= 'A' && (a) <= 'Z')
1418 memset(buf, 0, sizeof(buf));
1419 SetLastError(0xdeadbeef);
1420 ret = GetWindowsDirectory(buf, sizeof(buf));
1421 ok(ret, "GetWindowsDirectory error %u\n", GetLastError());
1422 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1423 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1424 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1426 /* re-use the buffer returned by GetFullPathName */
1428 SetLastError(0xdeadbeef);
1429 ret = GetFullPathName(buf + 2, sizeof(buf), buf, NULL);
1430 ok(ret, "GetFullPathName error %u\n", GetLastError());
1431 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1432 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1433 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1435 memset(buf, 0, sizeof(buf));
1436 SetLastError(0xdeadbeef);
1437 ret = GetSystemDirectory(buf, sizeof(buf));
1438 ok(ret, "GetSystemDirectory error %u\n", GetLastError());
1439 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1440 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1441 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1443 memset(buf, 0, sizeof(buf));
1444 SetLastError(0xdeadbeef);
1445 ret = GetCurrentDirectory(sizeof(buf), buf);
1446 ok(ret, "GetCurrentDirectory error %u\n", GetLastError());
1447 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1448 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1449 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1451 /* TEMP is an environment variable, so it can't be tested for case-sensitivity */
1452 memset(buf, 0, sizeof(buf));
1453 SetLastError(0xdeadbeef);
1454 ret = GetTempPath(sizeof(buf), buf);
1455 ok(ret, "GetTempPath error %u\n", GetLastError());
1456 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(buf[strlen(buf)-1] == '\\', "Temporary path (%s) doesn't end in a slash\n", buf);
1463 memset(buf, 0, sizeof(buf));
1464 SetLastError(0xdeadbeef);
1465 ret = GetFullPathName(".", sizeof(buf), buf, NULL);
1466 ok(ret, "GetFullPathName error %u\n", GetLastError());
1467 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1468 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1469 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1471 /* re-use the buffer returned by GetFullPathName */
1472 SetLastError(0xdeadbeef);
1473 ret = GetShortPathName(buf, buf, sizeof(buf));
1474 ok(ret, "GetShortPathName error %u\n", GetLastError());
1475 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1476 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1477 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1479 if (pGetLongPathNameA)
1481 /* re-use the buffer returned by GetShortPathName */
1482 SetLastError(0xdeadbeef);
1483 ret = pGetLongPathNameA(buf, buf, sizeof(buf));
1484 ok(ret, "GetLongPathNameA error %u\n", GetLastError());
1485 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(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1489 #undef is_upper_case_letter
1492 static void test_SearchPathA(void)
1494 CHAR pathA[MAX_PATH], fileA[] = "", buffA[MAX_PATH];
1500 win_skip("SearchPathA isn't available\n");
1504 GetWindowsDirectoryA(pathA, sizeof(pathA)/sizeof(CHAR));
1507 SetLastError(0xdeadbeef);
1508 ret = pSearchPathA(pathA, NULL, NULL, sizeof(buffA)/sizeof(CHAR), buffA, &ptrA);
1509 ok(ret == 0, "Expected failure, got %d\n", ret);
1510 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1511 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1513 /* empty filename */
1514 SetLastError(0xdeadbeef);
1515 ret = pSearchPathA(pathA, fileA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, &ptrA);
1516 ok(ret == 0, "Expected failure, got %d\n", ret);
1517 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1518 broken(GetLastError() == ERROR_FILE_NOT_FOUND) /* win9x */,
1519 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1522 static void test_SearchPathW(void)
1524 WCHAR pathW[MAX_PATH], fileW[] = { 0 }, buffW[MAX_PATH];
1530 win_skip("SearchPathW isn't available\n");
1534 /* SearchPathW is a stub on win9x and doesn't return sane error,
1535 so quess if it's implemented indirectly */
1536 SetLastError(0xdeadbeef);
1537 GetWindowsDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR));
1538 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1540 win_skip("SearchPathW not implemented\n");
1546 /* NULL filename, crashes on nt4 */
1547 SetLastError(0xdeadbeef);
1548 ret = pSearchPathW(pathW, NULL, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW);
1549 ok(ret == 0, "Expected failure, got %d\n", ret);
1550 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1551 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1554 /* empty filename */
1555 SetLastError(0xdeadbeef);
1556 ret = pSearchPathW(pathW, fileW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW);
1557 ok(ret == 0, "Expected failure, got %d\n", ret);
1558 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1559 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1562 static void init_pointers(void)
1564 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
1566 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hKernel32, #f))
1567 MAKEFUNC(GetLongPathNameA);
1568 MAKEFUNC(GetLongPathNameW);
1569 MAKEFUNC(NeedCurrentDirectoryForExePathA);
1570 MAKEFUNC(NeedCurrentDirectoryForExePathW);
1571 MAKEFUNC(SearchPathA);
1572 MAKEFUNC(SearchPathW);
1578 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
1582 /* Report only once */
1583 if (!pGetLongPathNameA)
1584 win_skip("GetLongPathNameA is not available\n");
1585 if (!pGetLongPathNameW)
1586 win_skip("GetLongPathNameW is not available\n");
1588 test_InitPathA(curdir, &curDrive, &otherDrive);
1589 test_CurrentDirectoryA(origdir,curdir);
1590 test_PathNameA(curdir, curDrive, otherDrive);
1591 test_CleanupPathA(origdir,curdir);
1593 test_GetLongPathNameA();
1594 test_GetLongPathNameW();
1595 test_GetShortPathNameW();
1596 test_GetSystemDirectory();
1597 test_GetWindowsDirectory();
1598 test_NeedCurrentDirectoryForExePathA();
1599 test_NeedCurrentDirectoryForExePathW();
1600 test_drive_letter_case();