mshtml: Print wine_gecko version in load_wine_gecko.
[wine] / dlls / kernel32 / tests / path.c
1 /*
2  * Unit test suite for Get*PathNamesA and (Get|Set)CurrentDirectoryA.
3  *
4  * Copyright 2002 Geoffrey Hausheer
5  *
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.
10  *
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.
15  *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
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"
29
30 #define HAS_TRAIL_SLASH_A(string) (string[lstrlenA(string)-1]=='\\')
31
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 "NonExistent File"
38 #define NONDIR_SHORT "notadir"
39 #define NONDIR_LONG "NonExistent Directory"
40
41 #define NOT_A_VALID_DRIVE '@'
42
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       |<>"
48 */
49 static const CHAR funny_chars[]="!@#$%^&*()=+{}[],?'`";
50 static const CHAR is_char_ok[] ="11111110111111111011";
51
52 static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR,LPSTR,DWORD);
53 static DWORD (WINAPI *pGetLongPathNameW)(LPWSTR,LPWSTR,DWORD);
54
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;
64
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
69 */
70 static void test_ValidPathA(const CHAR *curdir, const CHAR *subdir, const CHAR *filename,
71                          CHAR *shortstr, SLpassfail *passfail, const CHAR *errstr)
72 {
73   CHAR tmpstr[MAX_PATH],
74        fullpath[MAX_PATH],      /*full path to the file (not short/long) */
75        subpath[MAX_PATH],       /*relative path to the file */
76        fullpathshort[MAX_PATH], /*absolue path to the file (short format) */
77        fullpathlong[MAX_PATH],  /*absolute path to the file (long format) */
78        curdirshort[MAX_PATH],   /*absolute path to the current dir (short) */
79        curdirlong[MAX_PATH];    /*absolute path to the current dir (long) */
80   LPSTR strptr;                 /*ptr to the filename portion of the path */
81   DWORD len;
82 /* if passfail is NULL, we can perform all checks within this function,
83    otherwise, we will return the relevant data in the passfail struct, so
84    we must initialize it first
85 */
86   if(passfail!=NULL) {
87     passfail->shortlen=-1;passfail->s2llen=-1;passfail->longlen=-1;
88     passfail->shorterror=0;passfail->s2lerror=0;passfail->longerror=0;
89   }
90 /* GetLongPathNameA is only supported on Win2k+ and Win98+ */
91   if(pGetLongPathNameA) {
92     ok((len=pGetLongPathNameA(curdir,curdirlong,MAX_PATH)),
93        "%s: GetLongPathNameA failed\n",errstr);
94 /*GetLongPathNameA can return a trailing '\\' but shouldn't do so here */
95     ok(! HAS_TRAIL_SLASH_A(curdirlong),
96        "%s: GetLongPathNameA should not have a trailing \\\n",errstr);
97   }
98   ok((len=GetShortPathNameA(curdir,curdirshort,MAX_PATH)),
99      "%s: GetShortPathNameA failed\n",errstr);
100 /*GetShortPathNameA can return a trailing '\\' but shouldn't do so here */
101   ok(! HAS_TRAIL_SLASH_A(curdirshort),
102      "%s: GetShortPathNameA should not have a trailing \\\n",errstr);
103 /* build relative and absolute paths from inputs */
104   if(lstrlenA(subdir)) {
105     sprintf(subpath,"%s\\%s",subdir,filename);
106   } else {
107     lstrcpyA(subpath,filename);
108   }
109   sprintf(fullpath,"%s\\%s",curdir,subpath);
110   sprintf(fullpathshort,"%s\\%s",curdirshort,subpath);
111   sprintf(fullpathlong,"%s\\%s",curdirlong,subpath);
112 /* Test GetFullPathNameA functionality */
113   len=GetFullPathNameA(subpath,MAX_PATH,tmpstr,&strptr);
114   ok(len, "GetFullPathNameA failed for: '%s'\n",subpath);
115   if(HAS_TRAIL_SLASH_A(subpath)) {
116     ok(strptr==NULL,
117        "%s: GetFullPathNameA should not return a filename ptr\n",errstr);
118     ok(lstrcmpiA(fullpath,tmpstr)==0,
119        "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
120        errstr,tmpstr,fullpath);
121   } else {
122     ok(lstrcmpiA(strptr,filename)==0,
123        "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
124        errstr,strptr,filename);
125     ok(lstrcmpiA(fullpath,tmpstr)==0,
126        "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
127        errstr,tmpstr,fullpath);
128   }
129 /* Test GetShortPathNameA functionality */
130   SetLastError(0);
131   len=GetShortPathNameA(fullpathshort,shortstr,MAX_PATH);
132   if(passfail==NULL) {
133     ok(len, "%s: GetShortPathNameA failed\n",errstr);
134   } else {
135     passfail->shortlen=len;
136     passfail->shorterror=GetLastError();
137   }
138 /* Test GetLongPathNameA functionality
139    We test both conversion from GetFullPathNameA and from GetShortPathNameA
140 */
141   if(pGetLongPathNameA) {
142     if(len!=0) {
143       SetLastError(0);
144       len=pGetLongPathNameA(shortstr,tmpstr,MAX_PATH);
145       if(passfail==NULL) {
146         ok(len,
147           "%s: GetLongPathNameA failed during Short->Long conversion\n", errstr);
148         ok(lstrcmpiA(fullpathlong,tmpstr)==0,
149            "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
150            errstr,tmpstr,fullpathlong);
151       } else {
152         passfail->s2llen=len;
153         passfail->s2lerror=GetLastError();
154       }
155     }
156     SetLastError(0);
157     len=pGetLongPathNameA(fullpath,tmpstr,MAX_PATH);
158     if(passfail==NULL) {
159       ok(len, "%s: GetLongPathNameA failed\n",errstr);
160       if(HAS_TRAIL_SLASH_A(fullpath)) {
161         ok(lstrcmpiA(fullpathlong,tmpstr)==0,
162            "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
163            errstr,tmpstr,fullpathlong);
164       } else {
165         ok(lstrcmpiA(fullpathlong,tmpstr)==0,
166           "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
167           errstr,tmpstr,fullpathlong);
168       }
169     } else {
170       passfail->longlen=len;
171       passfail->longerror=GetLastError();
172     }
173   }
174 }
175
176 /* split path into leading directory, and 8.3 filename */
177 static void test_SplitShortPathA(CHAR *path,CHAR *dir,CHAR *eight,CHAR *three) {
178   int done,error;
179   int ext,fil;
180   int len,i;
181   len=lstrlenA(path);
182   ext=len; fil=len; done=0; error=0;
183 /* walk backwards over path looking for '.' or '\\' separators */
184   for(i=len-1;(i>=0) && (!done);i--) {
185     if(path[i]=='.')
186       if(ext!=len) error=1; else ext=i;
187     else if(path[i]=='\\') {
188       if(i==len-1) {
189         error=1;
190       } else {
191         fil=i;
192         done=1;
193       }
194     }
195   }
196 /* Check that we didn't find a trailing '\\' or multiple '.' */
197   ok(!error,"Illegal file found in 8.3 path '%s'\n",path);
198 /* Separate dir, root, and extension */
199   if(ext!=len) lstrcpyA(three,path+ext+1); else lstrcpyA(three,"");
200   if(fil!=len) {
201     lstrcpynA(eight,path+fil+1,ext-fil);
202     lstrcpynA(dir,path,fil+1);
203   } else {
204     lstrcpynA(eight,path,ext+1);
205     lstrcpyA(dir,"");
206   }
207 /* Validate that root and extension really are 8.3 */
208   ok(lstrlenA(eight)<=8 && lstrlenA(three)<=3,
209      "GetShortPathNAmeA did not return an 8.3 path\n");
210 }
211
212 /* Check that GetShortPathNameA returns a valid 8.3 path */
213 static void test_LongtoShortA(CHAR *teststr,const CHAR *goodstr,
214                               const CHAR *ext,const CHAR *errstr) {
215   CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
216
217   test_SplitShortPathA(teststr,dir,eight,three);
218   ok(lstrcmpiA(dir,goodstr)==0,
219      "GetShortPathNameA returned '%s' instead of '%s'\n",dir,goodstr);
220   ok(lstrcmpiA(three,ext)==0,
221      "GetShortPathNameA returned '%s' with incorrect extension\n",three);
222 }
223
224 /* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
225    characters in the filename.
226      'valid' indicates whether this would be an allowed filename
227      'todo' indicates that wine doesn't get this right yet.
228    NOTE: We always call this routine with a nonexistent filename, so
229          Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
230          should.
231 */
232 static void test_FunnyChars(CHAR *curdir,CHAR *curdir_short,CHAR *filename, INT valid,CHAR *errstr)
233 {
234   CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
235   SLpassfail passfail;
236
237   test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
238   if(valid) {
239     sprintf(tmpstr1,"%s\\%s",curdir_short,filename);
240       ok((passfail.shortlen==0 &&
241           (passfail.shorterror==ERROR_FILE_NOT_FOUND || passfail.shorterror==ERROR_PATH_NOT_FOUND || !passfail.shorterror)) ||
242          (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
243          "%s: GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
244          errstr,passfail.shortlen,passfail.shorterror,tmpstr);
245   } else {
246       ok(passfail.shortlen==0 &&
247          (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),
248          "%s: GetShortPathA should have failed len=%d, error=%d\n",
249          errstr,passfail.shortlen,passfail.shorterror);
250   }
251   if(pGetLongPathNameA) {
252     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
253     if(valid) {
254       ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
255          "%s: GetLongPathA returned %d and not %d\n",
256          errstr,passfail.longerror,ERROR_FILE_NOT_FOUND);
257     } else {
258       ok(passfail.longerror==ERROR_INVALID_NAME ||
259          passfail.longerror==ERROR_FILE_NOT_FOUND,
260          "%s: GetLongPathA returned %d and not %d or %d'\n",
261          errstr, passfail.longerror,ERROR_INVALID_NAME,ERROR_FILE_NOT_FOUND);
262     }
263   }
264 }
265
266 /* Routine to test that SetCurrentDirectory behaves as expected. */
267 static void test_setdir(CHAR *olddir,CHAR *newdir,
268                         CHAR *cmprstr, INT pass, const CHAR *errstr)
269 {
270   CHAR tmppath[MAX_PATH], *dirptr;
271   DWORD val,len,chklen;
272
273   val=SetCurrentDirectoryA(newdir);
274   len=GetCurrentDirectoryA(MAX_PATH,tmppath);
275 /* if 'pass' then the SetDirectoryA was supposed to pass */
276   if(pass) {
277     dirptr=(cmprstr==NULL) ? newdir : cmprstr;
278     chklen=lstrlenA(dirptr);
279     ok(val,"%s: SetCurrentDirectoryA failed\n",errstr);
280     ok(len==chklen,
281        "%s: SetCurrentDirectory did not change the directory, though it passed\n",
282        errstr);
283     ok(lstrcmpiA(dirptr,tmppath)==0,
284        "%s: SetCurrentDirectory did not change the directory, though it passed\n",
285        errstr);
286     ok(SetCurrentDirectoryA(olddir),
287        "%s: Couldn't set directory to it's original value\n",errstr);
288   } else {
289 /* else thest that it fails correctly */
290     chklen=lstrlenA(olddir);
291     ok(val==0,
292        "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr);
293     ok(len==chklen,
294        "%s: SetCurrentDirectory changed the directory, though it failed\n",
295        errstr);
296     ok(lstrcmpiA(olddir,tmppath)==0,
297        "%s: SetCurrentDirectory changed the directory, though it failed\n",
298        errstr);
299   }
300 }
301 static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
302 {
303   CHAR tmppath[MAX_PATH], /*path to TEMP */
304        tmpstr[MAX_PATH],
305        tmpstr1[MAX_PATH];
306   DWORD len,len1,drives;
307   INT id;
308   HANDLE hndl;
309   BOOL bRes;
310
311   *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
312
313 /* Get the current drive letter */
314   if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
315     *curDrive = tmpstr[0];
316   else
317     trace( "Unable to discover current drive, some tests will not be conducted.\n");
318
319 /* Test GetTempPathA */
320   len=GetTempPathA(MAX_PATH,tmppath);
321   ok(len!=0 && len < MAX_PATH,"GetTempPathA failed\n");
322   ok(HAS_TRAIL_SLASH_A(tmppath),
323      "GetTempPathA returned a path that did not end in '\\'\n");
324   lstrcpyA(tmpstr,"aaaaaaaa");
325   len1=GetTempPathA(len,tmpstr);
326   ok(len1==len+1,
327      "GetTempPathA should return string length %d instead of %d\n",len+1,len1);
328
329 /* Test GetTmpFileNameA
330    The only test we do here is whether GetTempFileNameA passes or not.
331    We do not thoroughly test this function yet (specifically, whether
332    it behaves correctly when 'unique' is non zero)
333 */
334   ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
335   sprintf(tmpstr,"pat%.4x.tmp",id & 0xffff);
336   sprintf(tmpstr1,"pat%x.tmp",id & 0xffff);
337   ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
338      lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
339      "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
340      newdir,tmpstr,tmpstr1,id);
341   ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");     
342
343   id=GetTempFileNameA(tmppath,NULL,0,newdir);
344 /* Windows 95, 98 return 0==id, while Windows 2000, XP return 0!=id */
345   if (id)
346   {
347     sprintf(tmpstr,"%.4x.tmp",id & 0xffff);
348     sprintf(tmpstr1,"%x.tmp",id & 0xffff);
349     ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
350        lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
351        "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
352        newdir,tmpstr,tmpstr1,id);
353     ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
354   }
355
356 /* Find first valid drive letter that is neither newdir[0] nor curDrive */
357   drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
358   if( *curDrive != NOT_A_VALID_DRIVE)
359     drives &= ~(1<<(*curDrive-'A'));
360   if( drives)
361     for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
362   else
363     trace( "Could not find alternative drive, some tests will not be conducted.\n");
364
365 /* Do some CreateDirectoryA tests */
366 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
367    really understand how they work.
368    More formal tests should be done along with CreateFile tests
369 */
370   ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
371   ok(CreateDirectoryA(newdir,NULL)==0,
372      "CreateDirectoryA succeeded even though a file of the same name exists\n");
373   ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
374   ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
375 /* Create some files to test other functions.  Note, we will test CreateFileA
376    at some later point
377 */
378   sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
379   ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
380   sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
381   ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
382   bRes = CreateDirectoryA("c:",NULL);
383   ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED  || 
384                GetLastError() == ERROR_ALREADY_EXISTS),
385      "CreateDirectoryA(\"c:\" should have failed (%d)\n", GetLastError());
386   bRes = CreateDirectoryA("c:\\",NULL);
387   ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED  ||
388                GetLastError() == ERROR_ALREADY_EXISTS),
389      "CreateDirectoryA(\"c:\\\" should have failed (%d)\n", GetLastError());
390   sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
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,SHORTDIR,LONGFILE);
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,SHORTFILE);
401   hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
402                    CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
403   ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
404   ok(CloseHandle(hndl),"CloseHandle failed\n");
405   sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
406   hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
407                    CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
408   ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
409   ok(CloseHandle(hndl),"CloseHandle failed\n");
410 }
411
412 /* Test GetCurrentDirectory & SetCurrentDirectory */
413 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
414 {
415   CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
416   DWORD len,len1;
417 /* Save the original directory, so that we can return to it at the end
418    of the test
419 */
420   len=GetCurrentDirectoryA(MAX_PATH,origdir);
421   ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
422 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
423    buffer size is too small to hold the current directory
424 */
425   lstrcpyA(tmpstr,"aaaaaaa");
426   len1=GetCurrentDirectoryA(len,tmpstr);
427   ok(len1==len+1, "GetCurrentDirectoryA returned %d instead of %d\n",len1,len+1);
428   ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
429      "GetCurrentDirectoryA should not have modified the buffer\n");
430 /* SetCurrentDirectoryA shouldn't care whether the string has a
431    trailing '\\' or not
432 */
433   sprintf(tmpstr,"%s\\",newdir);
434   test_setdir(origdir,tmpstr,newdir,1,"check 1");
435   test_setdir(origdir,newdir,NULL,1,"check 2");
436 /* Set the directory to the working area.  We just tested that this works,
437    so why check it again.
438 */
439   SetCurrentDirectoryA(newdir);
440 /* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
441   sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
442   test_setdir(newdir,tmpstr,NULL,0,"check 3");
443 /* Check that SetCurrentDirectory fails for a nonexistent lond directory */
444   sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
445   test_setdir(newdir,tmpstr,NULL,0,"check 4");
446 /* Check that SetCurrentDirectory passes with a long directory */
447   sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
448   test_setdir(newdir,tmpstr,NULL,1,"check 5");
449 /* Check that SetCurrentDirectory passes with a short relative directory */
450   sprintf(tmpstr,"%s",SHORTDIR);
451   sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
452   test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
453 /* starting with a '.' */
454   sprintf(tmpstr,".\\%s",SHORTDIR);
455   test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
456 /* Check that SetCurrentDirectory passes with a short relative directory */
457   sprintf(tmpstr,"%s",LONGDIR);
458   sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
459   test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
460 /* starting with a '.' */
461   sprintf(tmpstr,".\\%s",LONGDIR);
462   test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
463 }
464
465 /* Cleanup the mess we made while executing these tests */
466 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
467 {
468   CHAR tmpstr[MAX_PATH];
469   sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
470   ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
471   sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
472   ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
473   sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
474   ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
475   sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
476   ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
477   sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
478   ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
479   sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
480   ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
481   ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
482   ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
483 }
484
485 /* This routine will test Get(Full|Short|Long)PathNameA */
486 static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
487 {
488   CHAR curdir_short[MAX_PATH],
489        longdir_short[MAX_PATH];
490   CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH],tmpstr2[MAX_PATH];
491   LPSTR strptr;                 /*ptr to the filename portion of the path */
492   DWORD len;
493   INT i;
494   CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
495   SLpassfail passfail;
496
497 /* Get the short form of the current directory */
498   ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
499      "GetShortPathNameA failed\n");
500   ok(!HAS_TRAIL_SLASH_A(curdir_short),
501      "GetShortPathNameA should not have a trailing \\\n");
502 /* Get the short form of the absolute-path to LONGDIR */
503   sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
504   ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
505      "GetShortPathNameA failed\n");
506   ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
507      "GetShortPathNameA should not have a trailing \\\n");
508
509   if (pGetLongPathNameA) {
510     DWORD rc1,rc2;
511     sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
512     rc1=(*pGetLongPathNameA)(tmpstr,NULL,0);
513     rc2=(*pGetLongPathNameA)(curdir,NULL,0);
514     ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
515        "GetLongPathNameA: wrong return code, %d instead of %d\n",
516        rc1, lstrlenA(tmpstr)+1);
517
518     sprintf(dir,"%c:",curDrive);
519     rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
520     ok(strcmp(dir,tmpstr)==0,
521        "GetLongPathNameA: returned '%s' instead of '%s' (rc=%d)\n",
522        tmpstr,dir,rc1);
523   }
524
525 /* Check the cases where both file and directory exist first */
526 /* Start with a 8.3 directory, 8.3 filename */
527   test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
528   sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
529   ok(lstrcmpiA(tmpstr,tmpstr1)==0,
530      "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
531 /* Now try a 8.3 directory, long file name */
532   test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
533   sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
534   test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
535 /* Next is a long directory, 8.3 file */
536   test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
537   sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
538   ok(lstrcmpiA(tmpstr,tmpstr1)==0,
539      "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
540 /*Lastly a long directory, long file */
541   test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
542   test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
543
544 /* Now check all of the invalid file w/ valid directory combinations */
545 /* Start with a 8.3 directory, 8.3 filename */
546   test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
547   sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
548   ok((passfail.shortlen==0 &&
549       (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
550        passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
551      (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
552      "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
553      passfail.shortlen,passfail.shorterror,tmpstr);
554   if(pGetLongPathNameA) {
555     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
556     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
557        "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
558   }
559 /* Now try a 8.3 directory, long file name */
560   test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
561   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
562   ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
563      passfail.shorterror==ERROR_FILE_NOT_FOUND ||
564      !passfail.shorterror,
565      "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
566   if(pGetLongPathNameA) {
567     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
568     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
569        "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
570   }
571 /* Next is a long directory, 8.3 file */
572   test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
573   sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
574   GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
575   strcat(tmpstr1,"\\" NONFILE_SHORT);
576   ok((passfail.shortlen==0 &&
577       (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
578        passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
579      (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
580      "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
581      passfail.shortlen,passfail.shorterror,tmpstr);
582   if(pGetLongPathNameA) {
583     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
584     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
585       "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
586   }
587 /*Lastly a long directory, long file */
588   test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
589   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
590   ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
591      passfail.shorterror==ERROR_FILE_NOT_FOUND ||
592      !passfail.shorterror,
593      "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
594   if(pGetLongPathNameA) {
595     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
596     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
597        "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
598   }
599 /* Now try again with directories that don't exist */
600 /* 8.3 directory, 8.3 filename */
601   test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
602   sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
603   ok((passfail.shortlen==0 &&
604       (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
605        passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
606      (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
607      "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
608      passfail.shortlen,passfail.shorterror,tmpstr);
609   if(pGetLongPathNameA) {
610     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
611     ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
612        passfail.longerror==ERROR_FILE_NOT_FOUND,
613        "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
614        passfail.longerror);
615   }
616 /* Now try a 8.3 directory, long file name */
617   test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
618   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
619   ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
620      passfail.shorterror==ERROR_FILE_NOT_FOUND ||
621      !passfail.shorterror,
622      "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
623       passfail.shorterror);
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 /* Next is a long directory, 8.3 file */
632   test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
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 /*Lastly a long directory, long file */
647   test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
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 /* Next try directories ending with '\\' */
662 /* Existing Directories */
663   sprintf(tmpstr,"%s\\",SHORTDIR);
664   test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
665   sprintf(tmpstr,"%s\\",LONGDIR);
666   test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
667 /* Nonexistent directories */
668   sprintf(tmpstr,"%s\\",NONDIR_SHORT);
669   test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
670   sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
671   ok((passfail.shortlen==0 &&
672       (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
673        passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
674      (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
675      "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
676      passfail.shortlen,passfail.shorterror,tmpstr);
677   if(pGetLongPathNameA) {
678     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
679     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
680        "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
681        passfail.longerror);
682   }
683   sprintf(tmpstr,"%s\\",NONDIR_LONG);
684   test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
685   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
686   ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
687      passfail.shorterror==ERROR_FILE_NOT_FOUND ||
688      !passfail.shorterror,
689      "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
690       passfail.shorterror);
691   if(pGetLongPathNameA) {
692     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
693     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
694        "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
695        passfail.longerror);
696   }
697 /* Test GetFullPathNameA with drive letters */
698   if( curDrive != NOT_A_VALID_DRIVE) {
699     sprintf(tmpstr,"%c:",curdir[0]);
700     ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
701        "GetFullPathNameA(%c:) failed\n", curdir[0]);
702     GetCurrentDirectoryA(MAX_PATH,tmpstr);
703     sprintf(tmpstr1,"%s\\",tmpstr);
704     ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
705        "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
706        curdir[0],tmpstr2,tmpstr,tmpstr1);
707
708     sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
709     ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
710     ok(lstrcmpiA(tmpstr,tmpstr1)==0,
711        "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
712     ok(lstrcmpiA(SHORTFILE,strptr)==0,
713        "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
714   }
715 /* Without a leading slash, insert the current directory if on the current drive */
716   sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
717   ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
718   sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
719   ok(lstrcmpiA(tmpstr,tmpstr1)==0,
720       "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
721   ok(lstrcmpiA(SHORTFILE,strptr)==0,
722       "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
723 /* Otherwise insert the missing leading slash */
724   if( otherDrive != NOT_A_VALID_DRIVE) {
725     sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
726     ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
727     sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
728     ok(lstrcmpiA(tmpstr,tmpstr1)==0,
729        "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
730     ok(lstrcmpiA(SHORTFILE,strptr)==0,
731        "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
732   }
733 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
734    So test for them. */
735   if( curDrive != NOT_A_VALID_DRIVE) {
736     sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
737     ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
738     sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
739     ok(lstrcmpiA(tmpstr,tmpstr1)==0,
740        "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
741     ok(lstrcmpiA(SHORTFILE,strptr)==0,
742        "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
743   }
744 /**/
745   sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
746   ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
747   sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
748   ok(lstrcmpiA(tmpstr,tmpstr1)==0,
749       "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
750   ok(lstrcmpiA(SHORTFILE,strptr)==0,
751       "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
752 /* Windows will insert a drive letter in front of an absolute UNIX path */
753   sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
754   ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
755   sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
756   ok(lstrcmpiA(tmpstr,tmpstr1)==0,
757      "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
758 /* This passes in Wine because it still contains the pointer from the previous test */
759   ok(lstrcmpiA(SHORTFILE,strptr)==0,
760       "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
761
762 /* Now try some relative paths */
763   ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
764   test_SplitShortPathA(tmpstr,dir,eight,three);
765   if(pGetLongPathNameA) {
766     ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
767     ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
768        "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
769   }
770   sprintf(tmpstr,".\\%s",LONGDIR);
771   ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
772   test_SplitShortPathA(tmpstr1,dir,eight,three);
773   ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
774      "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
775   if(pGetLongPathNameA) {
776     ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
777        tmpstr);
778     ok(lstrcmpiA(tmpstr1,tmpstr)==0,
779        "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
780   }
781 /* Check out Get*PathNameA on some funny characters */
782   for(i=0;i<lstrlenA(funny_chars);i++) {
783     INT valid;
784     valid=(is_char_ok[i]=='0') ? 0 : 1;
785     sprintf(tmpstr1,"check%d-1",i);
786     sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
787     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
788     sprintf(tmpstr1,"check%d-2",i);
789     sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
790     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
791     sprintf(tmpstr1,"check%d-3",i);
792     sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
793     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
794     sprintf(tmpstr1,"check%d-4",i);
795     sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
796     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
797     sprintf(tmpstr1,"check%d-5",i);
798     sprintf(tmpstr,"Long %c File",funny_chars[i]);
799     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
800     sprintf(tmpstr1,"check%d-6",i);
801     sprintf(tmpstr,"%c Long File",funny_chars[i]);
802     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
803     sprintf(tmpstr1,"check%d-7",i);
804     sprintf(tmpstr,"Long File %c",funny_chars[i]);
805     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
806   }
807 }
808
809 static void test_GetTempPathA(char* tmp_dir)
810 {
811     DWORD len, len_with_null;
812     char buf[MAX_PATH];
813
814     len_with_null = strlen(tmp_dir) + 1;
815
816     lstrcpyA(buf, "foo");
817     len = GetTempPathA(MAX_PATH, buf);
818     ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
819     ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
820     ok(len == strlen(buf), "returned length should be equal to the length of string\n");
821
822     /* Some versions of Windows touch the buffer, some don't so we don't
823      * test that. Also, NT sometimes exagerates the required buffer size
824      * so we cannot test for an exact match. Finally, the
825      * 'len_with_null - 1' case is so buggy on Windows it's not testable.
826      * For instance in some cases Win98 returns len_with_null - 1 instead
827      * of len_with_null.
828      */
829     len = GetTempPathA(1, buf);
830     ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
831
832     len = GetTempPathA(0, NULL);
833     ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
834
835     /* The call above gave us the buffer size that Windows thinks is needed
836      * so the next call should work
837      */
838     lstrcpyA(buf, "foo");
839     len = GetTempPathA(len, buf);
840     ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
841     ok(len == strlen(buf), "returned length should be equal to the length of string\n");
842 }
843
844 static void test_GetTempPathW(char* tmp_dir)
845 {
846     DWORD len, len_with_null;
847     WCHAR buf[MAX_PATH];
848     WCHAR tmp_dirW[MAX_PATH];
849     static const WCHAR fooW[] = {'f','o','o',0};
850
851     MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
852     len_with_null = lstrlenW(tmp_dirW) + 1;
853
854     /* This one is different from ANSI version: ANSI version doesn't
855      * touch the buffer, unicode version usually truncates the buffer
856      * to zero size. NT still exagerates the required buffer size
857      * sometimes so we cannot test for an exact match. Finally, the
858      * 'len_with_null - 1' case is so buggy on Windows it's not testable.
859      * For instance on NT4 it will sometimes return a path without the
860      * trailing '\\' and sometimes return an error.
861      */
862
863     lstrcpyW(buf, fooW);
864     len = GetTempPathW(MAX_PATH, buf);
865     if (len==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
866         return;
867     ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
868     ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
869
870     lstrcpyW(buf, fooW);
871     len = GetTempPathW(1, buf);
872     ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
873     ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
874
875     len = GetTempPathW(0, NULL);
876     ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
877
878     lstrcpyW(buf, fooW);
879     len = GetTempPathW(len, buf);
880     ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
881     ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
882 }
883
884 static void test_GetTempPath(void)
885 {
886     char save_TMP[MAX_PATH];
887     char windir[MAX_PATH];
888     char buf[MAX_PATH];
889
890     GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP));
891
892     /* test default configuration */
893     trace("TMP=%s\n", save_TMP);
894     strcpy(buf,save_TMP);
895     if (buf[strlen(buf)-1]!='\\')
896         strcat(buf,"\\");
897     test_GetTempPathA(buf);
898     test_GetTempPathW(buf);
899
900     /* TMP=C:\WINDOWS */
901     GetWindowsDirectoryA(windir, sizeof(windir));
902     SetEnvironmentVariableA("TMP", windir);
903     GetEnvironmentVariableA("TMP", buf, sizeof(buf));
904     trace("TMP=%s\n", buf);
905     strcat(windir,"\\");
906     test_GetTempPathA(windir);
907     test_GetTempPathW(windir);
908
909     /* TMP=C:\ */
910     GetWindowsDirectoryA(windir, sizeof(windir));
911     windir[3] = 0;
912     SetEnvironmentVariableA("TMP", windir);
913     GetEnvironmentVariableA("TMP", buf, sizeof(buf));
914     trace("TMP=%s\n", buf);
915     test_GetTempPathA(windir);
916     test_GetTempPathW(windir);
917
918     /* TMP=C: i.e. use current working directory of the specified drive */
919     GetWindowsDirectoryA(windir, sizeof(windir));
920     SetCurrentDirectoryA(windir);
921     windir[2] = 0;
922     SetEnvironmentVariableA("TMP", windir);
923     GetEnvironmentVariableA("TMP", buf, sizeof(buf));
924     trace("TMP=%s\n", buf);
925     GetWindowsDirectoryA(windir, sizeof(windir));
926     strcat(windir,"\\");
927     test_GetTempPathA(windir);
928     test_GetTempPathW(windir);
929
930     SetEnvironmentVariableA("TMP", save_TMP);
931 }
932
933 static void test_GetLongPathNameW(void)
934 {
935     DWORD length; 
936     WCHAR empty[MAX_PATH];
937
938     SetLastError(0xdeadbeef); 
939     length = pGetLongPathNameW(NULL,NULL,0);
940     if(pGetLongPathNameW) 
941     {
942     ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
943     ok(GetLastError()==ERROR_INVALID_PARAMETER,"GetLastError returned %x but expected ERROR_INVALID_PARAMETER\n",GetLastError());
944
945     SetLastError(0xdeadbeef); 
946     empty[0]=0;
947     length = pGetLongPathNameW(empty,NULL,0);
948     ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
949     ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %x but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
950     }
951 }
952
953 START_TEST(path)
954 {
955     CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
956     pGetLongPathNameA = (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
957                                                "GetLongPathNameA" );
958     pGetLongPathNameW = (void*)GetProcAddress(GetModuleHandleA("kernel32.dll") ,
959                                                "GetLongPathNameW" );
960     test_InitPathA(curdir, &curDrive, &otherDrive);
961     test_CurrentDirectoryA(origdir,curdir);
962     test_PathNameA(curdir, curDrive, otherDrive);
963     test_CleanupPathA(origdir,curdir);
964     test_GetTempPath();
965     test_GetLongPathNameW();
966 }