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 /* a structure to deal with wine todos somewhat cleanly */
70 /* function that tests GetFullPathNameA, GetShortPathNameA,GetLongPathNameA */
71 /* NOTE: the passfail structure is used to allow cutomizeable todo checking
72 for wine. It is not very pretty, but it sure beats duplicating this
73 function lots of times
75 static void test_ValidPathA(const CHAR *curdir, const CHAR *subdir, const CHAR *filename,
76 CHAR *shortstr, SLpassfail *passfail, const CHAR *errstr)
78 CHAR tmpstr[MAX_PATH],
79 fullpath[MAX_PATH], /*full path to the file (not short/long) */
80 subpath[MAX_PATH], /*relative path to the file */
81 fullpathshort[MAX_PATH], /*absolue path to the file (short format) */
82 fullpathlong[MAX_PATH], /*absolute path to the file (long format) */
83 curdirshort[MAX_PATH], /*absolute path to the current dir (short) */
84 curdirlong[MAX_PATH]; /*absolute path to the current dir (long) */
85 LPSTR strptr; /*ptr to the filename portion of the path */
87 /* if passfail is NULL, we can perform all checks within this function,
88 otherwise, we will return the relevant data in the passfail struct, so
89 we must initialize it first
92 passfail->shortlen=-1;passfail->s2llen=-1;passfail->longlen=-1;
93 passfail->shorterror=0;passfail->s2lerror=0;passfail->longerror=0;
95 /* GetLongPathNameA is only supported on Win2k+ and Win98+ */
96 if(pGetLongPathNameA) {
97 ok((len=pGetLongPathNameA(curdir,curdirlong,MAX_PATH)),
98 "%s: GetLongPathNameA failed\n",errstr);
99 /*GetLongPathNameA can return a trailing '\\' but shouldn't do so here */
100 ok(! HAS_TRAIL_SLASH_A(curdirlong),
101 "%s: GetLongPathNameA should not have a trailing \\\n",errstr);
103 ok((len=GetShortPathNameA(curdir,curdirshort,MAX_PATH)),
104 "%s: GetShortPathNameA failed\n",errstr);
105 /*GetShortPathNameA can return a trailing '\\' but shouldn't do so here */
106 ok(! HAS_TRAIL_SLASH_A(curdirshort),
107 "%s: GetShortPathNameA should not have a trailing \\\n",errstr);
108 /* build relative and absolute paths from inputs */
109 if(lstrlenA(subdir)) {
110 sprintf(subpath,"%s\\%s",subdir,filename);
112 lstrcpyA(subpath,filename);
114 sprintf(fullpath,"%s\\%s",curdir,subpath);
115 sprintf(fullpathshort,"%s\\%s",curdirshort,subpath);
116 sprintf(fullpathlong,"%s\\%s",curdirlong,subpath);
117 /* Test GetFullPathNameA functionality */
118 len=GetFullPathNameA(subpath,MAX_PATH,tmpstr,&strptr);
119 ok(len, "GetFullPathNameA failed for: '%s'\n",subpath);
120 if(HAS_TRAIL_SLASH_A(subpath)) {
122 "%s: GetFullPathNameA should not return a filename ptr\n",errstr);
123 ok(lstrcmpiA(fullpath,tmpstr)==0,
124 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
125 errstr,tmpstr,fullpath);
127 ok(lstrcmpiA(strptr,filename)==0,
128 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
129 errstr,strptr,filename);
130 ok(lstrcmpiA(fullpath,tmpstr)==0,
131 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
132 errstr,tmpstr,fullpath);
134 /* Test GetShortPathNameA functionality */
136 len=GetShortPathNameA(fullpathshort,shortstr,MAX_PATH);
138 ok(len, "%s: GetShortPathNameA failed\n",errstr);
140 passfail->shortlen=len;
141 passfail->shorterror=GetLastError();
143 /* Test GetLongPathNameA functionality
144 We test both conversion from GetFullPathNameA and from GetShortPathNameA
146 if(pGetLongPathNameA) {
149 len=pGetLongPathNameA(shortstr,tmpstr,MAX_PATH);
152 "%s: GetLongPathNameA failed during Short->Long conversion\n", errstr);
153 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
154 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
155 errstr,tmpstr,fullpathlong);
157 passfail->s2llen=len;
158 passfail->s2lerror=GetLastError();
162 len=pGetLongPathNameA(fullpath,tmpstr,MAX_PATH);
164 ok(len, "%s: GetLongPathNameA failed\n",errstr);
165 if(HAS_TRAIL_SLASH_A(fullpath)) {
166 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
167 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
168 errstr,tmpstr,fullpathlong);
170 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
171 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
172 errstr,tmpstr,fullpathlong);
175 passfail->longlen=len;
176 passfail->longerror=GetLastError();
181 /* split path into leading directory, and 8.3 filename */
182 static void test_SplitShortPathA(CHAR *path,CHAR *dir,CHAR *eight,CHAR *three) {
187 ext=len; fil=len; done=0; error=0;
188 /* walk backwards over path looking for '.' or '\\' separators */
189 for(i=len-1;(i>=0) && (!done);i--) {
191 if(ext!=len) error=1; else ext=i;
192 else if(path[i]=='\\') {
201 /* Check that we didn't find a trailing '\\' or multiple '.' */
202 ok(!error,"Illegal file found in 8.3 path '%s'\n",path);
203 /* Separate dir, root, and extension */
204 if(ext!=len) lstrcpyA(three,path+ext+1); else lstrcpyA(three,"");
206 lstrcpynA(eight,path+fil+1,ext-fil);
207 lstrcpynA(dir,path,fil+1);
209 lstrcpynA(eight,path,ext+1);
212 /* Validate that root and extension really are 8.3 */
213 ok(lstrlenA(eight)<=8 && lstrlenA(three)<=3,
214 "GetShortPathNAmeA did not return an 8.3 path\n");
217 /* Check that GetShortPathNameA returns a valid 8.3 path */
218 static void test_LongtoShortA(CHAR *teststr,const CHAR *goodstr,
219 const CHAR *ext,const CHAR *errstr) {
220 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
222 test_SplitShortPathA(teststr,dir,eight,three);
223 ok(lstrcmpiA(dir,goodstr)==0,
224 "GetShortPathNameA returned '%s' instead of '%s'\n",dir,goodstr);
225 ok(lstrcmpiA(three,ext)==0,
226 "GetShortPathNameA returned '%s' with incorrect extension\n",three);
229 /* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
230 characters in the filename.
231 'valid' indicates whether this would be an allowed filename
232 'todo' indicates that wine doesn't get this right yet.
233 NOTE: We always call this routine with a nonexistent filename, so
234 Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
237 static void test_FunnyChars(CHAR *curdir,CHAR *curdir_short,CHAR *filename, INT valid,CHAR *errstr)
239 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
242 test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
244 sprintf(tmpstr1,"%s\\%s",curdir_short,filename);
245 ok((passfail.shortlen==0 &&
246 (passfail.shorterror==ERROR_FILE_NOT_FOUND || passfail.shorterror==ERROR_PATH_NOT_FOUND || !passfail.shorterror)) ||
247 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
248 "%s: GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
249 errstr,passfail.shortlen,passfail.shorterror,tmpstr);
251 ok(passfail.shortlen==0 &&
252 (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),
253 "%s: GetShortPathA should have failed len=%d, error=%d\n",
254 errstr,passfail.shortlen,passfail.shorterror);
256 if(pGetLongPathNameA) {
257 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
259 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
260 "%s: GetLongPathA returned %d and not %d\n",
261 errstr,passfail.longerror,ERROR_FILE_NOT_FOUND);
263 ok(passfail.longerror==ERROR_INVALID_NAME ||
264 passfail.longerror==ERROR_FILE_NOT_FOUND,
265 "%s: GetLongPathA returned %d and not %d or %d'\n",
266 errstr, passfail.longerror,ERROR_INVALID_NAME,ERROR_FILE_NOT_FOUND);
271 /* Routine to test that SetCurrentDirectory behaves as expected. */
272 static void test_setdir(CHAR *olddir,CHAR *newdir,
273 CHAR *cmprstr, INT pass, const CHAR *errstr)
275 CHAR tmppath[MAX_PATH], *dirptr;
276 DWORD val,len,chklen;
278 val=SetCurrentDirectoryA(newdir);
279 len=GetCurrentDirectoryA(MAX_PATH,tmppath);
280 /* if 'pass' then the SetDirectoryA was supposed to pass */
282 dirptr=(cmprstr==NULL) ? newdir : cmprstr;
283 chklen=lstrlenA(dirptr);
284 ok(val,"%s: SetCurrentDirectoryA failed\n",errstr);
286 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
288 ok(lstrcmpiA(dirptr,tmppath)==0,
289 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
291 ok(SetCurrentDirectoryA(olddir),
292 "%s: Couldn't set directory to it's original value\n",errstr);
294 /* else thest that it fails correctly */
295 chklen=lstrlenA(olddir);
297 "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr);
299 "%s: SetCurrentDirectory changed the directory, though it failed\n",
301 ok(lstrcmpiA(olddir,tmppath)==0,
302 "%s: SetCurrentDirectory changed the directory, though it failed\n",
306 static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
308 CHAR tmppath[MAX_PATH], /*path to TEMP */
311 DWORD len,len1,drives;
316 *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
318 /* Get the current drive letter */
319 if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
320 *curDrive = tmpstr[0];
322 trace( "Unable to discover current drive, some tests will not be conducted.\n");
324 /* Test GetTempPathA */
325 len=GetTempPathA(MAX_PATH,tmppath);
326 ok(len!=0 && len < MAX_PATH,"GetTempPathA failed\n");
327 ok(HAS_TRAIL_SLASH_A(tmppath),
328 "GetTempPathA returned a path that did not end in '\\'\n");
329 lstrcpyA(tmpstr,"aaaaaaaa");
330 len1=GetTempPathA(len,tmpstr);
332 "GetTempPathA should return string length %d instead of %d\n",len+1,len1);
334 /* Test GetTmpFileNameA
335 The only test we do here is whether GetTempFileNameA passes or not.
336 We do not thoroughly test this function yet (specifically, whether
337 it behaves correctly when 'unique' is non zero)
339 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
340 sprintf(tmpstr,"pat%.4x.tmp",id & 0xffff);
341 sprintf(tmpstr1,"pat%x.tmp",id & 0xffff);
342 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
343 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
344 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
345 newdir,tmpstr,tmpstr1,id);
346 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
348 id=GetTempFileNameA(tmppath,NULL,0,newdir);
349 /* Windows 95, 98 return 0==id, while Windows 2000, XP return 0!=id */
352 sprintf(tmpstr,"%.4x.tmp",id & 0xffff);
353 sprintf(tmpstr1,"%x.tmp",id & 0xffff);
354 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
355 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
356 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
357 newdir,tmpstr,tmpstr1,id);
358 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
361 /* Find first valid drive letter that is neither newdir[0] nor curDrive */
362 drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
363 if( *curDrive != NOT_A_VALID_DRIVE)
364 drives &= ~(1<<(*curDrive-'A'));
366 for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
368 trace( "Could not find alternative drive, some tests will not be conducted.\n");
370 /* Do some CreateDirectoryA tests */
371 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
372 really understand how they work.
373 More formal tests should be done along with CreateFile tests
375 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
376 ok(CreateDirectoryA(newdir,NULL)==0,
377 "CreateDirectoryA succeeded even though a file of the same name exists\n");
378 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
379 ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
380 /* Create some files to test other functions. Note, we will test CreateFileA
383 sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
384 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
385 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
386 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
387 bRes = CreateDirectoryA("c:",NULL);
388 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
389 GetLastError() == ERROR_ALREADY_EXISTS),
390 "CreateDirectoryA(\"c:\" should have failed (%d)\n", GetLastError());
391 bRes = CreateDirectoryA("c:\\",NULL);
392 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
393 GetLastError() == ERROR_ALREADY_EXISTS),
394 "CreateDirectoryA(\"c:\\\" should have failed (%d)\n", GetLastError());
395 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
396 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
397 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
398 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
399 ok(CloseHandle(hndl),"CloseHandle failed\n");
400 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
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,LONGDIR,SHORTFILE);
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,LONGFILE);
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");
417 /* Test GetCurrentDirectory & SetCurrentDirectory */
418 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
420 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
422 /* Save the original directory, so that we can return to it at the end
425 len=GetCurrentDirectoryA(MAX_PATH,origdir);
426 ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
427 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
428 buffer size is too small to hold the current directory
430 lstrcpyA(tmpstr,"aaaaaaa");
431 len1=GetCurrentDirectoryA(len,tmpstr);
432 ok(len1==len+1, "GetCurrentDirectoryA returned %d instead of %d\n",len1,len+1);
433 ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
434 "GetCurrentDirectoryA should not have modified the buffer\n");
435 /* SetCurrentDirectoryA shouldn't care whether the string has a
438 sprintf(tmpstr,"%s\\",newdir);
439 test_setdir(origdir,tmpstr,newdir,1,"check 1");
440 test_setdir(origdir,newdir,NULL,1,"check 2");
441 /* Set the directory to the working area. We just tested that this works,
442 so why check it again.
444 SetCurrentDirectoryA(newdir);
445 /* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
446 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
447 test_setdir(newdir,tmpstr,NULL,0,"check 3");
448 /* Check that SetCurrentDirectory fails for a nonexistent lond directory */
449 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
450 test_setdir(newdir,tmpstr,NULL,0,"check 4");
451 /* Check that SetCurrentDirectory passes with a long directory */
452 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
453 test_setdir(newdir,tmpstr,NULL,1,"check 5");
454 /* Check that SetCurrentDirectory passes with a short relative directory */
455 sprintf(tmpstr,"%s",SHORTDIR);
456 sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
457 test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
458 /* starting with a '.' */
459 sprintf(tmpstr,".\\%s",SHORTDIR);
460 test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
461 /* Check that SetCurrentDirectory passes with a short relative directory */
462 sprintf(tmpstr,"%s",LONGDIR);
463 sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
464 test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
465 /* starting with a '.' */
466 sprintf(tmpstr,".\\%s",LONGDIR);
467 test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
470 /* Cleanup the mess we made while executing these tests */
471 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
473 CHAR tmpstr[MAX_PATH];
474 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
475 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
476 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
477 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
478 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
479 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
480 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
481 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
482 sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
483 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
484 sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
485 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
486 ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
487 ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
490 /* This routine will test Get(Full|Short|Long)PathNameA */
491 static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
493 CHAR curdir_short[MAX_PATH],
494 longdir_short[MAX_PATH];
495 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH],tmpstr2[MAX_PATH];
496 LPSTR strptr; /*ptr to the filename portion of the path */
499 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
502 /* Get the short form of the current directory */
503 ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
504 "GetShortPathNameA failed\n");
505 ok(!HAS_TRAIL_SLASH_A(curdir_short),
506 "GetShortPathNameA should not have a trailing \\\n");
507 /* Get the short form of the absolute-path to LONGDIR */
508 sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
509 ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
510 "GetShortPathNameA failed\n");
511 ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
512 "GetShortPathNameA should not have a trailing \\\n");
514 if (pGetLongPathNameA) {
516 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
517 rc1=(*pGetLongPathNameA)(tmpstr,NULL,0);
518 rc2=(*pGetLongPathNameA)(curdir,NULL,0);
519 ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
520 "GetLongPathNameA: wrong return code, %d instead of %d\n",
521 rc1, lstrlenA(tmpstr)+1);
523 sprintf(dir,"%c:",curDrive);
524 rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
525 ok(strcmp(dir,tmpstr)==0,
526 "GetLongPathNameA: returned '%s' instead of '%s' (rc=%d)\n",
530 /* Check the cases where both file and directory exist first */
531 /* Start with a 8.3 directory, 8.3 filename */
532 test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
533 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
534 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
535 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
536 /* Now try a 8.3 directory, long file name */
537 test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
538 sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
539 test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
540 /* Next is a long directory, 8.3 file */
541 test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
542 sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
543 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
544 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
545 /*Lastly a long directory, long file */
546 test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
547 test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
549 /* Now check all of the invalid file w/ valid directory combinations */
550 /* Start with a 8.3 directory, 8.3 filename */
551 test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
552 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
553 ok((passfail.shortlen==0 &&
554 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
555 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
556 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
557 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
558 passfail.shortlen,passfail.shorterror,tmpstr);
559 if(pGetLongPathNameA) {
560 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
561 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
562 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
564 /* Now try a 8.3 directory, long file name */
565 test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
566 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
567 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
568 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
569 !passfail.shorterror,
570 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
571 if(pGetLongPathNameA) {
572 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
573 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
574 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
576 /* Next is a long directory, 8.3 file */
577 test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
578 sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
579 GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
580 strcat(tmpstr1,"\\" NONFILE_SHORT);
581 ok((passfail.shortlen==0 &&
582 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
583 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
584 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
585 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
586 passfail.shortlen,passfail.shorterror,tmpstr);
587 if(pGetLongPathNameA) {
588 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
589 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
590 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
592 /*Lastly a long directory, long file */
593 test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
594 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
595 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
596 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
597 !passfail.shorterror,
598 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
599 if(pGetLongPathNameA) {
600 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
601 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
602 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
604 /* Now try again with directories that don't exist */
605 /* 8.3 directory, 8.3 filename */
606 test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
607 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
608 ok((passfail.shortlen==0 &&
609 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
610 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
611 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
612 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
613 passfail.shortlen,passfail.shorterror,tmpstr);
614 if(pGetLongPathNameA) {
615 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
616 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
617 passfail.longerror==ERROR_FILE_NOT_FOUND,
618 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
621 /* Now try a 8.3 directory, long file name */
622 test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
623 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
624 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
625 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
626 !passfail.shorterror,
627 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
628 passfail.shorterror);
629 if(pGetLongPathNameA) {
630 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
631 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
632 passfail.longerror==ERROR_FILE_NOT_FOUND,
633 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
636 /* Next is a long directory, 8.3 file */
637 test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
638 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
639 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
640 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
641 !passfail.shorterror,
642 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
643 passfail.shorterror);
644 if(pGetLongPathNameA) {
645 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
646 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
647 passfail.longerror==ERROR_FILE_NOT_FOUND,
648 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
651 /*Lastly a long directory, long file */
652 test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
653 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
654 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
655 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
656 !passfail.shorterror,
657 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
658 passfail.shorterror);
659 if(pGetLongPathNameA) {
660 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
661 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
662 passfail.longerror==ERROR_FILE_NOT_FOUND,
663 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
666 /* Next try directories ending with '\\' */
667 /* Existing Directories */
668 sprintf(tmpstr,"%s\\",SHORTDIR);
669 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
670 sprintf(tmpstr,"%s\\",LONGDIR);
671 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
672 /* Nonexistent directories */
673 sprintf(tmpstr,"%s\\",NONDIR_SHORT);
674 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
675 sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
676 ok((passfail.shortlen==0 &&
677 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
678 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
679 (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
680 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
681 passfail.shortlen,passfail.shorterror,tmpstr);
682 if(pGetLongPathNameA) {
683 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
684 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
685 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
688 sprintf(tmpstr,"%s\\",NONDIR_LONG);
689 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
690 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
691 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
692 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
693 !passfail.shorterror,
694 "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
695 passfail.shorterror);
696 if(pGetLongPathNameA) {
697 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
698 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
699 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
702 /* Test GetFullPathNameA with drive letters */
703 if( curDrive != NOT_A_VALID_DRIVE) {
704 sprintf(tmpstr,"%c:",curdir[0]);
705 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
706 "GetFullPathNameA(%c:) failed\n", curdir[0]);
707 GetCurrentDirectoryA(MAX_PATH,tmpstr);
708 sprintf(tmpstr1,"%s\\",tmpstr);
709 ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
710 "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
711 curdir[0],tmpstr2,tmpstr,tmpstr1);
713 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
714 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
715 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
716 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
717 ok(lstrcmpiA(SHORTFILE,strptr)==0,
718 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
720 /* Without a leading slash, insert the current directory if on the current drive */
721 sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
722 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
723 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
724 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
725 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
726 ok(lstrcmpiA(SHORTFILE,strptr)==0,
727 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
728 /* Otherwise insert the missing leading slash */
729 if( otherDrive != NOT_A_VALID_DRIVE) {
730 sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
731 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
732 sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
733 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
734 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
735 ok(lstrcmpiA(SHORTFILE,strptr)==0,
736 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
738 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
740 if( curDrive != NOT_A_VALID_DRIVE) {
741 sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
742 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
743 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
744 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
745 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
746 ok(lstrcmpiA(SHORTFILE,strptr)==0,
747 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
750 sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
751 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
752 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
753 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
754 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
755 ok(lstrcmpiA(SHORTFILE,strptr)==0,
756 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
757 /* Windows will insert a drive letter in front of an absolute UNIX path */
758 sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
759 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
760 sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
761 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
762 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
763 /* This passes in Wine because it still contains the pointer from the previous test */
764 ok(lstrcmpiA(SHORTFILE,strptr)==0,
765 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
767 /* Now try some relative paths */
768 ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
769 test_SplitShortPathA(tmpstr,dir,eight,three);
770 if(pGetLongPathNameA) {
771 ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
772 ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
773 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
775 sprintf(tmpstr,".\\%s",LONGDIR);
776 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
777 test_SplitShortPathA(tmpstr1,dir,eight,three);
778 ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
779 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
780 if(pGetLongPathNameA) {
781 ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
783 ok(lstrcmpiA(tmpstr1,tmpstr)==0,
784 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
786 /* Check out Get*PathNameA on some funny characters */
787 for(i=0;i<lstrlenA(funny_chars);i++) {
789 valid=(is_char_ok[i]=='0') ? 0 : 1;
790 sprintf(tmpstr1,"check%d-1",i);
791 sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
792 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
793 sprintf(tmpstr1,"check%d-2",i);
794 sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
795 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
796 sprintf(tmpstr1,"check%d-3",i);
797 sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
798 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
799 sprintf(tmpstr1,"check%d-4",i);
800 sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
801 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
802 sprintf(tmpstr1,"check%d-5",i);
803 sprintf(tmpstr,"Long %c File",funny_chars[i]);
804 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
805 sprintf(tmpstr1,"check%d-6",i);
806 sprintf(tmpstr,"%c Long File",funny_chars[i]);
807 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
808 sprintf(tmpstr1,"check%d-7",i);
809 sprintf(tmpstr,"Long File %c",funny_chars[i]);
810 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
814 static void test_GetTempPathA(char* tmp_dir)
816 DWORD len, len_with_null;
819 len_with_null = strlen(tmp_dir) + 1;
821 lstrcpyA(buf, "foo");
822 len = GetTempPathA(MAX_PATH, buf);
823 ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
824 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
825 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
827 /* Some versions of Windows touch the buffer, some don't so we don't
828 * test that. Also, NT sometimes exagerates the required buffer size
829 * so we cannot test for an exact match. Finally, the
830 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
831 * For instance in some cases Win98 returns len_with_null - 1 instead
834 len = GetTempPathA(1, buf);
835 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
837 len = GetTempPathA(0, NULL);
838 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
840 /* The call above gave us the buffer size that Windows thinks is needed
841 * so the next call should work
843 lstrcpyA(buf, "foo");
844 len = GetTempPathA(len, buf);
845 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
846 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
849 static void test_GetTempPathW(char* tmp_dir)
851 DWORD len, len_with_null;
853 WCHAR tmp_dirW[MAX_PATH];
854 static const WCHAR fooW[] = {'f','o','o',0};
856 MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
857 len_with_null = lstrlenW(tmp_dirW) + 1;
859 /* This one is different from ANSI version: ANSI version doesn't
860 * touch the buffer, unicode version usually truncates the buffer
861 * to zero size. NT still exagerates the required buffer size
862 * sometimes so we cannot test for an exact match. Finally, the
863 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
864 * For instance on NT4 it will sometimes return a path without the
865 * trailing '\\' and sometimes return an error.
869 len = GetTempPathW(MAX_PATH, buf);
870 if (len==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
872 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
873 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
876 len = GetTempPathW(1, buf);
877 ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
878 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
880 len = GetTempPathW(0, NULL);
881 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
884 len = GetTempPathW(len, buf);
885 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
886 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
889 static void test_GetTempPath(void)
891 char save_TMP[MAX_PATH];
892 char windir[MAX_PATH];
895 GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP));
897 /* test default configuration */
898 trace("TMP=%s\n", save_TMP);
899 strcpy(buf,save_TMP);
900 if (buf[strlen(buf)-1]!='\\')
902 test_GetTempPathA(buf);
903 test_GetTempPathW(buf);
906 GetWindowsDirectoryA(windir, sizeof(windir));
907 SetEnvironmentVariableA("TMP", windir);
908 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
909 trace("TMP=%s\n", buf);
911 test_GetTempPathA(windir);
912 test_GetTempPathW(windir);
915 GetWindowsDirectoryA(windir, sizeof(windir));
917 SetEnvironmentVariableA("TMP", windir);
918 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
919 trace("TMP=%s\n", buf);
920 test_GetTempPathA(windir);
921 test_GetTempPathW(windir);
923 /* TMP=C: i.e. use current working directory of the specified drive */
924 GetWindowsDirectoryA(windir, sizeof(windir));
925 SetCurrentDirectoryA(windir);
927 SetEnvironmentVariableA("TMP", windir);
928 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
929 trace("TMP=%s\n", buf);
930 GetWindowsDirectoryA(windir, sizeof(windir));
932 test_GetTempPathA(windir);
933 test_GetTempPathW(windir);
935 SetEnvironmentVariableA("TMP", save_TMP);
938 static void test_GetLongPathNameW(void)
941 WCHAR empty[MAX_PATH];
943 /* Not present in all windows versions */
944 if(pGetLongPathNameW)
946 SetLastError(0xdeadbeef);
947 length = pGetLongPathNameW(NULL,NULL,0);
948 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
950 skip("GetLongPathNameW is not implemented\n");
953 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
954 ok(GetLastError()==ERROR_INVALID_PARAMETER,"GetLastError returned %d but expected ERROR_INVALID_PARAMETER\n",GetLastError());
956 SetLastError(0xdeadbeef);
958 length = pGetLongPathNameW(empty,NULL,0);
959 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
960 ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
964 static void test_GetShortPathNameW(void)
966 WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
967 WCHAR path[MAX_PATH];
968 WCHAR short_path[MAX_PATH];
972 WCHAR name[] = { 't', 'e', 's', 't', 0 };
973 WCHAR backSlash[] = { '\\', 0 };
975 GetTempPathW( MAX_PATH, path );
976 lstrcatW( path, test_path );
977 lstrcatW( path, backSlash );
978 ret = CreateDirectoryW( path, NULL );
979 ok( ret, "Directory was not created. LastError = %d\n", GetLastError() );
981 /* Starting a main part of test */
982 length = GetShortPathNameW( path, short_path, 0 );
983 ok( length, "GetShortPathNameW returned 0.\n" );
984 ret = GetShortPathNameW( path, short_path, length );
985 ok( ret, "GetShortPathNameW returned 0.\n" );
986 lstrcatW( short_path, name );
987 file = CreateFileW( short_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
988 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
992 ret = DeleteFileW( short_path );
993 ok( ret, "Cannot delete file.\n" );
994 ret = RemoveDirectoryW( path );
995 ok( ret, "Cannot delete directory.\n" );
998 static void test_GetSystemDirectory(void)
1000 CHAR buffer[MAX_PATH + 4];
1004 SetLastError(0xdeadbeef);
1005 res = GetSystemDirectory(NULL, 0);
1006 /* res includes the terminating Zero */
1007 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1011 /* this crashes on XP */
1012 if (0) res = GetSystemDirectory(NULL, total);
1014 SetLastError(0xdeadbeef);
1015 res = GetSystemDirectory(NULL, total-1);
1016 /* 95+NT: total (includes the terminating Zero)
1017 98+ME: 0 with ERROR_INVALID_PARAMETER */
1018 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1019 "returned %d with %d (expected '%d' or: '0' with "
1020 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1022 if (total > MAX_PATH) return;
1025 SetLastError(0xdeadbeef);
1026 res = GetSystemDirectory(buffer, total);
1027 /* res does not include the terminating Zero */
1028 ok( (res == (total-1)) && (buffer[0]),
1029 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1030 res, GetLastError(), buffer, total-1);
1033 SetLastError(0xdeadbeef);
1034 res = GetSystemDirectory(buffer, total + 1);
1035 /* res does not include the terminating Zero */
1036 ok( (res == (total-1)) && (buffer[0]),
1037 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1038 res, GetLastError(), buffer, total-1);
1040 memset(buffer, '#', total + 1);
1041 buffer[total + 2] = '\0';
1042 SetLastError(0xdeadbeef);
1043 res = GetSystemDirectory(buffer, total-1);
1044 /* res includes the terminating Zero) */
1045 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1046 res, GetLastError(), buffer, total);
1048 memset(buffer, '#', total + 1);
1049 buffer[total + 2] = '\0';
1050 SetLastError(0xdeadbeef);
1051 res = GetSystemDirectory(buffer, total-2);
1052 /* res includes the terminating Zero) */
1053 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1054 res, GetLastError(), buffer, total);
1057 static void test_GetWindowsDirectory(void)
1059 CHAR buffer[MAX_PATH + 4];
1063 SetLastError(0xdeadbeef);
1064 res = GetWindowsDirectory(NULL, 0);
1065 /* res includes the terminating Zero */
1066 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1069 /* this crashes on XP */
1070 if (0) res = GetWindowsDirectory(NULL, total);
1072 SetLastError(0xdeadbeef);
1073 res = GetWindowsDirectory(NULL, total-1);
1074 /* 95+NT: total (includes the terminating Zero)
1075 98+ME: 0 with ERROR_INVALID_PARAMETER */
1076 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1077 "returned %d with %d (expected '%d' or: '0' with "
1078 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1080 if (total > MAX_PATH) return;
1083 SetLastError(0xdeadbeef);
1084 res = GetWindowsDirectory(buffer, total);
1085 /* res does not include the terminating Zero */
1086 ok( (res == (total-1)) && (buffer[0]),
1087 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1088 res, GetLastError(), buffer, total-1);
1091 SetLastError(0xdeadbeef);
1092 res = GetWindowsDirectory(buffer, total + 1);
1093 /* res does not include the terminating Zero */
1094 ok( (res == (total-1)) && (buffer[0]),
1095 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1096 res, GetLastError(), buffer, total-1);
1098 memset(buffer, '#', total + 1);
1099 buffer[total + 2] = '\0';
1100 SetLastError(0xdeadbeef);
1101 res = GetWindowsDirectory(buffer, total-1);
1102 /* res includes the terminating Zero) */
1103 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1104 res, GetLastError(), buffer, total);
1106 memset(buffer, '#', total + 1);
1107 buffer[total + 2] = '\0';
1108 SetLastError(0xdeadbeef);
1109 res = GetWindowsDirectory(buffer, total-2);
1110 /* res includes the terminating Zero) */
1111 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1112 res, GetLastError(), buffer, total);
1115 static void test_NeedCurrentDirectoryForExePathA(void)
1117 /* Crashes in Windows */
1119 ok(pNeedCurrentDirectoryForExePathA(NULL), "returned FALSE for NULL\n");
1121 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1122 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1123 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1124 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1126 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1127 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1128 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1129 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1132 static void test_NeedCurrentDirectoryForExePathW(void)
1134 const WCHAR thispath[] = {'.', 0};
1135 const WCHAR fullpath[] = {'c', ':', '\\', 0};
1136 const WCHAR cmdname[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1138 /* Crashes in Windows */
1140 ok(pNeedCurrentDirectoryForExePathW(NULL), "returned FALSE for NULL\n");
1142 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1143 ok(pNeedCurrentDirectoryForExePathW(thispath), "returned FALSE for \".\"\n");
1144 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1145 ok(pNeedCurrentDirectoryForExePathW(cmdname), "returned FALSE for \"cmd.exe\"\n");
1147 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1148 ok(!pNeedCurrentDirectoryForExePathW(thispath), "returned TRUE for \".\"\n");
1149 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1150 ok(!pNeedCurrentDirectoryForExePathW(cmdname), "returned TRUE for \"cmd.exe\"\n");
1155 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
1156 pGetLongPathNameA = (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
1157 "GetLongPathNameA" );
1158 pGetLongPathNameW = (void*)GetProcAddress(GetModuleHandleA("kernel32.dll") ,
1159 "GetLongPathNameW" );
1160 pNeedCurrentDirectoryForExePathA =
1161 (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
1162 "NeedCurrentDirectoryForExePathA" );
1163 pNeedCurrentDirectoryForExePathW =
1164 (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
1165 "NeedCurrentDirectoryForExePathW" );
1167 test_InitPathA(curdir, &curDrive, &otherDrive);
1168 test_CurrentDirectoryA(origdir,curdir);
1169 test_PathNameA(curdir, curDrive, otherDrive);
1170 test_CleanupPathA(origdir,curdir);
1172 test_GetLongPathNameW();
1173 test_GetShortPathNameW();
1174 test_GetSystemDirectory();
1175 test_GetWindowsDirectory();
1176 if (pNeedCurrentDirectoryForExePathA)
1178 test_NeedCurrentDirectoryForExePathA();
1180 if (pNeedCurrentDirectoryForExePathW)
1182 test_NeedCurrentDirectoryForExePathW();