Rewrote the collapsing of . and .. in RtlGetFullPathName_U for better
[wine.git] / dlls / kernel / tests / path.c
blobb5f5b536c7928b12a4d78dc0a807d7674d88a493
1 /*
2 * Unit test suite for Get*PathNamesA and (Get|Set)CurrentDirectoryA.
4 * Copyright 2002 Geoffrey Hausheer
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "winerror.h"
28 #include "winnls.h"
30 #define HAS_TRAIL_SLASH_A(string) (string[lstrlenA(string)-1]=='\\')
32 #define LONGFILE "Long File test.path"
33 #define SHORTFILE "pathtest.pth"
34 #define SHORTDIR "shortdir"
35 #define LONGDIR "Long Directory"
36 #define NONFILE_SHORT "noexist.pth"
37 #define NONFILE_LONG "Non Existent File"
38 #define NONDIR_SHORT "notadir"
39 #define NONDIR_LONG "Non Existent Directory"
41 #define NOT_A_VALID_DRIVE '@'
43 /* the following characters don't work well with GetFullPathNameA
44 in Win98. I don't know if this is a FAT thing, or if it is an OS thing
45 but I don't test these characters now.
46 NOTE: Win2k allows GetFullPathNameA to work with them though
47 |<>"
49 static const CHAR funny_chars[]="!@#$%^&*()=+{}[],?'`";
50 static const CHAR is_char_ok[] ="11111110111111111011";
51 static const CHAR wine_todo[] ="00000000000000000000";
53 static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR,LPSTR,DWORD);
55 /* a structure to deal with wine todos somewhat cleanly */
56 typedef struct {
57 DWORD shortlen;
58 DWORD shorterror;
59 DWORD s2llen;
60 DWORD s2lerror;
61 DWORD longlen;
62 DWORD longerror;
63 } SLpassfail;
65 /* function that tests GetFullPathNameA, GetShortPathNameA,GetLongPathNameA */
66 /* NOTE: the passfail structure is used to allow cutomizeable todo checking
67 for wine. It is not very pretty, but it sure beats duplicating this
68 function lots of times
70 static void test_ValidPathA(CHAR *curdir, CHAR *subdir, CHAR *filename,
71 CHAR *shortstr, SLpassfail *passfail, CHAR *errstr) {
72 CHAR tmpstr[MAX_PATH],
73 fullpath[MAX_PATH], /*full path to the file (not short/long) */
74 subpath[MAX_PATH], /*relative path to the file */
75 fullpathshort[MAX_PATH], /*absolue path to the file (short format) */
76 fullpathlong[MAX_PATH], /*absolute path to the file (long format) */
77 curdirshort[MAX_PATH], /*absolute path to the current dir (short) */
78 curdirlong[MAX_PATH]; /*absolute path to the current dir (long) */
79 LPSTR strptr; /*ptr to the filename portion of the path */
80 DWORD len;
81 /* if passfail is NULL, we can perform all checks within this function,
82 otherwise, we will return the relevant data in the passfail struct, so
83 we must initialize it first
85 if(passfail!=NULL) {
86 passfail->shortlen=-1;passfail->s2llen=-1;passfail->longlen=-1;
87 passfail->shorterror=0;passfail->s2lerror=0;passfail->longerror=0;
89 /* GetLongPathNameA is only supported on Win2k+ and Win98+ */
90 if(pGetLongPathNameA) {
91 ok((len=pGetLongPathNameA(curdir,curdirlong,MAX_PATH)),
92 "%s: GetLongPathNameA failed\n",errstr);
93 /*GetLongPathNameA can return a trailing '\\' but shouldn't do so here */
94 ok(! HAS_TRAIL_SLASH_A(curdirlong),
95 "%s: GetLongPathNameA should not have a trailing \\\n",errstr);
97 ok((len=GetShortPathNameA(curdir,curdirshort,MAX_PATH)),
98 "%s: GetShortPathNameA failed\n",errstr);
99 /*GetShortPathNameA can return a trailing '\\' but shouldn't do so here */
100 ok(! HAS_TRAIL_SLASH_A(curdirshort),
101 "%s: GetShortPathNameA should not have a trailing \\\n",errstr);
102 /* build relative and absolute paths from inputs */
103 if(lstrlenA(subdir)) {
104 sprintf(subpath,"%s\\%s",subdir,filename);
105 } else {
106 lstrcpyA(subpath,filename);
108 sprintf(fullpath,"%s\\%s",curdir,subpath);
109 sprintf(fullpathshort,"%s\\%s",curdirshort,subpath);
110 sprintf(fullpathlong,"%s\\%s",curdirlong,subpath);
111 /* Test GetFullPathNameA functionality */
112 len=GetFullPathNameA(subpath,MAX_PATH,tmpstr,&strptr);
113 ok(len, "GetFullPathNameA failed for: '%s'\n",subpath);
114 if(HAS_TRAIL_SLASH_A(subpath)) {
115 ok(strptr==NULL,
116 "%s: GetFullPathNameA should not return a filename ptr\n",errstr);
117 ok(lstrcmpiA(fullpath,tmpstr)==0,
118 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
119 errstr,tmpstr,fullpath);
120 } else {
121 ok(lstrcmpiA(strptr,filename)==0,
122 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
123 errstr,strptr,filename);
124 ok(lstrcmpiA(fullpath,tmpstr)==0,
125 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
126 errstr,tmpstr,fullpath);
128 /* Test GetShortPathNameA functionality */
129 SetLastError(0);
130 len=GetShortPathNameA(fullpathshort,shortstr,MAX_PATH);
131 if(passfail==NULL) {
132 ok(len, "%s: GetShortPathNameA failed\n",errstr);
133 } else {
134 passfail->shortlen=len;
135 passfail->shorterror=GetLastError();
137 /* Test GetLongPathNameA functionality
138 We test both conversion from GetFullPathNameA and from GetShortPathNameA
140 if(pGetLongPathNameA) {
141 if(len!=0) {
142 SetLastError(0);
143 len=pGetLongPathNameA(shortstr,tmpstr,MAX_PATH);
144 if(passfail==NULL) {
145 ok(len,
146 "%s: GetLongPathNameA failed during Short->Long conversion\n", errstr);
147 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
148 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
149 errstr,tmpstr,fullpathlong);
150 } else {
151 passfail->s2llen=len;
152 passfail->s2lerror=GetLastError();
155 SetLastError(0);
156 len=pGetLongPathNameA(fullpath,tmpstr,MAX_PATH);
157 if(passfail==NULL) {
158 ok(len, "%s: GetLongPathNameA failed\n",errstr);
159 if(HAS_TRAIL_SLASH_A(fullpath)) {
160 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
161 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
162 errstr,tmpstr,fullpathlong);
163 } else {
164 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
165 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
166 errstr,tmpstr,fullpathlong);
168 } else {
169 passfail->longlen=len;
170 passfail->longerror=GetLastError();
175 /* split path into leading directory, and 8.3 filename */
176 static void test_SplitShortPathA(CHAR *path,CHAR *dir,CHAR *eight,CHAR *three) {
177 int done,error;
178 int ext,fil;
179 int len,i;
180 len=lstrlenA(path);
181 ext=len; fil=len; done=0; error=0;
182 /* walk backwards over path looking for '.' or '\\' separators */
183 for(i=len-1;(i>=0) && (!done);i--) {
184 if(path[i]=='.')
185 if(ext!=len) error=1; else ext=i;
186 else if(path[i]=='\\') {
187 if(i==len-1) {
188 error=1;
189 } else {
190 fil=i;
191 done=1;
195 /* Check that we didn't find a trailing '\\' or multiple '.' */
196 ok(!error,"Illegal file found in 8.3 path '%s'\n",path);
197 /* Separate dir, root, and extension */
198 if(ext!=len) lstrcpyA(three,path+ext+1); else lstrcpyA(three,"");
199 if(fil!=len) {
200 lstrcpynA(eight,path+fil+1,ext-fil);
201 lstrcpynA(dir,path,fil+1);
202 } else {
203 lstrcpynA(eight,path,ext+1);
204 lstrcpyA(dir,"");
206 /* Validate that root and extension really are 8.3 */
207 ok(lstrlenA(eight)<=8 && lstrlenA(three)<=3,
208 "GetShortPathNAmeA did not return an 8.3 path\n");
211 /* Check that GetShortPathNameA returns a valid 8.3 path */
212 static void test_LongtoShortA(CHAR *teststr,CHAR *goodstr,
213 CHAR *ext,CHAR *errstr) {
214 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
216 test_SplitShortPathA(teststr,dir,eight,three);
217 ok(lstrcmpiA(dir,goodstr)==0,
218 "GetShortPathNameA returned '%s' instead of '%s'\n",dir,goodstr);
219 ok(lstrcmpiA(three,ext)==0,
220 "GetShortPathNameA returned '%s' with incorrect extension\n",three);
223 /* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
224 characters in the filename.
225 'valid' indicates whether this would be an allowed filename
226 'todo' indicates that wine doesn't get this right yet.
227 NOTE: We always call this routine with a non-existent filename, so
228 Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
229 should.
231 static void test_FunnyChars(CHAR *curdir,CHAR *filename,
232 INT valid,INT todo,CHAR *errstr) {
233 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
234 SLpassfail passfail;
236 test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
237 if(valid) {
238 sprintf(tmpstr1,"%s\\%s",curdir,filename);
239 if(todo) {
240 todo_wine {
241 ok((passfail.shortlen==0 &&
242 (passfail.shorterror==ERROR_FILE_NOT_FOUND || passfail.shorterror==ERROR_PATH_NOT_FOUND || !passfail.shorterror)) ||
243 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
244 "%s: GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
245 errstr,passfail.shortlen,passfail.shorterror,tmpstr);
247 } else {
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=%ld error=%ld tmpstr=[%s]\n",
252 errstr,passfail.shortlen,passfail.shorterror,tmpstr);
254 } else {
255 if(todo) {
256 todo_wine {
257 /* Win2k returns ERROR_INVALID_NAME, Win98, wine return ERROR_FILE_NOT_FOUND, NT4 doesn't set last error */
258 ok(passfail.shortlen==0 &&
259 (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),
260 "%s: GetShortPathA should have failed len=%ld, error=%ld\n",
261 errstr,passfail.shortlen,passfail.shorterror);
263 } else {
264 ok(passfail.shortlen==0 &&
265 (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),
266 "%s: GetShortPathA should have failed len=%ld, error=%ld\n",
267 errstr,passfail.shortlen,passfail.shorterror);
270 if(pGetLongPathNameA) {
271 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
272 if(valid) {
273 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
274 "%s: GetLongPathA returned %ld and not %d\n",
275 errstr,passfail.longerror,ERROR_FILE_NOT_FOUND);
276 } else {
277 ok(passfail.longerror==ERROR_INVALID_NAME ||
278 passfail.longerror==ERROR_FILE_NOT_FOUND,
279 "%s: GetLongPathA returned %ld and not %d or %d'\n",
280 errstr, passfail.longerror,ERROR_INVALID_NAME,ERROR_FILE_NOT_FOUND);
285 /* Routine to test that SetCurrentDirectory behaves as expected. */
286 static void test_setdir(CHAR *olddir,CHAR *newdir,
287 CHAR *cmprstr, INT pass,CHAR *errstr)
289 CHAR tmppath[MAX_PATH], *dirptr;
290 DWORD val,len,chklen;
292 val=SetCurrentDirectoryA(newdir);
293 len=GetCurrentDirectoryA(MAX_PATH,tmppath);
294 /* if 'pass' then the SetDirectoryA was supposed to pass */
295 if(pass) {
296 dirptr=(cmprstr==NULL) ? newdir : cmprstr;
297 chklen=lstrlenA(dirptr);
298 ok(val,"%s: SetCurrentDirectoryA failed\n",errstr);
299 ok(len==chklen,
300 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
301 errstr);
302 ok(lstrcmpiA(dirptr,tmppath)==0,
303 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
304 errstr);
305 ok(SetCurrentDirectoryA(olddir),
306 "%s: Couldn't set directory to it's original value\n",errstr);
307 } else {
308 /* else thest that it fails correctly */
309 chklen=lstrlenA(olddir);
310 ok(val==0,
311 "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr);
312 ok(len==chklen,
313 "%s: SetCurrentDirectory changed the directory, though it failed\n",
314 errstr);
315 ok(lstrcmpiA(olddir,tmppath)==0,
316 "%s: SetCurrentDirectory changed the directory, though it failed\n",
317 errstr);
320 static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
322 CHAR tmppath[MAX_PATH], /*path to TEMP */
323 tmpstr[MAX_PATH],
324 tmpstr1[MAX_PATH];
325 DWORD len,len1,drives;
326 INT id;
327 HANDLE hndl;
329 *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
331 /* Get the current drive letter */
332 if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
333 *curDrive = tmpstr[0];
334 else
335 trace( "Unable to discover current drive, some tests will not be conducted.\n");
337 /* Test GetTempPathA */
338 len=GetTempPathA(MAX_PATH,tmppath);
339 ok(len!=0 && len < MAX_PATH,"GetTempPathA failed\n");
340 ok(HAS_TRAIL_SLASH_A(tmppath),
341 "GetTempPathA returned a path that did not end in '\\'\n");
342 lstrcpyA(tmpstr,"aaaaaaaa");
343 len1=GetTempPathA(len,tmpstr);
344 ok(len1==len+1,
345 "GetTempPathA should return string length %ld instead of %ld\n",len+1,len1);
347 /* Test GetTmpFileNameA
348 The only test we do here is whether GetTempFileNameA passes or not.
349 We do not thoroughly test this function yet (specifically, whether
350 it behaves correctly when 'unique' is non zero)
352 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
353 sprintf(tmpstr,"pat%.4x.tmp",id & 0xffff);
354 sprintf(tmpstr1,"pat%x.tmp",id & 0xffff);
355 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
356 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
357 "GetTempPath returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
358 newdir,tmpstr,tmpstr1,id);
360 /* Find first valid drive letter that is neither newdir[0] nor curDrive */
361 drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
362 if( *curDrive != NOT_A_VALID_DRIVE)
363 drives &= ~(1<<(*curDrive-'A'));
364 if( drives)
365 for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
366 else
367 trace( "Could not find alternative drive, some tests will not be conducted.\n");
369 /* Do some CreateDirectoryA tests */
370 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
371 really understand how they work.
372 More formal tests should be done along with CreateFile tests
374 ok(CreateDirectoryA(newdir,NULL)==0,
375 "CreateDirectoryA succeeded even though a file of the same name exists\n");
376 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
377 ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
378 /* Create some files to test other functions. Note, we will test CreateFileA
379 at some later point
381 sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
382 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
383 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
384 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
385 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
386 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
387 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
388 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
389 ok(CloseHandle(hndl),"CloseHandle failed\n");
390 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
391 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
392 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
393 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
394 ok(CloseHandle(hndl),"CloseHandle failed\n");
395 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
396 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
397 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
398 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
399 ok(CloseHandle(hndl),"CloseHandle failed\n");
400 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
401 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
402 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
403 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
404 ok(CloseHandle(hndl),"CloseHandle failed\n");
407 /* Test GetCurrentDirectory & SetCurrentDirectory */
408 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
410 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
411 DWORD len,len1;
412 /* Save the original directory, so that we can return to it at the end
413 of the test
415 len=GetCurrentDirectoryA(MAX_PATH,origdir);
416 ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
417 ok(lstrcmpiA(origdir+(len-1),"\\")!=0,
418 "GetCurrentDirectoryA should not have a trailing \\\n");
419 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
420 buffer size is too small to hold the current directory
422 lstrcpyA(tmpstr,"aaaaaaa");
423 len1=GetCurrentDirectoryA(len,tmpstr);
424 ok(len1==len+1, "GetCurrentDirectoryA returned %ld instead of %ld\n",len1,len+1);
425 ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
426 "GetCurrentDirectoryA should not have modified the buffer\n");
427 /* SetCurrentDirectoryA shouldn't care whether the string has a
428 trailing '\\' or not
430 sprintf(tmpstr,"%s\\",newdir);
431 test_setdir(origdir,tmpstr,newdir,1,"check 1");
432 test_setdir(origdir,newdir,NULL,1,"check 2");
433 /* Set the directory to the working area. We just tested that this works,
434 so why check it again.
436 SetCurrentDirectoryA(newdir);
437 /* Check that SetCurrentDirectory fails when a non-existent dir is specified */
438 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
439 test_setdir(newdir,tmpstr,NULL,0,"check 3");
440 /* Check that SetCurrentDirectory fails for a non-existent lond directory */
441 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
442 test_setdir(newdir,tmpstr,NULL,0,"check 4");
443 /* Check that SetCurrentDirectory passes with a long directory */
444 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
445 test_setdir(newdir,tmpstr,NULL,1,"check 5");
446 /* Check that SetCurrentDirectory passes with a short relative directory */
447 sprintf(tmpstr,"%s",SHORTDIR);
448 sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
449 test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
450 /* starting with a '.' */
451 sprintf(tmpstr,".\\%s",SHORTDIR);
452 test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
453 /* Check that SetCurrentDirectory passes with a short relative directory */
454 sprintf(tmpstr,"%s",LONGDIR);
455 sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
456 test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
457 /* starting with a '.' */
458 sprintf(tmpstr,".\\%s",LONGDIR);
459 test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
462 /* Cleanup the mess we made while executing these tests */
463 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
465 CHAR tmpstr[MAX_PATH];
466 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
467 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
468 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
469 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
470 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
471 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
472 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
473 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
474 sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
475 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
476 sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
477 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
478 ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
479 ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
482 /* This routine will test Get(Full|Short|Long)PathNameA */
483 static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
485 CHAR curdir_short[MAX_PATH],
486 longdir_short[MAX_PATH];
487 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH],tmpstr2[MAX_PATH];
488 LPSTR strptr; /*ptr to the filename portion of the path */
489 DWORD len;
490 INT i;
491 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
492 SLpassfail passfail;
494 /* Get the short form of the current directory */
495 ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
496 "GetShortPathNameA failed\n");
497 ok(!HAS_TRAIL_SLASH_A(curdir_short),
498 "GetShortPathNameA should not have a trailing \\\n");
499 /* Get the short form of the absolute-path to LONGDIR */
500 sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
501 ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
502 "GetShortPathNameA failed\n");
503 ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
504 "GetShortPathNameA should not have a trailing \\\n");
506 if (pGetLongPathNameA) {
507 DWORD rc1,rc2;
508 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
509 rc1=(*pGetLongPathNameA)(tmpstr,NULL,0);
510 rc2=(*pGetLongPathNameA)(curdir,NULL,0);
511 ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
512 "GetLongPathNameA: wrong return code, %ld instead of %d\n",
513 rc1, strlen(tmpstr)+1);
515 sprintf(dir,"%c:",curDrive);
516 rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
517 ok(strcmp(dir,tmpstr)==0,
518 "GetLongPathNameA: returned '%s' instead of '%s' (rc=%ld)\n",
519 tmpstr,dir,rc1);
522 /* Check the cases where both file and directory exist first */
523 /* Start with a 8.3 directory, 8.3 filename */
524 test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
525 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
526 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
527 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
528 /* Now try a 8.3 directory, long file name */
529 test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
530 sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
531 test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
532 /* Next is a long directory, 8.3 file */
533 test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
534 sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
535 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
536 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
537 /*Lastly a long directory, long file */
538 test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
539 test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
541 /* Now check all of the invalid file w/ valid directory combinations */
542 /* Start with a 8.3 directory, 8.3 filename */
543 test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
544 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
545 ok((passfail.shortlen==0 &&
546 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
547 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
548 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
549 "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
550 passfail.shortlen,passfail.shorterror,tmpstr);
551 if(pGetLongPathNameA) {
552 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
553 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
554 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
556 /* Now try a 8.3 directory, long file name */
557 test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
558 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
559 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
560 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
561 !passfail.shorterror,
562 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
563 if(pGetLongPathNameA) {
564 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
565 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
566 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
568 /* Next is a long directory, 8.3 file */
569 test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
570 sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
571 GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
572 strcat(tmpstr1,"\\" NONFILE_SHORT);
573 ok((passfail.shortlen==0 &&
574 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
575 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
576 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
577 "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
578 passfail.shortlen,passfail.shorterror,tmpstr);
579 if(pGetLongPathNameA) {
580 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
581 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
582 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
584 /*Lastly a long directory, long file */
585 test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
586 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
587 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
588 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
589 !passfail.shorterror,
590 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
591 if(pGetLongPathNameA) {
592 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
593 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
594 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
596 /* Now try again with directories that don't exist */
597 /* 8.3 directory, 8.3 filename */
598 test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
599 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
600 ok((passfail.shortlen==0 &&
601 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
602 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
603 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
604 "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
605 passfail.shortlen,passfail.shorterror,tmpstr);
606 if(pGetLongPathNameA) {
607 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
608 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
609 passfail.longerror==ERROR_FILE_NOT_FOUND,
610 "GetLongPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
611 passfail.longerror);
613 /* Now try a 8.3 directory, long file name */
614 test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
615 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
616 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
617 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
618 !passfail.shorterror,
619 "GetShortPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
620 passfail.shorterror);
621 if(pGetLongPathNameA) {
622 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
623 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
624 passfail.longerror==ERROR_FILE_NOT_FOUND,
625 "GetLongPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
626 passfail.longerror);
628 /* Next is a long directory, 8.3 file */
629 test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
630 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
631 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
632 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
633 !passfail.shorterror,
634 "GetShortPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
635 passfail.shorterror);
636 if(pGetLongPathNameA) {
637 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
638 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
639 passfail.longerror==ERROR_FILE_NOT_FOUND,
640 "GetLongPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
641 passfail.longerror);
643 /*Lastly a long directory, long file */
644 test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
645 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
646 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
647 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
648 !passfail.shorterror,
649 "GetShortPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
650 passfail.shorterror);
651 if(pGetLongPathNameA) {
652 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
653 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
654 passfail.longerror==ERROR_FILE_NOT_FOUND,
655 "GetLongPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
656 passfail.longerror);
658 /* Next try directories ending with '\\' */
659 /* Existing Directories */
660 sprintf(tmpstr,"%s\\",SHORTDIR);
661 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
662 sprintf(tmpstr,"%s\\",LONGDIR);
663 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
664 /* Non-existent directories */
665 sprintf(tmpstr,"%s\\",NONDIR_SHORT);
666 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
667 sprintf(tmpstr2,"%s\\%s",curdir,tmpstr);
668 ok((passfail.shortlen==0 &&
669 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
670 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
671 (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
672 "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
673 passfail.shortlen,passfail.shorterror,tmpstr);
674 if(pGetLongPathNameA) {
675 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
676 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
677 "GetLongPathA returned %ld and not 'ERROR_FILE_NOT_FOUND'\n",
678 passfail.longerror);
680 sprintf(tmpstr,"%s\\",NONDIR_LONG);
681 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
682 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
683 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
684 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
685 !passfail.shorterror,
686 "GetShortPathA returned %ld and not 'ERROR_FILE_NOT_FOUND'\n",
687 passfail.shorterror);
688 if(pGetLongPathNameA) {
689 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
690 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
691 "GetLongPathA returned %ld and not 'ERROR_FILE_NOT_FOUND'\n",
692 passfail.longerror);
694 /* Test GetFullPathNameA with drive letters */
695 if( curDrive != NOT_A_VALID_DRIVE) {
696 sprintf(tmpstr,"%c:",curdir[0]);
697 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
698 "GetFullPathNameA(%c:) failed\n", curdir[0]);
699 GetCurrentDirectoryA(MAX_PATH,tmpstr);
700 sprintf(tmpstr1,"%s\\",tmpstr);
701 ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
702 "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
703 curdir[0],tmpstr2,tmpstr,tmpstr1);
705 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
706 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
707 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
708 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
709 ok(lstrcmpiA(SHORTFILE,strptr)==0,
710 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
712 /* Without a leading slash, insert the current directory if on the current drive */
713 sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
714 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
715 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
716 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
717 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
718 ok(lstrcmpiA(SHORTFILE,strptr)==0,
719 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
720 /* Otherwise insert the missing leading slash */
721 if( otherDrive != NOT_A_VALID_DRIVE) {
722 sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
723 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
724 sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
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);
730 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
731 So test for them. */
732 if( curDrive != NOT_A_VALID_DRIVE) {
733 sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
734 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
735 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
736 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
737 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
738 ok(lstrcmpiA(SHORTFILE,strptr)==0,
739 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
741 /**/
742 sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
743 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
744 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
745 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
746 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
747 ok(lstrcmpiA(SHORTFILE,strptr)==0,
748 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
749 /* Windows will insert a drive letter in front of an absolute UNIX path, but
750 Wine probably shouldn't. */
751 sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
752 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
753 todo_wine {
754 if( curDrive != NOT_A_VALID_DRIVE) {
755 sprintf(tmpstr,"C:\\%s\\%s",SHORTDIR,SHORTFILE);
756 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
757 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
760 /* This passes in Wine because it still contains the pointer from the previous test */
761 ok(lstrcmpiA(SHORTFILE,strptr)==0,
762 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
764 /* Now try some relative paths */
765 ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
766 test_SplitShortPathA(tmpstr,dir,eight,three);
767 if(pGetLongPathNameA) {
768 ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
769 ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
770 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
772 sprintf(tmpstr,".\\%s",LONGDIR);
773 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
774 test_SplitShortPathA(tmpstr1,dir,eight,three);
775 ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
776 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
777 if(pGetLongPathNameA) {
778 ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
779 tmpstr);
780 ok(lstrcmpiA(tmpstr1,tmpstr)==0,
781 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
783 /* Check out Get*PathNameA on some funny characters */
784 for(i=0;i<lstrlenA(funny_chars);i++) {
785 INT valid,todo;
786 valid=(is_char_ok[i]=='0') ? 0 : 1;
787 todo=(wine_todo[i]=='0') ? 0 : 1;
788 sprintf(tmpstr1,"check%d-1",i);
789 sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
790 test_FunnyChars(curdir,tmpstr,valid,todo,tmpstr1);
791 sprintf(tmpstr1,"check%d-2",i);
792 sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
793 test_FunnyChars(curdir,tmpstr,valid,todo,tmpstr1);
794 sprintf(tmpstr1,"check%d-3",i);
795 sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
796 test_FunnyChars(curdir,tmpstr,valid,todo,tmpstr1);
797 sprintf(tmpstr1,"check%d-4",i);
798 sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
799 test_FunnyChars(curdir,tmpstr,valid,todo,tmpstr1);
800 sprintf(tmpstr1,"check%d-5",i);
801 sprintf(tmpstr,"Long %c File",funny_chars[i]);
802 test_FunnyChars(curdir,tmpstr,valid,0,tmpstr1);
803 sprintf(tmpstr1,"check%d-6",i);
804 sprintf(tmpstr,"%c Long File",funny_chars[i]);
805 test_FunnyChars(curdir,tmpstr,valid,0,tmpstr1);
806 sprintf(tmpstr1,"check%d-7",i);
807 sprintf(tmpstr,"Long File %c",funny_chars[i]);
808 test_FunnyChars(curdir,tmpstr,valid,0,tmpstr1);
812 static void test_GetTempPathA(char* tmp_dir)
814 DWORD len, len_with_null;
815 char buf[MAX_PATH];
817 len_with_null = strlen(tmp_dir) + 1;
819 lstrcpyA(buf, "foo");
820 len = GetTempPathA(MAX_PATH, buf);
821 ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
822 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
823 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
825 /* Some versions of Windows touch the buffer, some don't so we don't
826 * test that. Also, NT sometimes exagerates the required buffer size
827 * so we cannot test for an exact match. Finally, the
828 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
829 * For instance in some cases Win98 returns len_with_null - 1 instead
830 * of len_with_null.
832 len = GetTempPathA(1, buf);
833 ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
835 len = GetTempPathA(0, NULL);
836 ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
838 /* The call above gave us the buffer size that Windows thinks is needed
839 * so the next call should work
841 lstrcpyA(buf, "foo");
842 len = GetTempPathA(len, buf);
843 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
844 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
847 static void test_GetTempPathW(char* tmp_dir)
849 DWORD len, len_with_null;
850 WCHAR buf[MAX_PATH];
851 WCHAR tmp_dirW[MAX_PATH];
852 static const WCHAR fooW[] = {'f','o','o',0};
854 MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
855 len_with_null = lstrlenW(tmp_dirW) + 1;
857 /* This one is different from ANSI version: ANSI version doesn't
858 * touch the buffer, unicode version usually truncates the buffer
859 * to zero size. NT still exagerates the required buffer size
860 * sometimes so we cannot test for an exact match. Finally, the
861 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
862 * For instance on NT4 it will sometimes return a path without the
863 * trailing '\\' and sometimes return an error.
866 lstrcpyW(buf, fooW);
867 len = GetTempPathW(MAX_PATH, buf);
868 if (len==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
869 return;
870 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
871 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
873 lstrcpyW(buf, fooW);
874 len = GetTempPathW(1, buf);
875 ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
876 ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
878 len = GetTempPathW(0, NULL);
879 ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
881 lstrcpyW(buf, fooW);
882 len = GetTempPathW(len, buf);
883 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
884 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
887 static void test_GetTempPath(void)
889 char save_TMP[MAX_PATH];
890 char windir[MAX_PATH];
891 char buf[MAX_PATH];
893 GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP));
895 /* test default configuration */
896 trace("TMP=%s\n", save_TMP);
897 strcpy(buf,save_TMP);
898 if (buf[strlen(buf)-1]!='\\')
899 strcat(buf,"\\");
900 test_GetTempPathA(buf);
901 test_GetTempPathW(buf);
903 /* TMP=C:\WINDOWS */
904 GetWindowsDirectoryA(windir, sizeof(windir));
905 SetEnvironmentVariableA("TMP", windir);
906 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
907 trace("TMP=%s\n", buf);
908 strcat(windir,"\\");
909 test_GetTempPathA(windir);
910 test_GetTempPathW(windir);
912 /* TMP=C:\ */
913 GetWindowsDirectoryA(windir, sizeof(windir));
914 windir[3] = 0;
915 SetEnvironmentVariableA("TMP", windir);
916 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
917 trace("TMP=%s\n", buf);
918 test_GetTempPathA(windir);
919 test_GetTempPathW(windir);
921 /* TMP=C: i.e. use current working directory of the specified drive */
922 GetWindowsDirectoryA(windir, sizeof(windir));
923 SetCurrentDirectoryA(windir);
924 windir[2] = 0;
925 SetEnvironmentVariableA("TMP", windir);
926 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
927 trace("TMP=%s\n", buf);
928 GetWindowsDirectoryA(windir, sizeof(windir));
929 strcat(windir,"\\");
930 test_GetTempPathA(windir);
931 test_GetTempPathW(windir);
933 SetEnvironmentVariableA("TMP", save_TMP);
936 START_TEST(path)
938 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
939 pGetLongPathNameA = (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
940 "GetLongPathNameA" );
941 test_InitPathA(curdir, &curDrive, &otherDrive);
942 test_CurrentDirectoryA(origdir,curdir);
943 test_PathNameA(curdir, curDrive, otherDrive);
944 test_CleanupPathA(origdir,curdir);
945 test_GetTempPath();