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