wined3d: Implement more GLSL instructions and a little cleanup.
[wine] / dlls / kernel / 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
54 /* a structure to deal with wine todos somewhat cleanly */
55 typedef struct {
56   DWORD shortlen;
57   DWORD shorterror;
58   DWORD s2llen;
59   DWORD s2lerror;
60   DWORD longlen;
61   DWORD longerror;
62 } SLpassfail;
63
64 /* function that tests GetFullPathNameA, GetShortPathNameA,GetLongPathNameA */
65 /* NOTE: the passfail structure is used to allow cutomizeable todo checking
66          for wine.  It is not very pretty, but it sure beats duplicating this
67          function lots of times
68 */
69 static void test_ValidPathA(const CHAR *curdir, const CHAR *subdir, const CHAR *filename,
70                          CHAR *shortstr, SLpassfail *passfail, const CHAR *errstr)
71 {
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
84 */
85   if(passfail!=NULL) {
86     passfail->shortlen=-1;passfail->s2llen=-1;passfail->longlen=-1;
87     passfail->shorterror=0;passfail->s2lerror=0;passfail->longerror=0;
88   }
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);
96   }
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);
107   }
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);
127   }
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();
136   }
137 /* Test GetLongPathNameA functionality
138    We test both conversion from GetFullPathNameA and from GetShortPathNameA
139 */
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();
153       }
154     }
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);
167       }
168     } else {
169       passfail->longlen=len;
170       passfail->longerror=GetLastError();
171     }
172   }
173 }
174
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;
192       }
193     }
194   }
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,"");
205   }
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");
209 }
210
211 /* Check that GetShortPathNameA returns a valid 8.3 path */
212 static void test_LongtoShortA(CHAR *teststr,const CHAR *goodstr,
213                               const CHAR *ext,const CHAR *errstr) {
214   CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
215
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);
221 }
222
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 nonexistent filename, so
228          Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
229          should.
230 */
231 static void test_FunnyChars(CHAR *curdir,CHAR *curdir_short,CHAR *filename, INT valid,CHAR *errstr)
232 {
233   CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
234   SLpassfail passfail;
235
236   test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
237   if(valid) {
238     sprintf(tmpstr1,"%s\\%s",curdir_short,filename);
239       ok((passfail.shortlen==0 &&
240           (passfail.shorterror==ERROR_FILE_NOT_FOUND || passfail.shorterror==ERROR_PATH_NOT_FOUND || !passfail.shorterror)) ||
241          (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
242          "%s: GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
243          errstr,passfail.shortlen,passfail.shorterror,tmpstr);
244   } else {
245       ok(passfail.shortlen==0 &&
246          (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),
247          "%s: GetShortPathA should have failed len=%ld, error=%ld\n",
248          errstr,passfail.shortlen,passfail.shorterror);
249   }
250   if(pGetLongPathNameA) {
251     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
252     if(valid) {
253       ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
254          "%s: GetLongPathA returned %ld and not %d\n",
255          errstr,passfail.longerror,ERROR_FILE_NOT_FOUND);
256     } else {
257       ok(passfail.longerror==ERROR_INVALID_NAME ||
258          passfail.longerror==ERROR_FILE_NOT_FOUND,
259          "%s: GetLongPathA returned %ld and not %d or %d'\n",
260          errstr, passfail.longerror,ERROR_INVALID_NAME,ERROR_FILE_NOT_FOUND);
261     }
262   }
263 }
264
265 /* Routine to test that SetCurrentDirectory behaves as expected. */
266 static void test_setdir(CHAR *olddir,CHAR *newdir,
267                         CHAR *cmprstr, INT pass, const CHAR *errstr)
268 {
269   CHAR tmppath[MAX_PATH], *dirptr;
270   DWORD val,len,chklen;
271
272   val=SetCurrentDirectoryA(newdir);
273   len=GetCurrentDirectoryA(MAX_PATH,tmppath);
274 /* if 'pass' then the SetDirectoryA was supposed to pass */
275   if(pass) {
276     dirptr=(cmprstr==NULL) ? newdir : cmprstr;
277     chklen=lstrlenA(dirptr);
278     ok(val,"%s: SetCurrentDirectoryA failed\n",errstr);
279     ok(len==chklen,
280        "%s: SetCurrentDirectory did not change the directory, though it passed\n",
281        errstr);
282     ok(lstrcmpiA(dirptr,tmppath)==0,
283        "%s: SetCurrentDirectory did not change the directory, though it passed\n",
284        errstr);
285     ok(SetCurrentDirectoryA(olddir),
286        "%s: Couldn't set directory to it's original value\n",errstr);
287   } else {
288 /* else thest that it fails correctly */
289     chklen=lstrlenA(olddir);
290     ok(val==0,
291        "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr);
292     ok(len==chklen,
293        "%s: SetCurrentDirectory changed the directory, though it failed\n",
294        errstr);
295     ok(lstrcmpiA(olddir,tmppath)==0,
296        "%s: SetCurrentDirectory changed the directory, though it failed\n",
297        errstr);
298   }
299 }
300 static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
301 {
302   CHAR tmppath[MAX_PATH], /*path to TEMP */
303        tmpstr[MAX_PATH],
304        tmpstr1[MAX_PATH];
305   DWORD len,len1,drives;
306   INT id;
307   HANDLE hndl;
308   BOOL bRes;
309
310   *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
311
312 /* Get the current drive letter */
313   if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
314     *curDrive = tmpstr[0];
315   else
316     trace( "Unable to discover current drive, some tests will not be conducted.\n");
317
318 /* Test GetTempPathA */
319   len=GetTempPathA(MAX_PATH,tmppath);
320   ok(len!=0 && len < MAX_PATH,"GetTempPathA failed\n");
321   ok(HAS_TRAIL_SLASH_A(tmppath),
322      "GetTempPathA returned a path that did not end in '\\'\n");
323   lstrcpyA(tmpstr,"aaaaaaaa");
324   len1=GetTempPathA(len,tmpstr);
325   ok(len1==len+1,
326      "GetTempPathA should return string length %ld instead of %ld\n",len+1,len1);
327
328 /* Test GetTmpFileNameA
329    The only test we do here is whether GetTempFileNameA passes or not.
330    We do not thoroughly test this function yet (specifically, whether
331    it behaves correctly when 'unique' is non zero)
332 */
333   ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
334   sprintf(tmpstr,"pat%.4x.tmp",id & 0xffff);
335   sprintf(tmpstr1,"pat%x.tmp",id & 0xffff);
336   ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
337      lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
338      "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
339      newdir,tmpstr,tmpstr1,id);
340   ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");     
341
342   id=GetTempFileNameA(tmppath,NULL,0,newdir);
343 /* Windows 95, 98 return 0==id, while Windows 2000, XP return 0!=id */
344   if (id)
345   {
346     sprintf(tmpstr,"%.4x.tmp",id & 0xffff);
347     sprintf(tmpstr1,"%x.tmp",id & 0xffff);
348     ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
349        lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
350        "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
351        newdir,tmpstr,tmpstr1,id);
352     ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
353   }
354
355 /* Find first valid drive letter that is neither newdir[0] nor curDrive */
356   drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
357   if( *curDrive != NOT_A_VALID_DRIVE)
358     drives &= ~(1<<(*curDrive-'A'));
359   if( drives)
360     for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
361   else
362     trace( "Could not find alternative drive, some tests will not be conducted.\n");
363
364 /* Do some CreateDirectoryA tests */
365 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
366    really understand how they work.
367    More formal tests should be done along with CreateFile tests
368 */
369   ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
370   ok(CreateDirectoryA(newdir,NULL)==0,
371      "CreateDirectoryA succeeded even though a file of the same name exists\n");
372   ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
373   ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
374 /* Create some files to test other functions.  Note, we will test CreateFileA
375    at some later point
376 */
377   sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
378   ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
379   sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
380   ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
381   bRes = CreateDirectoryA("c:",NULL);
382   ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED  || 
383                GetLastError() == ERROR_ALREADY_EXISTS),
384      "CreateDirectoryA(\"c:\" should have failed (%ld)\n", GetLastError());
385   bRes = CreateDirectoryA("c:\\",NULL);
386   ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED  ||
387                GetLastError() == ERROR_ALREADY_EXISTS),
388      "CreateDirectoryA(\"c:\\\" should have failed (%ld)\n", GetLastError());
389   sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
390   hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
391                    CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
392   ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
393   ok(CloseHandle(hndl),"CloseHandle failed\n");
394   sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
395   hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
396                    CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
397   ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
398   ok(CloseHandle(hndl),"CloseHandle failed\n");
399   sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
400   hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
401                    CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
402   ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
403   ok(CloseHandle(hndl),"CloseHandle failed\n");
404   sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
405   hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
406                    CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
407   ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
408   ok(CloseHandle(hndl),"CloseHandle failed\n");
409 }
410
411 /* Test GetCurrentDirectory & SetCurrentDirectory */
412 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
413 {
414   CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
415   DWORD len,len1;
416 /* Save the original directory, so that we can return to it at the end
417    of the test
418 */
419   len=GetCurrentDirectoryA(MAX_PATH,origdir);
420   ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
421 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
422    buffer size is too small to hold the current directory
423 */
424   lstrcpyA(tmpstr,"aaaaaaa");
425   len1=GetCurrentDirectoryA(len,tmpstr);
426   ok(len1==len+1, "GetCurrentDirectoryA returned %ld instead of %ld\n",len1,len+1);
427   ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
428      "GetCurrentDirectoryA should not have modified the buffer\n");
429 /* SetCurrentDirectoryA shouldn't care whether the string has a
430    trailing '\\' or not
431 */
432   sprintf(tmpstr,"%s\\",newdir);
433   test_setdir(origdir,tmpstr,newdir,1,"check 1");
434   test_setdir(origdir,newdir,NULL,1,"check 2");
435 /* Set the directory to the working area.  We just tested that this works,
436    so why check it again.
437 */
438   SetCurrentDirectoryA(newdir);
439 /* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
440   sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
441   test_setdir(newdir,tmpstr,NULL,0,"check 3");
442 /* Check that SetCurrentDirectory fails for a nonexistent lond directory */
443   sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
444   test_setdir(newdir,tmpstr,NULL,0,"check 4");
445 /* Check that SetCurrentDirectory passes with a long directory */
446   sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
447   test_setdir(newdir,tmpstr,NULL,1,"check 5");
448 /* Check that SetCurrentDirectory passes with a short relative directory */
449   sprintf(tmpstr,"%s",SHORTDIR);
450   sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
451   test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
452 /* starting with a '.' */
453   sprintf(tmpstr,".\\%s",SHORTDIR);
454   test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
455 /* Check that SetCurrentDirectory passes with a short relative directory */
456   sprintf(tmpstr,"%s",LONGDIR);
457   sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
458   test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
459 /* starting with a '.' */
460   sprintf(tmpstr,".\\%s",LONGDIR);
461   test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
462 }
463
464 /* Cleanup the mess we made while executing these tests */
465 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
466 {
467   CHAR tmpstr[MAX_PATH];
468   sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
469   ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
470   sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
471   ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
472   sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
473   ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
474   sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
475   ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
476   sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
477   ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
478   sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
479   ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
480   ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
481   ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
482 }
483
484 /* This routine will test Get(Full|Short|Long)PathNameA */
485 static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
486 {
487   CHAR curdir_short[MAX_PATH],
488        longdir_short[MAX_PATH];
489   CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH],tmpstr2[MAX_PATH];
490   LPSTR strptr;                 /*ptr to the filename portion of the path */
491   DWORD len;
492   INT i;
493   CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
494   SLpassfail passfail;
495
496 /* Get the short form of the current directory */
497   ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
498      "GetShortPathNameA failed\n");
499   ok(!HAS_TRAIL_SLASH_A(curdir_short),
500      "GetShortPathNameA should not have a trailing \\\n");
501 /* Get the short form of the absolute-path to LONGDIR */
502   sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
503   ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
504      "GetShortPathNameA failed\n");
505   ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
506      "GetShortPathNameA should not have a trailing \\\n");
507
508   if (pGetLongPathNameA) {
509     DWORD rc1,rc2;
510     sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
511     rc1=(*pGetLongPathNameA)(tmpstr,NULL,0);
512     rc2=(*pGetLongPathNameA)(curdir,NULL,0);
513     ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
514        "GetLongPathNameA: wrong return code, %ld instead of %d\n",
515        rc1, lstrlenA(tmpstr)+1);
516
517     sprintf(dir,"%c:",curDrive);
518     rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
519     ok(strcmp(dir,tmpstr)==0,
520        "GetLongPathNameA: returned '%s' instead of '%s' (rc=%ld)\n",
521        tmpstr,dir,rc1);
522   }
523
524 /* Check the cases where both file and directory exist first */
525 /* Start with a 8.3 directory, 8.3 filename */
526   test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
527   sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
528   ok(lstrcmpiA(tmpstr,tmpstr1)==0,
529      "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
530 /* Now try a 8.3 directory, long file name */
531   test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
532   sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
533   test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
534 /* Next is a long directory, 8.3 file */
535   test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
536   sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
537   ok(lstrcmpiA(tmpstr,tmpstr1)==0,
538      "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
539 /*Lastly a long directory, long file */
540   test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
541   test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
542
543 /* Now check all of the invalid file w/ valid directory combinations */
544 /* Start with a 8.3 directory, 8.3 filename */
545   test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
546   sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
547   ok((passfail.shortlen==0 &&
548       (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
549        passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
550      (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
551      "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
552      passfail.shortlen,passfail.shorterror,tmpstr);
553   if(pGetLongPathNameA) {
554     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
555     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
556        "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
557   }
558 /* Now try a 8.3 directory, long file name */
559   test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
560   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
561   ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
562      passfail.shorterror==ERROR_FILE_NOT_FOUND ||
563      !passfail.shorterror,
564      "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
565   if(pGetLongPathNameA) {
566     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
567     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
568        "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
569   }
570 /* Next is a long directory, 8.3 file */
571   test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
572   sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
573   GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
574   strcat(tmpstr1,"\\" NONFILE_SHORT);
575   ok((passfail.shortlen==0 &&
576       (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
577        passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
578      (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
579      "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
580      passfail.shortlen,passfail.shorterror,tmpstr);
581   if(pGetLongPathNameA) {
582     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
583     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
584       "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
585   }
586 /*Lastly a long directory, long file */
587   test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
588   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
589   ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
590      passfail.shorterror==ERROR_FILE_NOT_FOUND ||
591      !passfail.shorterror,
592      "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
593   if(pGetLongPathNameA) {
594     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
595     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
596        "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
597   }
598 /* Now try again with directories that don't exist */
599 /* 8.3 directory, 8.3 filename */
600   test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
601   sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
602   ok((passfail.shortlen==0 &&
603       (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
604        passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
605      (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
606      "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
607      passfail.shortlen,passfail.shorterror,tmpstr);
608   if(pGetLongPathNameA) {
609     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
610     ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
611        passfail.longerror==ERROR_FILE_NOT_FOUND,
612        "GetLongPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
613        passfail.longerror);
614   }
615 /* Now try a 8.3 directory, long file name */
616   test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
617   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
618   ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
619      passfail.shorterror==ERROR_FILE_NOT_FOUND ||
620      !passfail.shorterror,
621      "GetShortPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
622       passfail.shorterror);
623   if(pGetLongPathNameA) {
624     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
625     ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
626        passfail.longerror==ERROR_FILE_NOT_FOUND,
627        "GetLongPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
628        passfail.longerror);
629   }
630 /* Next is a long directory, 8.3 file */
631   test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
632   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
633   ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
634      passfail.shorterror==ERROR_FILE_NOT_FOUND ||
635      !passfail.shorterror,
636      "GetShortPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
637       passfail.shorterror);
638   if(pGetLongPathNameA) {
639     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
640     ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
641        passfail.longerror==ERROR_FILE_NOT_FOUND,
642        "GetLongPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
643        passfail.longerror);
644   }
645 /*Lastly a long directory, long file */
646   test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
647   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
648   ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
649      passfail.shorterror==ERROR_FILE_NOT_FOUND ||
650      !passfail.shorterror,
651      "GetShortPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
652       passfail.shorterror);
653   if(pGetLongPathNameA) {
654     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
655     ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
656        passfail.longerror==ERROR_FILE_NOT_FOUND,
657        "GetLongPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
658        passfail.longerror);
659   }
660 /* Next try directories ending with '\\' */
661 /* Existing Directories */
662   sprintf(tmpstr,"%s\\",SHORTDIR);
663   test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
664   sprintf(tmpstr,"%s\\",LONGDIR);
665   test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
666 /* Nonexistent directories */
667   sprintf(tmpstr,"%s\\",NONDIR_SHORT);
668   test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
669   sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
670   ok((passfail.shortlen==0 &&
671       (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
672        passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
673      (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
674      "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
675      passfail.shortlen,passfail.shorterror,tmpstr);
676   if(pGetLongPathNameA) {
677     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
678     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
679        "GetLongPathA returned %ld and not 'ERROR_FILE_NOT_FOUND'\n",
680        passfail.longerror);
681   }
682   sprintf(tmpstr,"%s\\",NONDIR_LONG);
683   test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
684   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
685   ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
686      passfail.shorterror==ERROR_FILE_NOT_FOUND ||
687      !passfail.shorterror,
688      "GetShortPathA returned %ld and not 'ERROR_FILE_NOT_FOUND'\n",
689       passfail.shorterror);
690   if(pGetLongPathNameA) {
691     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
692     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
693        "GetLongPathA returned %ld and not 'ERROR_FILE_NOT_FOUND'\n",
694        passfail.longerror);
695   }
696 /* Test GetFullPathNameA with drive letters */
697   if( curDrive != NOT_A_VALID_DRIVE) {
698     sprintf(tmpstr,"%c:",curdir[0]);
699     ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
700        "GetFullPathNameA(%c:) failed\n", curdir[0]);
701     GetCurrentDirectoryA(MAX_PATH,tmpstr);
702     sprintf(tmpstr1,"%s\\",tmpstr);
703     ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
704        "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
705        curdir[0],tmpstr2,tmpstr,tmpstr1);
706
707     sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
708     ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
709     ok(lstrcmpiA(tmpstr,tmpstr1)==0,
710        "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
711     ok(lstrcmpiA(SHORTFILE,strptr)==0,
712        "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
713   }
714 /* Without a leading slash, insert the current directory if on the current drive */
715   sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
716   ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
717   sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
718   ok(lstrcmpiA(tmpstr,tmpstr1)==0,
719       "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
720   ok(lstrcmpiA(SHORTFILE,strptr)==0,
721       "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
722 /* Otherwise insert the missing leading slash */
723   if( otherDrive != NOT_A_VALID_DRIVE) {
724     sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
725     ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
726     sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
727     ok(lstrcmpiA(tmpstr,tmpstr1)==0,
728        "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
729     ok(lstrcmpiA(SHORTFILE,strptr)==0,
730        "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
731   }
732 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
733    So test for them. */
734   if( curDrive != NOT_A_VALID_DRIVE) {
735     sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
736     ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
737     sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
738     ok(lstrcmpiA(tmpstr,tmpstr1)==0,
739        "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
740     ok(lstrcmpiA(SHORTFILE,strptr)==0,
741        "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
742   }
743 /**/
744   sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
745   ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
746   sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
747   ok(lstrcmpiA(tmpstr,tmpstr1)==0,
748       "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
749   ok(lstrcmpiA(SHORTFILE,strptr)==0,
750       "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
751 /* Windows will insert a drive letter in front of an absolute UNIX path */
752   sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
753   ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
754   sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
755   ok(lstrcmpiA(tmpstr,tmpstr1)==0,
756      "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
757 /* This passes in Wine because it still contains the pointer from the previous test */
758   ok(lstrcmpiA(SHORTFILE,strptr)==0,
759       "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
760
761 /* Now try some relative paths */
762   ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
763   test_SplitShortPathA(tmpstr,dir,eight,three);
764   if(pGetLongPathNameA) {
765     ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
766     ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
767        "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
768   }
769   sprintf(tmpstr,".\\%s",LONGDIR);
770   ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
771   test_SplitShortPathA(tmpstr1,dir,eight,three);
772   ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
773      "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
774   if(pGetLongPathNameA) {
775     ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
776        tmpstr);
777     ok(lstrcmpiA(tmpstr1,tmpstr)==0,
778        "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
779   }
780 /* Check out Get*PathNameA on some funny characters */
781   for(i=0;i<lstrlenA(funny_chars);i++) {
782     INT valid;
783     valid=(is_char_ok[i]=='0') ? 0 : 1;
784     sprintf(tmpstr1,"check%d-1",i);
785     sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
786     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
787     sprintf(tmpstr1,"check%d-2",i);
788     sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
789     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
790     sprintf(tmpstr1,"check%d-3",i);
791     sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
792     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
793     sprintf(tmpstr1,"check%d-4",i);
794     sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
795     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
796     sprintf(tmpstr1,"check%d-5",i);
797     sprintf(tmpstr,"Long %c File",funny_chars[i]);
798     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
799     sprintf(tmpstr1,"check%d-6",i);
800     sprintf(tmpstr,"%c Long File",funny_chars[i]);
801     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
802     sprintf(tmpstr1,"check%d-7",i);
803     sprintf(tmpstr,"Long File %c",funny_chars[i]);
804     test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
805   }
806 }
807
808 static void test_GetTempPathA(char* tmp_dir)
809 {
810     DWORD len, len_with_null;
811     char buf[MAX_PATH];
812
813     len_with_null = strlen(tmp_dir) + 1;
814
815     lstrcpyA(buf, "foo");
816     len = GetTempPathA(MAX_PATH, buf);
817     ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
818     ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
819     ok(len == strlen(buf), "returned length should be equal to the length of string\n");
820
821     /* Some versions of Windows touch the buffer, some don't so we don't
822      * test that. Also, NT sometimes exagerates the required buffer size
823      * so we cannot test for an exact match. Finally, the
824      * 'len_with_null - 1' case is so buggy on Windows it's not testable.
825      * For instance in some cases Win98 returns len_with_null - 1 instead
826      * of len_with_null.
827      */
828     len = GetTempPathA(1, buf);
829     ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
830
831     len = GetTempPathA(0, NULL);
832     ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
833
834     /* The call above gave us the buffer size that Windows thinks is needed
835      * so the next call should work
836      */
837     lstrcpyA(buf, "foo");
838     len = GetTempPathA(len, buf);
839     ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
840     ok(len == strlen(buf), "returned length should be equal to the length of string\n");
841 }
842
843 static void test_GetTempPathW(char* tmp_dir)
844 {
845     DWORD len, len_with_null;
846     WCHAR buf[MAX_PATH];
847     WCHAR tmp_dirW[MAX_PATH];
848     static const WCHAR fooW[] = {'f','o','o',0};
849
850     MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
851     len_with_null = lstrlenW(tmp_dirW) + 1;
852
853     /* This one is different from ANSI version: ANSI version doesn't
854      * touch the buffer, unicode version usually truncates the buffer
855      * to zero size. NT still exagerates the required buffer size
856      * sometimes so we cannot test for an exact match. Finally, the
857      * 'len_with_null - 1' case is so buggy on Windows it's not testable.
858      * For instance on NT4 it will sometimes return a path without the
859      * trailing '\\' and sometimes return an error.
860      */
861
862     lstrcpyW(buf, fooW);
863     len = GetTempPathW(MAX_PATH, buf);
864     if (len==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
865         return;
866     ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
867     ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
868
869     lstrcpyW(buf, fooW);
870     len = GetTempPathW(1, buf);
871     ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
872     ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
873
874     len = GetTempPathW(0, NULL);
875     ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
876
877     lstrcpyW(buf, fooW);
878     len = GetTempPathW(len, buf);
879     ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
880     ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
881 }
882
883 static void test_GetTempPath(void)
884 {
885     char save_TMP[MAX_PATH];
886     char windir[MAX_PATH];
887     char buf[MAX_PATH];
888
889     GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP));
890
891     /* test default configuration */
892     trace("TMP=%s\n", save_TMP);
893     strcpy(buf,save_TMP);
894     if (buf[strlen(buf)-1]!='\\')
895         strcat(buf,"\\");
896     test_GetTempPathA(buf);
897     test_GetTempPathW(buf);
898
899     /* TMP=C:\WINDOWS */
900     GetWindowsDirectoryA(windir, sizeof(windir));
901     SetEnvironmentVariableA("TMP", windir);
902     GetEnvironmentVariableA("TMP", buf, sizeof(buf));
903     trace("TMP=%s\n", buf);
904     strcat(windir,"\\");
905     test_GetTempPathA(windir);
906     test_GetTempPathW(windir);
907
908     /* TMP=C:\ */
909     GetWindowsDirectoryA(windir, sizeof(windir));
910     windir[3] = 0;
911     SetEnvironmentVariableA("TMP", windir);
912     GetEnvironmentVariableA("TMP", buf, sizeof(buf));
913     trace("TMP=%s\n", buf);
914     test_GetTempPathA(windir);
915     test_GetTempPathW(windir);
916
917     /* TMP=C: i.e. use current working directory of the specified drive */
918     GetWindowsDirectoryA(windir, sizeof(windir));
919     SetCurrentDirectoryA(windir);
920     windir[2] = 0;
921     SetEnvironmentVariableA("TMP", windir);
922     GetEnvironmentVariableA("TMP", buf, sizeof(buf));
923     trace("TMP=%s\n", buf);
924     GetWindowsDirectoryA(windir, sizeof(windir));
925     strcat(windir,"\\");
926     test_GetTempPathA(windir);
927     test_GetTempPathW(windir);
928
929     SetEnvironmentVariableA("TMP", save_TMP);
930 }
931
932 START_TEST(path)
933 {
934     CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
935     pGetLongPathNameA = (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
936                                                "GetLongPathNameA" );
937     test_InitPathA(curdir, &curDrive, &otherDrive);
938     test_CurrentDirectoryA(origdir,curdir);
939     test_PathNameA(curdir, curDrive, otherDrive);
940     test_CleanupPathA(origdir,curdir);
941     test_GetTempPath();
942 }