kernel32/tests: Use '%d' to print GetLastError().
[wine/multimedia.git] / dlls / kernel32 / tests / path.c
blob25f5c1bfbbd0d142785280c59beafb8354c24f48
1 /*
2 * Unit test suite for various Path and Directory Functions
4 * Copyright 2002 Geoffrey Hausheer
5 * Copyright 2006 Detlef Riekenberg
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include "wine/test.h"
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "winerror.h"
29 #include "winnls.h"
31 #define HAS_TRAIL_SLASH_A(string) (string[lstrlenA(string)-1]=='\\')
33 #define LONGFILE "Long File test.path"
34 #define SHORTFILE "pathtest.pth"
35 #define SHORTDIR "shortdir"
36 #define LONGDIR "Long Directory"
37 #define NONFILE_SHORT "noexist.pth"
38 #define NONFILE_LONG "NonExistent File"
39 #define NONDIR_SHORT "notadir"
40 #define NONDIR_LONG "NonExistent Directory"
42 #define NOT_A_VALID_DRIVE '@'
44 /* the following characters don't work well with GetFullPathNameA
45 in Win98. I don't know if this is a FAT thing, or if it is an OS thing
46 but I don't test these characters now.
47 NOTE: Win2k allows GetFullPathNameA to work with them though
48 |<>"
50 static const CHAR funny_chars[]="!@#$%^&*()=+{}[],?'`";
51 static const CHAR is_char_ok[] ="11111110111111111011";
53 static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR,LPSTR,DWORD);
54 static DWORD (WINAPI *pGetLongPathNameW)(LPWSTR,LPWSTR,DWORD);
56 /* a structure to deal with wine todos somewhat cleanly */
57 typedef struct {
58 DWORD shortlen;
59 DWORD shorterror;
60 DWORD s2llen;
61 DWORD s2lerror;
62 DWORD longlen;
63 DWORD longerror;
64 } SLpassfail;
66 /* function that tests GetFullPathNameA, GetShortPathNameA,GetLongPathNameA */
67 /* NOTE: the passfail structure is used to allow cutomizeable todo checking
68 for wine. It is not very pretty, but it sure beats duplicating this
69 function lots of times
71 static void test_ValidPathA(const CHAR *curdir, const CHAR *subdir, const CHAR *filename,
72 CHAR *shortstr, SLpassfail *passfail, const CHAR *errstr)
74 CHAR tmpstr[MAX_PATH],
75 fullpath[MAX_PATH], /*full path to the file (not short/long) */
76 subpath[MAX_PATH], /*relative path to the file */
77 fullpathshort[MAX_PATH], /*absolue path to the file (short format) */
78 fullpathlong[MAX_PATH], /*absolute path to the file (long format) */
79 curdirshort[MAX_PATH], /*absolute path to the current dir (short) */
80 curdirlong[MAX_PATH]; /*absolute path to the current dir (long) */
81 LPSTR strptr; /*ptr to the filename portion of the path */
82 DWORD len;
83 /* if passfail is NULL, we can perform all checks within this function,
84 otherwise, we will return the relevant data in the passfail struct, so
85 we must initialize it first
87 if(passfail!=NULL) {
88 passfail->shortlen=-1;passfail->s2llen=-1;passfail->longlen=-1;
89 passfail->shorterror=0;passfail->s2lerror=0;passfail->longerror=0;
91 /* GetLongPathNameA is only supported on Win2k+ and Win98+ */
92 if(pGetLongPathNameA) {
93 ok((len=pGetLongPathNameA(curdir,curdirlong,MAX_PATH)),
94 "%s: GetLongPathNameA failed\n",errstr);
95 /*GetLongPathNameA can return a trailing '\\' but shouldn't do so here */
96 ok(! HAS_TRAIL_SLASH_A(curdirlong),
97 "%s: GetLongPathNameA should not have a trailing \\\n",errstr);
99 ok((len=GetShortPathNameA(curdir,curdirshort,MAX_PATH)),
100 "%s: GetShortPathNameA failed\n",errstr);
101 /*GetShortPathNameA can return a trailing '\\' but shouldn't do so here */
102 ok(! HAS_TRAIL_SLASH_A(curdirshort),
103 "%s: GetShortPathNameA should not have a trailing \\\n",errstr);
104 /* build relative and absolute paths from inputs */
105 if(lstrlenA(subdir)) {
106 sprintf(subpath,"%s\\%s",subdir,filename);
107 } else {
108 lstrcpyA(subpath,filename);
110 sprintf(fullpath,"%s\\%s",curdir,subpath);
111 sprintf(fullpathshort,"%s\\%s",curdirshort,subpath);
112 sprintf(fullpathlong,"%s\\%s",curdirlong,subpath);
113 /* Test GetFullPathNameA functionality */
114 len=GetFullPathNameA(subpath,MAX_PATH,tmpstr,&strptr);
115 ok(len, "GetFullPathNameA failed for: '%s'\n",subpath);
116 if(HAS_TRAIL_SLASH_A(subpath)) {
117 ok(strptr==NULL,
118 "%s: GetFullPathNameA should not return a filename ptr\n",errstr);
119 ok(lstrcmpiA(fullpath,tmpstr)==0,
120 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
121 errstr,tmpstr,fullpath);
122 } else {
123 ok(lstrcmpiA(strptr,filename)==0,
124 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
125 errstr,strptr,filename);
126 ok(lstrcmpiA(fullpath,tmpstr)==0,
127 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
128 errstr,tmpstr,fullpath);
130 /* Test GetShortPathNameA functionality */
131 SetLastError(0);
132 len=GetShortPathNameA(fullpathshort,shortstr,MAX_PATH);
133 if(passfail==NULL) {
134 ok(len, "%s: GetShortPathNameA failed\n",errstr);
135 } else {
136 passfail->shortlen=len;
137 passfail->shorterror=GetLastError();
139 /* Test GetLongPathNameA functionality
140 We test both conversion from GetFullPathNameA and from GetShortPathNameA
142 if(pGetLongPathNameA) {
143 if(len!=0) {
144 SetLastError(0);
145 len=pGetLongPathNameA(shortstr,tmpstr,MAX_PATH);
146 if(passfail==NULL) {
147 ok(len,
148 "%s: GetLongPathNameA failed during Short->Long conversion\n", errstr);
149 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
150 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
151 errstr,tmpstr,fullpathlong);
152 } else {
153 passfail->s2llen=len;
154 passfail->s2lerror=GetLastError();
157 SetLastError(0);
158 len=pGetLongPathNameA(fullpath,tmpstr,MAX_PATH);
159 if(passfail==NULL) {
160 ok(len, "%s: GetLongPathNameA failed\n",errstr);
161 if(HAS_TRAIL_SLASH_A(fullpath)) {
162 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
163 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
164 errstr,tmpstr,fullpathlong);
165 } else {
166 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
167 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
168 errstr,tmpstr,fullpathlong);
170 } else {
171 passfail->longlen=len;
172 passfail->longerror=GetLastError();
177 /* split path into leading directory, and 8.3 filename */
178 static void test_SplitShortPathA(CHAR *path,CHAR *dir,CHAR *eight,CHAR *three) {
179 int done,error;
180 int ext,fil;
181 int len,i;
182 len=lstrlenA(path);
183 ext=len; fil=len; done=0; error=0;
184 /* walk backwards over path looking for '.' or '\\' separators */
185 for(i=len-1;(i>=0) && (!done);i--) {
186 if(path[i]=='.')
187 if(ext!=len) error=1; else ext=i;
188 else if(path[i]=='\\') {
189 if(i==len-1) {
190 error=1;
191 } else {
192 fil=i;
193 done=1;
197 /* Check that we didn't find a trailing '\\' or multiple '.' */
198 ok(!error,"Illegal file found in 8.3 path '%s'\n",path);
199 /* Separate dir, root, and extension */
200 if(ext!=len) lstrcpyA(three,path+ext+1); else lstrcpyA(three,"");
201 if(fil!=len) {
202 lstrcpynA(eight,path+fil+1,ext-fil);
203 lstrcpynA(dir,path,fil+1);
204 } else {
205 lstrcpynA(eight,path,ext+1);
206 lstrcpyA(dir,"");
208 /* Validate that root and extension really are 8.3 */
209 ok(lstrlenA(eight)<=8 && lstrlenA(three)<=3,
210 "GetShortPathNAmeA did not return an 8.3 path\n");
213 /* Check that GetShortPathNameA returns a valid 8.3 path */
214 static void test_LongtoShortA(CHAR *teststr,const CHAR *goodstr,
215 const CHAR *ext,const CHAR *errstr) {
216 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
218 test_SplitShortPathA(teststr,dir,eight,three);
219 ok(lstrcmpiA(dir,goodstr)==0,
220 "GetShortPathNameA returned '%s' instead of '%s'\n",dir,goodstr);
221 ok(lstrcmpiA(three,ext)==0,
222 "GetShortPathNameA returned '%s' with incorrect extension\n",three);
225 /* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
226 characters in the filename.
227 'valid' indicates whether this would be an allowed filename
228 'todo' indicates that wine doesn't get this right yet.
229 NOTE: We always call this routine with a nonexistent filename, so
230 Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
231 should.
233 static void test_FunnyChars(CHAR *curdir,CHAR *curdir_short,CHAR *filename, INT valid,CHAR *errstr)
235 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
236 SLpassfail passfail;
238 test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
239 if(valid) {
240 sprintf(tmpstr1,"%s\\%s",curdir_short,filename);
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=%d error=%d tmpstr=[%s]\n",
245 errstr,passfail.shortlen,passfail.shorterror,tmpstr);
246 } else {
247 ok(passfail.shortlen==0 &&
248 (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),
249 "%s: GetShortPathA should have failed len=%d, error=%d\n",
250 errstr,passfail.shortlen,passfail.shorterror);
252 if(pGetLongPathNameA) {
253 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
254 if(valid) {
255 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
256 "%s: GetLongPathA returned %d and not %d\n",
257 errstr,passfail.longerror,ERROR_FILE_NOT_FOUND);
258 } else {
259 ok(passfail.longerror==ERROR_INVALID_NAME ||
260 passfail.longerror==ERROR_FILE_NOT_FOUND,
261 "%s: GetLongPathA returned %d and not %d or %d'\n",
262 errstr, passfail.longerror,ERROR_INVALID_NAME,ERROR_FILE_NOT_FOUND);
267 /* Routine to test that SetCurrentDirectory behaves as expected. */
268 static void test_setdir(CHAR *olddir,CHAR *newdir,
269 CHAR *cmprstr, INT pass, const CHAR *errstr)
271 CHAR tmppath[MAX_PATH], *dirptr;
272 DWORD val,len,chklen;
274 val=SetCurrentDirectoryA(newdir);
275 len=GetCurrentDirectoryA(MAX_PATH,tmppath);
276 /* if 'pass' then the SetDirectoryA was supposed to pass */
277 if(pass) {
278 dirptr=(cmprstr==NULL) ? newdir : cmprstr;
279 chklen=lstrlenA(dirptr);
280 ok(val,"%s: SetCurrentDirectoryA failed\n",errstr);
281 ok(len==chklen,
282 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
283 errstr);
284 ok(lstrcmpiA(dirptr,tmppath)==0,
285 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
286 errstr);
287 ok(SetCurrentDirectoryA(olddir),
288 "%s: Couldn't set directory to it's original value\n",errstr);
289 } else {
290 /* else thest that it fails correctly */
291 chklen=lstrlenA(olddir);
292 ok(val==0,
293 "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr);
294 ok(len==chklen,
295 "%s: SetCurrentDirectory changed the directory, though it failed\n",
296 errstr);
297 ok(lstrcmpiA(olddir,tmppath)==0,
298 "%s: SetCurrentDirectory changed the directory, though it failed\n",
299 errstr);
302 static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
304 CHAR tmppath[MAX_PATH], /*path to TEMP */
305 tmpstr[MAX_PATH],
306 tmpstr1[MAX_PATH];
307 DWORD len,len1,drives;
308 INT id;
309 HANDLE hndl;
310 BOOL bRes;
312 *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
314 /* Get the current drive letter */
315 if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
316 *curDrive = tmpstr[0];
317 else
318 trace( "Unable to discover current drive, some tests will not be conducted.\n");
320 /* Test GetTempPathA */
321 len=GetTempPathA(MAX_PATH,tmppath);
322 ok(len!=0 && len < MAX_PATH,"GetTempPathA failed\n");
323 ok(HAS_TRAIL_SLASH_A(tmppath),
324 "GetTempPathA returned a path that did not end in '\\'\n");
325 lstrcpyA(tmpstr,"aaaaaaaa");
326 len1=GetTempPathA(len,tmpstr);
327 ok(len1==len+1,
328 "GetTempPathA should return string length %d instead of %d\n",len+1,len1);
330 /* Test GetTmpFileNameA
331 The only test we do here is whether GetTempFileNameA passes or not.
332 We do not thoroughly test this function yet (specifically, whether
333 it behaves correctly when 'unique' is non zero)
335 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
336 sprintf(tmpstr,"pat%.4x.tmp",id & 0xffff);
337 sprintf(tmpstr1,"pat%x.tmp",id & 0xffff);
338 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
339 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
340 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
341 newdir,tmpstr,tmpstr1,id);
342 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
344 id=GetTempFileNameA(tmppath,NULL,0,newdir);
345 /* Windows 95, 98 return 0==id, while Windows 2000, XP return 0!=id */
346 if (id)
348 sprintf(tmpstr,"%.4x.tmp",id & 0xffff);
349 sprintf(tmpstr1,"%x.tmp",id & 0xffff);
350 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
351 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
352 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
353 newdir,tmpstr,tmpstr1,id);
354 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
357 /* Find first valid drive letter that is neither newdir[0] nor curDrive */
358 drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
359 if( *curDrive != NOT_A_VALID_DRIVE)
360 drives &= ~(1<<(*curDrive-'A'));
361 if( drives)
362 for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
363 else
364 trace( "Could not find alternative drive, some tests will not be conducted.\n");
366 /* Do some CreateDirectoryA tests */
367 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
368 really understand how they work.
369 More formal tests should be done along with CreateFile tests
371 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
372 ok(CreateDirectoryA(newdir,NULL)==0,
373 "CreateDirectoryA succeeded even though a file of the same name exists\n");
374 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
375 ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
376 /* Create some files to test other functions. Note, we will test CreateFileA
377 at some later point
379 sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
380 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
381 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
382 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
383 bRes = CreateDirectoryA("c:",NULL);
384 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
385 GetLastError() == ERROR_ALREADY_EXISTS),
386 "CreateDirectoryA(\"c:\" should have failed (%d)\n", GetLastError());
387 bRes = CreateDirectoryA("c:\\",NULL);
388 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
389 GetLastError() == ERROR_ALREADY_EXISTS),
390 "CreateDirectoryA(\"c:\\\" should have failed (%d)\n", GetLastError());
391 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
392 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
393 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
394 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
395 ok(CloseHandle(hndl),"CloseHandle failed\n");
396 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
397 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
398 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
399 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
400 ok(CloseHandle(hndl),"CloseHandle failed\n");
401 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
402 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
403 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
404 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
405 ok(CloseHandle(hndl),"CloseHandle failed\n");
406 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
407 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
408 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
409 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
410 ok(CloseHandle(hndl),"CloseHandle failed\n");
413 /* Test GetCurrentDirectory & SetCurrentDirectory */
414 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
416 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
417 DWORD len,len1;
418 /* Save the original directory, so that we can return to it at the end
419 of the test
421 len=GetCurrentDirectoryA(MAX_PATH,origdir);
422 ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
423 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
424 buffer size is too small to hold the current directory
426 lstrcpyA(tmpstr,"aaaaaaa");
427 len1=GetCurrentDirectoryA(len,tmpstr);
428 ok(len1==len+1, "GetCurrentDirectoryA returned %d instead of %d\n",len1,len+1);
429 ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
430 "GetCurrentDirectoryA should not have modified the buffer\n");
431 /* SetCurrentDirectoryA shouldn't care whether the string has a
432 trailing '\\' or not
434 sprintf(tmpstr,"%s\\",newdir);
435 test_setdir(origdir,tmpstr,newdir,1,"check 1");
436 test_setdir(origdir,newdir,NULL,1,"check 2");
437 /* Set the directory to the working area. We just tested that this works,
438 so why check it again.
440 SetCurrentDirectoryA(newdir);
441 /* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
442 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
443 test_setdir(newdir,tmpstr,NULL,0,"check 3");
444 /* Check that SetCurrentDirectory fails for a nonexistent lond directory */
445 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
446 test_setdir(newdir,tmpstr,NULL,0,"check 4");
447 /* Check that SetCurrentDirectory passes with a long directory */
448 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
449 test_setdir(newdir,tmpstr,NULL,1,"check 5");
450 /* Check that SetCurrentDirectory passes with a short relative directory */
451 sprintf(tmpstr,"%s",SHORTDIR);
452 sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
453 test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
454 /* starting with a '.' */
455 sprintf(tmpstr,".\\%s",SHORTDIR);
456 test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
457 /* Check that SetCurrentDirectory passes with a short relative directory */
458 sprintf(tmpstr,"%s",LONGDIR);
459 sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
460 test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
461 /* starting with a '.' */
462 sprintf(tmpstr,".\\%s",LONGDIR);
463 test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
466 /* Cleanup the mess we made while executing these tests */
467 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
469 CHAR tmpstr[MAX_PATH];
470 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
471 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
472 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
473 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
474 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
475 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
476 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
477 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
478 sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
479 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
480 sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
481 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
482 ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
483 ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
486 /* This routine will test Get(Full|Short|Long)PathNameA */
487 static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
489 CHAR curdir_short[MAX_PATH],
490 longdir_short[MAX_PATH];
491 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH],tmpstr2[MAX_PATH];
492 LPSTR strptr; /*ptr to the filename portion of the path */
493 DWORD len;
494 INT i;
495 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
496 SLpassfail passfail;
498 /* Get the short form of the current directory */
499 ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
500 "GetShortPathNameA failed\n");
501 ok(!HAS_TRAIL_SLASH_A(curdir_short),
502 "GetShortPathNameA should not have a trailing \\\n");
503 /* Get the short form of the absolute-path to LONGDIR */
504 sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
505 ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
506 "GetShortPathNameA failed\n");
507 ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
508 "GetShortPathNameA should not have a trailing \\\n");
510 if (pGetLongPathNameA) {
511 DWORD rc1,rc2;
512 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
513 rc1=(*pGetLongPathNameA)(tmpstr,NULL,0);
514 rc2=(*pGetLongPathNameA)(curdir,NULL,0);
515 ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
516 "GetLongPathNameA: wrong return code, %d instead of %d\n",
517 rc1, lstrlenA(tmpstr)+1);
519 sprintf(dir,"%c:",curDrive);
520 rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
521 ok(strcmp(dir,tmpstr)==0,
522 "GetLongPathNameA: returned '%s' instead of '%s' (rc=%d)\n",
523 tmpstr,dir,rc1);
526 /* Check the cases where both file and directory exist first */
527 /* Start with a 8.3 directory, 8.3 filename */
528 test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
529 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
530 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
531 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
532 /* Now try a 8.3 directory, long file name */
533 test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
534 sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
535 test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
536 /* Next is a long directory, 8.3 file */
537 test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
538 sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
539 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
540 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
541 /*Lastly a long directory, long file */
542 test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
543 test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
545 /* Now check all of the invalid file w/ valid directory combinations */
546 /* Start with a 8.3 directory, 8.3 filename */
547 test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
548 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
549 ok((passfail.shortlen==0 &&
550 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
551 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
552 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
553 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
554 passfail.shortlen,passfail.shorterror,tmpstr);
555 if(pGetLongPathNameA) {
556 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
557 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
558 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
560 /* Now try a 8.3 directory, long file name */
561 test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
562 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
563 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
564 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
565 !passfail.shorterror,
566 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
567 if(pGetLongPathNameA) {
568 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
569 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
570 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
572 /* Next is a long directory, 8.3 file */
573 test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
574 sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
575 GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
576 strcat(tmpstr1,"\\" NONFILE_SHORT);
577 ok((passfail.shortlen==0 &&
578 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
579 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
580 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
581 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
582 passfail.shortlen,passfail.shorterror,tmpstr);
583 if(pGetLongPathNameA) {
584 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
585 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
586 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
588 /*Lastly a long directory, long file */
589 test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
590 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
591 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
592 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
593 !passfail.shorterror,
594 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
595 if(pGetLongPathNameA) {
596 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
597 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
598 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
600 /* Now try again with directories that don't exist */
601 /* 8.3 directory, 8.3 filename */
602 test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
603 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
604 ok((passfail.shortlen==0 &&
605 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
606 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
607 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
608 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
609 passfail.shortlen,passfail.shorterror,tmpstr);
610 if(pGetLongPathNameA) {
611 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
612 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
613 passfail.longerror==ERROR_FILE_NOT_FOUND,
614 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
615 passfail.longerror);
617 /* Now try a 8.3 directory, long file name */
618 test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
619 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
620 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
621 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
622 !passfail.shorterror,
623 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
624 passfail.shorterror);
625 if(pGetLongPathNameA) {
626 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
627 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
628 passfail.longerror==ERROR_FILE_NOT_FOUND,
629 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
630 passfail.longerror);
632 /* Next is a long directory, 8.3 file */
633 test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
634 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
635 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
636 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
637 !passfail.shorterror,
638 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
639 passfail.shorterror);
640 if(pGetLongPathNameA) {
641 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
642 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
643 passfail.longerror==ERROR_FILE_NOT_FOUND,
644 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
645 passfail.longerror);
647 /*Lastly a long directory, long file */
648 test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
649 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
650 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
651 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
652 !passfail.shorterror,
653 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
654 passfail.shorterror);
655 if(pGetLongPathNameA) {
656 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
657 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
658 passfail.longerror==ERROR_FILE_NOT_FOUND,
659 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
660 passfail.longerror);
662 /* Next try directories ending with '\\' */
663 /* Existing Directories */
664 sprintf(tmpstr,"%s\\",SHORTDIR);
665 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
666 sprintf(tmpstr,"%s\\",LONGDIR);
667 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
668 /* Nonexistent directories */
669 sprintf(tmpstr,"%s\\",NONDIR_SHORT);
670 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
671 sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
672 ok((passfail.shortlen==0 &&
673 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
674 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
675 (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
676 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
677 passfail.shortlen,passfail.shorterror,tmpstr);
678 if(pGetLongPathNameA) {
679 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
680 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
681 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
682 passfail.longerror);
684 sprintf(tmpstr,"%s\\",NONDIR_LONG);
685 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
686 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
687 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
688 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
689 !passfail.shorterror,
690 "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
691 passfail.shorterror);
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);
698 /* Test GetFullPathNameA with drive letters */
699 if( curDrive != NOT_A_VALID_DRIVE) {
700 sprintf(tmpstr,"%c:",curdir[0]);
701 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
702 "GetFullPathNameA(%c:) failed\n", curdir[0]);
703 GetCurrentDirectoryA(MAX_PATH,tmpstr);
704 sprintf(tmpstr1,"%s\\",tmpstr);
705 ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
706 "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
707 curdir[0],tmpstr2,tmpstr,tmpstr1);
709 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
710 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
711 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
712 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
713 ok(lstrcmpiA(SHORTFILE,strptr)==0,
714 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
716 /* Without a leading slash, insert the current directory if on the current drive */
717 sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
718 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
719 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
720 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
721 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
722 ok(lstrcmpiA(SHORTFILE,strptr)==0,
723 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
724 /* Otherwise insert the missing leading slash */
725 if( otherDrive != NOT_A_VALID_DRIVE) {
726 sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
727 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
728 sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
729 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
730 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
731 ok(lstrcmpiA(SHORTFILE,strptr)==0,
732 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
734 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
735 So test for them. */
736 if( curDrive != NOT_A_VALID_DRIVE) {
737 sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
738 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
739 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
740 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
741 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
742 ok(lstrcmpiA(SHORTFILE,strptr)==0,
743 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
745 /**/
746 sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
747 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
748 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
749 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
750 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
751 ok(lstrcmpiA(SHORTFILE,strptr)==0,
752 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
753 /* Windows will insert a drive letter in front of an absolute UNIX path */
754 sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
755 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
756 sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
757 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
758 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
759 /* This passes in Wine because it still contains the pointer from the previous test */
760 ok(lstrcmpiA(SHORTFILE,strptr)==0,
761 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
763 /* Now try some relative paths */
764 ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
765 test_SplitShortPathA(tmpstr,dir,eight,three);
766 if(pGetLongPathNameA) {
767 ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
768 ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
769 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
771 sprintf(tmpstr,".\\%s",LONGDIR);
772 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
773 test_SplitShortPathA(tmpstr1,dir,eight,three);
774 ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
775 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
776 if(pGetLongPathNameA) {
777 ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
778 tmpstr);
779 ok(lstrcmpiA(tmpstr1,tmpstr)==0,
780 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
782 /* Check out Get*PathNameA on some funny characters */
783 for(i=0;i<lstrlenA(funny_chars);i++) {
784 INT valid;
785 valid=(is_char_ok[i]=='0') ? 0 : 1;
786 sprintf(tmpstr1,"check%d-1",i);
787 sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
788 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
789 sprintf(tmpstr1,"check%d-2",i);
790 sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
791 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
792 sprintf(tmpstr1,"check%d-3",i);
793 sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
794 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
795 sprintf(tmpstr1,"check%d-4",i);
796 sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
797 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
798 sprintf(tmpstr1,"check%d-5",i);
799 sprintf(tmpstr,"Long %c File",funny_chars[i]);
800 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
801 sprintf(tmpstr1,"check%d-6",i);
802 sprintf(tmpstr,"%c Long File",funny_chars[i]);
803 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
804 sprintf(tmpstr1,"check%d-7",i);
805 sprintf(tmpstr,"Long File %c",funny_chars[i]);
806 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
810 static void test_GetTempPathA(char* tmp_dir)
812 DWORD len, len_with_null;
813 char buf[MAX_PATH];
815 len_with_null = strlen(tmp_dir) + 1;
817 lstrcpyA(buf, "foo");
818 len = GetTempPathA(MAX_PATH, buf);
819 ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
820 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
821 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
823 /* Some versions of Windows touch the buffer, some don't so we don't
824 * test that. Also, NT sometimes exagerates the required buffer size
825 * so we cannot test for an exact match. Finally, the
826 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
827 * For instance in some cases Win98 returns len_with_null - 1 instead
828 * of len_with_null.
830 len = GetTempPathA(1, buf);
831 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
833 len = GetTempPathA(0, NULL);
834 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
836 /* The call above gave us the buffer size that Windows thinks is needed
837 * so the next call should work
839 lstrcpyA(buf, "foo");
840 len = GetTempPathA(len, buf);
841 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
842 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
845 static void test_GetTempPathW(char* tmp_dir)
847 DWORD len, len_with_null;
848 WCHAR buf[MAX_PATH];
849 WCHAR tmp_dirW[MAX_PATH];
850 static const WCHAR fooW[] = {'f','o','o',0};
852 MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
853 len_with_null = lstrlenW(tmp_dirW) + 1;
855 /* This one is different from ANSI version: ANSI version doesn't
856 * touch the buffer, unicode version usually truncates the buffer
857 * to zero size. NT still exagerates the required buffer size
858 * sometimes so we cannot test for an exact match. Finally, the
859 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
860 * For instance on NT4 it will sometimes return a path without the
861 * trailing '\\' and sometimes return an error.
864 lstrcpyW(buf, fooW);
865 len = GetTempPathW(MAX_PATH, buf);
866 if (len==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
867 return;
868 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
869 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
871 lstrcpyW(buf, fooW);
872 len = GetTempPathW(1, buf);
873 ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
874 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
876 len = GetTempPathW(0, NULL);
877 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
879 lstrcpyW(buf, fooW);
880 len = GetTempPathW(len, buf);
881 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
882 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
885 static void test_GetTempPath(void)
887 char save_TMP[MAX_PATH];
888 char windir[MAX_PATH];
889 char buf[MAX_PATH];
891 GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP));
893 /* test default configuration */
894 trace("TMP=%s\n", save_TMP);
895 strcpy(buf,save_TMP);
896 if (buf[strlen(buf)-1]!='\\')
897 strcat(buf,"\\");
898 test_GetTempPathA(buf);
899 test_GetTempPathW(buf);
901 /* TMP=C:\WINDOWS */
902 GetWindowsDirectoryA(windir, sizeof(windir));
903 SetEnvironmentVariableA("TMP", windir);
904 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
905 trace("TMP=%s\n", buf);
906 strcat(windir,"\\");
907 test_GetTempPathA(windir);
908 test_GetTempPathW(windir);
910 /* TMP=C:\ */
911 GetWindowsDirectoryA(windir, sizeof(windir));
912 windir[3] = 0;
913 SetEnvironmentVariableA("TMP", windir);
914 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
915 trace("TMP=%s\n", buf);
916 test_GetTempPathA(windir);
917 test_GetTempPathW(windir);
919 /* TMP=C: i.e. use current working directory of the specified drive */
920 GetWindowsDirectoryA(windir, sizeof(windir));
921 SetCurrentDirectoryA(windir);
922 windir[2] = 0;
923 SetEnvironmentVariableA("TMP", windir);
924 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
925 trace("TMP=%s\n", buf);
926 GetWindowsDirectoryA(windir, sizeof(windir));
927 strcat(windir,"\\");
928 test_GetTempPathA(windir);
929 test_GetTempPathW(windir);
931 SetEnvironmentVariableA("TMP", save_TMP);
934 static void test_GetLongPathNameW(void)
936 DWORD length;
937 WCHAR empty[MAX_PATH];
939 /* Not present in all windows versions */
940 if(pGetLongPathNameW)
942 SetLastError(0xdeadbeef);
943 length = pGetLongPathNameW(NULL,NULL,0);
944 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
945 ok(GetLastError()==ERROR_INVALID_PARAMETER,"GetLastError returned %d but expected ERROR_INVALID_PARAMETER\n",GetLastError());
947 SetLastError(0xdeadbeef);
948 empty[0]=0;
949 length = pGetLongPathNameW(empty,NULL,0);
950 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
951 ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
955 static void test_GetSystemDirectory(void)
957 CHAR buffer[MAX_PATH + 4];
958 DWORD res;
959 DWORD total;
961 SetLastError(0xdeadbeef);
962 res = GetSystemDirectory(NULL, 0);
963 /* res includes the terminating Zero */
964 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
966 total = res;
967 #if 0
968 /* this test crash on XP */
969 res = GetSystemDirectory(NULL, total);
970 #endif
972 SetLastError(0xdeadbeef);
973 res = GetSystemDirectory(NULL, total-1);
974 /* 95+NT: total (includes the terminating Zero)
975 98+ME: 0 with ERROR_INVALID_PARAMETER */
976 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
977 "returned %d with %d (expected '%d' or: '0' with "
978 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
980 if (total > MAX_PATH) return;
982 buffer[0] = '\0';
983 SetLastError(0xdeadbeef);
984 res = GetSystemDirectory(buffer, total);
985 /* res does not include the terminating Zero */
986 ok( (res == (total-1)) && (buffer[0]),
987 "returned %d with %d and '%s' (expected '%d' and a string)\n",
988 res, GetLastError(), buffer, total-1);
990 buffer[0] = '\0';
991 SetLastError(0xdeadbeef);
992 res = GetSystemDirectory(buffer, total + 1);
993 /* res does not include the terminating Zero */
994 ok( (res == (total-1)) && (buffer[0]),
995 "returned %d with %d and '%s' (expected '%d' and a string)\n",
996 res, GetLastError(), buffer, total-1);
998 memset(buffer, '#', total + 1);
999 buffer[total + 2] = '\0';
1000 SetLastError(0xdeadbeef);
1001 res = GetSystemDirectory(buffer, total-1);
1002 /* res includes the terminating Zero) */
1003 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1004 res, GetLastError(), buffer, total);
1006 memset(buffer, '#', total + 1);
1007 buffer[total + 2] = '\0';
1008 SetLastError(0xdeadbeef);
1009 res = GetSystemDirectory(buffer, total-2);
1010 /* res includes the terminating Zero) */
1011 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1012 res, GetLastError(), buffer, total);
1015 static void test_GetWindowsDirectory(void)
1017 CHAR buffer[MAX_PATH + 4];
1018 DWORD res;
1019 DWORD total;
1021 SetLastError(0xdeadbeef);
1022 res = GetWindowsDirectory(NULL, 0);
1023 /* res includes the terminating Zero */
1024 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1026 total = res;
1027 #if 0
1028 /* this test crash on XP */
1029 res = GetWindowsDirectory(NULL, total);
1030 #endif
1032 SetLastError(0xdeadbeef);
1033 res = GetWindowsDirectory(NULL, total-1);
1034 /* 95+NT: total (includes the terminating Zero)
1035 98+ME: 0 with ERROR_INVALID_PARAMETER */
1036 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1037 "returned %d with %d (expected '%d' or: '0' with "
1038 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1040 if (total > MAX_PATH) return;
1042 buffer[0] = '\0';
1043 SetLastError(0xdeadbeef);
1044 res = GetWindowsDirectory(buffer, total);
1045 /* res does not include the terminating Zero */
1046 ok( (res == (total-1)) && (buffer[0]),
1047 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1048 res, GetLastError(), buffer, total-1);
1050 buffer[0] = '\0';
1051 SetLastError(0xdeadbeef);
1052 res = GetWindowsDirectory(buffer, total + 1);
1053 /* res does not include the terminating Zero */
1054 ok( (res == (total-1)) && (buffer[0]),
1055 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1056 res, GetLastError(), buffer, total-1);
1058 memset(buffer, '#', total + 1);
1059 buffer[total + 2] = '\0';
1060 SetLastError(0xdeadbeef);
1061 res = GetWindowsDirectory(buffer, total-1);
1062 /* res includes the terminating Zero) */
1063 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1064 res, GetLastError(), buffer, total);
1066 memset(buffer, '#', total + 1);
1067 buffer[total + 2] = '\0';
1068 SetLastError(0xdeadbeef);
1069 res = GetWindowsDirectory(buffer, total-2);
1070 /* res includes the terminating Zero) */
1071 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1072 res, GetLastError(), buffer, total);
1075 START_TEST(path)
1077 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
1078 pGetLongPathNameA = (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
1079 "GetLongPathNameA" );
1080 pGetLongPathNameW = (void*)GetProcAddress(GetModuleHandleA("kernel32.dll") ,
1081 "GetLongPathNameW" );
1082 test_InitPathA(curdir, &curDrive, &otherDrive);
1083 test_CurrentDirectoryA(origdir,curdir);
1084 test_PathNameA(curdir, curDrive, otherDrive);
1085 test_CleanupPathA(origdir,curdir);
1086 test_GetTempPath();
1087 test_GetLongPathNameW();
1088 test_GetSystemDirectory();
1089 test_GetWindowsDirectory();