Merge trunk r45185
[reactos.git] / rostests / winetests / kernel32 / path.c
1 /*
2 * Unit test suite for various Path and Directory Functions
3 *
4 * Copyright 2002 Geoffrey Hausheer
5 * Copyright 2006 Detlef Riekenberg
6 *
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.
11 *
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.
16 *
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
20 */
21
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"
30
31 #define HAS_TRAIL_SLASH_A(string) (string[lstrlenA(string)-1]=='\\')
32
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"
41
42 #define NOT_A_VALID_DRIVE '@'
43
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 |<>"
49 */
50 static const CHAR funny_chars[]="!@#$%^&*()=+{}[],?'`";
51 static const CHAR is_char_ok[] ="11111110111111111011";
52
53 static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR,LPSTR,DWORD);
54 static DWORD (WINAPI *pGetLongPathNameW)(LPWSTR,LPWSTR,DWORD);
55
56 /* Present in Win2003+ */
57 static BOOL (WINAPI *pNeedCurrentDirectoryForExePathA)(LPCSTR);
58 static BOOL (WINAPI *pNeedCurrentDirectoryForExePathW)(LPCWSTR);
59
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;
69
70 /* function that tests GetFullPathNameA, GetShortPathNameA,GetLongPathNameA */
71 /* NOTE: the passfail structure is used to allow customizable todo checking
72 for wine. It is not very pretty, but it sure beats duplicating this
73 function lots of times
74 */
75 static void test_ValidPathA(const CHAR *curdir, const CHAR *subdir, const CHAR *filename,
76 CHAR *shortstr, SLpassfail *passfail, const CHAR *errstr)
77 {
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], /*absolute 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
90 */
91 if(passfail!=NULL) {
92 passfail->shortlen=-1;passfail->s2llen=-1;passfail->longlen=-1;
93 passfail->shorterror=0;passfail->s2lerror=0;passfail->longerror=0;
94 }
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);
102 }
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);
113 }
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);
133 }
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();
142 }
143 /* Test GetLongPathNameA functionality
144 We test both conversion from GetFullPathNameA and from GetShortPathNameA
145 */
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();
159 }
160 }
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);
173 }
174 } else {
175 passfail->longlen=len;
176 passfail->longerror=GetLastError();
177 }
178 }
179 }
180
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;
198 }
199 }
200 }
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,"");
211 }
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");
215 }
216
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];
221
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);
227 }
228
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.
236 */
237 static void test_FunnyChars(CHAR *curdir,CHAR *curdir_short,CHAR *filename, INT valid,CHAR *errstr)
238 {
239 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
240 SLpassfail passfail;
241
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);
255 }
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);
267 }
268 }
269 }
270
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)
274 {
275 CHAR tmppath[MAX_PATH], *dirptr;
276 DWORD val,len,chklen;
277
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);
304 }
305 }
306 static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
307 {
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;
315
316 *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
317
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");
323
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 || broken(len1 == len), /* WinME */
332 "GetTempPathA should return string length %d instead of %d\n",len+1,len1);
333
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)
338 */
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");
347
348 id=GetTempFileNameA(tmppath,NULL,0,newdir);
349 /* Windows 95, 98 return 0==id, while Windows 2000, XP return 0!=id */
350 if (id)
351 {
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");
359 }
360
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");
369
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
374 */
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
382 */
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 sprintf(tmpstr,"%c:", *curDrive);
388 bRes = CreateDirectoryA(tmpstr,NULL);
389 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
390 GetLastError() == ERROR_ALREADY_EXISTS),
391 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
392 sprintf(tmpstr,"%c:\\", *curDrive);
393 bRes = CreateDirectoryA(tmpstr,NULL);
394 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
395 GetLastError() == ERROR_ALREADY_EXISTS),
396 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
397 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
398 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
399 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
400 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
401 ok(CloseHandle(hndl),"CloseHandle failed\n");
402 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
403 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
404 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
405 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
406 ok(CloseHandle(hndl),"CloseHandle failed\n");
407 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
408 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
409 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
410 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
411 ok(CloseHandle(hndl),"CloseHandle failed\n");
412 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
413 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
414 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
415 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
416 ok(CloseHandle(hndl),"CloseHandle failed\n");
417 }
418
419 /* Test GetCurrentDirectory & SetCurrentDirectory */
420 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
421 {
422 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
423 DWORD len,len1;
424 /* Save the original directory, so that we can return to it at the end
425 of the test
426 */
427 len=GetCurrentDirectoryA(MAX_PATH,origdir);
428 ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
429 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
430 buffer size is too small to hold the current directory
431 */
432 lstrcpyA(tmpstr,"aaaaaaa");
433 len1=GetCurrentDirectoryA(len,tmpstr);
434 ok(len1==len+1, "GetCurrentDirectoryA returned %d instead of %d\n",len1,len+1);
435 ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
436 "GetCurrentDirectoryA should not have modified the buffer\n");
437 /* SetCurrentDirectoryA shouldn't care whether the string has a
438 trailing '\\' or not
439 */
440 sprintf(tmpstr,"%s\\",newdir);
441 test_setdir(origdir,tmpstr,newdir,1,"check 1");
442 test_setdir(origdir,newdir,NULL,1,"check 2");
443 /* Set the directory to the working area. We just tested that this works,
444 so why check it again.
445 */
446 SetCurrentDirectoryA(newdir);
447 /* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
448 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
449 test_setdir(newdir,tmpstr,NULL,0,"check 3");
450 /* Check that SetCurrentDirectory fails for a nonexistent lond directory */
451 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
452 test_setdir(newdir,tmpstr,NULL,0,"check 4");
453 /* Check that SetCurrentDirectory passes with a long directory */
454 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
455 test_setdir(newdir,tmpstr,NULL,1,"check 5");
456 /* Check that SetCurrentDirectory passes with a short relative directory */
457 sprintf(tmpstr,"%s",SHORTDIR);
458 sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
459 test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
460 /* starting with a '.' */
461 sprintf(tmpstr,".\\%s",SHORTDIR);
462 test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
463 /* Check that SetCurrentDirectory passes with a short relative directory */
464 sprintf(tmpstr,"%s",LONGDIR);
465 sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
466 test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
467 /* starting with a '.' */
468 sprintf(tmpstr,".\\%s",LONGDIR);
469 test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
470 /* change to root without a trailing backslash. The function call succeeds
471 but the directory is not changed.
472 */
473 sprintf(tmpstr, "%c:", newdir[0]);
474 test_setdir(newdir,tmpstr,newdir,1,"check 10");
475 /* works however with a trailing backslash */
476 sprintf(tmpstr, "%c:\\", newdir[0]);
477 test_setdir(newdir,tmpstr,NULL,1,"check 11");
478 }
479
480 /* Cleanup the mess we made while executing these tests */
481 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
482 {
483 CHAR tmpstr[MAX_PATH];
484 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
485 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
486 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
487 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
488 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
489 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
490 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
491 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
492 sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
493 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
494 sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
495 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
496 ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
497 ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
498 }
499
500 /* This routine will test Get(Full|Short|Long)PathNameA */
501 static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
502 {
503 CHAR curdir_short[MAX_PATH],
504 longdir_short[MAX_PATH];
505 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH],tmpstr2[MAX_PATH];
506 LPSTR strptr; /*ptr to the filename portion of the path */
507 DWORD len;
508 INT i;
509 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
510 SLpassfail passfail;
511
512 /* Get the short form of the current directory */
513 ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
514 "GetShortPathNameA failed\n");
515 ok(!HAS_TRAIL_SLASH_A(curdir_short),
516 "GetShortPathNameA should not have a trailing \\\n");
517 /* Get the short form of the absolute-path to LONGDIR */
518 sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
519 ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
520 "GetShortPathNameA failed\n");
521 ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
522 "GetShortPathNameA should not have a trailing \\\n");
523
524 if (pGetLongPathNameA) {
525 DWORD rc1,rc2;
526 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
527 rc1=(*pGetLongPathNameA)(tmpstr,NULL,0);
528 rc2=(*pGetLongPathNameA)(curdir,NULL,0);
529 ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
530 "GetLongPathNameA: wrong return code, %d instead of %d\n",
531 rc1, lstrlenA(tmpstr)+1);
532
533 sprintf(dir,"%c:",curDrive);
534 rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
535 ok(strcmp(dir,tmpstr)==0,
536 "GetLongPathNameA: returned '%s' instead of '%s' (rc=%d)\n",
537 tmpstr,dir,rc1);
538 }
539
540 /* Check the cases where both file and directory exist first */
541 /* Start with a 8.3 directory, 8.3 filename */
542 test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
543 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
544 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
545 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
546 /* Now try a 8.3 directory, long file name */
547 test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
548 sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
549 test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
550 /* Next is a long directory, 8.3 file */
551 test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
552 sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
553 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
554 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
555 /*Lastly a long directory, long file */
556 test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
557 test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
558
559 /* Now check all of the invalid file w/ valid directory combinations */
560 /* Start with a 8.3 directory, 8.3 filename */
561 test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
562 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
563 ok((passfail.shortlen==0 &&
564 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
565 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
566 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
567 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
568 passfail.shortlen,passfail.shorterror,tmpstr);
569 if(pGetLongPathNameA) {
570 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
571 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
572 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
573 }
574 /* Now try a 8.3 directory, long file name */
575 test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
576 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
577 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
578 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
579 !passfail.shorterror,
580 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
581 if(pGetLongPathNameA) {
582 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
583 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
584 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
585 }
586 /* Next is a long directory, 8.3 file */
587 test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
588 sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
589 GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
590 strcat(tmpstr1,"\\" NONFILE_SHORT);
591 ok((passfail.shortlen==0 &&
592 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
593 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
594 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
595 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
596 passfail.shortlen,passfail.shorterror,tmpstr);
597 if(pGetLongPathNameA) {
598 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
599 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
600 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
601 }
602 /*Lastly a long directory, long file */
603 test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
604 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
605 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
606 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
607 !passfail.shorterror,
608 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
609 if(pGetLongPathNameA) {
610 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
611 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
612 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
613 }
614 /* Now try again with directories that don't exist */
615 /* 8.3 directory, 8.3 filename */
616 test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
617 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
618 ok((passfail.shortlen==0 &&
619 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
620 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
621 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
622 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
623 passfail.shortlen,passfail.shorterror,tmpstr);
624 if(pGetLongPathNameA) {
625 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
626 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
627 passfail.longerror==ERROR_FILE_NOT_FOUND,
628 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
629 passfail.longerror);
630 }
631 /* Now try a 8.3 directory, long file name */
632 test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
633 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
634 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
635 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
636 !passfail.shorterror,
637 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
638 passfail.shorterror);
639 if(pGetLongPathNameA) {
640 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
641 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
642 passfail.longerror==ERROR_FILE_NOT_FOUND,
643 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
644 passfail.longerror);
645 }
646 /* Next is a long directory, 8.3 file */
647 test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
648 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
649 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
650 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
651 !passfail.shorterror,
652 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
653 passfail.shorterror);
654 if(pGetLongPathNameA) {
655 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
656 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
657 passfail.longerror==ERROR_FILE_NOT_FOUND,
658 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
659 passfail.longerror);
660 }
661 /*Lastly a long directory, long file */
662 test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
663 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
664 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
665 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
666 !passfail.shorterror,
667 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
668 passfail.shorterror);
669 if(pGetLongPathNameA) {
670 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
671 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
672 passfail.longerror==ERROR_FILE_NOT_FOUND,
673 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
674 passfail.longerror);
675 }
676 /* Next try directories ending with '\\' */
677 /* Existing Directories */
678 sprintf(tmpstr,"%s\\",SHORTDIR);
679 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
680 sprintf(tmpstr,"%s\\",LONGDIR);
681 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
682 /* Nonexistent directories */
683 sprintf(tmpstr,"%s\\",NONDIR_SHORT);
684 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
685 sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
686 ok((passfail.shortlen==0 &&
687 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
688 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
689 (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
690 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
691 passfail.shortlen,passfail.shorterror,tmpstr);
692 if(pGetLongPathNameA) {
693 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
694 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
695 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
696 passfail.longerror);
697 }
698 sprintf(tmpstr,"%s\\",NONDIR_LONG);
699 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
700 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
701 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
702 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
703 !passfail.shorterror,
704 "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
705 passfail.shorterror);
706 if(pGetLongPathNameA) {
707 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
708 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
709 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
710 passfail.longerror);
711 }
712 /* Test GetFullPathNameA with drive letters */
713 if( curDrive != NOT_A_VALID_DRIVE) {
714 sprintf(tmpstr,"%c:",curdir[0]);
715 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
716 "GetFullPathNameA(%c:) failed\n", curdir[0]);
717 GetCurrentDirectoryA(MAX_PATH,tmpstr);
718 sprintf(tmpstr1,"%s\\",tmpstr);
719 ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
720 "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
721 curdir[0],tmpstr2,tmpstr,tmpstr1);
722
723 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
724 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
725 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
726 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
727 ok(lstrcmpiA(SHORTFILE,strptr)==0,
728 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
729 }
730 /* Without a leading slash, insert the current directory if on the current drive */
731 sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
732 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
733 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
734 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
735 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
736 ok(lstrcmpiA(SHORTFILE,strptr)==0,
737 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
738 /* Otherwise insert the missing leading slash */
739 if( otherDrive != NOT_A_VALID_DRIVE) {
740 /* FIXME: this test assumes that current directory on other drive is root */
741 sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
742 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
743 sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,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);
748 }
749 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
750 So test for them. */
751 if( curDrive != NOT_A_VALID_DRIVE) {
752 sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
753 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
754 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
755 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
756 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
757 ok(lstrcmpiA(SHORTFILE,strptr)==0,
758 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
759 }
760 /**/
761 sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
762 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
763 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
764 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
765 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
766 ok(lstrcmpiA(SHORTFILE,strptr)==0,
767 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
768 /* Windows will insert a drive letter in front of an absolute UNIX path */
769 sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
770 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
771 sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
772 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
773 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
774 /* This passes in Wine because it still contains the pointer from the previous test */
775 ok(lstrcmpiA(SHORTFILE,strptr)==0,
776 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
777
778 /* Now try some relative paths */
779 ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
780 test_SplitShortPathA(tmpstr,dir,eight,three);
781 if(pGetLongPathNameA) {
782 ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
783 ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
784 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
785 }
786 sprintf(tmpstr,".\\%s",LONGDIR);
787 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
788 test_SplitShortPathA(tmpstr1,dir,eight,three);
789 ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
790 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
791 if(pGetLongPathNameA) {
792 ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
793 tmpstr);
794 ok(lstrcmpiA(tmpstr1,tmpstr)==0,
795 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
796 }
797 /* Check out Get*PathNameA on some funny characters */
798 for(i=0;i<lstrlenA(funny_chars);i++) {
799 INT valid;
800 valid=(is_char_ok[i]=='0') ? 0 : 1;
801 sprintf(tmpstr1,"check%d-1",i);
802 sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
803 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
804 sprintf(tmpstr1,"check%d-2",i);
805 sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
806 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
807 sprintf(tmpstr1,"check%d-3",i);
808 sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
809 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
810 sprintf(tmpstr1,"check%d-4",i);
811 sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
812 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
813 sprintf(tmpstr1,"check%d-5",i);
814 sprintf(tmpstr,"Long %c File",funny_chars[i]);
815 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
816 sprintf(tmpstr1,"check%d-6",i);
817 sprintf(tmpstr,"%c Long File",funny_chars[i]);
818 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
819 sprintf(tmpstr1,"check%d-7",i);
820 sprintf(tmpstr,"Long File %c",funny_chars[i]);
821 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
822 }
823 }
824
825 static void test_GetTempPathA(char* tmp_dir)
826 {
827 DWORD len, len_with_null;
828 char buf[MAX_PATH];
829
830 len_with_null = strlen(tmp_dir) + 1;
831
832 lstrcpyA(buf, "foo");
833 len = GetTempPathA(MAX_PATH, buf);
834 ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
835 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
836 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
837
838 /* Some versions of Windows touch the buffer, some don't so we don't
839 * test that. Also, NT sometimes exaggerates the required buffer size
840 * so we cannot test for an exact match. Finally, the
841 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
842 * For instance in some cases Win98 returns len_with_null - 1 instead
843 * of len_with_null.
844 */
845 len = GetTempPathA(1, buf);
846 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
847
848 len = GetTempPathA(0, NULL);
849 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
850
851 /* The call above gave us the buffer size that Windows thinks is needed
852 * so the next call should work
853 */
854 lstrcpyA(buf, "foo");
855 len = GetTempPathA(len, buf);
856 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
857 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
858 }
859
860 static void test_GetTempPathW(char* tmp_dir)
861 {
862 DWORD len, len_with_null;
863 WCHAR buf[MAX_PATH];
864 WCHAR tmp_dirW[MAX_PATH];
865 static const WCHAR fooW[] = {'f','o','o',0};
866
867 MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
868 len_with_null = lstrlenW(tmp_dirW) + 1;
869
870 /* This one is different from ANSI version: ANSI version doesn't
871 * touch the buffer, unicode version usually truncates the buffer
872 * to zero size. NT still exaggerates the required buffer size
873 * sometimes so we cannot test for an exact match. Finally, the
874 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
875 * For instance on NT4 it will sometimes return a path without the
876 * trailing '\\' and sometimes return an error.
877 */
878
879 lstrcpyW(buf, fooW);
880 len = GetTempPathW(MAX_PATH, buf);
881 if (len==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
882 {
883 win_skip("GetTempPathW is not available\n");
884 return;
885 }
886 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
887 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
888
889 lstrcpyW(buf, fooW);
890 len = GetTempPathW(1, buf);
891 ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
892 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
893
894 len = GetTempPathW(0, NULL);
895 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
896
897 lstrcpyW(buf, fooW);
898 len = GetTempPathW(len, buf);
899 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
900 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
901 }
902
903 static void test_GetTempPath(void)
904 {
905 char save_TMP[MAX_PATH];
906 char windir[MAX_PATH];
907 char buf[MAX_PATH];
908
909 if (!GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP))) save_TMP[0] = 0;
910
911 /* test default configuration */
912 trace("TMP=%s\n", save_TMP);
913 if (save_TMP[0])
914 {
915 strcpy(buf,save_TMP);
916 if (buf[strlen(buf)-1]!='\\')
917 strcat(buf,"\\");
918 test_GetTempPathA(buf);
919 test_GetTempPathW(buf);
920 }
921
922 /* TMP=C:\WINDOWS */
923 GetWindowsDirectoryA(windir, sizeof(windir));
924 SetEnvironmentVariableA("TMP", windir);
925 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
926 trace("TMP=%s\n", buf);
927 strcat(windir,"\\");
928 test_GetTempPathA(windir);
929 test_GetTempPathW(windir);
930
931 /* TMP=C:\ */
932 GetWindowsDirectoryA(windir, sizeof(windir));
933 windir[3] = 0;
934 SetEnvironmentVariableA("TMP", windir);
935 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
936 trace("TMP=%s\n", buf);
937 test_GetTempPathA(windir);
938 test_GetTempPathW(windir);
939
940 /* TMP=C: i.e. use current working directory of the specified drive */
941 GetWindowsDirectoryA(windir, sizeof(windir));
942 SetCurrentDirectoryA(windir);
943 windir[2] = 0;
944 SetEnvironmentVariableA("TMP", windir);
945 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
946 trace("TMP=%s\n", buf);
947 GetWindowsDirectoryA(windir, sizeof(windir));
948 strcat(windir,"\\");
949 test_GetTempPathA(windir);
950 test_GetTempPathW(windir);
951
952 SetEnvironmentVariableA("TMP", save_TMP);
953 }
954
955 static void test_GetLongPathNameA(void)
956 {
957 DWORD length, explength, hostsize;
958 char tempfile[MAX_PATH];
959 char longpath[MAX_PATH];
960 char unc_prefix[MAX_PATH];
961 char unc_short[MAX_PATH], unc_long[MAX_PATH];
962 char temppath[MAX_PATH], temppath2[MAX_PATH];
963 HANDLE file;
964
965 if (!pGetLongPathNameA)
966 return;
967
968 GetTempPathA(MAX_PATH, tempfile);
969 lstrcatA(tempfile, "longfilename.longext");
970
971 file = CreateFileA(tempfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
972 CloseHandle(file);
973
974 /* Test a normal path with a small buffer size */
975 memset(temppath, 0, MAX_PATH);
976 length = pGetLongPathNameA(tempfile, temppath, 4);
977 /* We have a failure so length should be the minumum plus the terminating '0' */
978 ok(length >= lstrlen(tempfile) + 1, "Wrong length\n");
979 ok(temppath[0] == 0, "Buffer should not have been touched\n");
980
981 /* Some UNC syntax tests */
982
983 memset(temppath, 0, MAX_PATH);
984 memset(temppath2, 0, MAX_PATH);
985 lstrcpyA(temppath2, "\\\\?\\");
986 lstrcatA(temppath2, tempfile);
987 explength = length + 4;
988
989 SetLastError(0xdeadbeef);
990 length = pGetLongPathNameA(temppath2, NULL, 0);
991 if (length == 0 && GetLastError() == ERROR_BAD_NET_NAME)
992 {
993 win_skip("UNC syntax tests don't work on Win98/WinMe\n");
994 DeleteFileA(tempfile);
995 return;
996 }
997 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
998
999 length = pGetLongPathNameA(temppath2, NULL, MAX_PATH);
1000 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1001
1002 length = pGetLongPathNameA(temppath2, temppath, 4);
1003 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1004 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1005
1006 /* Now an UNC path with the computername */
1007 lstrcpyA(unc_prefix, "\\\\");
1008 hostsize = sizeof(unc_prefix) - 2;
1009 GetComputerName(unc_prefix + 2, &hostsize);
1010 lstrcatA(unc_prefix, "\\");
1011
1012 /* Create a short syntax for the whole unc path */
1013 memset(unc_short, 0, MAX_PATH);
1014 GetShortPathNameA(tempfile, temppath, MAX_PATH);
1015 lstrcpyA(unc_short, unc_prefix);
1016 unc_short[lstrlenA(unc_short)] = temppath[0];
1017 lstrcatA(unc_short, "$\\");
1018 lstrcatA(unc_short, strchr(temppath, '\\') + 1);
1019
1020 /* Create a long syntax for reference */
1021 memset(longpath, 0, MAX_PATH);
1022 pGetLongPathNameA(tempfile, temppath, MAX_PATH);
1023 lstrcpyA(longpath, unc_prefix);
1024 longpath[lstrlenA(longpath)] = temppath[0];
1025 lstrcatA(longpath, "$\\");
1026 lstrcatA(longpath, strchr(temppath, '\\') + 1);
1027
1028 /* NULL test */
1029 SetLastError(0xdeadbeef);
1030 length = pGetLongPathNameA(unc_short, NULL, 0);
1031 if (length == 0 && GetLastError() == ERROR_BAD_NETPATH)
1032 {
1033 /* Seen on Window XP Home */
1034 win_skip("UNC with computername is not supported\n");
1035 DeleteFileA(tempfile);
1036 return;
1037 }
1038 explength = lstrlenA(longpath) + 1;
1039 todo_wine
1040 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1041
1042 length = pGetLongPathNameA(unc_short, NULL, MAX_PATH);
1043 todo_wine
1044 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1045
1046 memset(unc_long, 0, MAX_PATH);
1047 length = pGetLongPathNameA(unc_short, unc_long, lstrlenA(unc_short));
1048 /* length will include terminating '0' on failure */
1049 todo_wine
1050 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1051 ok(unc_long[0] == 0, "Buffer should not have been touched\n");
1052
1053 memset(unc_long, 0, MAX_PATH);
1054 length = pGetLongPathNameA(unc_short, unc_long, length);
1055 /* length doesn't include terminating '0' on success */
1056 explength--;
1057 todo_wine
1058 {
1059 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1060 ok(!lstrcmpiA(unc_long, longpath), "Expected (%s), got (%s)\n", longpath, unc_long);
1061 }
1062
1063 DeleteFileA(tempfile);
1064 }
1065
1066 static void test_GetLongPathNameW(void)
1067 {
1068 DWORD length, expanded;
1069 BOOL ret;
1070 HANDLE file;
1071 WCHAR empty[MAX_PATH];
1072 WCHAR tempdir[MAX_PATH], name[200];
1073 WCHAR dirpath[4 + MAX_PATH + 200]; /* To ease removal */
1074 WCHAR shortpath[4 + MAX_PATH + 200 + 1 + 200];
1075 static const WCHAR prefix[] = { '\\','\\','?','\\', 0};
1076 static const WCHAR backslash[] = { '\\', 0};
1077 static const WCHAR letterX[] = { 'X', 0};
1078
1079 if (!pGetLongPathNameW)
1080 return;
1081
1082 SetLastError(0xdeadbeef);
1083 length = pGetLongPathNameW(NULL,NULL,0);
1084 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1085 {
1086 win_skip("GetLongPathNameW is not implemented\n");
1087 return;
1088 }
1089 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1090 ok(GetLastError()==ERROR_INVALID_PARAMETER,"GetLastError returned %d but expected ERROR_INVALID_PARAMETER\n",GetLastError());
1091
1092 SetLastError(0xdeadbeef);
1093 empty[0]=0;
1094 length = pGetLongPathNameW(empty,NULL,0);
1095 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1096 ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
1097
1098 /* Create a long path name. The path needs to exist for these tests to
1099 * succeed so we need the "\\?\" prefix when creating directories and
1100 * files.
1101 */
1102 name[0] = 0;
1103 while (lstrlenW(name) < (sizeof(name)/sizeof(WCHAR) - 1))
1104 lstrcatW(name, letterX);
1105
1106 GetTempPathW(MAX_PATH, tempdir);
1107
1108 lstrcpyW(shortpath, prefix);
1109 lstrcatW(shortpath, tempdir);
1110 lstrcatW(shortpath, name);
1111 lstrcpyW(dirpath, shortpath);
1112 ret = CreateDirectoryW(shortpath, NULL);
1113 ok(ret, "Could not create the temporary directory : %d\n", GetLastError());
1114 lstrcatW(shortpath, backslash);
1115 lstrcatW(shortpath, name);
1116
1117 /* Path does not exist yet and we know it overruns MAX_PATH */
1118
1119 /* No prefix */
1120 SetLastError(0xdeadbeef);
1121 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1122 ok(length == 0, "Expected 0, got %d\n", length);
1123 todo_wine
1124 ok(GetLastError() == ERROR_PATH_NOT_FOUND,
1125 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1126 /* With prefix */
1127 SetLastError(0xdeadbeef);
1128 length = pGetLongPathNameW(shortpath, NULL, 0);
1129 todo_wine
1130 {
1131 ok(length == 0, "Expected 0, got %d\n", length);
1132 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
1133 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1134 }
1135
1136 file = CreateFileW(shortpath, GENERIC_READ|GENERIC_WRITE, 0, NULL,
1137 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1138 ok(file != INVALID_HANDLE_VALUE,
1139 "Could not create the temporary file : %d.\n", GetLastError());
1140 CloseHandle(file);
1141
1142 /* Path exists */
1143
1144 /* No prefix */
1145 SetLastError(0xdeadbeef);
1146 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1147 todo_wine
1148 {
1149 ok(length == 0, "Expected 0, got %d\n", length);
1150 ok(GetLastError() == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1151 }
1152 /* With prefix */
1153 expanded = 4 + (pGetLongPathNameW(tempdir, NULL, 0) - 1) + lstrlenW(name) + 1 + lstrlenW(name) + 1;
1154 SetLastError(0xdeadbeef);
1155 length = pGetLongPathNameW(shortpath, NULL, 0);
1156 ok(length == expanded, "Expected %d, got %d\n", expanded, length);
1157
1158 /* NULL buffer with length crashes on Windows */
1159 if (0)
1160 length = pGetLongPathNameW(shortpath, NULL, 20);
1161
1162 ok(DeleteFileW(shortpath), "Could not delete temporary file\n");
1163 ok(RemoveDirectoryW(dirpath), "Could not delete temporary directory\n");
1164 }
1165
1166 static void test_GetShortPathNameW(void)
1167 {
1168 WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
1169 WCHAR path[MAX_PATH];
1170 WCHAR short_path[MAX_PATH];
1171 DWORD length;
1172 HANDLE file;
1173 int ret;
1174 WCHAR name[] = { 't', 'e', 's', 't', 0 };
1175 WCHAR backSlash[] = { '\\', 0 };
1176
1177 SetLastError(0xdeadbeef);
1178 GetTempPathW( MAX_PATH, path );
1179 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1180 {
1181 win_skip("GetTempPathW is not implemented\n");
1182 return;
1183 }
1184
1185 lstrcatW( path, test_path );
1186 lstrcatW( path, backSlash );
1187 ret = CreateDirectoryW( path, NULL );
1188 ok( ret, "Directory was not created. LastError = %d\n", GetLastError() );
1189
1190 /* Starting a main part of test */
1191 length = GetShortPathNameW( path, short_path, 0 );
1192 ok( length, "GetShortPathNameW returned 0.\n" );
1193 ret = GetShortPathNameW( path, short_path, length );
1194 ok( ret, "GetShortPathNameW returned 0.\n" );
1195 lstrcatW( short_path, name );
1196 file = CreateFileW( short_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1197 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
1198
1199 /* End test */
1200 CloseHandle( file );
1201 ret = DeleteFileW( short_path );
1202 ok( ret, "Cannot delete file.\n" );
1203 ret = RemoveDirectoryW( path );
1204 ok( ret, "Cannot delete directory.\n" );
1205 }
1206
1207 static void test_GetSystemDirectory(void)
1208 {
1209 CHAR buffer[MAX_PATH + 4];
1210 DWORD res;
1211 DWORD total;
1212
1213 SetLastError(0xdeadbeef);
1214 res = GetSystemDirectory(NULL, 0);
1215 /* res includes the terminating Zero */
1216 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1217
1218 total = res;
1219
1220 /* this crashes on XP */
1221 if (0) res = GetSystemDirectory(NULL, total);
1222
1223 SetLastError(0xdeadbeef);
1224 res = GetSystemDirectory(NULL, total-1);
1225 /* 95+NT: total (includes the terminating Zero)
1226 98+ME: 0 with ERROR_INVALID_PARAMETER */
1227 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1228 "returned %d with %d (expected '%d' or: '0' with "
1229 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1230
1231 if (total > MAX_PATH) return;
1232
1233 buffer[0] = '\0';
1234 SetLastError(0xdeadbeef);
1235 res = GetSystemDirectory(buffer, total);
1236 /* res does not include the terminating Zero */
1237 ok( (res == (total-1)) && (buffer[0]),
1238 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1239 res, GetLastError(), buffer, total-1);
1240
1241 buffer[0] = '\0';
1242 SetLastError(0xdeadbeef);
1243 res = GetSystemDirectory(buffer, total + 1);
1244 /* res does not include the terminating Zero */
1245 ok( (res == (total-1)) && (buffer[0]),
1246 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1247 res, GetLastError(), buffer, total-1);
1248
1249 memset(buffer, '#', total + 1);
1250 buffer[total + 2] = '\0';
1251 SetLastError(0xdeadbeef);
1252 res = GetSystemDirectory(buffer, total-1);
1253 /* res includes the terminating Zero) */
1254 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1255 res, GetLastError(), buffer, total);
1256
1257 memset(buffer, '#', total + 1);
1258 buffer[total + 2] = '\0';
1259 SetLastError(0xdeadbeef);
1260 res = GetSystemDirectory(buffer, total-2);
1261 /* res includes the terminating Zero) */
1262 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1263 res, GetLastError(), buffer, total);
1264 }
1265
1266 static void test_GetWindowsDirectory(void)
1267 {
1268 CHAR buffer[MAX_PATH + 4];
1269 DWORD res;
1270 DWORD total;
1271
1272 SetLastError(0xdeadbeef);
1273 res = GetWindowsDirectory(NULL, 0);
1274 /* res includes the terminating Zero */
1275 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1276
1277 total = res;
1278 /* this crashes on XP */
1279 if (0) res = GetWindowsDirectory(NULL, total);
1280
1281 SetLastError(0xdeadbeef);
1282 res = GetWindowsDirectory(NULL, total-1);
1283 /* 95+NT: total (includes the terminating Zero)
1284 98+ME: 0 with ERROR_INVALID_PARAMETER */
1285 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1286 "returned %d with %d (expected '%d' or: '0' with "
1287 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1288
1289 if (total > MAX_PATH) return;
1290
1291 buffer[0] = '\0';
1292 SetLastError(0xdeadbeef);
1293 res = GetWindowsDirectory(buffer, total);
1294 /* res does not include the terminating Zero */
1295 ok( (res == (total-1)) && (buffer[0]),
1296 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1297 res, GetLastError(), buffer, total-1);
1298
1299 buffer[0] = '\0';
1300 SetLastError(0xdeadbeef);
1301 res = GetWindowsDirectory(buffer, total + 1);
1302 /* res does not include the terminating Zero */
1303 ok( (res == (total-1)) && (buffer[0]),
1304 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1305 res, GetLastError(), buffer, total-1);
1306
1307 memset(buffer, '#', total + 1);
1308 buffer[total + 2] = '\0';
1309 SetLastError(0xdeadbeef);
1310 res = GetWindowsDirectory(buffer, total-1);
1311 /* res includes the terminating Zero) */
1312 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1313 res, GetLastError(), buffer, total);
1314
1315 memset(buffer, '#', total + 1);
1316 buffer[total + 2] = '\0';
1317 SetLastError(0xdeadbeef);
1318 res = GetWindowsDirectory(buffer, total-2);
1319 /* res includes the terminating Zero) */
1320 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1321 res, GetLastError(), buffer, total);
1322 }
1323
1324 static void test_NeedCurrentDirectoryForExePathA(void)
1325 {
1326 /* Crashes in Windows */
1327 if (0)
1328 ok(pNeedCurrentDirectoryForExePathA(NULL), "returned FALSE for NULL\n");
1329
1330 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1331 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1332 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1333 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1334
1335 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1336 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1337 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1338 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1339 }
1340
1341 static void test_NeedCurrentDirectoryForExePathW(void)
1342 {
1343 const WCHAR thispath[] = {'.', 0};
1344 const WCHAR fullpath[] = {'c', ':', '\\', 0};
1345 const WCHAR cmdname[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1346
1347 /* Crashes in Windows */
1348 if (0)
1349 ok(pNeedCurrentDirectoryForExePathW(NULL), "returned FALSE for NULL\n");
1350
1351 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1352 ok(pNeedCurrentDirectoryForExePathW(thispath), "returned FALSE for \".\"\n");
1353 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1354 ok(pNeedCurrentDirectoryForExePathW(cmdname), "returned FALSE for \"cmd.exe\"\n");
1355
1356 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1357 ok(!pNeedCurrentDirectoryForExePathW(thispath), "returned TRUE for \".\"\n");
1358 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1359 ok(!pNeedCurrentDirectoryForExePathW(cmdname), "returned TRUE for \"cmd.exe\"\n");
1360 }
1361
1362 /* Call various path/file name retrieving APIs and check the case of
1363 * the returned drive letter. Some apps (for instance Adobe Photoshop CS3
1364 * installer) depend on the drive letter being in upper case.
1365 */
1366 static void test_drive_letter_case(void)
1367 {
1368 UINT ret;
1369 char buf[MAX_PATH];
1370
1371 #define is_upper_case_letter(a) ((a) >= 'A' && (a) <= 'Z')
1372
1373 memset(buf, 0, sizeof(buf));
1374 SetLastError(0xdeadbeef);
1375 ret = GetWindowsDirectory(buf, sizeof(buf));
1376 ok(ret, "GetWindowsDirectory error %u\n", GetLastError());
1377 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1378 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1379 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1380
1381 /* re-use the buffer returned by GetFullPathName */
1382 buf[2] = '/';
1383 SetLastError(0xdeadbeef);
1384 ret = GetFullPathName(buf + 2, sizeof(buf), buf, NULL);
1385 ok(ret, "GetFullPathName error %u\n", GetLastError());
1386 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1387 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1388 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1389
1390 memset(buf, 0, sizeof(buf));
1391 SetLastError(0xdeadbeef);
1392 ret = GetSystemDirectory(buf, sizeof(buf));
1393 ok(ret, "GetSystemDirectory error %u\n", GetLastError());
1394 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1395 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1396 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1397
1398 memset(buf, 0, sizeof(buf));
1399 SetLastError(0xdeadbeef);
1400 ret = GetCurrentDirectory(sizeof(buf), buf);
1401 ok(ret, "GetCurrentDirectory error %u\n", GetLastError());
1402 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1403 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1404 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1405
1406 /* TEMP is an environment variable, so it can't be tested for case-sensitivity */
1407 memset(buf, 0, sizeof(buf));
1408 SetLastError(0xdeadbeef);
1409 ret = GetTempPath(sizeof(buf), buf);
1410 ok(ret, "GetTempPath error %u\n", GetLastError());
1411 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1412 if (buf[0])
1413 {
1414 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1415 ok(buf[strlen(buf)-1] == '\\', "Temporary path (%s) doesn't end in a slash\n", buf);
1416 }
1417
1418 memset(buf, 0, sizeof(buf));
1419 SetLastError(0xdeadbeef);
1420 ret = GetFullPathName(".", sizeof(buf), buf, NULL);
1421 ok(ret, "GetFullPathName error %u\n", GetLastError());
1422 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1423 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1424 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1425
1426 /* re-use the buffer returned by GetFullPathName */
1427 SetLastError(0xdeadbeef);
1428 ret = GetShortPathName(buf, buf, sizeof(buf));
1429 ok(ret, "GetShortPathName error %u\n", GetLastError());
1430 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1431 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1432 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1433
1434 if (pGetLongPathNameA)
1435 {
1436 /* re-use the buffer returned by GetShortPathName */
1437 SetLastError(0xdeadbeef);
1438 ret = pGetLongPathNameA(buf, buf, sizeof(buf));
1439 ok(ret, "GetLongPathNameA error %u\n", GetLastError());
1440 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1441 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1442 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1443 }
1444 #undef is_upper_case_letter
1445 }
1446
1447 START_TEST(path)
1448 {
1449 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
1450 pGetLongPathNameA = (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
1451 "GetLongPathNameA" );
1452 pGetLongPathNameW = (void*)GetProcAddress(GetModuleHandleA("kernel32.dll") ,
1453 "GetLongPathNameW" );
1454 pNeedCurrentDirectoryForExePathA =
1455 (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
1456 "NeedCurrentDirectoryForExePathA" );
1457 pNeedCurrentDirectoryForExePathW =
1458 (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
1459 "NeedCurrentDirectoryForExePathW" );
1460
1461 /* Report only once */
1462 if (!pGetLongPathNameA)
1463 win_skip("GetLongPathNameA is not available\n");
1464 if (!pGetLongPathNameW)
1465 win_skip("GetLongPathNameW is not available\n");
1466
1467 test_InitPathA(curdir, &curDrive, &otherDrive);
1468 test_CurrentDirectoryA(origdir,curdir);
1469 test_PathNameA(curdir, curDrive, otherDrive);
1470 test_CleanupPathA(origdir,curdir);
1471 test_GetTempPath();
1472 test_GetLongPathNameA();
1473 test_GetLongPathNameW();
1474 test_GetShortPathNameW();
1475 test_GetSystemDirectory();
1476 test_GetWindowsDirectory();
1477 if (pNeedCurrentDirectoryForExePathA)
1478 {
1479 test_NeedCurrentDirectoryForExePathA();
1480 }
1481 if (pNeedCurrentDirectoryForExePathW)
1482 {
1483 test_NeedCurrentDirectoryForExePathW();
1484 }
1485 test_drive_letter_case();
1486 }