push 480b0ab11d721a21c8618d4f9374bf7a3008a5c8
[wine/hacks.git] / dlls / kernel32 / tests / path.c
blob4c0aac5d04952bb4623d25a7f8e705d4a7063acc
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 static DWORD (WINAPI *pSearchPathA)(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*);
61 static DWORD (WINAPI *pSearchPathW)(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,LPWSTR,LPWSTR*);
63 /* a structure to deal with wine todos somewhat cleanly */
64 typedef struct {
65 DWORD shortlen;
66 DWORD shorterror;
67 DWORD s2llen;
68 DWORD s2lerror;
69 DWORD longlen;
70 DWORD longerror;
71 } SLpassfail;
73 /* function that tests GetFullPathNameA, GetShortPathNameA,GetLongPathNameA */
74 /* NOTE: the passfail structure is used to allow customizable todo checking
75 for wine. It is not very pretty, but it sure beats duplicating this
76 function lots of times
78 static void test_ValidPathA(const CHAR *curdir, const CHAR *subdir, const CHAR *filename,
79 CHAR *shortstr, SLpassfail *passfail, const CHAR *errstr)
81 CHAR tmpstr[MAX_PATH],
82 fullpath[MAX_PATH], /*full path to the file (not short/long) */
83 subpath[MAX_PATH], /*relative path to the file */
84 fullpathshort[MAX_PATH], /*absolute path to the file (short format) */
85 fullpathlong[MAX_PATH], /*absolute path to the file (long format) */
86 curdirshort[MAX_PATH], /*absolute path to the current dir (short) */
87 curdirlong[MAX_PATH]; /*absolute path to the current dir (long) */
88 LPSTR strptr; /*ptr to the filename portion of the path */
89 DWORD len;
90 /* if passfail is NULL, we can perform all checks within this function,
91 otherwise, we will return the relevant data in the passfail struct, so
92 we must initialize it first
94 if(passfail!=NULL) {
95 passfail->shortlen=-1;passfail->s2llen=-1;passfail->longlen=-1;
96 passfail->shorterror=0;passfail->s2lerror=0;passfail->longerror=0;
98 /* GetLongPathNameA is only supported on Win2k+ and Win98+ */
99 if(pGetLongPathNameA) {
100 ok((len=pGetLongPathNameA(curdir,curdirlong,MAX_PATH)),
101 "%s: GetLongPathNameA failed\n",errstr);
102 /*GetLongPathNameA can return a trailing '\\' but shouldn't do so here */
103 ok(! HAS_TRAIL_SLASH_A(curdirlong),
104 "%s: GetLongPathNameA should not have a trailing \\\n",errstr);
106 ok((len=GetShortPathNameA(curdir,curdirshort,MAX_PATH)),
107 "%s: GetShortPathNameA failed\n",errstr);
108 /*GetShortPathNameA can return a trailing '\\' but shouldn't do so here */
109 ok(! HAS_TRAIL_SLASH_A(curdirshort),
110 "%s: GetShortPathNameA should not have a trailing \\\n",errstr);
111 /* build relative and absolute paths from inputs */
112 if(lstrlenA(subdir)) {
113 sprintf(subpath,"%s\\%s",subdir,filename);
114 } else {
115 lstrcpyA(subpath,filename);
117 sprintf(fullpath,"%s\\%s",curdir,subpath);
118 sprintf(fullpathshort,"%s\\%s",curdirshort,subpath);
119 sprintf(fullpathlong,"%s\\%s",curdirlong,subpath);
120 /* Test GetFullPathNameA functionality */
121 len=GetFullPathNameA(subpath,MAX_PATH,tmpstr,&strptr);
122 ok(len, "GetFullPathNameA failed for: '%s'\n",subpath);
123 if(HAS_TRAIL_SLASH_A(subpath)) {
124 ok(strptr==NULL,
125 "%s: GetFullPathNameA should not return a filename ptr\n",errstr);
126 ok(lstrcmpiA(fullpath,tmpstr)==0,
127 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
128 errstr,tmpstr,fullpath);
129 } else {
130 ok(lstrcmpiA(strptr,filename)==0,
131 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
132 errstr,strptr,filename);
133 ok(lstrcmpiA(fullpath,tmpstr)==0,
134 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
135 errstr,tmpstr,fullpath);
137 /* Test GetShortPathNameA functionality */
138 SetLastError(0);
139 len=GetShortPathNameA(fullpathshort,shortstr,MAX_PATH);
140 if(passfail==NULL) {
141 ok(len, "%s: GetShortPathNameA failed\n",errstr);
142 } else {
143 passfail->shortlen=len;
144 passfail->shorterror=GetLastError();
146 /* Test GetLongPathNameA functionality
147 We test both conversion from GetFullPathNameA and from GetShortPathNameA
149 if(pGetLongPathNameA) {
150 if(len!=0) {
151 SetLastError(0);
152 len=pGetLongPathNameA(shortstr,tmpstr,MAX_PATH);
153 if(passfail==NULL) {
154 ok(len,
155 "%s: GetLongPathNameA failed during Short->Long conversion\n", errstr);
156 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
157 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
158 errstr,tmpstr,fullpathlong);
159 } else {
160 passfail->s2llen=len;
161 passfail->s2lerror=GetLastError();
164 SetLastError(0);
165 len=pGetLongPathNameA(fullpath,tmpstr,MAX_PATH);
166 if(passfail==NULL) {
167 ok(len, "%s: GetLongPathNameA failed\n",errstr);
168 if(HAS_TRAIL_SLASH_A(fullpath)) {
169 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
170 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
171 errstr,tmpstr,fullpathlong);
172 } else {
173 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
174 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
175 errstr,tmpstr,fullpathlong);
177 } else {
178 passfail->longlen=len;
179 passfail->longerror=GetLastError();
184 /* split path into leading directory, and 8.3 filename */
185 static void test_SplitShortPathA(CHAR *path,CHAR *dir,CHAR *eight,CHAR *three) {
186 int done,error;
187 int ext,fil;
188 int len,i;
189 len=lstrlenA(path);
190 ext=len; fil=len; done=0; error=0;
191 /* walk backwards over path looking for '.' or '\\' separators */
192 for(i=len-1;(i>=0) && (!done);i--) {
193 if(path[i]=='.')
194 if(ext!=len) error=1; else ext=i;
195 else if(path[i]=='\\') {
196 if(i==len-1) {
197 error=1;
198 } else {
199 fil=i;
200 done=1;
204 /* Check that we didn't find a trailing '\\' or multiple '.' */
205 ok(!error,"Illegal file found in 8.3 path '%s'\n",path);
206 /* Separate dir, root, and extension */
207 if(ext!=len) lstrcpyA(three,path+ext+1); else lstrcpyA(three,"");
208 if(fil!=len) {
209 lstrcpynA(eight,path+fil+1,ext-fil);
210 lstrcpynA(dir,path,fil+1);
211 } else {
212 lstrcpynA(eight,path,ext+1);
213 lstrcpyA(dir,"");
215 /* Validate that root and extension really are 8.3 */
216 ok(lstrlenA(eight)<=8 && lstrlenA(three)<=3,
217 "GetShortPathNAmeA did not return an 8.3 path\n");
220 /* Check that GetShortPathNameA returns a valid 8.3 path */
221 static void test_LongtoShortA(CHAR *teststr,const CHAR *goodstr,
222 const CHAR *ext,const CHAR *errstr) {
223 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
225 test_SplitShortPathA(teststr,dir,eight,three);
226 ok(lstrcmpiA(dir,goodstr)==0,
227 "GetShortPathNameA returned '%s' instead of '%s'\n",dir,goodstr);
228 ok(lstrcmpiA(three,ext)==0,
229 "GetShortPathNameA returned '%s' with incorrect extension\n",three);
232 /* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
233 characters in the filename.
234 'valid' indicates whether this would be an allowed filename
235 'todo' indicates that wine doesn't get this right yet.
236 NOTE: We always call this routine with a nonexistent filename, so
237 Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
238 should.
240 static void test_FunnyChars(CHAR *curdir,CHAR *curdir_short,CHAR *filename, INT valid,CHAR *errstr)
242 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
243 SLpassfail passfail;
245 test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
246 if(valid) {
247 sprintf(tmpstr1,"%s\\%s",curdir_short,filename);
248 ok((passfail.shortlen==0 &&
249 (passfail.shorterror==ERROR_FILE_NOT_FOUND || passfail.shorterror==ERROR_PATH_NOT_FOUND || !passfail.shorterror)) ||
250 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
251 "%s: GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
252 errstr,passfail.shortlen,passfail.shorterror,tmpstr);
253 } else {
254 ok(passfail.shortlen==0 &&
255 (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),
256 "%s: GetShortPathA should have failed len=%d, error=%d\n",
257 errstr,passfail.shortlen,passfail.shorterror);
259 if(pGetLongPathNameA) {
260 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
261 if(valid) {
262 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
263 "%s: GetLongPathA returned %d and not %d\n",
264 errstr,passfail.longerror,ERROR_FILE_NOT_FOUND);
265 } else {
266 ok(passfail.longerror==ERROR_INVALID_NAME ||
267 passfail.longerror==ERROR_FILE_NOT_FOUND,
268 "%s: GetLongPathA returned %d and not %d or %d'\n",
269 errstr, passfail.longerror,ERROR_INVALID_NAME,ERROR_FILE_NOT_FOUND);
274 /* Routine to test that SetCurrentDirectory behaves as expected. */
275 static void test_setdir(CHAR *olddir,CHAR *newdir,
276 CHAR *cmprstr, INT pass, const CHAR *errstr)
278 CHAR tmppath[MAX_PATH], *dirptr;
279 DWORD val,len,chklen;
281 val=SetCurrentDirectoryA(newdir);
282 len=GetCurrentDirectoryA(MAX_PATH,tmppath);
283 /* if 'pass' then the SetDirectoryA was supposed to pass */
284 if(pass) {
285 dirptr=(cmprstr==NULL) ? newdir : cmprstr;
286 chklen=lstrlenA(dirptr);
287 ok(val,"%s: SetCurrentDirectoryA failed\n",errstr);
288 ok(len==chklen,
289 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
290 errstr);
291 ok(lstrcmpiA(dirptr,tmppath)==0,
292 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
293 errstr);
294 ok(SetCurrentDirectoryA(olddir),
295 "%s: Couldn't set directory to it's original value\n",errstr);
296 } else {
297 /* else thest that it fails correctly */
298 chklen=lstrlenA(olddir);
299 ok(val==0,
300 "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr);
301 ok(len==chklen,
302 "%s: SetCurrentDirectory changed the directory, though it failed\n",
303 errstr);
304 ok(lstrcmpiA(olddir,tmppath)==0,
305 "%s: SetCurrentDirectory changed the directory, though it failed\n",
306 errstr);
309 static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
311 CHAR tmppath[MAX_PATH], /*path to TEMP */
312 tmpstr[MAX_PATH],
313 tmpstr1[MAX_PATH];
314 DWORD len,len1,drives;
315 INT id;
316 HANDLE hndl;
317 BOOL bRes;
319 *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
321 /* Get the current drive letter */
322 if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
323 *curDrive = tmpstr[0];
324 else
325 trace( "Unable to discover current drive, some tests will not be conducted.\n");
327 /* Test GetTempPathA */
328 len=GetTempPathA(MAX_PATH,tmppath);
329 ok(len!=0 && len < MAX_PATH,"GetTempPathA failed\n");
330 ok(HAS_TRAIL_SLASH_A(tmppath),
331 "GetTempPathA returned a path that did not end in '\\'\n");
332 lstrcpyA(tmpstr,"aaaaaaaa");
333 len1=GetTempPathA(len,tmpstr);
334 ok(len1==len+1 || broken(len1 == len), /* WinME */
335 "GetTempPathA should return string length %d instead of %d\n",len+1,len1);
337 /* Test GetTmpFileNameA
338 The only test we do here is whether GetTempFileNameA passes or not.
339 We do not thoroughly test this function yet (specifically, whether
340 it behaves correctly when 'unique' is non zero)
342 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
343 sprintf(tmpstr,"pat%.4x.tmp",id & 0xffff);
344 sprintf(tmpstr1,"pat%x.tmp",id & 0xffff);
345 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
346 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
347 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
348 newdir,tmpstr,tmpstr1,id);
349 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
351 id=GetTempFileNameA(tmppath,NULL,0,newdir);
352 /* Windows 95, 98 return 0==id, while Windows 2000, XP return 0!=id */
353 if (id)
355 sprintf(tmpstr,"%.4x.tmp",id & 0xffff);
356 sprintf(tmpstr1,"%x.tmp",id & 0xffff);
357 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
358 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
359 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
360 newdir,tmpstr,tmpstr1,id);
361 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
364 /* Find first valid drive letter that is neither newdir[0] nor curDrive */
365 drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
366 if( *curDrive != NOT_A_VALID_DRIVE)
367 drives &= ~(1<<(*curDrive-'A'));
368 if( drives)
369 for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
370 else
371 trace( "Could not find alternative drive, some tests will not be conducted.\n");
373 /* Do some CreateDirectoryA tests */
374 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
375 really understand how they work.
376 More formal tests should be done along with CreateFile tests
378 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
379 ok(CreateDirectoryA(newdir,NULL)==0,
380 "CreateDirectoryA succeeded even though a file of the same name exists\n");
381 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
382 ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
383 /* Create some files to test other functions. Note, we will test CreateFileA
384 at some later point
386 sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
387 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
388 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
389 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
390 sprintf(tmpstr,"%c:", *curDrive);
391 bRes = CreateDirectoryA(tmpstr,NULL);
392 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
393 GetLastError() == ERROR_ALREADY_EXISTS),
394 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
395 sprintf(tmpstr,"%c:\\", *curDrive);
396 bRes = CreateDirectoryA(tmpstr,NULL);
397 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
398 GetLastError() == ERROR_ALREADY_EXISTS),
399 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
400 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
401 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
402 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
403 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
404 ok(CloseHandle(hndl),"CloseHandle failed\n");
405 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
406 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
407 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
408 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
409 ok(CloseHandle(hndl),"CloseHandle failed\n");
410 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
411 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
412 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
413 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
414 ok(CloseHandle(hndl),"CloseHandle failed\n");
415 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
416 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
417 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
418 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
419 ok(CloseHandle(hndl),"CloseHandle failed\n");
422 /* Test GetCurrentDirectory & SetCurrentDirectory */
423 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
425 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
426 DWORD len,len1;
427 /* Save the original directory, so that we can return to it at the end
428 of the test
430 len=GetCurrentDirectoryA(MAX_PATH,origdir);
431 ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
432 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
433 buffer size is too small to hold the current directory
435 lstrcpyA(tmpstr,"aaaaaaa");
436 len1=GetCurrentDirectoryA(len,tmpstr);
437 ok(len1==len+1, "GetCurrentDirectoryA returned %d instead of %d\n",len1,len+1);
438 ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
439 "GetCurrentDirectoryA should not have modified the buffer\n");
440 /* SetCurrentDirectoryA shouldn't care whether the string has a
441 trailing '\\' or not
443 sprintf(tmpstr,"%s\\",newdir);
444 test_setdir(origdir,tmpstr,newdir,1,"check 1");
445 test_setdir(origdir,newdir,NULL,1,"check 2");
446 /* Set the directory to the working area. We just tested that this works,
447 so why check it again.
449 SetCurrentDirectoryA(newdir);
450 /* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
451 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
452 test_setdir(newdir,tmpstr,NULL,0,"check 3");
453 /* Check that SetCurrentDirectory fails for a nonexistent lond directory */
454 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
455 test_setdir(newdir,tmpstr,NULL,0,"check 4");
456 /* Check that SetCurrentDirectory passes with a long directory */
457 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
458 test_setdir(newdir,tmpstr,NULL,1,"check 5");
459 /* Check that SetCurrentDirectory passes with a short relative directory */
460 sprintf(tmpstr,"%s",SHORTDIR);
461 sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
462 test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
463 /* starting with a '.' */
464 sprintf(tmpstr,".\\%s",SHORTDIR);
465 test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
466 /* Check that SetCurrentDirectory passes with a short relative directory */
467 sprintf(tmpstr,"%s",LONGDIR);
468 sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
469 test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
470 /* starting with a '.' */
471 sprintf(tmpstr,".\\%s",LONGDIR);
472 test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
473 /* change to root without a trailing backslash. The function call succeeds
474 but the directory is not changed.
476 sprintf(tmpstr, "%c:", newdir[0]);
477 test_setdir(newdir,tmpstr,newdir,1,"check 10");
478 /* works however with a trailing backslash */
479 sprintf(tmpstr, "%c:\\", newdir[0]);
480 test_setdir(newdir,tmpstr,NULL,1,"check 11");
483 /* Cleanup the mess we made while executing these tests */
484 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
486 CHAR tmpstr[MAX_PATH];
487 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
488 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
489 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
490 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
491 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
492 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
493 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
494 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
495 sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
496 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
497 sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
498 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
499 ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
500 ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
503 /* This routine will test Get(Full|Short|Long)PathNameA */
504 static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
506 CHAR curdir_short[MAX_PATH],
507 longdir_short[MAX_PATH];
508 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH],tmpstr2[MAX_PATH];
509 LPSTR strptr; /*ptr to the filename portion of the path */
510 DWORD len;
511 INT i;
512 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
513 SLpassfail passfail;
515 /* Get the short form of the current directory */
516 ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
517 "GetShortPathNameA failed\n");
518 ok(!HAS_TRAIL_SLASH_A(curdir_short),
519 "GetShortPathNameA should not have a trailing \\\n");
520 /* Get the short form of the absolute-path to LONGDIR */
521 sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
522 ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
523 "GetShortPathNameA failed\n");
524 ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
525 "GetShortPathNameA should not have a trailing \\\n");
527 if (pGetLongPathNameA) {
528 DWORD rc1,rc2;
529 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
530 rc1=(*pGetLongPathNameA)(tmpstr,NULL,0);
531 rc2=(*pGetLongPathNameA)(curdir,NULL,0);
532 ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
533 "GetLongPathNameA: wrong return code, %d instead of %d\n",
534 rc1, lstrlenA(tmpstr)+1);
536 sprintf(dir,"%c:",curDrive);
537 rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
538 ok(strcmp(dir,tmpstr)==0,
539 "GetLongPathNameA: returned '%s' instead of '%s' (rc=%d)\n",
540 tmpstr,dir,rc1);
543 /* Check the cases where both file and directory exist first */
544 /* Start with a 8.3 directory, 8.3 filename */
545 test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
546 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
547 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
548 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
549 /* Now try a 8.3 directory, long file name */
550 test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
551 sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
552 test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
553 /* Next is a long directory, 8.3 file */
554 test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
555 sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
556 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
557 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
558 /*Lastly a long directory, long file */
559 test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
560 test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
562 /* Now check all of the invalid file w/ valid directory combinations */
563 /* Start with a 8.3 directory, 8.3 filename */
564 test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
565 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
566 ok((passfail.shortlen==0 &&
567 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
568 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
569 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
570 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
571 passfail.shortlen,passfail.shorterror,tmpstr);
572 if(pGetLongPathNameA) {
573 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
574 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
575 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
577 /* Now try a 8.3 directory, long file name */
578 test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
579 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
580 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
581 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
582 !passfail.shorterror,
583 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
584 if(pGetLongPathNameA) {
585 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
586 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
587 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
589 /* Next is a long directory, 8.3 file */
590 test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
591 sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
592 GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
593 strcat(tmpstr1,"\\" NONFILE_SHORT);
594 ok((passfail.shortlen==0 &&
595 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
596 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
597 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
598 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
599 passfail.shortlen,passfail.shorterror,tmpstr);
600 if(pGetLongPathNameA) {
601 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
602 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
603 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
605 /*Lastly a long directory, long file */
606 test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
607 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
608 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
609 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
610 !passfail.shorterror,
611 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
612 if(pGetLongPathNameA) {
613 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
614 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
615 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
617 /* Now try again with directories that don't exist */
618 /* 8.3 directory, 8.3 filename */
619 test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
620 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
621 ok((passfail.shortlen==0 &&
622 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
623 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
624 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
625 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
626 passfail.shortlen,passfail.shorterror,tmpstr);
627 if(pGetLongPathNameA) {
628 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
629 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
630 passfail.longerror==ERROR_FILE_NOT_FOUND,
631 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
632 passfail.longerror);
634 /* Now try a 8.3 directory, long file name */
635 test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
636 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
637 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
638 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
639 !passfail.shorterror,
640 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
641 passfail.shorterror);
642 if(pGetLongPathNameA) {
643 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
644 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
645 passfail.longerror==ERROR_FILE_NOT_FOUND,
646 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
647 passfail.longerror);
649 /* Next is a long directory, 8.3 file */
650 test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
651 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
652 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
653 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
654 !passfail.shorterror,
655 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
656 passfail.shorterror);
657 if(pGetLongPathNameA) {
658 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
659 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
660 passfail.longerror==ERROR_FILE_NOT_FOUND,
661 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
662 passfail.longerror);
664 /*Lastly a long directory, long file */
665 test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
666 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
667 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
668 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
669 !passfail.shorterror,
670 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
671 passfail.shorterror);
672 if(pGetLongPathNameA) {
673 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
674 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
675 passfail.longerror==ERROR_FILE_NOT_FOUND,
676 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
677 passfail.longerror);
679 /* Next try directories ending with '\\' */
680 /* Existing Directories */
681 sprintf(tmpstr,"%s\\",SHORTDIR);
682 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
683 sprintf(tmpstr,"%s\\",LONGDIR);
684 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
685 /* Nonexistent directories */
686 sprintf(tmpstr,"%s\\",NONDIR_SHORT);
687 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
688 sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
689 ok((passfail.shortlen==0 &&
690 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
691 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
692 (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
693 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
694 passfail.shortlen,passfail.shorterror,tmpstr);
695 if(pGetLongPathNameA) {
696 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
697 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
698 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
699 passfail.longerror);
701 sprintf(tmpstr,"%s\\",NONDIR_LONG);
702 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
703 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
704 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
705 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
706 !passfail.shorterror,
707 "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
708 passfail.shorterror);
709 if(pGetLongPathNameA) {
710 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
711 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
712 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
713 passfail.longerror);
715 /* Test GetFullPathNameA with drive letters */
716 if( curDrive != NOT_A_VALID_DRIVE) {
717 sprintf(tmpstr,"%c:",curdir[0]);
718 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
719 "GetFullPathNameA(%c:) failed\n", curdir[0]);
720 GetCurrentDirectoryA(MAX_PATH,tmpstr);
721 sprintf(tmpstr1,"%s\\",tmpstr);
722 ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
723 "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
724 curdir[0],tmpstr2,tmpstr,tmpstr1);
726 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
727 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
728 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
729 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
730 ok(lstrcmpiA(SHORTFILE,strptr)==0,
731 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
733 /* Without a leading slash, insert the current directory if on the current drive */
734 sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
735 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
736 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
737 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
738 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
739 ok(lstrcmpiA(SHORTFILE,strptr)==0,
740 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
741 /* Otherwise insert the missing leading slash */
742 if( otherDrive != NOT_A_VALID_DRIVE) {
743 /* FIXME: this test assumes that current directory on other drive is root */
744 sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
745 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
746 sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
747 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
748 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
749 ok(lstrcmpiA(SHORTFILE,strptr)==0,
750 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
752 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
753 So test for them. */
754 if( curDrive != NOT_A_VALID_DRIVE) {
755 sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
756 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
757 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
758 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
759 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
760 ok(lstrcmpiA(SHORTFILE,strptr)==0,
761 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
763 /**/
764 sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
765 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
766 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
767 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
768 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
769 ok(lstrcmpiA(SHORTFILE,strptr)==0,
770 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
771 /* Windows will insert a drive letter in front of an absolute UNIX path */
772 sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
773 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
774 sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
775 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
776 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
777 /* This passes in Wine because it still contains the pointer from the previous test */
778 ok(lstrcmpiA(SHORTFILE,strptr)==0,
779 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
781 /* Now try some relative paths */
782 ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
783 test_SplitShortPathA(tmpstr,dir,eight,three);
784 if(pGetLongPathNameA) {
785 ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
786 ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
787 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
789 sprintf(tmpstr,".\\%s",LONGDIR);
790 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
791 test_SplitShortPathA(tmpstr1,dir,eight,three);
792 ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
793 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
794 if(pGetLongPathNameA) {
795 ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
796 tmpstr);
797 ok(lstrcmpiA(tmpstr1,tmpstr)==0,
798 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
800 /* Check out Get*PathNameA on some funny characters */
801 for(i=0;i<lstrlenA(funny_chars);i++) {
802 INT valid;
803 valid=(is_char_ok[i]=='0') ? 0 : 1;
804 sprintf(tmpstr1,"check%d-1",i);
805 sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
806 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
807 sprintf(tmpstr1,"check%d-2",i);
808 sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
809 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
810 sprintf(tmpstr1,"check%d-3",i);
811 sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
812 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
813 sprintf(tmpstr1,"check%d-4",i);
814 sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
815 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
816 sprintf(tmpstr1,"check%d-5",i);
817 sprintf(tmpstr,"Long %c File",funny_chars[i]);
818 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
819 sprintf(tmpstr1,"check%d-6",i);
820 sprintf(tmpstr,"%c Long File",funny_chars[i]);
821 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
822 sprintf(tmpstr1,"check%d-7",i);
823 sprintf(tmpstr,"Long File %c",funny_chars[i]);
824 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
828 static void test_GetTempPathA(char* tmp_dir)
830 DWORD len, len_with_null;
831 char buf[MAX_PATH];
833 len_with_null = strlen(tmp_dir) + 1;
835 lstrcpyA(buf, "foo");
836 len = GetTempPathA(MAX_PATH, buf);
837 ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
838 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
839 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
841 /* Some versions of Windows touch the buffer, some don't so we don't
842 * test that. Also, NT sometimes exaggerates the required buffer size
843 * so we cannot test for an exact match. Finally, the
844 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
845 * For instance in some cases Win98 returns len_with_null - 1 instead
846 * of len_with_null.
848 len = GetTempPathA(1, buf);
849 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
851 len = GetTempPathA(0, NULL);
852 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
854 /* The call above gave us the buffer size that Windows thinks is needed
855 * so the next call should work
857 lstrcpyA(buf, "foo");
858 len = GetTempPathA(len, buf);
859 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
860 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
863 static void test_GetTempPathW(char* tmp_dir)
865 DWORD len, len_with_null;
866 WCHAR buf[MAX_PATH];
867 WCHAR tmp_dirW[MAX_PATH];
868 static const WCHAR fooW[] = {'f','o','o',0};
870 MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
871 len_with_null = lstrlenW(tmp_dirW) + 1;
873 /* This one is different from ANSI version: ANSI version doesn't
874 * touch the buffer, unicode version usually truncates the buffer
875 * to zero size. NT still exaggerates the required buffer size
876 * sometimes so we cannot test for an exact match. Finally, the
877 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
878 * For instance on NT4 it will sometimes return a path without the
879 * trailing '\\' and sometimes return an error.
882 lstrcpyW(buf, fooW);
883 len = GetTempPathW(MAX_PATH, buf);
884 if (len == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
886 win_skip("GetTempPathW is not available\n");
887 return;
889 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
890 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
892 lstrcpyW(buf, fooW);
893 len = GetTempPathW(1, buf);
894 ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
895 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
897 len = GetTempPathW(0, NULL);
898 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
900 lstrcpyW(buf, fooW);
901 len = GetTempPathW(len, buf);
902 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
903 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
906 static void test_GetTempPath(void)
908 char save_TMP[MAX_PATH];
909 char windir[MAX_PATH];
910 char buf[MAX_PATH];
912 if (!GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP))) save_TMP[0] = 0;
914 /* test default configuration */
915 trace("TMP=%s\n", save_TMP);
916 if (save_TMP[0])
918 strcpy(buf,save_TMP);
919 if (buf[strlen(buf)-1]!='\\')
920 strcat(buf,"\\");
921 test_GetTempPathA(buf);
922 test_GetTempPathW(buf);
925 /* TMP=C:\WINDOWS */
926 GetWindowsDirectoryA(windir, sizeof(windir));
927 SetEnvironmentVariableA("TMP", windir);
928 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
929 trace("TMP=%s\n", buf);
930 strcat(windir,"\\");
931 test_GetTempPathA(windir);
932 test_GetTempPathW(windir);
934 /* TMP=C:\ */
935 GetWindowsDirectoryA(windir, sizeof(windir));
936 windir[3] = 0;
937 SetEnvironmentVariableA("TMP", windir);
938 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
939 trace("TMP=%s\n", buf);
940 test_GetTempPathA(windir);
941 test_GetTempPathW(windir);
943 /* TMP=C: i.e. use current working directory of the specified drive */
944 GetWindowsDirectoryA(windir, sizeof(windir));
945 SetCurrentDirectoryA(windir);
946 windir[2] = 0;
947 SetEnvironmentVariableA("TMP", windir);
948 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
949 trace("TMP=%s\n", buf);
950 GetWindowsDirectoryA(windir, sizeof(windir));
951 strcat(windir,"\\");
952 test_GetTempPathA(windir);
953 test_GetTempPathW(windir);
955 SetEnvironmentVariableA("TMP", save_TMP);
958 static void test_GetLongPathNameA(void)
960 DWORD length, explength, hostsize;
961 char tempfile[MAX_PATH];
962 char longpath[MAX_PATH];
963 char unc_prefix[MAX_PATH];
964 char unc_short[MAX_PATH], unc_long[MAX_PATH];
965 char temppath[MAX_PATH], temppath2[MAX_PATH];
966 HANDLE file;
968 if (!pGetLongPathNameA)
969 return;
971 GetTempPathA(MAX_PATH, tempfile);
972 lstrcatA(tempfile, "longfilename.longext");
974 file = CreateFileA(tempfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
975 CloseHandle(file);
977 /* Test a normal path with a small buffer size */
978 memset(temppath, 0, MAX_PATH);
979 length = pGetLongPathNameA(tempfile, temppath, 4);
980 /* We have a failure so length should be the minumum plus the terminating '0' */
981 ok(length >= lstrlen(tempfile) + 1, "Wrong length\n");
982 ok(temppath[0] == 0, "Buffer should not have been touched\n");
984 /* Some UNC syntax tests */
986 memset(temppath, 0, MAX_PATH);
987 memset(temppath2, 0, MAX_PATH);
988 lstrcpyA(temppath2, "\\\\?\\");
989 lstrcatA(temppath2, tempfile);
990 explength = length + 4;
992 SetLastError(0xdeadbeef);
993 length = pGetLongPathNameA(temppath2, NULL, 0);
994 if (length == 0 && GetLastError() == ERROR_BAD_NET_NAME)
996 win_skip("UNC syntax tests don't work on Win98/WinMe\n");
997 DeleteFileA(tempfile);
998 return;
1000 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1002 length = pGetLongPathNameA(temppath2, NULL, MAX_PATH);
1003 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1005 length = pGetLongPathNameA(temppath2, temppath, 4);
1006 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1007 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1009 /* Now an UNC path with the computername */
1010 lstrcpyA(unc_prefix, "\\\\");
1011 hostsize = sizeof(unc_prefix) - 2;
1012 GetComputerName(unc_prefix + 2, &hostsize);
1013 lstrcatA(unc_prefix, "\\");
1015 /* Create a short syntax for the whole unc path */
1016 memset(unc_short, 0, MAX_PATH);
1017 GetShortPathNameA(tempfile, temppath, MAX_PATH);
1018 lstrcpyA(unc_short, unc_prefix);
1019 unc_short[lstrlenA(unc_short)] = temppath[0];
1020 lstrcatA(unc_short, "$\\");
1021 lstrcatA(unc_short, strchr(temppath, '\\') + 1);
1023 /* Create a long syntax for reference */
1024 memset(longpath, 0, MAX_PATH);
1025 pGetLongPathNameA(tempfile, temppath, MAX_PATH);
1026 lstrcpyA(longpath, unc_prefix);
1027 longpath[lstrlenA(longpath)] = temppath[0];
1028 lstrcatA(longpath, "$\\");
1029 lstrcatA(longpath, strchr(temppath, '\\') + 1);
1031 /* NULL test */
1032 SetLastError(0xdeadbeef);
1033 length = pGetLongPathNameA(unc_short, NULL, 0);
1034 if (length == 0 && GetLastError() == ERROR_BAD_NETPATH)
1036 /* Seen on Window XP Home */
1037 win_skip("UNC with computername is not supported\n");
1038 DeleteFileA(tempfile);
1039 return;
1041 explength = lstrlenA(longpath) + 1;
1042 todo_wine
1043 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1045 length = pGetLongPathNameA(unc_short, NULL, MAX_PATH);
1046 todo_wine
1047 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1049 memset(unc_long, 0, MAX_PATH);
1050 length = pGetLongPathNameA(unc_short, unc_long, lstrlenA(unc_short));
1051 /* length will include terminating '0' on failure */
1052 todo_wine
1053 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1054 ok(unc_long[0] == 0, "Buffer should not have been touched\n");
1056 memset(unc_long, 0, MAX_PATH);
1057 length = pGetLongPathNameA(unc_short, unc_long, length);
1058 /* length doesn't include terminating '0' on success */
1059 explength--;
1060 todo_wine
1062 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1063 ok(!lstrcmpiA(unc_long, longpath), "Expected (%s), got (%s)\n", longpath, unc_long);
1066 DeleteFileA(tempfile);
1069 static void test_GetLongPathNameW(void)
1071 DWORD length, expanded;
1072 BOOL ret;
1073 HANDLE file;
1074 WCHAR empty[MAX_PATH];
1075 WCHAR tempdir[MAX_PATH], name[200];
1076 WCHAR dirpath[4 + MAX_PATH + 200]; /* To ease removal */
1077 WCHAR shortpath[4 + MAX_PATH + 200 + 1 + 200];
1078 static const WCHAR prefix[] = { '\\','\\','?','\\', 0};
1079 static const WCHAR backslash[] = { '\\', 0};
1080 static const WCHAR letterX[] = { 'X', 0};
1082 if (!pGetLongPathNameW)
1083 return;
1085 SetLastError(0xdeadbeef);
1086 length = pGetLongPathNameW(NULL,NULL,0);
1087 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1089 win_skip("GetLongPathNameW is not implemented\n");
1090 return;
1092 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1093 ok(GetLastError()==ERROR_INVALID_PARAMETER,"GetLastError returned %d but expected ERROR_INVALID_PARAMETER\n",GetLastError());
1095 SetLastError(0xdeadbeef);
1096 empty[0]=0;
1097 length = pGetLongPathNameW(empty,NULL,0);
1098 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1099 ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
1101 /* Create a long path name. The path needs to exist for these tests to
1102 * succeed so we need the "\\?\" prefix when creating directories and
1103 * files.
1105 name[0] = 0;
1106 while (lstrlenW(name) < (sizeof(name)/sizeof(WCHAR) - 1))
1107 lstrcatW(name, letterX);
1109 GetTempPathW(MAX_PATH, tempdir);
1111 lstrcpyW(shortpath, prefix);
1112 lstrcatW(shortpath, tempdir);
1113 lstrcatW(shortpath, name);
1114 lstrcpyW(dirpath, shortpath);
1115 ret = CreateDirectoryW(shortpath, NULL);
1116 ok(ret, "Could not create the temporary directory : %d\n", GetLastError());
1117 lstrcatW(shortpath, backslash);
1118 lstrcatW(shortpath, name);
1120 /* Path does not exist yet and we know it overruns MAX_PATH */
1122 /* No prefix */
1123 SetLastError(0xdeadbeef);
1124 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1125 ok(length == 0, "Expected 0, got %d\n", length);
1126 todo_wine
1127 ok(GetLastError() == ERROR_PATH_NOT_FOUND,
1128 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1129 /* With prefix */
1130 SetLastError(0xdeadbeef);
1131 length = pGetLongPathNameW(shortpath, NULL, 0);
1132 todo_wine
1134 ok(length == 0, "Expected 0, got %d\n", length);
1135 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
1136 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1139 file = CreateFileW(shortpath, GENERIC_READ|GENERIC_WRITE, 0, NULL,
1140 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1141 ok(file != INVALID_HANDLE_VALUE,
1142 "Could not create the temporary file : %d.\n", GetLastError());
1143 CloseHandle(file);
1145 /* Path exists */
1147 /* No prefix */
1148 SetLastError(0xdeadbeef);
1149 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1150 todo_wine
1152 ok(length == 0, "Expected 0, got %d\n", length);
1153 ok(GetLastError() == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1155 /* With prefix */
1156 expanded = 4 + (pGetLongPathNameW(tempdir, NULL, 0) - 1) + lstrlenW(name) + 1 + lstrlenW(name) + 1;
1157 SetLastError(0xdeadbeef);
1158 length = pGetLongPathNameW(shortpath, NULL, 0);
1159 ok(length == expanded, "Expected %d, got %d\n", expanded, length);
1161 /* NULL buffer with length crashes on Windows */
1162 if (0)
1163 length = pGetLongPathNameW(shortpath, NULL, 20);
1165 ok(DeleteFileW(shortpath), "Could not delete temporary file\n");
1166 ok(RemoveDirectoryW(dirpath), "Could not delete temporary directory\n");
1169 static void test_GetShortPathNameW(void)
1171 WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
1172 WCHAR path[MAX_PATH];
1173 WCHAR short_path[MAX_PATH];
1174 DWORD length;
1175 HANDLE file;
1176 int ret;
1177 WCHAR name[] = { 't', 'e', 's', 't', 0 };
1178 WCHAR backSlash[] = { '\\', 0 };
1180 SetLastError(0xdeadbeef);
1181 GetTempPathW( MAX_PATH, path );
1182 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1184 win_skip("GetTempPathW is not implemented\n");
1185 return;
1188 lstrcatW( path, test_path );
1189 lstrcatW( path, backSlash );
1190 ret = CreateDirectoryW( path, NULL );
1191 ok( ret, "Directory was not created. LastError = %d\n", GetLastError() );
1193 /* Starting a main part of test */
1194 length = GetShortPathNameW( path, short_path, 0 );
1195 ok( length, "GetShortPathNameW returned 0.\n" );
1196 ret = GetShortPathNameW( path, short_path, length );
1197 ok( ret, "GetShortPathNameW returned 0.\n" );
1198 lstrcatW( short_path, name );
1199 file = CreateFileW( short_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1200 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
1202 /* End test */
1203 CloseHandle( file );
1204 ret = DeleteFileW( short_path );
1205 ok( ret, "Cannot delete file.\n" );
1206 ret = RemoveDirectoryW( path );
1207 ok( ret, "Cannot delete directory.\n" );
1210 static void test_GetSystemDirectory(void)
1212 CHAR buffer[MAX_PATH + 4];
1213 DWORD res;
1214 DWORD total;
1216 SetLastError(0xdeadbeef);
1217 res = GetSystemDirectory(NULL, 0);
1218 /* res includes the terminating Zero */
1219 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1221 total = res;
1223 /* this crashes on XP */
1224 if (0) res = GetSystemDirectory(NULL, total);
1226 SetLastError(0xdeadbeef);
1227 res = GetSystemDirectory(NULL, total-1);
1228 /* 95+NT: total (includes the terminating Zero)
1229 98+ME: 0 with ERROR_INVALID_PARAMETER */
1230 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1231 "returned %d with %d (expected '%d' or: '0' with "
1232 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1234 if (total > MAX_PATH) return;
1236 buffer[0] = '\0';
1237 SetLastError(0xdeadbeef);
1238 res = GetSystemDirectory(buffer, total);
1239 /* res does not include the terminating Zero */
1240 ok( (res == (total-1)) && (buffer[0]),
1241 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1242 res, GetLastError(), buffer, total-1);
1244 buffer[0] = '\0';
1245 SetLastError(0xdeadbeef);
1246 res = GetSystemDirectory(buffer, total + 1);
1247 /* res does not include the terminating Zero */
1248 ok( (res == (total-1)) && (buffer[0]),
1249 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1250 res, GetLastError(), buffer, total-1);
1252 memset(buffer, '#', total + 1);
1253 buffer[total + 2] = '\0';
1254 SetLastError(0xdeadbeef);
1255 res = GetSystemDirectory(buffer, total-1);
1256 /* res includes the terminating Zero) */
1257 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1258 res, GetLastError(), buffer, total);
1260 memset(buffer, '#', total + 1);
1261 buffer[total + 2] = '\0';
1262 SetLastError(0xdeadbeef);
1263 res = GetSystemDirectory(buffer, total-2);
1264 /* res includes the terminating Zero) */
1265 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1266 res, GetLastError(), buffer, total);
1269 static void test_GetWindowsDirectory(void)
1271 CHAR buffer[MAX_PATH + 4];
1272 DWORD res;
1273 DWORD total;
1275 SetLastError(0xdeadbeef);
1276 res = GetWindowsDirectory(NULL, 0);
1277 /* res includes the terminating Zero */
1278 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1280 total = res;
1281 /* this crashes on XP */
1282 if (0) res = GetWindowsDirectory(NULL, total);
1284 SetLastError(0xdeadbeef);
1285 res = GetWindowsDirectory(NULL, total-1);
1286 /* 95+NT: total (includes the terminating Zero)
1287 98+ME: 0 with ERROR_INVALID_PARAMETER */
1288 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1289 "returned %d with %d (expected '%d' or: '0' with "
1290 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1292 if (total > MAX_PATH) return;
1294 buffer[0] = '\0';
1295 SetLastError(0xdeadbeef);
1296 res = GetWindowsDirectory(buffer, total);
1297 /* res does not include the terminating Zero */
1298 ok( (res == (total-1)) && (buffer[0]),
1299 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1300 res, GetLastError(), buffer, total-1);
1302 buffer[0] = '\0';
1303 SetLastError(0xdeadbeef);
1304 res = GetWindowsDirectory(buffer, total + 1);
1305 /* res does not include the terminating Zero */
1306 ok( (res == (total-1)) && (buffer[0]),
1307 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1308 res, GetLastError(), buffer, total-1);
1310 memset(buffer, '#', total + 1);
1311 buffer[total + 2] = '\0';
1312 SetLastError(0xdeadbeef);
1313 res = GetWindowsDirectory(buffer, total-1);
1314 /* res includes the terminating Zero) */
1315 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1316 res, GetLastError(), buffer, total);
1318 memset(buffer, '#', total + 1);
1319 buffer[total + 2] = '\0';
1320 SetLastError(0xdeadbeef);
1321 res = GetWindowsDirectory(buffer, total-2);
1322 /* res includes the terminating Zero) */
1323 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1324 res, GetLastError(), buffer, total);
1327 static void test_NeedCurrentDirectoryForExePathA(void)
1329 if (!pNeedCurrentDirectoryForExePathA)
1331 win_skip("NeedCurrentDirectoryForExePathA is not available\n");
1332 return;
1335 /* Crashes in Windows */
1336 if (0)
1337 ok(pNeedCurrentDirectoryForExePathA(NULL), "returned FALSE for NULL\n");
1339 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1340 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1341 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1342 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1344 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1345 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1346 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1347 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1350 static void test_NeedCurrentDirectoryForExePathW(void)
1352 const WCHAR thispath[] = {'.', 0};
1353 const WCHAR fullpath[] = {'c', ':', '\\', 0};
1354 const WCHAR cmdname[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1356 if (!pNeedCurrentDirectoryForExePathW)
1358 win_skip("NeedCurrentDirectoryForExePathW is not available\n");
1359 return;
1362 /* Crashes in Windows */
1363 if (0)
1364 ok(pNeedCurrentDirectoryForExePathW(NULL), "returned FALSE for NULL\n");
1366 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1367 ok(pNeedCurrentDirectoryForExePathW(thispath), "returned FALSE for \".\"\n");
1368 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1369 ok(pNeedCurrentDirectoryForExePathW(cmdname), "returned FALSE for \"cmd.exe\"\n");
1371 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1372 ok(!pNeedCurrentDirectoryForExePathW(thispath), "returned TRUE for \".\"\n");
1373 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1374 ok(!pNeedCurrentDirectoryForExePathW(cmdname), "returned TRUE for \"cmd.exe\"\n");
1377 /* Call various path/file name retrieving APIs and check the case of
1378 * the returned drive letter. Some apps (for instance Adobe Photoshop CS3
1379 * installer) depend on the drive letter being in upper case.
1381 static void test_drive_letter_case(void)
1383 UINT ret;
1384 char buf[MAX_PATH];
1386 #define is_upper_case_letter(a) ((a) >= 'A' && (a) <= 'Z')
1388 memset(buf, 0, sizeof(buf));
1389 SetLastError(0xdeadbeef);
1390 ret = GetWindowsDirectory(buf, sizeof(buf));
1391 ok(ret, "GetWindowsDirectory error %u\n", GetLastError());
1392 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1393 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1394 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1396 /* re-use the buffer returned by GetFullPathName */
1397 buf[2] = '/';
1398 SetLastError(0xdeadbeef);
1399 ret = GetFullPathName(buf + 2, sizeof(buf), buf, NULL);
1400 ok(ret, "GetFullPathName error %u\n", GetLastError());
1401 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1402 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1403 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1405 memset(buf, 0, sizeof(buf));
1406 SetLastError(0xdeadbeef);
1407 ret = GetSystemDirectory(buf, sizeof(buf));
1408 ok(ret, "GetSystemDirectory error %u\n", GetLastError());
1409 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1410 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1411 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1413 memset(buf, 0, sizeof(buf));
1414 SetLastError(0xdeadbeef);
1415 ret = GetCurrentDirectory(sizeof(buf), buf);
1416 ok(ret, "GetCurrentDirectory error %u\n", GetLastError());
1417 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1418 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1419 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1421 /* TEMP is an environment variable, so it can't be tested for case-sensitivity */
1422 memset(buf, 0, sizeof(buf));
1423 SetLastError(0xdeadbeef);
1424 ret = GetTempPath(sizeof(buf), buf);
1425 ok(ret, "GetTempPath error %u\n", GetLastError());
1426 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1427 if (buf[0])
1429 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1430 ok(buf[strlen(buf)-1] == '\\', "Temporary path (%s) doesn't end in a slash\n", buf);
1433 memset(buf, 0, sizeof(buf));
1434 SetLastError(0xdeadbeef);
1435 ret = GetFullPathName(".", sizeof(buf), buf, NULL);
1436 ok(ret, "GetFullPathName error %u\n", GetLastError());
1437 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1438 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1439 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1441 /* re-use the buffer returned by GetFullPathName */
1442 SetLastError(0xdeadbeef);
1443 ret = GetShortPathName(buf, buf, sizeof(buf));
1444 ok(ret, "GetShortPathName error %u\n", GetLastError());
1445 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1446 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1447 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1449 if (pGetLongPathNameA)
1451 /* re-use the buffer returned by GetShortPathName */
1452 SetLastError(0xdeadbeef);
1453 ret = pGetLongPathNameA(buf, buf, sizeof(buf));
1454 ok(ret, "GetLongPathNameA error %u\n", GetLastError());
1455 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1456 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1457 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1459 #undef is_upper_case_letter
1462 static void test_SearchPathA(void)
1464 CHAR pathA[MAX_PATH], fileA[] = "", buffA[MAX_PATH];
1465 CHAR *ptrA = NULL;
1466 DWORD ret;
1468 if (!pSearchPathA)
1470 win_skip("SearchPathA isn't available\n");
1471 return;
1474 GetWindowsDirectoryA(pathA, sizeof(pathA)/sizeof(CHAR));
1476 /* NULL filename */
1477 SetLastError(0xdeadbeef);
1478 ret = pSearchPathA(pathA, NULL, NULL, sizeof(buffA)/sizeof(CHAR), buffA, &ptrA);
1479 ok(ret == 0, "Expected failure, got %d\n", ret);
1480 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1481 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1483 /* empty filename */
1484 SetLastError(0xdeadbeef);
1485 ret = pSearchPathA(pathA, fileA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, &ptrA);
1486 ok(ret == 0, "Expected failure, got %d\n", ret);
1487 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1488 broken(GetLastError() == ERROR_FILE_NOT_FOUND) /* win9x */,
1489 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1492 static void test_SearchPathW(void)
1494 WCHAR pathW[MAX_PATH], fileW[] = { 0 }, buffW[MAX_PATH];
1495 WCHAR *ptrW = NULL;
1496 DWORD ret;
1498 if (!pSearchPathW)
1500 win_skip("SearchPathW isn't available\n");
1501 return;
1504 /* SearchPathW is a stub on win9x and doesn't return sane error,
1505 so quess if it's implemented indirectly */
1506 SetLastError(0xdeadbeef);
1507 GetWindowsDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR));
1508 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1510 win_skip("SearchPathW not implemented\n");
1511 return;
1514 if (0)
1516 /* NULL filename, crashes on nt4 */
1517 SetLastError(0xdeadbeef);
1518 ret = pSearchPathW(pathW, NULL, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW);
1519 ok(ret == 0, "Expected failure, got %d\n", ret);
1520 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1521 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1524 /* empty filename */
1525 SetLastError(0xdeadbeef);
1526 ret = pSearchPathW(pathW, fileW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW);
1527 ok(ret == 0, "Expected failure, got %d\n", ret);
1528 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1529 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1532 static void init_pointers(void)
1534 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
1536 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hKernel32, #f))
1537 MAKEFUNC(GetLongPathNameA);
1538 MAKEFUNC(GetLongPathNameW);
1539 MAKEFUNC(NeedCurrentDirectoryForExePathA);
1540 MAKEFUNC(NeedCurrentDirectoryForExePathW);
1541 MAKEFUNC(SearchPathA);
1542 MAKEFUNC(SearchPathW);
1543 #undef MAKEFUNC
1546 START_TEST(path)
1548 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
1550 init_pointers();
1552 /* Report only once */
1553 if (!pGetLongPathNameA)
1554 win_skip("GetLongPathNameA is not available\n");
1555 if (!pGetLongPathNameW)
1556 win_skip("GetLongPathNameW is not available\n");
1558 test_InitPathA(curdir, &curDrive, &otherDrive);
1559 test_CurrentDirectoryA(origdir,curdir);
1560 test_PathNameA(curdir, curDrive, otherDrive);
1561 test_CleanupPathA(origdir,curdir);
1562 test_GetTempPath();
1563 test_GetLongPathNameA();
1564 test_GetLongPathNameW();
1565 test_GetShortPathNameW();
1566 test_GetSystemDirectory();
1567 test_GetWindowsDirectory();
1568 test_NeedCurrentDirectoryForExePathA();
1569 test_NeedCurrentDirectoryForExePathW();
1570 test_drive_letter_case();
1571 test_SearchPathA();
1572 test_SearchPathW();