Faster serial speed cases for non Linux systems.
[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 WIN2K_PLUS(version) (version.dwMajorVersion==5)
28 #define WIN98_PLUS(version) (version.dwMajorVersion==4 && \
29                              version.dwMajorVersion>0)
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 "Non Existant File"
38 #define NONDIR_SHORT "notadir"
39 #define NONDIR_LONG "Non Existant Directory"
40
41 OSVERSIONINFOA version;
42 /* the following characters don't work well with GetFullPathNameA
43    in Win98.  I don't know if this is a FAT thing, or if it is an OS thing
44    but I don't test these characters now.
45    NOTE: Win2k allows GetFullPathNameA to work with them though
46       |<>
47 */
48 const CHAR funny_chars[]="!@#$%^&*()=+{}[],?'`\"";
49 const CHAR is_char_ok[] ="111111101111111110110";
50 const CHAR wine_todo[]  ="111111101100110000110";
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(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
88     ok((len=GetLongPathNameA(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(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
141     if(len==0) {
142       SetLastError(0);
143       len=GetLongPathNameA(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=GetLongPathNameA(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 %d 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 %d 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 %d 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 %d and not %d or %d",
274          errstr,passfail.shorterror,ERROR_INVALID_NAME,ERROR_FILE_NOT_FOUND);
275     }
276   }
277   if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
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 %d 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 %d 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");
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 directrory, though it failed",
321        errstr);
322     ok(lstrcmpiA(olddir,tmppath)==0,
323        "%s: SetCurrentDirectory changed the directrory, though it failed",
324        errstr);
325   }
326 }
327 static void test_InitPathA(CHAR *newdir)
328 {
329   CHAR tmppath[MAX_PATH], /*path to TEMP */
330        tmpstr[MAX_PATH],
331        tmpstr1[MAX_PATH];
332   DWORD len,len1;
333   INT id;
334   HANDLE hndl;
335
336 /* Test GetTempPathA */
337   len=GetTempPathA(MAX_PATH,tmppath);
338   ok(len!=0 && len < MAX_PATH,"GetTempPathA failed");
339   ok(HAS_TRAIL_SLASH_A(tmppath),
340      "GetTempPathA returned a path that did not end in '\\'");
341   lstrcpyA(tmpstr,"aaaaaaaa");
342   len1=GetTempPathA(len,tmpstr);
343   ok(len1==len+1,
344      "GetTempPathA should return string length %d instead of %d",len+1,len1);
345   if(WIN2K_PLUS(version)) {
346 /* in Win2k, the path won't be modified, but in win98, wine  it is */
347     todo_wine {
348       ok(lstrcmpiA(tmpstr,"aaaaaaaa")==0,
349          "GetTempPathA should not have modified the buffer");
350     }
351   }
352 /* Test GetTmpFileNameA 
353    The only test we do here is whether GetTempFileNameA passes or not.
354    We do not thoroughly test this function yet (specifically, whether
355    it behaves correctly when 'unique' is non zero)
356 */
357   ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed");
358   sprintf(tmpstr,"pat%.4x.tmp",id);
359   sprintf(tmpstr1,"pat%x.tmp",id);
360   ok(lstrcmpiA(newdir+(lstrlenA(newdir)-lstrlenA(tmpstr)),tmpstr)==0 ||
361      lstrcmpiA(newdir+(lstrlenA(newdir)-lstrlenA(tmpstr1)),tmpstr1)==0,
362      "GetTempPath returned '%s' which doesn't match '%s' or '%s'",
363      newdir,tmpstr,tmpstr1);
364  
365 /* Do some CreateDirectoryA tests */
366 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
367    really understand how they work.
368    More formal tests should be done along with CreateFile tests
369 */
370   ok(CreateDirectoryA(newdir,NULL)==0,
371      "CreateDirectoryA succeeded even though a file of the same name exists");
372   ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created");
373   ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed");
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");
379   sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
380   ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed");
381   sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
382   hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
383                    CREATE_NEW,FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
384   ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed");
385   ok(CloseHandle(hndl),"CloseHandle failed");
386   sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
387   hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
388                    CREATE_NEW,FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
389   ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed");
390   ok(CloseHandle(hndl),"CloseHandle failed");
391   sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
392   hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
393                    CREATE_NEW,FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
394   ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed");
395   ok(CloseHandle(hndl),"CloseHandle failed");
396   sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
397   hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
398                    CREATE_NEW,FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
399   ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed");
400   ok(CloseHandle(hndl),"CloseHandle failed");
401 }
402
403 /* Test GetCurrentDirectory & SetCurrentDirectory */
404 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
405 {
406   CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
407   DWORD len,len1;
408 /* Save the original directory, so that we can return to it at the end
409    of the test
410 */
411   len=GetCurrentDirectoryA(MAX_PATH,origdir);
412   ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed");
413   ok(lstrcmpiA(origdir+(len-1),"\\")!=0,
414      "GetCurrentDirectoryA should not have a trailing \\");
415 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
416    buffer size is too small to hold the current directory
417 */
418   lstrcpyA(tmpstr,"aaaaaaa");
419   len1=GetCurrentDirectoryA(len,tmpstr);
420   ok(len1==len+1, "GetCurrentDirectoryA returned %d instead of %d",len1,len+1);
421   ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
422      "GetCurrentDirectoryA should not have modified the buffer");
423 /* SetCurrentDirectoryA shouldn't care whether the string has a 
424    trailing '\\' or not
425 */
426   sprintf(tmpstr,"%s\\",newdir);
427   test_setdir(origdir,tmpstr,newdir,1,"check 1");
428   test_setdir(origdir,newdir,NULL,1,"check 2");
429 /* Set the directory to the working area.  We just tested that this works, 
430    so why check it again.
431 */
432   SetCurrentDirectoryA(newdir);
433 /* Check that SetCurrentDirectory fails when a non-existant dir is specified */
434   sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
435   test_setdir(newdir,tmpstr,NULL,0,"check 3");
436 /* Check that SetCurrentDirectory fails for a non-existant lond directory */
437   sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
438   test_setdir(newdir,tmpstr,NULL,0,"check 4");
439 /* Check that SetCurrentDirectory passes with a long directory */
440   sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
441   test_setdir(newdir,tmpstr,NULL,1,"check 5");
442 /* Check that SetCurrentDirectory passes with a short relative directory */
443   sprintf(tmpstr,"%s",SHORTDIR);
444   sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
445   test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
446 /* starting with a '.' */
447   sprintf(tmpstr,".\\%s",SHORTDIR);
448   test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
449 /* Check that SetCurrentDirectory passes with a short relative directory */
450   sprintf(tmpstr,"%s",LONGDIR);
451   sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
452   test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
453 /* starting with a '.' */
454   sprintf(tmpstr,".\\%s",LONGDIR);
455   test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
456 }
457
458 /* Cleanup the mess we made while executing these tests */
459 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
460 {
461   CHAR tmpstr[MAX_PATH];
462   sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
463   ok(DeleteFileA(tmpstr),"DeleteFileA failed");
464   sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
465   ok(DeleteFileA(tmpstr),"DeleteFileA failed");
466   sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
467   ok(DeleteFileA(tmpstr),"DeleteFileA failed");
468   sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
469   ok(DeleteFileA(tmpstr),"DeleteFileA failed");
470   sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
471   ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed");
472   sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
473   ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed");
474   ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed");
475   ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed");
476 }
477
478 /* This routine will test Get(Full|Short|Long)PathNameA */
479 static void test_PathNameA(CHAR *curdir)
480 {
481   CHAR curdir_short[MAX_PATH],
482        longdir_short[MAX_PATH];
483   CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
484   DWORD len;
485   INT i;
486   CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
487   SLpassfail passfail;
488
489 /* Get the short form of the current directory */
490   ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
491      "GetShortPathNameA failed");
492   ok(!HAS_TRAIL_SLASH_A(curdir_short),
493      "GetShortPathNameA should not have a trailing \\");
494 /* Get the short form of the absolute-path to LONGDIR */
495   sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
496   ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
497      "GetShortPathNameA failed");
498   ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
499      "GetShortPathNameA should not have a trailing \\");
500
501 /* Check the cases where both file and directory exist first */
502 /* Start with a 8.3 directory, 8.3 filename */
503   test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
504   sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
505   ok(lstrcmpiA(tmpstr,tmpstr1)==0,
506      "GetShortPathNameA returned '%s' instead of '%s'",tmpstr,tmpstr1);
507 /* Now try a 8.3 directory, long file name */
508   test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
509   sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
510   test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
511 /* Next is a long directory, 8.3 file */
512   test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
513   sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
514   ok(lstrcmpiA(tmpstr,tmpstr1)==0,
515      "GetShortPathNameA returned '%s' instead of '%s'",tmpstr,tmpstr1);
516 /*Lastly a long directory, long file */
517   test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
518   test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
519
520 /* Now check all of the invalid file w/ valid directroy combinations */
521 /* Start with a 8.3 directory, 8.3 filename */
522   test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
523   todo_wine {
524     ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
525     ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
526        "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'");
527   }
528   if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
529     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
530     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
531        "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'");
532   }
533 /* Now try a 8.3 directory, long file name */
534   test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
535   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
536   ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
537      "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'");
538   if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
539     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
540     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
541        "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'");
542   }
543 /* Next is a long directory, 8.3 file */
544   test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
545   todo_wine {
546     ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
547     ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
548        "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'");
549   }
550   if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
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 /*Lastly a long directory, long file */
556   test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
557   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
558   ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
559      "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'");
560   if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
561     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
562     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
563        "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'");
564   }
565 /* Now try again with directories that don't exist */
566 /* 8.3 directory, 8.3 filename */
567   test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
568   todo_wine {
569     ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
570     ok(passfail.shorterror==ERROR_PATH_NOT_FOUND || 
571        passfail.shorterror==ERROR_FILE_NOT_FOUND,
572        "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
573         passfail.shorterror);
574   }
575   if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
576     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
577     ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
578        passfail.longerror==ERROR_FILE_NOT_FOUND,
579        "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
580        passfail.longerror);
581   }
582 /* Now try a 8.3 directory, long file name */
583   test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
584   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
585   ok(passfail.shorterror==ERROR_PATH_NOT_FOUND || 
586      passfail.shorterror==ERROR_FILE_NOT_FOUND,
587      "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
588       passfail.shorterror);
589   if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
590     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
591     ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
592        passfail.longerror==ERROR_FILE_NOT_FOUND,
593        "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
594        passfail.longerror);
595   }
596 /* Next is a long directory, 8.3 file */
597   test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
598   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
599   ok(passfail.shorterror==ERROR_PATH_NOT_FOUND || 
600      passfail.shorterror==ERROR_FILE_NOT_FOUND,
601      "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
602       passfail.shorterror);
603   if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
604     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
605     ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
606        passfail.longerror==ERROR_FILE_NOT_FOUND,
607        "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
608        passfail.longerror);
609   }
610 /*Lastly a long directory, long file */
611   test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
612   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
613   ok(passfail.shorterror==ERROR_PATH_NOT_FOUND || 
614      passfail.shorterror==ERROR_FILE_NOT_FOUND,
615      "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
616       passfail.shorterror);
617   if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
618     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
619     ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
620        passfail.longerror==ERROR_FILE_NOT_FOUND,
621        "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
622        passfail.longerror);
623   }
624 /* Next try directories ending with '\\' */
625 /* Existing Directories */
626   sprintf(tmpstr,"%s\\",SHORTDIR);
627   test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
628   sprintf(tmpstr,"%s\\",LONGDIR);
629   test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
630 /* Non-existant directories */
631   sprintf(tmpstr,"%s\\",NONDIR_SHORT);
632   test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
633   todo_wine {
634     ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
635     ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
636      "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'",
637       passfail.shorterror);
638   }
639   if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
640     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
641     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
642        "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'",
643        passfail.longerror);
644   }
645   sprintf(tmpstr,"%s\\",NONDIR_LONG);
646   test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
647   ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
648   ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
649      "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'",
650       passfail.shorterror);
651   if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
652     ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
653     ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
654        "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'",
655        passfail.longerror);
656   }
657 /* Now try some relative paths */
658   ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed");
659   test_SplitShortPathA(tmpstr,dir,eight,three);
660   if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
661     ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed");
662     todo_wine {
663       ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
664          "GetLongPathNameA returned '%s' instead of '%s'",tmpstr1,LONGDIR);
665     }
666   }
667   sprintf(tmpstr,".\\%s",LONGDIR);
668   ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed");
669   test_SplitShortPathA(tmpstr1,dir,eight,three);
670   ok(lstrcmpiA(dir,".")==0,"GetShortPathNameA did not keep relative directory");
671   if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
672     ok(GetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetShortPathNameA failed");
673     todo_wine {
674       ok(lstrcmpiA(tmpstr1,tmpstr)==0,
675          "GetLongPathNameA returned '%s' instead of '%s'",tmpstr1,tmpstr);
676     }
677   }
678 /* Check out Get*PathNameA on some funny characters */
679   for(i=0;i<lstrlenA(funny_chars);i++) {
680     INT valid,todo;
681     valid=(is_char_ok[i]=='0') ? 0 : 1;
682     todo=(wine_todo[i]=='0') ? 0 : 1;
683     sprintf(tmpstr1,"check%d-1",i);
684     sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
685     test_FunnyChars(curdir,tmpstr,valid,todo,tmpstr1);
686     sprintf(tmpstr1,"check%d-2",i);
687     sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
688     test_FunnyChars(curdir,tmpstr,valid,todo,tmpstr1);
689     sprintf(tmpstr1,"check%d-3",i);
690     sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
691     test_FunnyChars(curdir,tmpstr,valid,todo,tmpstr1);
692     sprintf(tmpstr1,"check%d-4",i);
693     sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
694     test_FunnyChars(curdir,tmpstr,valid,todo,tmpstr1);
695     sprintf(tmpstr1,"check%d-5",i);
696     sprintf(tmpstr,"Long %c File",funny_chars[i]);
697     test_FunnyChars(curdir,tmpstr,valid,0,tmpstr1);
698     sprintf(tmpstr1,"check%d-6",i);
699     sprintf(tmpstr,"%c Long File",funny_chars[i]);
700     test_FunnyChars(curdir,tmpstr,valid,0,tmpstr1);
701     sprintf(tmpstr1,"check%d-7",i);
702     sprintf(tmpstr,"Long File %c",funny_chars[i]);
703     test_FunnyChars(curdir,tmpstr,valid,0,tmpstr1);
704   }
705 /* ':' is a special case and is allowed only in certain cases */
706     test_FunnyChars(curdir,"file:000.ext",1,1,"check-1");
707     test_FunnyChars(curdir,"file000.e:t" ,1,1,"check-2");
708     test_FunnyChars(curdir,":file000.ext",0,1,"check-3");
709     test_FunnyChars(curdir,"file000:.ext",1,1,"check-4");
710     test_FunnyChars(curdir,"Long : File" ,1,0,"check-5");
711     test_FunnyChars(curdir,": Long File" ,0,0,"check-6");
712     test_FunnyChars(curdir,"Long File :" ,0,0,"check-7");
713 }
714
715 START_TEST(path)
716 {
717     CHAR origdir[MAX_PATH],curdir[MAX_PATH];
718     version.dwOSVersionInfoSize=sizeof(OSVERSIONINFOA);
719     ok(GetVersionExA(&version),"GetVersionEx failed: %d",GetLastError());
720     test_InitPathA(curdir);
721     test_CurrentDirectoryA(origdir,curdir);
722     test_PathNameA(curdir);
723     test_CleanupPathA(origdir,curdir);
724 }