kernel32/tests: Add tests for NeedCurrentDirectoryForExePath.
[wine.git] / dlls / kernel32 / tests / path.c
blob47ec23ff88c00e1dd2fa82c76382678873da3c7c
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 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.
739 So test for them. */
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);
749 /**/
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",
782 tmpstr);
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++) {
788 INT valid;
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;
817 char buf[MAX_PATH];
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
832 * of len_with_null.
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;
852 WCHAR buf[MAX_PATH];
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.
868 lstrcpyW(buf, fooW);
869 len = GetTempPathW(MAX_PATH, buf);
870 if (len==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
871 return;
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");
875 lstrcpyW(buf, fooW);
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);
883 lstrcpyW(buf, fooW);
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];
893 char buf[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]!='\\')
901 strcat(buf,"\\");
902 test_GetTempPathA(buf);
903 test_GetTempPathW(buf);
905 /* TMP=C:\WINDOWS */
906 GetWindowsDirectoryA(windir, sizeof(windir));
907 SetEnvironmentVariableA("TMP", windir);
908 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
909 trace("TMP=%s\n", buf);
910 strcat(windir,"\\");
911 test_GetTempPathA(windir);
912 test_GetTempPathW(windir);
914 /* TMP=C:\ */
915 GetWindowsDirectoryA(windir, sizeof(windir));
916 windir[3] = 0;
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);
926 windir[2] = 0;
927 SetEnvironmentVariableA("TMP", windir);
928 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
929 trace("TMP=%s\n", buf);
930 GetWindowsDirectoryA(windir, sizeof(windir));
931 strcat(windir,"\\");
932 test_GetTempPathA(windir);
933 test_GetTempPathW(windir);
935 SetEnvironmentVariableA("TMP", save_TMP);
938 static void test_GetLongPathNameW(void)
940 DWORD length;
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");
951 return;
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);
957 empty[0]=0;
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_GetSystemDirectory(void)
966 CHAR buffer[MAX_PATH + 4];
967 DWORD res;
968 DWORD total;
970 SetLastError(0xdeadbeef);
971 res = GetSystemDirectory(NULL, 0);
972 /* res includes the terminating Zero */
973 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
975 total = res;
977 /* this crashes on XP */
978 if (0) res = GetSystemDirectory(NULL, total);
980 SetLastError(0xdeadbeef);
981 res = GetSystemDirectory(NULL, total-1);
982 /* 95+NT: total (includes the terminating Zero)
983 98+ME: 0 with ERROR_INVALID_PARAMETER */
984 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
985 "returned %d with %d (expected '%d' or: '0' with "
986 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
988 if (total > MAX_PATH) return;
990 buffer[0] = '\0';
991 SetLastError(0xdeadbeef);
992 res = GetSystemDirectory(buffer, total);
993 /* res does not include the terminating Zero */
994 ok( (res == (total-1)) && (buffer[0]),
995 "returned %d with %d and '%s' (expected '%d' and a string)\n",
996 res, GetLastError(), buffer, total-1);
998 buffer[0] = '\0';
999 SetLastError(0xdeadbeef);
1000 res = GetSystemDirectory(buffer, total + 1);
1001 /* res does not include the terminating Zero */
1002 ok( (res == (total-1)) && (buffer[0]),
1003 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1004 res, GetLastError(), buffer, total-1);
1006 memset(buffer, '#', total + 1);
1007 buffer[total + 2] = '\0';
1008 SetLastError(0xdeadbeef);
1009 res = GetSystemDirectory(buffer, total-1);
1010 /* res includes the terminating Zero) */
1011 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1012 res, GetLastError(), buffer, total);
1014 memset(buffer, '#', total + 1);
1015 buffer[total + 2] = '\0';
1016 SetLastError(0xdeadbeef);
1017 res = GetSystemDirectory(buffer, total-2);
1018 /* res includes the terminating Zero) */
1019 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1020 res, GetLastError(), buffer, total);
1023 static void test_GetWindowsDirectory(void)
1025 CHAR buffer[MAX_PATH + 4];
1026 DWORD res;
1027 DWORD total;
1029 SetLastError(0xdeadbeef);
1030 res = GetWindowsDirectory(NULL, 0);
1031 /* res includes the terminating Zero */
1032 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1034 total = res;
1035 /* this crashes on XP */
1036 if (0) res = GetWindowsDirectory(NULL, total);
1038 SetLastError(0xdeadbeef);
1039 res = GetWindowsDirectory(NULL, total-1);
1040 /* 95+NT: total (includes the terminating Zero)
1041 98+ME: 0 with ERROR_INVALID_PARAMETER */
1042 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1043 "returned %d with %d (expected '%d' or: '0' with "
1044 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1046 if (total > MAX_PATH) return;
1048 buffer[0] = '\0';
1049 SetLastError(0xdeadbeef);
1050 res = GetWindowsDirectory(buffer, total);
1051 /* res does not include the terminating Zero */
1052 ok( (res == (total-1)) && (buffer[0]),
1053 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1054 res, GetLastError(), buffer, total-1);
1056 buffer[0] = '\0';
1057 SetLastError(0xdeadbeef);
1058 res = GetWindowsDirectory(buffer, total + 1);
1059 /* res does not include the terminating Zero */
1060 ok( (res == (total-1)) && (buffer[0]),
1061 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1062 res, GetLastError(), buffer, total-1);
1064 memset(buffer, '#', total + 1);
1065 buffer[total + 2] = '\0';
1066 SetLastError(0xdeadbeef);
1067 res = GetWindowsDirectory(buffer, total-1);
1068 /* res includes the terminating Zero) */
1069 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1070 res, GetLastError(), buffer, total);
1072 memset(buffer, '#', total + 1);
1073 buffer[total + 2] = '\0';
1074 SetLastError(0xdeadbeef);
1075 res = GetWindowsDirectory(buffer, total-2);
1076 /* res includes the terminating Zero) */
1077 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1078 res, GetLastError(), buffer, total);
1081 static void test_NeedCurrentDirectoryForExePathA(void)
1083 /* Crashes in Windows */
1084 if (0)
1085 ok(pNeedCurrentDirectoryForExePathA(NULL), "returned FALSE for NULL\n");
1087 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1088 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1089 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1090 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1092 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1093 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1094 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1095 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1098 static void test_NeedCurrentDirectoryForExePathW(void)
1100 const WCHAR thispath[] = {'.', 0};
1101 const WCHAR fullpath[] = {'c', ':', '\\', 0};
1102 const WCHAR cmdname[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1104 /* Crashes in Windows */
1105 if (0)
1106 ok(pNeedCurrentDirectoryForExePathW(NULL), "returned FALSE for NULL\n");
1108 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1109 ok(pNeedCurrentDirectoryForExePathW(thispath), "returned FALSE for \".\"\n");
1110 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1111 ok(pNeedCurrentDirectoryForExePathW(cmdname), "returned FALSE for \"cmd.exe\"\n");
1113 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1114 ok(!pNeedCurrentDirectoryForExePathW(thispath), "returned TRUE for \".\"\n");
1115 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1116 ok(!pNeedCurrentDirectoryForExePathW(cmdname), "returned TRUE for \"cmd.exe\"\n");
1119 START_TEST(path)
1121 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
1122 pGetLongPathNameA = (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
1123 "GetLongPathNameA" );
1124 pGetLongPathNameW = (void*)GetProcAddress(GetModuleHandleA("kernel32.dll") ,
1125 "GetLongPathNameW" );
1126 pNeedCurrentDirectoryForExePathA =
1127 (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
1128 "NeedCurrentDirectoryForExePathA" );
1129 pNeedCurrentDirectoryForExePathW =
1130 (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
1131 "NeedCurrentDirectoryForExePathW" );
1133 test_InitPathA(curdir, &curDrive, &otherDrive);
1134 test_CurrentDirectoryA(origdir,curdir);
1135 test_PathNameA(curdir, curDrive, otherDrive);
1136 test_CleanupPathA(origdir,curdir);
1137 test_GetTempPath();
1138 test_GetLongPathNameW();
1139 test_GetSystemDirectory();
1140 test_GetWindowsDirectory();
1141 if (pNeedCurrentDirectoryForExePathA)
1143 test_NeedCurrentDirectoryForExePathA();
1145 if (pNeedCurrentDirectoryForExePathW)
1147 test_NeedCurrentDirectoryForExePathW();