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