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