push 014043c4937c940c54cd1214c96e33a3b3c8cf7d
[wine/hacks.git] / dlls / kernel32 / tests / path.c
blobdfb77481c99079cdf0c683496918d33028bc652d
1 /*
2 * Unit test suite for various Path and Directory Functions
4 * Copyright 2002 Geoffrey Hausheer
5 * Copyright 2006 Detlef Riekenberg
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include "wine/test.h"
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "winerror.h"
29 #include "winnls.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
48 |<>"
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 */
61 typedef struct {
62 DWORD shortlen;
63 DWORD shorterror;
64 DWORD s2llen;
65 DWORD s2lerror;
66 DWORD longlen;
67 DWORD longerror;
68 } SLpassfail;
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 */
86 DWORD len;
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
91 if(passfail!=NULL) {
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);
111 } else {
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)) {
121 ok(strptr==NULL,
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);
126 } else {
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 */
135 SetLastError(0);
136 len=GetShortPathNameA(fullpathshort,shortstr,MAX_PATH);
137 if(passfail==NULL) {
138 ok(len, "%s: GetShortPathNameA failed\n",errstr);
139 } else {
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) {
147 if(len!=0) {
148 SetLastError(0);
149 len=pGetLongPathNameA(shortstr,tmpstr,MAX_PATH);
150 if(passfail==NULL) {
151 ok(len,
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);
156 } else {
157 passfail->s2llen=len;
158 passfail->s2lerror=GetLastError();
161 SetLastError(0);
162 len=pGetLongPathNameA(fullpath,tmpstr,MAX_PATH);
163 if(passfail==NULL) {
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);
169 } else {
170 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
171 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
172 errstr,tmpstr,fullpathlong);
174 } else {
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) {
183 int done,error;
184 int ext,fil;
185 int len,i;
186 len=lstrlenA(path);
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--) {
190 if(path[i]=='.')
191 if(ext!=len) error=1; else ext=i;
192 else if(path[i]=='\\') {
193 if(i==len-1) {
194 error=1;
195 } else {
196 fil=i;
197 done=1;
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,"");
205 if(fil!=len) {
206 lstrcpynA(eight,path+fil+1,ext-fil);
207 lstrcpynA(dir,path,fil+1);
208 } else {
209 lstrcpynA(eight,path,ext+1);
210 lstrcpyA(dir,"");
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
235 should.
237 static void test_FunnyChars(CHAR *curdir,CHAR *curdir_short,CHAR *filename, INT valid,CHAR *errstr)
239 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
240 SLpassfail passfail;
242 test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
243 if(valid) {
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);
250 } else {
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");
258 if(valid) {
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);
262 } else {
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 */
281 if(pass) {
282 dirptr=(cmprstr==NULL) ? newdir : cmprstr;
283 chklen=lstrlenA(dirptr);
284 ok(val,"%s: SetCurrentDirectoryA failed\n",errstr);
285 ok(len==chklen,
286 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
287 errstr);
288 ok(lstrcmpiA(dirptr,tmppath)==0,
289 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
290 errstr);
291 ok(SetCurrentDirectoryA(olddir),
292 "%s: Couldn't set directory to it's original value\n",errstr);
293 } else {
294 /* else thest that it fails correctly */
295 chklen=lstrlenA(olddir);
296 ok(val==0,
297 "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr);
298 ok(len==chklen,
299 "%s: SetCurrentDirectory changed the directory, though it failed\n",
300 errstr);
301 ok(lstrcmpiA(olddir,tmppath)==0,
302 "%s: SetCurrentDirectory changed the directory, though it failed\n",
303 errstr);
306 static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
308 CHAR tmppath[MAX_PATH], /*path to TEMP */
309 tmpstr[MAX_PATH],
310 tmpstr1[MAX_PATH];
311 DWORD len,len1,drives;
312 INT id;
313 HANDLE hndl;
314 BOOL bRes;
316 *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
318 /* Get the current drive letter */
319 if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
320 *curDrive = tmpstr[0];
321 else
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);
331 ok(len1==len+1,
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 */
350 if (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'));
365 if( drives)
366 for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
367 else
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
381 at some later point
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];
421 DWORD len,len1;
422 /* Save the original directory, so that we can return to it at the end
423 of the test
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
436 trailing '\\' or not
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 */
497 DWORD len;
498 INT i;
499 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
500 SLpassfail passfail;
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) {
515 DWORD rc1,rc2;
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",
527 tmpstr,dir,rc1);
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",
619 passfail.longerror);
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",
634 passfail.longerror);
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",
649 passfail.longerror);
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",
664 passfail.longerror);
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",
686 passfail.longerror);
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",
700 passfail.longerror);
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 /* FIXME: this test assumes that current directory on other drive is root */
731 sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
732 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
733 sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
734 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
735 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
736 ok(lstrcmpiA(SHORTFILE,strptr)==0,
737 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
739 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
740 So test for them. */
741 if( curDrive != NOT_A_VALID_DRIVE) {
742 sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
743 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
744 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
745 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
746 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
747 ok(lstrcmpiA(SHORTFILE,strptr)==0,
748 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
750 /**/
751 sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
752 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
753 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
754 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
755 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
756 ok(lstrcmpiA(SHORTFILE,strptr)==0,
757 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
758 /* Windows will insert a drive letter in front of an absolute UNIX path */
759 sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
760 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
761 sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
762 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
763 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
764 /* This passes in Wine because it still contains the pointer from the previous test */
765 ok(lstrcmpiA(SHORTFILE,strptr)==0,
766 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
768 /* Now try some relative paths */
769 ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
770 test_SplitShortPathA(tmpstr,dir,eight,three);
771 if(pGetLongPathNameA) {
772 ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
773 ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
774 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
776 sprintf(tmpstr,".\\%s",LONGDIR);
777 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
778 test_SplitShortPathA(tmpstr1,dir,eight,three);
779 ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
780 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
781 if(pGetLongPathNameA) {
782 ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
783 tmpstr);
784 ok(lstrcmpiA(tmpstr1,tmpstr)==0,
785 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
787 /* Check out Get*PathNameA on some funny characters */
788 for(i=0;i<lstrlenA(funny_chars);i++) {
789 INT valid;
790 valid=(is_char_ok[i]=='0') ? 0 : 1;
791 sprintf(tmpstr1,"check%d-1",i);
792 sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
793 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
794 sprintf(tmpstr1,"check%d-2",i);
795 sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
796 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
797 sprintf(tmpstr1,"check%d-3",i);
798 sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
799 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
800 sprintf(tmpstr1,"check%d-4",i);
801 sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
802 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
803 sprintf(tmpstr1,"check%d-5",i);
804 sprintf(tmpstr,"Long %c File",funny_chars[i]);
805 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
806 sprintf(tmpstr1,"check%d-6",i);
807 sprintf(tmpstr,"%c Long File",funny_chars[i]);
808 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
809 sprintf(tmpstr1,"check%d-7",i);
810 sprintf(tmpstr,"Long File %c",funny_chars[i]);
811 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
815 static void test_GetTempPathA(char* tmp_dir)
817 DWORD len, len_with_null;
818 char buf[MAX_PATH];
820 len_with_null = strlen(tmp_dir) + 1;
822 lstrcpyA(buf, "foo");
823 len = GetTempPathA(MAX_PATH, buf);
824 ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
825 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
826 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
828 /* Some versions of Windows touch the buffer, some don't so we don't
829 * test that. Also, NT sometimes exagerates the required buffer size
830 * so we cannot test for an exact match. Finally, the
831 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
832 * For instance in some cases Win98 returns len_with_null - 1 instead
833 * of len_with_null.
835 len = GetTempPathA(1, buf);
836 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
838 len = GetTempPathA(0, NULL);
839 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
841 /* The call above gave us the buffer size that Windows thinks is needed
842 * so the next call should work
844 lstrcpyA(buf, "foo");
845 len = GetTempPathA(len, buf);
846 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
847 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
850 static void test_GetTempPathW(char* tmp_dir)
852 DWORD len, len_with_null;
853 WCHAR buf[MAX_PATH];
854 WCHAR tmp_dirW[MAX_PATH];
855 static const WCHAR fooW[] = {'f','o','o',0};
857 MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
858 len_with_null = lstrlenW(tmp_dirW) + 1;
860 /* This one is different from ANSI version: ANSI version doesn't
861 * touch the buffer, unicode version usually truncates the buffer
862 * to zero size. NT still exagerates the required buffer size
863 * sometimes so we cannot test for an exact match. Finally, the
864 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
865 * For instance on NT4 it will sometimes return a path without the
866 * trailing '\\' and sometimes return an error.
869 lstrcpyW(buf, fooW);
870 len = GetTempPathW(MAX_PATH, buf);
871 if (len==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
872 return;
873 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
874 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
876 lstrcpyW(buf, fooW);
877 len = GetTempPathW(1, buf);
878 ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
879 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
881 len = GetTempPathW(0, NULL);
882 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
884 lstrcpyW(buf, fooW);
885 len = GetTempPathW(len, buf);
886 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
887 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
890 static void test_GetTempPath(void)
892 char save_TMP[MAX_PATH];
893 char windir[MAX_PATH];
894 char buf[MAX_PATH];
896 GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP));
898 /* test default configuration */
899 trace("TMP=%s\n", save_TMP);
900 strcpy(buf,save_TMP);
901 if (buf[strlen(buf)-1]!='\\')
902 strcat(buf,"\\");
903 test_GetTempPathA(buf);
904 test_GetTempPathW(buf);
906 /* TMP=C:\WINDOWS */
907 GetWindowsDirectoryA(windir, sizeof(windir));
908 SetEnvironmentVariableA("TMP", windir);
909 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
910 trace("TMP=%s\n", buf);
911 strcat(windir,"\\");
912 test_GetTempPathA(windir);
913 test_GetTempPathW(windir);
915 /* TMP=C:\ */
916 GetWindowsDirectoryA(windir, sizeof(windir));
917 windir[3] = 0;
918 SetEnvironmentVariableA("TMP", windir);
919 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
920 trace("TMP=%s\n", buf);
921 test_GetTempPathA(windir);
922 test_GetTempPathW(windir);
924 /* TMP=C: i.e. use current working directory of the specified drive */
925 GetWindowsDirectoryA(windir, sizeof(windir));
926 SetCurrentDirectoryA(windir);
927 windir[2] = 0;
928 SetEnvironmentVariableA("TMP", windir);
929 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
930 trace("TMP=%s\n", buf);
931 GetWindowsDirectoryA(windir, sizeof(windir));
932 strcat(windir,"\\");
933 test_GetTempPathA(windir);
934 test_GetTempPathW(windir);
936 SetEnvironmentVariableA("TMP", save_TMP);
939 static void test_GetLongPathNameW(void)
941 DWORD length;
942 WCHAR empty[MAX_PATH];
944 /* Not present in all windows versions */
945 if(pGetLongPathNameW)
947 SetLastError(0xdeadbeef);
948 length = pGetLongPathNameW(NULL,NULL,0);
949 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
951 skip("GetLongPathNameW is not implemented\n");
952 return;
954 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
955 ok(GetLastError()==ERROR_INVALID_PARAMETER,"GetLastError returned %d but expected ERROR_INVALID_PARAMETER\n",GetLastError());
957 SetLastError(0xdeadbeef);
958 empty[0]=0;
959 length = pGetLongPathNameW(empty,NULL,0);
960 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
961 ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
965 static void test_GetShortPathNameW(void)
967 WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
968 WCHAR path[MAX_PATH];
969 WCHAR short_path[MAX_PATH];
970 DWORD length;
971 HANDLE file;
972 int ret;
973 WCHAR name[] = { 't', 'e', 's', 't', 0 };
974 WCHAR backSlash[] = { '\\', 0 };
976 SetLastError(0xdeadbeef);
977 GetTempPathW( MAX_PATH, path );
978 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
980 skip("GetTempPathW is not implemented\n");
981 return;
984 lstrcatW( path, test_path );
985 lstrcatW( path, backSlash );
986 ret = CreateDirectoryW( path, NULL );
987 ok( ret, "Directory was not created. LastError = %d\n", GetLastError() );
989 /* Starting a main part of test */
990 length = GetShortPathNameW( path, short_path, 0 );
991 ok( length, "GetShortPathNameW returned 0.\n" );
992 ret = GetShortPathNameW( path, short_path, length );
993 ok( ret, "GetShortPathNameW returned 0.\n" );
994 lstrcatW( short_path, name );
995 file = CreateFileW( short_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
996 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
998 /* End test */
999 CloseHandle( file );
1000 ret = DeleteFileW( short_path );
1001 ok( ret, "Cannot delete file.\n" );
1002 ret = RemoveDirectoryW( path );
1003 ok( ret, "Cannot delete directory.\n" );
1006 static void test_GetSystemDirectory(void)
1008 CHAR buffer[MAX_PATH + 4];
1009 DWORD res;
1010 DWORD total;
1012 SetLastError(0xdeadbeef);
1013 res = GetSystemDirectory(NULL, 0);
1014 /* res includes the terminating Zero */
1015 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1017 total = res;
1019 /* this crashes on XP */
1020 if (0) res = GetSystemDirectory(NULL, total);
1022 SetLastError(0xdeadbeef);
1023 res = GetSystemDirectory(NULL, total-1);
1024 /* 95+NT: total (includes the terminating Zero)
1025 98+ME: 0 with ERROR_INVALID_PARAMETER */
1026 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1027 "returned %d with %d (expected '%d' or: '0' with "
1028 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1030 if (total > MAX_PATH) return;
1032 buffer[0] = '\0';
1033 SetLastError(0xdeadbeef);
1034 res = GetSystemDirectory(buffer, total);
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 buffer[0] = '\0';
1041 SetLastError(0xdeadbeef);
1042 res = GetSystemDirectory(buffer, total + 1);
1043 /* res does not include the terminating Zero */
1044 ok( (res == (total-1)) && (buffer[0]),
1045 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1046 res, GetLastError(), buffer, total-1);
1048 memset(buffer, '#', total + 1);
1049 buffer[total + 2] = '\0';
1050 SetLastError(0xdeadbeef);
1051 res = GetSystemDirectory(buffer, total-1);
1052 /* res includes the terminating Zero) */
1053 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1054 res, GetLastError(), buffer, total);
1056 memset(buffer, '#', total + 1);
1057 buffer[total + 2] = '\0';
1058 SetLastError(0xdeadbeef);
1059 res = GetSystemDirectory(buffer, total-2);
1060 /* res includes the terminating Zero) */
1061 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1062 res, GetLastError(), buffer, total);
1065 static void test_GetWindowsDirectory(void)
1067 CHAR buffer[MAX_PATH + 4];
1068 DWORD res;
1069 DWORD total;
1071 SetLastError(0xdeadbeef);
1072 res = GetWindowsDirectory(NULL, 0);
1073 /* res includes the terminating Zero */
1074 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1076 total = res;
1077 /* this crashes on XP */
1078 if (0) res = GetWindowsDirectory(NULL, total);
1080 SetLastError(0xdeadbeef);
1081 res = GetWindowsDirectory(NULL, total-1);
1082 /* 95+NT: total (includes the terminating Zero)
1083 98+ME: 0 with ERROR_INVALID_PARAMETER */
1084 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1085 "returned %d with %d (expected '%d' or: '0' with "
1086 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1088 if (total > MAX_PATH) return;
1090 buffer[0] = '\0';
1091 SetLastError(0xdeadbeef);
1092 res = GetWindowsDirectory(buffer, total);
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 buffer[0] = '\0';
1099 SetLastError(0xdeadbeef);
1100 res = GetWindowsDirectory(buffer, total + 1);
1101 /* res does not include the terminating Zero */
1102 ok( (res == (total-1)) && (buffer[0]),
1103 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1104 res, GetLastError(), buffer, total-1);
1106 memset(buffer, '#', total + 1);
1107 buffer[total + 2] = '\0';
1108 SetLastError(0xdeadbeef);
1109 res = GetWindowsDirectory(buffer, total-1);
1110 /* res includes the terminating Zero) */
1111 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1112 res, GetLastError(), buffer, total);
1114 memset(buffer, '#', total + 1);
1115 buffer[total + 2] = '\0';
1116 SetLastError(0xdeadbeef);
1117 res = GetWindowsDirectory(buffer, total-2);
1118 /* res includes the terminating Zero) */
1119 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1120 res, GetLastError(), buffer, total);
1123 static void test_NeedCurrentDirectoryForExePathA(void)
1125 /* Crashes in Windows */
1126 if (0)
1127 ok(pNeedCurrentDirectoryForExePathA(NULL), "returned FALSE for NULL\n");
1129 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1130 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1131 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1132 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1134 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1135 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1136 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1137 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1140 static void test_NeedCurrentDirectoryForExePathW(void)
1142 const WCHAR thispath[] = {'.', 0};
1143 const WCHAR fullpath[] = {'c', ':', '\\', 0};
1144 const WCHAR cmdname[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1146 /* Crashes in Windows */
1147 if (0)
1148 ok(pNeedCurrentDirectoryForExePathW(NULL), "returned FALSE for NULL\n");
1150 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1151 ok(pNeedCurrentDirectoryForExePathW(thispath), "returned FALSE for \".\"\n");
1152 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1153 ok(pNeedCurrentDirectoryForExePathW(cmdname), "returned FALSE for \"cmd.exe\"\n");
1155 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1156 ok(!pNeedCurrentDirectoryForExePathW(thispath), "returned TRUE for \".\"\n");
1157 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1158 ok(!pNeedCurrentDirectoryForExePathW(cmdname), "returned TRUE for \"cmd.exe\"\n");
1161 /* Call various path/file name retrieving APIs and check the case of
1162 * the returned drive letter. Some apps (for instance Adobe Photoshop CS3
1163 * installer) depend on the driver letter being in upper case.
1165 static void test_drive_letter_case(void)
1167 UINT ret;
1168 char buf[MAX_PATH];
1170 #define is_upper_case_letter(a) ((a) >= 'A' && (a) <= 'Z')
1172 memset(buf, 0, sizeof(buf));
1173 SetLastError(0xdeadbeef);
1174 ret = GetWindowsDirectory(buf, sizeof(buf));
1175 ok(ret, "GetWindowsDirectory error %u\n", GetLastError());
1176 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1177 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1178 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1180 /* re-use the buffer returned by GetFullPathName */
1181 buf[2] = '/';
1182 SetLastError(0xdeadbeef);
1183 ret = GetFullPathName(buf + 2, sizeof(buf), buf, NULL);
1184 ok(ret, "GetFullPathName error %u\n", GetLastError());
1185 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1186 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1187 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1189 memset(buf, 0, sizeof(buf));
1190 SetLastError(0xdeadbeef);
1191 ret = GetSystemDirectory(buf, sizeof(buf));
1192 ok(ret, "GetSystemDirectory error %u\n", GetLastError());
1193 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1194 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1195 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1197 memset(buf, 0, sizeof(buf));
1198 SetLastError(0xdeadbeef);
1199 ret = GetCurrentDirectory(sizeof(buf), buf);
1200 ok(ret, "GetCurrentDirectory error %u\n", GetLastError());
1201 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1202 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1203 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1205 memset(buf, 0, sizeof(buf));
1206 SetLastError(0xdeadbeef);
1207 ret = GetTempPath(sizeof(buf), buf);
1208 ok(ret, "GetTempPath error %u\n", GetLastError());
1209 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1210 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1211 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1213 memset(buf, 0, sizeof(buf));
1214 SetLastError(0xdeadbeef);
1215 ret = GetFullPathName(".", sizeof(buf), buf, NULL);
1216 ok(ret, "GetFullPathName error %u\n", GetLastError());
1217 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1218 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1219 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1221 /* re-use the buffer returned by GetFullPathName */
1222 SetLastError(0xdeadbeef);
1223 ret = GetShortPathName(buf, buf, sizeof(buf));
1224 ok(ret, "GetShortPathName error %u\n", GetLastError());
1225 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1226 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1227 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1229 if (pGetLongPathNameA)
1231 /* re-use the buffer returned by GetShortPathName */
1232 SetLastError(0xdeadbeef);
1233 ret = pGetLongPathNameA(buf, buf, sizeof(buf));
1234 ok(ret, "GetLongPathNameA error %u\n", GetLastError());
1235 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1236 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1237 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1239 #undef is_upper_case_letter
1242 START_TEST(path)
1244 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
1245 pGetLongPathNameA = (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
1246 "GetLongPathNameA" );
1247 pGetLongPathNameW = (void*)GetProcAddress(GetModuleHandleA("kernel32.dll") ,
1248 "GetLongPathNameW" );
1249 pNeedCurrentDirectoryForExePathA =
1250 (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
1251 "NeedCurrentDirectoryForExePathA" );
1252 pNeedCurrentDirectoryForExePathW =
1253 (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
1254 "NeedCurrentDirectoryForExePathW" );
1256 test_InitPathA(curdir, &curDrive, &otherDrive);
1257 test_CurrentDirectoryA(origdir,curdir);
1258 test_PathNameA(curdir, curDrive, otherDrive);
1259 test_CleanupPathA(origdir,curdir);
1260 test_GetTempPath();
1261 test_GetLongPathNameW();
1262 test_GetShortPathNameW();
1263 test_GetSystemDirectory();
1264 test_GetWindowsDirectory();
1265 if (pNeedCurrentDirectoryForExePathA)
1267 test_NeedCurrentDirectoryForExePathA();
1269 if (pNeedCurrentDirectoryForExePathW)
1271 test_NeedCurrentDirectoryForExePathW();
1273 test_drive_letter_case();