2 * Unit test suite for various Path and Directory Functions
4 * Copyright 2002 Geoffrey Hausheer
5 * Copyright 2006 Detlef Riekenberg
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/test.h"
32 #define HAS_TRAIL_SLASH_A(string) (string[lstrlenA(string)-1]=='\\')
34 #define LONGFILE "Long File test.path"
35 #define SHORTFILE "pathtest.pth"
36 #define SHORTDIR "shortdir"
37 #define LONGDIR "Long Directory"
38 #define NONFILE_SHORT "noexist.pth"
39 #define NONFILE_LONG "NonExistent File"
40 #define NONDIR_SHORT "notadir"
41 #define NONDIR_LONG "NonExistent Directory"
43 #define NOT_A_VALID_DRIVE '@'
47 #elif defined __x86_64__
53 /* the following characters don't work well with GetFullPathNameA
54 in Win98. I don't know if this is a FAT thing, or if it is an OS thing
55 but I don't test these characters now.
56 NOTE: Win2k allows GetFullPathNameA to work with them though
59 static const CHAR funny_chars
[]="!@#$%^&*()=+{}[],?'`";
60 static const CHAR is_char_ok
[] ="11111110111111111011";
62 static DWORD (WINAPI
*pGetLongPathNameA
)(LPCSTR
,LPSTR
,DWORD
);
63 static DWORD (WINAPI
*pGetLongPathNameW
)(LPWSTR
,LPWSTR
,DWORD
);
65 /* Present in Win2003+ */
66 static BOOL (WINAPI
*pNeedCurrentDirectoryForExePathA
)(LPCSTR
);
67 static BOOL (WINAPI
*pNeedCurrentDirectoryForExePathW
)(LPCWSTR
);
69 static DWORD (WINAPI
*pSearchPathA
)(LPCSTR
,LPCSTR
,LPCSTR
,DWORD
,LPSTR
,LPSTR
*);
70 static DWORD (WINAPI
*pSearchPathW
)(LPCWSTR
,LPCWSTR
,LPCWSTR
,DWORD
,LPWSTR
,LPWSTR
*);
72 static BOOL (WINAPI
*pActivateActCtx
)(HANDLE
,ULONG_PTR
*);
73 static HANDLE (WINAPI
*pCreateActCtxW
)(PCACTCTXW
);
74 static BOOL (WINAPI
*pDeactivateActCtx
)(DWORD
,ULONG_PTR
);
75 static BOOL (WINAPI
*pGetCurrentActCtx
)(HANDLE
*);
76 static void (WINAPI
*pReleaseActCtx
)(HANDLE
);
78 /* a structure to deal with wine todos somewhat cleanly */
88 /* function that tests GetFullPathNameA, GetShortPathNameA,GetLongPathNameA */
89 /* NOTE: the passfail structure is used to allow customizable todo checking
90 for wine. It is not very pretty, but it sure beats duplicating this
91 function lots of times
93 static void test_ValidPathA(const CHAR
*curdir
, const CHAR
*subdir
, const CHAR
*filename
,
94 CHAR
*shortstr
, SLpassfail
*passfail
, const CHAR
*errstr
)
96 CHAR tmpstr
[MAX_PATH
],
97 fullpath
[MAX_PATH
], /*full path to the file (not short/long) */
98 subpath
[MAX_PATH
], /*relative path to the file */
99 fullpathshort
[MAX_PATH
], /*absolute path to the file (short format) */
100 fullpathlong
[MAX_PATH
], /*absolute path to the file (long format) */
101 curdirshort
[MAX_PATH
], /*absolute path to the current dir (short) */
102 curdirlong
[MAX_PATH
]; /*absolute path to the current dir (long) */
103 LPSTR strptr
; /*ptr to the filename portion of the path */
105 /* if passfail is NULL, we can perform all checks within this function,
106 otherwise, we will return the relevant data in the passfail struct, so
107 we must initialize it first
110 passfail
->shortlen
=-1;passfail
->s2llen
=-1;passfail
->longlen
=-1;
111 passfail
->shorterror
=0;passfail
->s2lerror
=0;passfail
->longerror
=0;
113 /* GetLongPathNameA is only supported on Win2k+ and Win98+ */
114 if(pGetLongPathNameA
) {
115 ok((len
=pGetLongPathNameA(curdir
,curdirlong
,MAX_PATH
)),
116 "%s: GetLongPathNameA failed\n",errstr
);
117 /*GetLongPathNameA can return a trailing '\\' but shouldn't do so here */
118 ok(! HAS_TRAIL_SLASH_A(curdirlong
),
119 "%s: GetLongPathNameA should not have a trailing \\\n",errstr
);
121 ok((len
=GetShortPathNameA(curdir
,curdirshort
,MAX_PATH
)),
122 "%s: GetShortPathNameA failed\n",errstr
);
123 /*GetShortPathNameA can return a trailing '\\' but shouldn't do so here */
124 ok(! HAS_TRAIL_SLASH_A(curdirshort
),
125 "%s: GetShortPathNameA should not have a trailing \\\n",errstr
);
126 /* build relative and absolute paths from inputs */
127 if(lstrlenA(subdir
)) {
128 sprintf(subpath
,"%s\\%s",subdir
,filename
);
130 lstrcpyA(subpath
,filename
);
132 sprintf(fullpath
,"%s\\%s",curdir
,subpath
);
133 sprintf(fullpathshort
,"%s\\%s",curdirshort
,subpath
);
134 sprintf(fullpathlong
,"%s\\%s",curdirlong
,subpath
);
135 /* Test GetFullPathNameA functionality */
136 len
=GetFullPathNameA(subpath
,MAX_PATH
,tmpstr
,&strptr
);
137 ok(len
, "GetFullPathNameA failed for: '%s'\n",subpath
);
138 if(HAS_TRAIL_SLASH_A(subpath
)) {
140 "%s: GetFullPathNameA should not return a filename ptr\n",errstr
);
141 ok(lstrcmpiA(fullpath
,tmpstr
)==0,
142 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
143 errstr
,tmpstr
,fullpath
);
145 ok(lstrcmpiA(strptr
,filename
)==0,
146 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
147 errstr
,strptr
,filename
);
148 ok(lstrcmpiA(fullpath
,tmpstr
)==0,
149 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
150 errstr
,tmpstr
,fullpath
);
152 /* Test GetShortPathNameA functionality */
154 len
=GetShortPathNameA(fullpathshort
,shortstr
,MAX_PATH
);
156 ok(len
, "%s: GetShortPathNameA failed\n",errstr
);
158 passfail
->shortlen
=len
;
159 passfail
->shorterror
=GetLastError();
161 /* Test GetLongPathNameA functionality
162 We test both conversion from GetFullPathNameA and from GetShortPathNameA
164 if(pGetLongPathNameA
) {
167 len
=pGetLongPathNameA(shortstr
,tmpstr
,MAX_PATH
);
170 "%s: GetLongPathNameA failed during Short->Long conversion\n", errstr
);
171 ok(lstrcmpiA(fullpathlong
,tmpstr
)==0,
172 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
173 errstr
,tmpstr
,fullpathlong
);
175 passfail
->s2llen
=len
;
176 passfail
->s2lerror
=GetLastError();
180 len
=pGetLongPathNameA(fullpath
,tmpstr
,MAX_PATH
);
182 ok(len
, "%s: GetLongPathNameA failed\n",errstr
);
183 if(HAS_TRAIL_SLASH_A(fullpath
)) {
184 ok(lstrcmpiA(fullpathlong
,tmpstr
)==0,
185 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
186 errstr
,tmpstr
,fullpathlong
);
188 ok(lstrcmpiA(fullpathlong
,tmpstr
)==0,
189 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
190 errstr
,tmpstr
,fullpathlong
);
193 passfail
->longlen
=len
;
194 passfail
->longerror
=GetLastError();
199 /* split path into leading directory, and 8.3 filename */
200 static void test_SplitShortPathA(CHAR
*path
,CHAR
*dir
,CHAR
*eight
,CHAR
*three
) {
201 BOOL done
= FALSE
, error
= FALSE
;
207 /* walk backwards over path looking for '.' or '\\' separators */
208 for(i
=len
-1;(i
>=0) && (!done
);i
--) {
210 if(ext
!=len
) error
=TRUE
; else ext
=i
;
211 else if(path
[i
]=='\\') {
220 /* Check that we didn't find a trailing '\\' or multiple '.' */
221 ok(!error
,"Illegal file found in 8.3 path '%s'\n",path
);
222 /* Separate dir, root, and extension */
223 if(ext
!=len
) lstrcpyA(three
,path
+ext
+1); else lstrcpyA(three
,"");
225 lstrcpynA(eight
,path
+fil
+1,ext
-fil
);
226 lstrcpynA(dir
,path
,fil
+1);
228 lstrcpynA(eight
,path
,ext
+1);
231 /* Validate that root and extension really are 8.3 */
232 ok(lstrlenA(eight
)<=8 && lstrlenA(three
)<=3,
233 "GetShortPathNAmeA did not return an 8.3 path\n");
236 /* Check that GetShortPathNameA returns a valid 8.3 path */
237 static void test_LongtoShortA(CHAR
*teststr
,const CHAR
*goodstr
,
238 const CHAR
*ext
,const CHAR
*errstr
) {
239 CHAR dir
[MAX_PATH
],eight
[MAX_PATH
],three
[MAX_PATH
];
241 test_SplitShortPathA(teststr
,dir
,eight
,three
);
242 ok(lstrcmpiA(dir
,goodstr
)==0,
243 "GetShortPathNameA returned '%s' instead of '%s'\n",dir
,goodstr
);
244 ok(lstrcmpiA(three
,ext
)==0,
245 "GetShortPathNameA returned '%s' with incorrect extension\n",three
);
248 /* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
249 characters in the filename.
250 'valid' indicates whether this would be an allowed filename
251 'todo' indicates that wine doesn't get this right yet.
252 NOTE: We always call this routine with a nonexistent filename, so
253 Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
256 static void test_FunnyChars(CHAR
*curdir
,CHAR
*curdir_short
,CHAR
*filename
, INT valid
,CHAR
*errstr
)
258 CHAR tmpstr
[MAX_PATH
],tmpstr1
[MAX_PATH
];
261 test_ValidPathA(curdir
,"",filename
,tmpstr
,&passfail
,errstr
);
263 sprintf(tmpstr1
,"%s\\%s",curdir_short
,filename
);
264 ok((passfail
.shortlen
==0 &&
265 (passfail
.shorterror
==ERROR_FILE_NOT_FOUND
|| passfail
.shorterror
==ERROR_PATH_NOT_FOUND
|| !passfail
.shorterror
)) ||
266 (passfail
.shortlen
==strlen(tmpstr1
) && lstrcmpiA(tmpstr
,tmpstr1
)==0),
267 "%s: GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
268 errstr
,passfail
.shortlen
,passfail
.shorterror
,tmpstr
);
270 ok(passfail
.shortlen
==0 &&
271 (passfail
.shorterror
==ERROR_INVALID_NAME
|| passfail
.shorterror
==ERROR_FILE_NOT_FOUND
|| !passfail
.shorterror
),
272 "%s: GetShortPathA should have failed len=%d, error=%d\n",
273 errstr
,passfail
.shortlen
,passfail
.shorterror
);
275 if(pGetLongPathNameA
) {
276 ok(passfail
.longlen
==0,"GetLongPathNameA passed when it shouldn't have\n");
278 ok(passfail
.longerror
==ERROR_FILE_NOT_FOUND
,
279 "%s: GetLongPathA returned %d and not %d\n",
280 errstr
,passfail
.longerror
,ERROR_FILE_NOT_FOUND
);
282 ok(passfail
.longerror
==ERROR_INVALID_NAME
||
283 passfail
.longerror
==ERROR_FILE_NOT_FOUND
,
284 "%s: GetLongPathA returned %d and not %d or %d'\n",
285 errstr
, passfail
.longerror
,ERROR_INVALID_NAME
,ERROR_FILE_NOT_FOUND
);
290 /* Routine to test that SetCurrentDirectory behaves as expected. */
291 static void test_setdir(CHAR
*olddir
,CHAR
*newdir
,
292 CHAR
*cmprstr
, INT pass
, const CHAR
*errstr
)
294 CHAR tmppath
[MAX_PATH
], *dirptr
;
295 DWORD val
,len
,chklen
;
297 val
=SetCurrentDirectoryA(newdir
);
298 len
=GetCurrentDirectoryA(MAX_PATH
,tmppath
);
299 /* if 'pass' then the SetDirectoryA was supposed to pass */
301 dirptr
=(cmprstr
==NULL
) ? newdir
: cmprstr
;
302 chklen
=lstrlenA(dirptr
);
303 ok(val
,"%s: SetCurrentDirectoryA failed\n",errstr
);
305 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
307 ok(lstrcmpiA(dirptr
,tmppath
)==0,
308 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
310 ok(SetCurrentDirectoryA(olddir
),
311 "%s: Couldn't set directory to its original value\n",errstr
);
313 /* else thest that it fails correctly */
314 chklen
=lstrlenA(olddir
);
316 "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr
);
318 "%s: SetCurrentDirectory changed the directory, though it failed\n",
320 ok(lstrcmpiA(olddir
,tmppath
)==0,
321 "%s: SetCurrentDirectory changed the directory, though it failed\n",
325 static void test_InitPathA(CHAR
*newdir
, CHAR
*curDrive
, CHAR
*otherDrive
)
327 CHAR tmppath
[MAX_PATH
], /*path to TEMP */
330 invalid_dir
[MAX_PATH
];
332 DWORD len
,len1
,drives
;
338 *curDrive
= *otherDrive
= NOT_A_VALID_DRIVE
;
340 /* Get the current drive letter */
341 if( GetCurrentDirectoryA( MAX_PATH
, tmpstr
))
342 *curDrive
= tmpstr
[0];
344 trace( "Unable to discover current drive, some tests will not be conducted.\n");
346 /* Test GetTempPathA */
347 len
=GetTempPathA(MAX_PATH
,tmppath
);
348 ok(len
!=0 && len
< MAX_PATH
,"GetTempPathA failed\n");
349 ok(HAS_TRAIL_SLASH_A(tmppath
),
350 "GetTempPathA returned a path that did not end in '\\'\n");
351 lstrcpyA(tmpstr
,"aaaaaaaa");
352 len1
=GetTempPathA(len
,tmpstr
);
353 ok(len1
==len
+1 || broken(len1
== len
), /* WinME */
354 "GetTempPathA should return string length %d instead of %d\n",len
+1,len1
);
356 /* Test GetTmpFileNameA */
357 ok((id
=GetTempFileNameA(tmppath
,"path",0,newdir
)),"GetTempFileNameA failed\n");
358 sprintf(tmpstr
,"pat%.4x.tmp",id
& 0xffff);
359 sprintf(tmpstr1
,"pat%x.tmp",id
& 0xffff);
360 ok(lstrcmpiA(newdir
+lstrlenA(tmppath
),tmpstr
)==0 ||
361 lstrcmpiA(newdir
+lstrlenA(tmppath
),tmpstr1
)==0,
362 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
363 newdir
,tmpstr
,tmpstr1
,id
);
364 ok(DeleteFileA(newdir
),"Couldn't delete the temporary file we just created\n");
366 id
=GetTempFileNameA(tmppath
,NULL
,0,newdir
);
367 /* Windows 95, 98 return 0==id, while Windows 2000, XP return 0!=id */
370 sprintf(tmpstr
,"%.4x.tmp",id
& 0xffff);
371 sprintf(tmpstr1
,"%x.tmp",id
& 0xffff);
372 ok(lstrcmpiA(newdir
+lstrlenA(tmppath
),tmpstr
)==0 ||
373 lstrcmpiA(newdir
+lstrlenA(tmppath
),tmpstr1
)==0,
374 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
375 newdir
,tmpstr
,tmpstr1
,id
);
376 ok(DeleteFileA(newdir
),"Couldn't delete the temporary file we just created\n");
379 for(unique
=0;unique
<3;unique
++) {
380 /* Nonexistent path */
381 sprintf(invalid_dir
, "%s\\%s",tmppath
,"non_existent_dir_1jwj3y32nb3");
382 SetLastError(0xdeadbeef);
383 ok(!GetTempFileNameA(invalid_dir
,"tfn",unique
,newdir
),"GetTempFileNameA should have failed\n");
384 ok(GetLastError()==ERROR_DIRECTORY
|| broken(GetLastError()==ERROR_PATH_NOT_FOUND
)/*win98*/,
385 "got %d, expected ERROR_DIRECTORY\n", GetLastError());
387 /* Check return value for unique !=0 */
389 ok((GetTempFileNameA(tmppath
,"tfn",unique
,newdir
) == unique
),"GetTempFileNameA unexpectedly failed\n");
390 /* if unique != 0, the actual temp files are not created: */
391 ok(!DeleteFileA(newdir
) && GetLastError() == ERROR_FILE_NOT_FOUND
,"Deleted a file that shouldn't exist!\n");
395 /* Find first valid drive letter that is neither newdir[0] nor curDrive */
396 drives
= GetLogicalDrives() & ~(1<<(newdir
[0]-'A'));
397 if( *curDrive
!= NOT_A_VALID_DRIVE
)
398 drives
&= ~(1<<(*curDrive
-'A'));
400 for( *otherDrive
='A'; (drives
& 1) == 0; drives
>>=1, (*otherDrive
)++);
402 trace( "Could not find alternative drive, some tests will not be conducted.\n");
404 /* Do some CreateDirectoryA tests */
405 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
406 really understand how they work.
407 More formal tests should be done along with CreateFile tests
409 ok((id
=GetTempFileNameA(tmppath
,"path",0,newdir
)),"GetTempFileNameA failed\n");
410 ok(CreateDirectoryA(newdir
,NULL
)==0,
411 "CreateDirectoryA succeeded even though a file of the same name exists\n");
412 ok(DeleteFileA(newdir
),"Couldn't delete the temporary file we just created\n");
413 ok(CreateDirectoryA(newdir
,NULL
),"CreateDirectoryA failed\n");
414 /* Create some files to test other functions. Note, we will test CreateFileA
417 sprintf(tmpstr
,"%s\\%s",newdir
,SHORTDIR
);
418 ok(CreateDirectoryA(tmpstr
,NULL
),"CreateDirectoryA failed\n");
419 sprintf(tmpstr
,"%s\\%s",newdir
,LONGDIR
);
420 ok(CreateDirectoryA(tmpstr
,NULL
),"CreateDirectoryA failed\n");
421 sprintf(tmpstr
,"%c:", *curDrive
);
422 bRes
= CreateDirectoryA(tmpstr
,NULL
);
423 ok(!bRes
&& (GetLastError() == ERROR_ACCESS_DENIED
||
424 GetLastError() == ERROR_ALREADY_EXISTS
),
425 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr
, GetLastError());
426 sprintf(tmpstr
,"%c:\\", *curDrive
);
427 bRes
= CreateDirectoryA(tmpstr
,NULL
);
428 ok(!bRes
&& (GetLastError() == ERROR_ACCESS_DENIED
||
429 GetLastError() == ERROR_ALREADY_EXISTS
),
430 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr
, GetLastError());
431 sprintf(tmpstr
,"%s\\%s\\%s",newdir
,SHORTDIR
,SHORTFILE
);
432 hndl
=CreateFileA(tmpstr
,GENERIC_WRITE
,0,NULL
,
433 CREATE_NEW
,FILE_ATTRIBUTE_NORMAL
,NULL
);
434 ok(hndl
!=INVALID_HANDLE_VALUE
,"CreateFileA failed\n");
435 ok(CloseHandle(hndl
),"CloseHandle failed\n");
436 sprintf(tmpstr
,"%s\\%s\\%s",newdir
,SHORTDIR
,LONGFILE
);
437 hndl
=CreateFileA(tmpstr
,GENERIC_WRITE
,0,NULL
,
438 CREATE_NEW
,FILE_ATTRIBUTE_NORMAL
,NULL
);
439 ok(hndl
!=INVALID_HANDLE_VALUE
,"CreateFileA failed\n");
440 ok(CloseHandle(hndl
),"CloseHandle failed\n");
441 sprintf(tmpstr
,"%s\\%s\\%s",newdir
,LONGDIR
,SHORTFILE
);
442 hndl
=CreateFileA(tmpstr
,GENERIC_WRITE
,0,NULL
,
443 CREATE_NEW
,FILE_ATTRIBUTE_NORMAL
,NULL
);
444 ok(hndl
!=INVALID_HANDLE_VALUE
,"CreateFileA failed\n");
445 ok(CloseHandle(hndl
),"CloseHandle failed\n");
446 sprintf(tmpstr
,"%s\\%s\\%s",newdir
,LONGDIR
,LONGFILE
);
447 hndl
=CreateFileA(tmpstr
,GENERIC_WRITE
,0,NULL
,
448 CREATE_NEW
,FILE_ATTRIBUTE_NORMAL
,NULL
);
449 ok(hndl
!=INVALID_HANDLE_VALUE
,"CreateFileA failed\n");
450 ok(CloseHandle(hndl
),"CloseHandle failed\n");
453 /* Test GetCurrentDirectory & SetCurrentDirectory */
454 static void test_CurrentDirectoryA(CHAR
*origdir
, CHAR
*newdir
)
456 CHAR tmpstr
[MAX_PATH
],tmpstr1
[MAX_PATH
];
459 /* Save the original directory, so that we can return to it at the end
462 len
=GetCurrentDirectoryA(MAX_PATH
,origdir
);
463 ok(len
!=0 && len
< MAX_PATH
,"GetCurrentDirectoryA failed\n");
464 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
465 buffer size is too small to hold the current directory
467 lstrcpyA(tmpstr
,"aaaaaaa");
468 len1
=GetCurrentDirectoryA(len
,tmpstr
);
469 ok(len1
==len
+1, "GetCurrentDirectoryA returned %d instead of %d\n",len1
,len
+1);
470 ok(lstrcmpiA(tmpstr
,"aaaaaaa")==0,
471 "GetCurrentDirectoryA should not have modified the buffer\n");
473 buffer
= HeapAlloc( GetProcessHeap(), 0, 2 * 65536 );
474 SetLastError( 0xdeadbeef );
475 strcpy( buffer
, "foo" );
476 len
= GetCurrentDirectoryA( 32767, buffer
);
477 ok( len
!= 0 && len
< MAX_PATH
, "GetCurrentDirectoryA failed %u err %u\n", len
, GetLastError() );
478 if (len
) ok( !strcmp( buffer
, origdir
), "wrong result %s\n", buffer
);
479 SetLastError( 0xdeadbeef );
480 strcpy( buffer
, "foo" );
481 len
= GetCurrentDirectoryA( 32768, buffer
);
482 ok( len
!= 0 && len
< MAX_PATH
, "GetCurrentDirectoryA failed %u err %u\n", len
, GetLastError() );
483 if (len
) ok( !strcmp( buffer
, origdir
), "wrong result %s\n", buffer
);
484 SetLastError( 0xdeadbeef );
485 strcpy( buffer
, "foo" );
486 len
= GetCurrentDirectoryA( 65535, buffer
);
487 ok( (len
!= 0 && len
< MAX_PATH
) || broken(!len
), /* nt4, win2k, xp */ "GetCurrentDirectoryA failed %u err %u\n", len
, GetLastError() );
488 if (len
) ok( !strcmp( buffer
, origdir
), "wrong result %s\n", buffer
);
489 SetLastError( 0xdeadbeef );
490 strcpy( buffer
, "foo" );
491 len
= GetCurrentDirectoryA( 65536, buffer
);
492 ok( (len
!= 0 && len
< MAX_PATH
) || broken(!len
), /* nt4 */ "GetCurrentDirectoryA failed %u err %u\n", len
, GetLastError() );
493 if (len
) ok( !strcmp( buffer
, origdir
), "wrong result %s\n", buffer
);
494 SetLastError( 0xdeadbeef );
495 strcpy( buffer
, "foo" );
496 len
= GetCurrentDirectoryA( 2 * 65536, buffer
);
497 ok( (len
!= 0 && len
< MAX_PATH
) || broken(!len
), /* nt4 */ "GetCurrentDirectoryA failed %u err %u\n", len
, GetLastError() );
498 if (len
) ok( !strcmp( buffer
, origdir
), "wrong result %s\n", buffer
);
499 HeapFree( GetProcessHeap(), 0, buffer
);
501 /* Check for crash prevention on swapped args. Crashes all but Win9x.
505 GetCurrentDirectoryA( 42, (LPSTR
)(MAX_PATH
+ 42) );
508 /* SetCurrentDirectoryA shouldn't care whether the string has a
511 sprintf(tmpstr
,"%s\\",newdir
);
512 test_setdir(origdir
,tmpstr
,newdir
,1,"check 1");
513 test_setdir(origdir
,newdir
,NULL
,1,"check 2");
514 /* Set the directory to the working area. We just tested that this works,
515 so why check it again.
517 SetCurrentDirectoryA(newdir
);
518 /* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
519 sprintf(tmpstr
,"%s\\%s\\%s",newdir
,SHORTDIR
,NONDIR_SHORT
);
520 test_setdir(newdir
,tmpstr
,NULL
,0,"check 3");
521 /* Check that SetCurrentDirectory fails for a nonexistent lond directory */
522 sprintf(tmpstr
,"%s\\%s\\%s",newdir
,SHORTDIR
,NONDIR_LONG
);
523 test_setdir(newdir
,tmpstr
,NULL
,0,"check 4");
524 /* Check that SetCurrentDirectory passes with a long directory */
525 sprintf(tmpstr
,"%s\\%s",newdir
,LONGDIR
);
526 test_setdir(newdir
,tmpstr
,NULL
,1,"check 5");
527 /* Check that SetCurrentDirectory passes with a short relative directory */
528 sprintf(tmpstr
,"%s",SHORTDIR
);
529 sprintf(tmpstr1
,"%s\\%s",newdir
,SHORTDIR
);
530 test_setdir(newdir
,tmpstr
,tmpstr1
,1,"check 6");
531 /* starting with a '.' */
532 sprintf(tmpstr
,".\\%s",SHORTDIR
);
533 test_setdir(newdir
,tmpstr
,tmpstr1
,1,"check 7");
534 /* Check that SetCurrentDirectory passes with a short relative directory */
535 sprintf(tmpstr
,"%s",LONGDIR
);
536 sprintf(tmpstr1
,"%s\\%s",newdir
,LONGDIR
);
537 test_setdir(newdir
,tmpstr
,tmpstr1
,1,"check 8");
538 /* starting with a '.' */
539 sprintf(tmpstr
,".\\%s",LONGDIR
);
540 test_setdir(newdir
,tmpstr
,tmpstr1
,1,"check 9");
541 /* change to root without a trailing backslash. The function call succeeds
542 but the directory is not changed.
544 sprintf(tmpstr
, "%c:", newdir
[0]);
545 test_setdir(newdir
,tmpstr
,newdir
,1,"check 10");
546 /* works however with a trailing backslash */
547 sprintf(tmpstr
, "%c:\\", newdir
[0]);
548 test_setdir(newdir
,tmpstr
,NULL
,1,"check 11");
551 /* Cleanup the mess we made while executing these tests */
552 static void test_CleanupPathA(CHAR
*origdir
, CHAR
*curdir
)
554 CHAR tmpstr
[MAX_PATH
];
555 sprintf(tmpstr
,"%s\\%s\\%s",curdir
,SHORTDIR
,SHORTFILE
);
556 ok(DeleteFileA(tmpstr
),"DeleteFileA failed\n");
557 sprintf(tmpstr
,"%s\\%s\\%s",curdir
,SHORTDIR
,LONGFILE
);
558 ok(DeleteFileA(tmpstr
),"DeleteFileA failed\n");
559 sprintf(tmpstr
,"%s\\%s\\%s",curdir
,LONGDIR
,SHORTFILE
);
560 ok(DeleteFileA(tmpstr
),"DeleteFileA failed\n");
561 sprintf(tmpstr
,"%s\\%s\\%s",curdir
,LONGDIR
,LONGFILE
);
562 ok(DeleteFileA(tmpstr
),"DeleteFileA failed\n");
563 sprintf(tmpstr
,"%s\\%s",curdir
,SHORTDIR
);
564 ok(RemoveDirectoryA(tmpstr
),"RemoveDirectoryA failed\n");
565 sprintf(tmpstr
,"%s\\%s",curdir
,LONGDIR
);
566 ok(RemoveDirectoryA(tmpstr
),"RemoveDirectoryA failed\n");
567 ok(SetCurrentDirectoryA(origdir
),"SetCurrentDirectoryA failed\n");
568 ok(RemoveDirectoryA(curdir
),"RemoveDirectoryA failed\n");
571 /* test that short path name functions work regardless of case */
572 static void test_ShortPathCase(const char *tmpdir
, const char *dirname
,
573 const char *filename
)
575 char buf
[MAX_PATH
], shortbuf
[MAX_PATH
];
579 assert(strlen(tmpdir
) + strlen(dirname
) + strlen(filename
) + 2 < sizeof(buf
));
580 sprintf(buf
,"%s\\%s\\%s",tmpdir
,dirname
,filename
);
581 GetShortPathNameA(buf
,shortbuf
,sizeof(shortbuf
));
582 hndl
= CreateFileA(shortbuf
,GENERIC_READ
|GENERIC_WRITE
,0,NULL
,OPEN_EXISTING
,0,NULL
);
583 ok(hndl
!=INVALID_HANDLE_VALUE
,"CreateFileA failed (%d)\n",GetLastError());
585 /* Now for the real test */
586 for(i
=0;i
<strlen(shortbuf
);i
++)
588 shortbuf
[i
] = tolower(shortbuf
[i
]);
589 hndl
= CreateFileA(shortbuf
,GENERIC_READ
|GENERIC_WRITE
,0,NULL
,OPEN_EXISTING
,0,NULL
);
590 ok(hndl
!=INVALID_HANDLE_VALUE
,"CreateFileA failed (%d)\n",GetLastError());
594 /* This routine will test Get(Full|Short|Long)PathNameA */
595 static void test_PathNameA(CHAR
*curdir
, CHAR curDrive
, CHAR otherDrive
)
597 CHAR curdir_short
[MAX_PATH
],
598 longdir_short
[MAX_PATH
];
599 CHAR tmpstr
[MAX_PATH
],tmpstr1
[MAX_PATH
],tmpstr2
[MAX_PATH
];
600 LPSTR strptr
; /*ptr to the filename portion of the path */
603 CHAR dir
[MAX_PATH
],eight
[MAX_PATH
],three
[MAX_PATH
];
606 /* Get the short form of the current directory */
607 ok((len
=GetShortPathNameA(curdir
,curdir_short
,MAX_PATH
)),
608 "GetShortPathNameA failed\n");
609 ok(!HAS_TRAIL_SLASH_A(curdir_short
),
610 "GetShortPathNameA should not have a trailing \\\n");
611 /* Get the short form of the absolute-path to LONGDIR */
612 sprintf(tmpstr
,"%s\\%s",curdir_short
,LONGDIR
);
613 ok((len
=GetShortPathNameA(tmpstr
,longdir_short
,MAX_PATH
)),
614 "GetShortPathNameA failed\n");
615 ok(lstrcmpiA(longdir_short
+(len
-1),"\\")!=0,
616 "GetShortPathNameA should not have a trailing \\\n");
618 if (pGetLongPathNameA
) {
620 sprintf(tmpstr
,"%s\\%s\\%s",curdir
,LONGDIR
,LONGFILE
);
621 rc1
=(*pGetLongPathNameA
)(tmpstr
,NULL
,0);
622 rc2
=(*pGetLongPathNameA
)(curdir
,NULL
,0);
623 ok((rc1
-strlen(tmpstr
))==(rc2
-strlen(curdir
)),
624 "GetLongPathNameA: wrong return code, %d instead of %d\n",
625 rc1
, lstrlenA(tmpstr
)+1);
627 sprintf(dir
,"%c:",curDrive
);
628 rc1
=(*pGetLongPathNameA
)(dir
,tmpstr
,sizeof(tmpstr
));
629 ok(strcmp(dir
,tmpstr
)==0,
630 "GetLongPathNameA: returned '%s' instead of '%s' (rc=%d)\n",
634 /* Check the cases where both file and directory exist first */
635 /* Start with a 8.3 directory, 8.3 filename */
636 test_ValidPathA(curdir
,SHORTDIR
,SHORTFILE
,tmpstr
,NULL
,"test1");
637 sprintf(tmpstr1
,"%s\\%s\\%s",curdir_short
,SHORTDIR
,SHORTFILE
);
638 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
639 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr
,tmpstr1
);
640 /* Now try a 8.3 directory, long file name */
641 test_ValidPathA(curdir
,SHORTDIR
,LONGFILE
,tmpstr
,NULL
,"test2");
642 sprintf(tmpstr1
,"%s\\%s",curdir_short
,SHORTDIR
);
643 test_LongtoShortA(tmpstr
,tmpstr1
,"PAT","test2");
644 /* Next is a long directory, 8.3 file */
645 test_ValidPathA(curdir
,LONGDIR
,SHORTFILE
,tmpstr
,NULL
,"test3");
646 sprintf(tmpstr1
,"%s\\%s",longdir_short
,SHORTFILE
);
647 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
648 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr
,tmpstr1
);
649 /*Lastly a long directory, long file */
650 test_ValidPathA(curdir
,LONGDIR
,LONGFILE
,tmpstr
,NULL
,"test4");
651 test_LongtoShortA(tmpstr
,longdir_short
,"PAT","test4");
653 /* Now check all of the invalid file w/ valid directory combinations */
654 /* Start with a 8.3 directory, 8.3 filename */
655 test_ValidPathA(curdir
,SHORTDIR
,NONFILE_SHORT
,tmpstr
,&passfail
,"test5");
656 sprintf(tmpstr1
,"%s\\%s\\%s",curdir_short
,SHORTDIR
,NONFILE_SHORT
);
657 ok((passfail
.shortlen
==0 &&
658 (passfail
.shorterror
==ERROR_PATH_NOT_FOUND
||
659 passfail
.shorterror
==ERROR_FILE_NOT_FOUND
)) ||
660 (passfail
.shortlen
==strlen(tmpstr1
) && lstrcmpiA(tmpstr
,tmpstr1
)==0),
661 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
662 passfail
.shortlen
,passfail
.shorterror
,tmpstr
);
663 if(pGetLongPathNameA
) {
664 ok(passfail
.longlen
==0,"GetLongPathNameA passed when it shouldn't have\n");
665 ok(passfail
.longerror
==ERROR_FILE_NOT_FOUND
,
666 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
668 /* Now try a 8.3 directory, long file name */
669 test_ValidPathA(curdir
,SHORTDIR
,NONFILE_LONG
,tmpstr
,&passfail
,"test6");
670 ok(passfail
.shortlen
==0,"GetShortPathNameA passed when it shouldn't have\n");
671 ok(passfail
.shorterror
==ERROR_PATH_NOT_FOUND
||
672 passfail
.shorterror
==ERROR_FILE_NOT_FOUND
||
673 !passfail
.shorterror
,
674 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
675 if(pGetLongPathNameA
) {
676 ok(passfail
.longlen
==0,"GetLongPathNameA passed when it shouldn't have\n");
677 ok(passfail
.longerror
==ERROR_FILE_NOT_FOUND
,
678 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
680 /* Next is a long directory, 8.3 file */
681 test_ValidPathA(curdir
,LONGDIR
,NONFILE_SHORT
,tmpstr
,&passfail
,"test7");
682 sprintf(tmpstr2
,"%s\\%s",curdir_short
,LONGDIR
);
683 GetShortPathNameA(tmpstr2
,tmpstr1
,MAX_PATH
);
684 strcat(tmpstr1
,"\\" NONFILE_SHORT
);
685 ok((passfail
.shortlen
==0 &&
686 (passfail
.shorterror
==ERROR_PATH_NOT_FOUND
||
687 passfail
.shorterror
==ERROR_FILE_NOT_FOUND
)) ||
688 (passfail
.shortlen
==strlen(tmpstr1
) && lstrcmpiA(tmpstr
,tmpstr1
)==0),
689 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
690 passfail
.shortlen
,passfail
.shorterror
,tmpstr
);
691 if(pGetLongPathNameA
) {
692 ok(passfail
.longlen
==0,"GetLongPathNameA passed when it shouldn't have\n");
693 ok(passfail
.longerror
==ERROR_FILE_NOT_FOUND
,
694 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
696 /*Lastly a long directory, long file */
697 test_ValidPathA(curdir
,LONGDIR
,NONFILE_LONG
,tmpstr
,&passfail
,"test8");
698 ok(passfail
.shortlen
==0,"GetShortPathNameA passed when it shouldn't have\n");
699 ok(passfail
.shorterror
==ERROR_PATH_NOT_FOUND
||
700 passfail
.shorterror
==ERROR_FILE_NOT_FOUND
||
701 !passfail
.shorterror
,
702 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
703 if(pGetLongPathNameA
) {
704 ok(passfail
.longlen
==0,"GetLongPathNameA passed when it shouldn't have\n");
705 ok(passfail
.longerror
==ERROR_FILE_NOT_FOUND
,
706 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
708 /* Now try again with directories that don't exist */
709 /* 8.3 directory, 8.3 filename */
710 test_ValidPathA(curdir
,NONDIR_SHORT
,SHORTFILE
,tmpstr
,&passfail
,"test9");
711 sprintf(tmpstr1
,"%s\\%s\\%s",curdir_short
,NONDIR_SHORT
,SHORTFILE
);
712 ok((passfail
.shortlen
==0 &&
713 (passfail
.shorterror
==ERROR_PATH_NOT_FOUND
||
714 passfail
.shorterror
==ERROR_FILE_NOT_FOUND
)) ||
715 (passfail
.shortlen
==strlen(tmpstr1
) && lstrcmpiA(tmpstr
,tmpstr1
)==0),
716 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
717 passfail
.shortlen
,passfail
.shorterror
,tmpstr
);
718 if(pGetLongPathNameA
) {
719 ok(passfail
.longlen
==0,"GetLongPathNameA passed when it shouldn't have\n");
720 ok(passfail
.longerror
==ERROR_PATH_NOT_FOUND
||
721 passfail
.longerror
==ERROR_FILE_NOT_FOUND
,
722 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
725 /* Now try a 8.3 directory, long file name */
726 test_ValidPathA(curdir
,NONDIR_SHORT
,LONGFILE
,tmpstr
,&passfail
,"test10");
727 ok(passfail
.shortlen
==0,"GetShortPathNameA passed when it shouldn't have\n");
728 ok(passfail
.shorterror
==ERROR_PATH_NOT_FOUND
||
729 passfail
.shorterror
==ERROR_FILE_NOT_FOUND
||
730 !passfail
.shorterror
,
731 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
732 passfail
.shorterror
);
733 if(pGetLongPathNameA
) {
734 ok(passfail
.longlen
==0,"GetLongPathNameA passed when it shouldn't have\n");
735 ok(passfail
.longerror
==ERROR_PATH_NOT_FOUND
||
736 passfail
.longerror
==ERROR_FILE_NOT_FOUND
,
737 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
740 /* Next is a long directory, 8.3 file */
741 test_ValidPathA(curdir
,NONDIR_LONG
,SHORTFILE
,tmpstr
,&passfail
,"test11");
742 ok(passfail
.shortlen
==0,"GetShortPathNameA passed when it shouldn't have\n");
743 ok(passfail
.shorterror
==ERROR_PATH_NOT_FOUND
||
744 passfail
.shorterror
==ERROR_FILE_NOT_FOUND
||
745 !passfail
.shorterror
,
746 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
747 passfail
.shorterror
);
748 if(pGetLongPathNameA
) {
749 ok(passfail
.longlen
==0,"GetLongPathNameA passed when it shouldn't have\n");
750 ok(passfail
.longerror
==ERROR_PATH_NOT_FOUND
||
751 passfail
.longerror
==ERROR_FILE_NOT_FOUND
,
752 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
755 /*Lastly a long directory, long file */
756 test_ValidPathA(curdir
,NONDIR_LONG
,LONGFILE
,tmpstr
,&passfail
,"test12");
757 ok(passfail
.shortlen
==0,"GetShortPathNameA passed when it shouldn't have\n");
758 ok(passfail
.shorterror
==ERROR_PATH_NOT_FOUND
||
759 passfail
.shorterror
==ERROR_FILE_NOT_FOUND
||
760 !passfail
.shorterror
,
761 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
762 passfail
.shorterror
);
763 if(pGetLongPathNameA
) {
764 ok(passfail
.longlen
==0,"GetLongPathNameA passed when it shouldn't have\n");
765 ok(passfail
.longerror
==ERROR_PATH_NOT_FOUND
||
766 passfail
.longerror
==ERROR_FILE_NOT_FOUND
,
767 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
770 /* Next try directories ending with '\\' */
771 /* Existing Directories */
772 sprintf(tmpstr
,"%s\\",SHORTDIR
);
773 test_ValidPathA(curdir
,"",tmpstr
,tmpstr1
,NULL
,"test13");
774 sprintf(tmpstr
,"%s\\",LONGDIR
);
775 test_ValidPathA(curdir
,"",tmpstr
,tmpstr1
,NULL
,"test14");
776 /* Nonexistent directories */
777 sprintf(tmpstr
,"%s\\",NONDIR_SHORT
);
778 test_ValidPathA(curdir
,"",tmpstr
,tmpstr1
,&passfail
,"test15");
779 sprintf(tmpstr2
,"%s\\%s",curdir_short
,tmpstr
);
780 ok((passfail
.shortlen
==0 &&
781 (passfail
.shorterror
==ERROR_PATH_NOT_FOUND
||
782 passfail
.shorterror
==ERROR_FILE_NOT_FOUND
)) ||
783 (passfail
.shortlen
==strlen(tmpstr2
) && lstrcmpiA(tmpstr1
,tmpstr2
)==0),
784 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
785 passfail
.shortlen
,passfail
.shorterror
,tmpstr
);
786 if(pGetLongPathNameA
) {
787 ok(passfail
.longlen
==0,"GetLongPathNameA passed when it shouldn't have\n");
788 ok(passfail
.longerror
==ERROR_FILE_NOT_FOUND
,
789 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
792 sprintf(tmpstr
,"%s\\",NONDIR_LONG
);
793 test_ValidPathA(curdir
,"",tmpstr
,tmpstr1
,&passfail
,"test16");
794 ok(passfail
.shortlen
==0,"GetShortPathNameA passed when it shouldn't have\n");
795 ok(passfail
.shorterror
==ERROR_PATH_NOT_FOUND
||
796 passfail
.shorterror
==ERROR_FILE_NOT_FOUND
||
797 !passfail
.shorterror
,
798 "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
799 passfail
.shorterror
);
800 if(pGetLongPathNameA
) {
801 ok(passfail
.longlen
==0,"GetLongPathNameA passed when it shouldn't have\n");
802 ok(passfail
.longerror
==ERROR_FILE_NOT_FOUND
,
803 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
806 /* Test GetFullPathNameA with drive letters */
807 if( curDrive
!= NOT_A_VALID_DRIVE
) {
808 sprintf(tmpstr
,"%c:",curdir
[0]);
809 ok(GetFullPathNameA(tmpstr
,MAX_PATH
,tmpstr2
,&strptr
),
810 "GetFullPathNameA(%c:) failed\n", curdir
[0]);
811 GetCurrentDirectoryA(MAX_PATH
,tmpstr
);
812 sprintf(tmpstr1
,"%s\\",tmpstr
);
813 ok(lstrcmpiA(tmpstr
,tmpstr2
)==0 || lstrcmpiA(tmpstr1
,tmpstr2
)==0,
814 "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
815 curdir
[0],tmpstr2
,tmpstr
,tmpstr1
);
817 sprintf(tmpstr
,"%c:\\%s\\%s",curDrive
,SHORTDIR
,SHORTFILE
);
818 ok(GetFullPathNameA(tmpstr
,MAX_PATH
,tmpstr1
,&strptr
),"GetFullPathNameA failed\n");
819 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
820 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
821 ok(lstrcmpiA(SHORTFILE
,strptr
)==0,
822 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr
,SHORTFILE
);
824 /* Without a leading slash, insert the current directory if on the current drive */
825 sprintf(tmpstr
,"%c:%s\\%s",curdir
[0],SHORTDIR
,SHORTFILE
);
826 ok(GetFullPathNameA(tmpstr
,MAX_PATH
,tmpstr1
,&strptr
),"GetFullPathNameA failed\n");
827 sprintf(tmpstr
,"%s\\%s\\%s",curdir
,SHORTDIR
,SHORTFILE
);
828 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
829 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
830 ok(lstrcmpiA(SHORTFILE
,strptr
)==0,
831 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr
,SHORTFILE
);
832 /* Otherwise insert the missing leading slash */
833 if( otherDrive
!= NOT_A_VALID_DRIVE
) {
834 /* FIXME: this test assumes that current directory on other drive is root */
835 sprintf(tmpstr
,"%c:%s\\%s",otherDrive
,SHORTDIR
,SHORTFILE
);
836 ok(GetFullPathNameA(tmpstr
,MAX_PATH
,tmpstr1
,&strptr
),"GetFullPathNameA failed for %s\n", tmpstr
);
837 sprintf(tmpstr
,"%c:\\%s\\%s",otherDrive
,SHORTDIR
,SHORTFILE
);
838 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
839 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
840 ok(lstrcmpiA(SHORTFILE
,strptr
)==0,
841 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr
,SHORTFILE
);
843 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
845 if( curDrive
!= NOT_A_VALID_DRIVE
) {
846 sprintf(tmpstr
,"%c:/%s\\%s",curDrive
,SHORTDIR
,SHORTFILE
);
847 ok(GetFullPathNameA(tmpstr
,MAX_PATH
,tmpstr1
,&strptr
),"GetFullPathNameA failed\n");
848 sprintf(tmpstr
,"%c:\\%s\\%s",curDrive
,SHORTDIR
,SHORTFILE
);
849 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
850 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
851 ok(lstrcmpiA(SHORTFILE
,strptr
)==0,
852 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr
,SHORTFILE
);
855 sprintf(tmpstr
,"%c:%s/%s",curdir
[0],SHORTDIR
,SHORTFILE
);
856 ok(GetFullPathNameA(tmpstr
,MAX_PATH
,tmpstr1
,&strptr
),"GetFullPathNameA failed\n");
857 sprintf(tmpstr
,"%s\\%s\\%s",curdir
,SHORTDIR
,SHORTFILE
);
858 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
859 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
860 ok(lstrcmpiA(SHORTFILE
,strptr
)==0,
861 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr
,SHORTFILE
);
862 /* Windows will insert a drive letter in front of an absolute UNIX path */
863 sprintf(tmpstr
,"/%s/%s",SHORTDIR
,SHORTFILE
);
864 ok(GetFullPathNameA(tmpstr
,MAX_PATH
,tmpstr1
,&strptr
),"GetFullPathNameA failed\n");
865 sprintf(tmpstr
,"%c:\\%s\\%s",*tmpstr1
,SHORTDIR
,SHORTFILE
);
866 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
867 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
868 /* This passes in Wine because it still contains the pointer from the previous test */
869 ok(lstrcmpiA(SHORTFILE
,strptr
)==0,
870 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr
,SHORTFILE
);
872 /* Now try some relative paths */
873 ok(GetShortPathNameA(LONGDIR
,tmpstr
,MAX_PATH
),"GetShortPathNameA failed\n");
874 test_SplitShortPathA(tmpstr
,dir
,eight
,three
);
875 if(pGetLongPathNameA
) {
876 ok(pGetLongPathNameA(tmpstr
,tmpstr1
,MAX_PATH
),"GetLongPathNameA failed\n");
877 ok(lstrcmpiA(tmpstr1
,LONGDIR
)==0,
878 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1
,LONGDIR
);
880 sprintf(tmpstr
,".\\%s",LONGDIR
);
881 ok(GetShortPathNameA(tmpstr
,tmpstr1
,MAX_PATH
),"GetShortPathNameA failed\n");
882 test_SplitShortPathA(tmpstr1
,dir
,eight
,three
);
883 ok(lstrcmpiA(dir
,".")==0 || dir
[0]=='\0',
884 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1
);
885 if(pGetLongPathNameA
) {
886 ok(pGetLongPathNameA(tmpstr1
,tmpstr1
,MAX_PATH
),"GetLongPathNameA failed %s\n",
888 ok(lstrcmpiA(tmpstr1
,tmpstr
)==0,
889 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
891 /* Check out Get*PathNameA on some funny characters */
892 for(i
=0;i
<lstrlenA(funny_chars
);i
++) {
894 valid
=(is_char_ok
[i
]=='0') ? 0 : 1;
895 sprintf(tmpstr1
,"check%d-1",i
);
896 sprintf(tmpstr
,"file%c000.ext",funny_chars
[i
]);
897 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
898 sprintf(tmpstr1
,"check%d-2",i
);
899 sprintf(tmpstr
,"file000.e%ct",funny_chars
[i
]);
900 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
901 sprintf(tmpstr1
,"check%d-3",i
);
902 sprintf(tmpstr
,"%cfile000.ext",funny_chars
[i
]);
903 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
904 sprintf(tmpstr1
,"check%d-4",i
);
905 sprintf(tmpstr
,"file000%c.ext",funny_chars
[i
]);
906 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
907 sprintf(tmpstr1
,"check%d-5",i
);
908 sprintf(tmpstr
,"Long %c File",funny_chars
[i
]);
909 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
910 sprintf(tmpstr1
,"check%d-6",i
);
911 sprintf(tmpstr
,"%c Long File",funny_chars
[i
]);
912 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
913 sprintf(tmpstr1
,"check%d-7",i
);
914 sprintf(tmpstr
,"Long File %c",funny_chars
[i
]);
915 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
917 /* Now try it on mixed case short names */
918 test_ShortPathCase(curdir
,SHORTDIR
,LONGFILE
);
919 test_ShortPathCase(curdir
,LONGDIR
,SHORTFILE
);
920 test_ShortPathCase(curdir
,LONGDIR
,LONGFILE
);
923 static void test_GetTempPathA(char* tmp_dir
)
925 DWORD len
, len_with_null
;
928 len_with_null
= strlen(tmp_dir
) + 1;
930 lstrcpyA(buf
, "foo");
931 len
= GetTempPathA(MAX_PATH
, buf
);
932 ok(len
<= MAX_PATH
, "should fit into MAX_PATH\n");
933 ok(lstrcmpiA(buf
, tmp_dir
) == 0, "expected [%s], got [%s]\n",tmp_dir
,buf
);
934 ok(len
== strlen(buf
), "returned length should be equal to the length of string\n");
936 /* Some versions of Windows touch the buffer, some don't so we don't
937 * test that. Also, NT sometimes exaggerates the required buffer size
938 * so we cannot test for an exact match. Finally, the
939 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
940 * For instance in some cases Win98 returns len_with_null - 1 instead
943 len
= GetTempPathA(1, buf
);
944 ok(len
>= len_with_null
, "Expected >= %u, got %u\n", len_with_null
, len
);
946 len
= GetTempPathA(0, NULL
);
947 ok(len
>= len_with_null
, "Expected >= %u, got %u\n", len_with_null
, len
);
949 /* The call above gave us the buffer size that Windows thinks is needed
950 * so the next call should work
952 lstrcpyA(buf
, "foo");
953 len
= GetTempPathA(len
, buf
);
954 ok(lstrcmpiA(buf
, tmp_dir
) == 0, "expected [%s], got [%s]\n",tmp_dir
,buf
);
955 ok(len
== strlen(buf
), "returned length should be equal to the length of string\n");
958 static void test_GetTempPathW(char* tmp_dir
)
960 DWORD len
, len_with_null
;
962 WCHAR tmp_dirW
[MAX_PATH
];
963 static const WCHAR fooW
[] = {'f','o','o',0};
965 MultiByteToWideChar(CP_ACP
,0,tmp_dir
,-1,tmp_dirW
,sizeof(tmp_dirW
)/sizeof(*tmp_dirW
));
966 len_with_null
= lstrlenW(tmp_dirW
) + 1;
968 /* This one is different from ANSI version: ANSI version doesn't
969 * touch the buffer, unicode version usually truncates the buffer
970 * to zero size. NT still exaggerates the required buffer size
971 * sometimes so we cannot test for an exact match. Finally, the
972 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
973 * For instance on NT4 it will sometimes return a path without the
974 * trailing '\\' and sometimes return an error.
978 len
= GetTempPathW(MAX_PATH
, buf
);
979 if (len
== 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
981 win_skip("GetTempPathW is not available\n");
984 ok(lstrcmpiW(buf
, tmp_dirW
) == 0, "GetTempPathW returned an incorrect temporary path\n");
985 ok(len
== lstrlenW(buf
), "returned length should be equal to the length of string\n");
988 len
= GetTempPathW(1, buf
);
989 ok(buf
[0] == 0, "unicode version should truncate the buffer to zero size\n");
990 ok(len
>= len_with_null
, "Expected >= %u, got %u\n", len_with_null
, len
);
992 len
= GetTempPathW(0, NULL
);
993 ok(len
>= len_with_null
, "Expected >= %u, got %u\n", len_with_null
, len
);
996 len
= GetTempPathW(len
, buf
);
997 ok(lstrcmpiW(buf
, tmp_dirW
) == 0, "GetTempPathW returned an incorrect temporary path\n");
998 ok(len
== lstrlenW(buf
), "returned length should be equal to the length of string\n");
1001 static void test_GetTempPath(void)
1003 char save_TMP
[MAX_PATH
];
1004 char windir
[MAX_PATH
];
1005 char origdir
[MAX_PATH
];
1008 GetCurrentDirectoryA(sizeof(origdir
), origdir
);
1009 if (!GetEnvironmentVariableA("TMP", save_TMP
, sizeof(save_TMP
))) save_TMP
[0] = 0;
1011 /* test default configuration */
1012 trace("TMP=%s\n", save_TMP
);
1015 strcpy(buf
,save_TMP
);
1016 if (buf
[strlen(buf
)-1]!='\\')
1018 test_GetTempPathA(buf
);
1019 test_GetTempPathW(buf
);
1022 /* TMP=C:\WINDOWS */
1023 GetWindowsDirectoryA(windir
, sizeof(windir
));
1024 SetEnvironmentVariableA("TMP", windir
);
1025 GetEnvironmentVariableA("TMP", buf
, sizeof(buf
));
1026 trace("TMP=%s\n", buf
);
1027 strcat(windir
,"\\");
1028 test_GetTempPathA(windir
);
1029 test_GetTempPathW(windir
);
1032 GetWindowsDirectoryA(windir
, sizeof(windir
));
1034 SetEnvironmentVariableA("TMP", windir
);
1035 GetEnvironmentVariableA("TMP", buf
, sizeof(buf
));
1036 trace("TMP=%s\n", buf
);
1037 test_GetTempPathA(windir
);
1038 test_GetTempPathW(windir
);
1040 /* TMP=C: i.e. use current working directory of the specified drive */
1041 GetWindowsDirectoryA(windir
, sizeof(windir
));
1042 SetCurrentDirectoryA(windir
);
1044 SetEnvironmentVariableA("TMP", windir
);
1045 GetEnvironmentVariableA("TMP", buf
, sizeof(buf
));
1046 trace("TMP=%s\n", buf
);
1047 GetWindowsDirectoryA(windir
, sizeof(windir
));
1048 strcat(windir
,"\\");
1049 test_GetTempPathA(windir
);
1050 test_GetTempPathW(windir
);
1052 SetEnvironmentVariableA("TMP", save_TMP
);
1053 SetCurrentDirectoryA(origdir
);
1056 static void test_GetLongPathNameA(void)
1058 DWORD length
, explength
, hostsize
;
1059 char tempfile
[MAX_PATH
];
1060 char longpath
[MAX_PATH
];
1061 char unc_prefix
[MAX_PATH
];
1062 char unc_short
[MAX_PATH
], unc_long
[MAX_PATH
];
1063 char temppath
[MAX_PATH
], temppath2
[MAX_PATH
];
1066 if (!pGetLongPathNameA
)
1069 GetTempPathA(MAX_PATH
, tempfile
);
1070 lstrcatA(tempfile
, "longfilename.longext");
1072 file
= CreateFileA(tempfile
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1075 /* Test a normal path with a small buffer size */
1076 memset(temppath
, 0, MAX_PATH
);
1077 length
= pGetLongPathNameA(tempfile
, temppath
, 4);
1078 /* We have a failure so length should be the minimum plus the terminating '0' */
1079 ok(length
>= strlen(tempfile
) + 1, "Wrong length\n");
1080 ok(temppath
[0] == 0, "Buffer should not have been touched\n");
1082 /* Some UNC syntax tests */
1084 memset(temppath
, 0, MAX_PATH
);
1085 memset(temppath2
, 0, MAX_PATH
);
1086 lstrcpyA(temppath2
, "\\\\?\\");
1087 lstrcatA(temppath2
, tempfile
);
1088 explength
= length
+ 4;
1090 SetLastError(0xdeadbeef);
1091 length
= pGetLongPathNameA(temppath2
, NULL
, 0);
1092 if (length
== 0 && GetLastError() == ERROR_BAD_NET_NAME
)
1094 win_skip("UNC syntax tests don't work on Win98/WinMe\n");
1095 DeleteFileA(tempfile
);
1098 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1100 length
= pGetLongPathNameA(temppath2
, NULL
, MAX_PATH
);
1101 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1103 length
= pGetLongPathNameA(temppath2
, temppath
, 4);
1104 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1105 ok(temppath
[0] == 0, "Buffer should not have been touched\n");
1107 /* Now an UNC path with the computername */
1108 lstrcpyA(unc_prefix
, "\\\\");
1109 hostsize
= sizeof(unc_prefix
) - 2;
1110 GetComputerNameA(unc_prefix
+ 2, &hostsize
);
1111 lstrcatA(unc_prefix
, "\\");
1113 /* Create a short syntax for the whole unc path */
1114 memset(unc_short
, 0, MAX_PATH
);
1115 GetShortPathNameA(tempfile
, temppath
, MAX_PATH
);
1116 lstrcpyA(unc_short
, unc_prefix
);
1117 unc_short
[lstrlenA(unc_short
)] = temppath
[0];
1118 lstrcatA(unc_short
, "$\\");
1119 lstrcatA(unc_short
, strchr(temppath
, '\\') + 1);
1121 /* Create a long syntax for reference */
1122 memset(longpath
, 0, MAX_PATH
);
1123 pGetLongPathNameA(tempfile
, temppath
, MAX_PATH
);
1124 lstrcpyA(longpath
, unc_prefix
);
1125 longpath
[lstrlenA(longpath
)] = temppath
[0];
1126 lstrcatA(longpath
, "$\\");
1127 lstrcatA(longpath
, strchr(temppath
, '\\') + 1);
1130 SetLastError(0xdeadbeef);
1131 length
= pGetLongPathNameA(unc_short
, NULL
, 0);
1132 if (length
== 0 && GetLastError() == ERROR_BAD_NETPATH
)
1134 /* Seen on Window XP Home */
1135 win_skip("UNC with computername is not supported\n");
1136 DeleteFileA(tempfile
);
1139 explength
= lstrlenA(longpath
) + 1;
1141 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1143 length
= pGetLongPathNameA(unc_short
, NULL
, MAX_PATH
);
1145 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1147 memset(unc_long
, 0, MAX_PATH
);
1148 length
= pGetLongPathNameA(unc_short
, unc_long
, lstrlenA(unc_short
));
1149 /* length will include terminating '0' on failure */
1151 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1152 ok(unc_long
[0] == 0, "Buffer should not have been touched\n");
1154 memset(unc_long
, 0, MAX_PATH
);
1155 length
= pGetLongPathNameA(unc_short
, unc_long
, length
);
1156 /* length doesn't include terminating '0' on success */
1160 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1161 ok(!lstrcmpiA(unc_long
, longpath
), "Expected (%s), got (%s)\n", longpath
, unc_long
);
1164 DeleteFileA(tempfile
);
1167 static void test_GetLongPathNameW(void)
1169 DWORD length
, expanded
;
1172 WCHAR empty
[MAX_PATH
];
1173 WCHAR tempdir
[MAX_PATH
], name
[200];
1174 WCHAR dirpath
[4 + MAX_PATH
+ 200]; /* To ease removal */
1175 WCHAR shortpath
[4 + MAX_PATH
+ 200 + 1 + 200];
1176 static const WCHAR prefix
[] = { '\\','\\','?','\\', 0};
1177 static const WCHAR backslash
[] = { '\\', 0};
1178 static const WCHAR letterX
[] = { 'X', 0};
1180 if (!pGetLongPathNameW
)
1183 SetLastError(0xdeadbeef);
1184 length
= pGetLongPathNameW(NULL
,NULL
,0);
1185 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1187 win_skip("GetLongPathNameW is not implemented\n");
1190 ok(0==length
,"GetLongPathNameW returned %d but expected 0\n",length
);
1191 ok(GetLastError()==ERROR_INVALID_PARAMETER
,"GetLastError returned %d but expected ERROR_INVALID_PARAMETER\n",GetLastError());
1193 SetLastError(0xdeadbeef);
1195 length
= pGetLongPathNameW(empty
,NULL
,0);
1196 ok(0==length
,"GetLongPathNameW returned %d but expected 0\n",length
);
1197 ok(GetLastError()==ERROR_PATH_NOT_FOUND
,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
1199 /* Create a long path name. The path needs to exist for these tests to
1200 * succeed so we need the "\\?\" prefix when creating directories and
1204 while (lstrlenW(name
) < (sizeof(name
)/sizeof(WCHAR
) - 1))
1205 lstrcatW(name
, letterX
);
1207 GetTempPathW(MAX_PATH
, tempdir
);
1209 lstrcpyW(shortpath
, prefix
);
1210 lstrcatW(shortpath
, tempdir
);
1211 lstrcatW(shortpath
, name
);
1212 lstrcpyW(dirpath
, shortpath
);
1213 ret
= CreateDirectoryW(shortpath
, NULL
);
1214 ok(ret
, "Could not create the temporary directory : %d\n", GetLastError());
1215 lstrcatW(shortpath
, backslash
);
1216 lstrcatW(shortpath
, name
);
1218 /* Path does not exist yet and we know it overruns MAX_PATH */
1221 SetLastError(0xdeadbeef);
1222 length
= pGetLongPathNameW(shortpath
+ 4, NULL
, 0);
1223 ok(length
== 0, "Expected 0, got %d\n", length
);
1225 ok(GetLastError() == ERROR_PATH_NOT_FOUND
,
1226 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1228 SetLastError(0xdeadbeef);
1229 length
= pGetLongPathNameW(shortpath
, NULL
, 0);
1232 ok(length
== 0, "Expected 0, got %d\n", length
);
1233 ok(GetLastError() == ERROR_FILE_NOT_FOUND
,
1234 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1237 file
= CreateFileW(shortpath
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
1238 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1239 ok(file
!= INVALID_HANDLE_VALUE
,
1240 "Could not create the temporary file : %d.\n", GetLastError());
1246 SetLastError(0xdeadbeef);
1247 length
= pGetLongPathNameW(shortpath
+ 4, NULL
, 0);
1250 ok(length
== 0, "Expected 0, got %d\n", length
);
1251 ok(GetLastError() == ERROR_PATH_NOT_FOUND
, "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1254 expanded
= 4 + (pGetLongPathNameW(tempdir
, NULL
, 0) - 1) + lstrlenW(name
) + 1 + lstrlenW(name
) + 1;
1255 SetLastError(0xdeadbeef);
1256 length
= pGetLongPathNameW(shortpath
, NULL
, 0);
1257 ok(length
== expanded
, "Expected %d, got %d\n", expanded
, length
);
1259 /* NULL buffer with length crashes on Windows */
1261 pGetLongPathNameW(shortpath
, NULL
, 20);
1263 ok(DeleteFileW(shortpath
), "Could not delete temporary file\n");
1264 ok(RemoveDirectoryW(dirpath
), "Could not delete temporary directory\n");
1267 static void test_GetShortPathNameW(void)
1269 WCHAR test_path
[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
1270 WCHAR path
[MAX_PATH
];
1271 WCHAR short_path
[MAX_PATH
];
1275 WCHAR name
[] = { 't', 'e', 's', 't', 0 };
1276 WCHAR backSlash
[] = { '\\', 0 };
1278 SetLastError(0xdeadbeef);
1279 GetTempPathW( MAX_PATH
, path
);
1280 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1282 win_skip("GetTempPathW is not implemented\n");
1286 lstrcatW( path
, test_path
);
1287 lstrcatW( path
, backSlash
);
1288 ret
= CreateDirectoryW( path
, NULL
);
1289 ok( ret
, "Directory was not created. LastError = %d\n", GetLastError() );
1291 /* Starting a main part of test */
1292 length
= GetShortPathNameW( path
, short_path
, 0 );
1293 ok( length
, "GetShortPathNameW returned 0.\n" );
1294 ret
= GetShortPathNameW( path
, short_path
, length
);
1295 ok( ret
, "GetShortPathNameW returned 0.\n" );
1297 lstrcatW( short_path
, name
);
1299 /* GetShortPathName for a non-existent short file name should fail */
1300 SetLastError(0xdeadbeef);
1301 length
= GetShortPathNameW( short_path
, path
, 0 );
1302 ok(!length
, "GetShortPathNameW should fail\n");
1303 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
1305 file
= CreateFileW( short_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1306 ok( file
!= INVALID_HANDLE_VALUE
, "File was not created.\n" );
1309 CloseHandle( file
);
1310 ret
= DeleteFileW( short_path
);
1311 ok( ret
, "Cannot delete file.\n" );
1312 ret
= RemoveDirectoryW( path
);
1313 ok( ret
, "Cannot delete directory.\n" );
1316 static void test_GetSystemDirectory(void)
1318 CHAR buffer
[MAX_PATH
+ 4];
1322 SetLastError(0xdeadbeef);
1323 res
= GetSystemDirectoryA(NULL
, 0);
1324 /* res includes the terminating Zero */
1325 ok(res
> 0, "returned %d with %d (expected '>0')\n", res
, GetLastError());
1329 /* this crashes on XP */
1331 GetSystemDirectoryA(NULL
, total
);
1333 SetLastError(0xdeadbeef);
1334 res
= GetSystemDirectoryA(NULL
, total
-1);
1335 /* 95+NT: total (includes the terminating Zero)
1336 98+ME: 0 with ERROR_INVALID_PARAMETER */
1337 ok( (res
== total
) || (!res
&& (GetLastError() == ERROR_INVALID_PARAMETER
)),
1338 "returned %d with %d (expected '%d' or: '0' with "
1339 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError(), total
);
1341 if (total
> MAX_PATH
) return;
1344 SetLastError(0xdeadbeef);
1345 res
= GetSystemDirectoryA(buffer
, total
);
1346 /* res does not include the terminating Zero */
1347 ok( (res
== (total
-1)) && (buffer
[0]),
1348 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1349 res
, GetLastError(), buffer
, total
-1);
1352 SetLastError(0xdeadbeef);
1353 res
= GetSystemDirectoryA(buffer
, total
+ 1);
1354 /* res does not include the terminating Zero */
1355 ok( (res
== (total
-1)) && (buffer
[0]),
1356 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1357 res
, GetLastError(), buffer
, total
-1);
1359 memset(buffer
, '#', total
+ 1);
1360 buffer
[total
+ 2] = '\0';
1361 SetLastError(0xdeadbeef);
1362 res
= GetSystemDirectoryA(buffer
, total
-1);
1363 /* res includes the terminating Zero) */
1364 ok( res
== total
, "returned %d with %d and '%s' (expected '%d')\n",
1365 res
, GetLastError(), buffer
, total
);
1367 memset(buffer
, '#', total
+ 1);
1368 buffer
[total
+ 2] = '\0';
1369 SetLastError(0xdeadbeef);
1370 res
= GetSystemDirectoryA(buffer
, total
-2);
1371 /* res includes the terminating Zero) */
1372 ok( res
== total
, "returned %d with %d and '%s' (expected '%d')\n",
1373 res
, GetLastError(), buffer
, total
);
1376 static void test_GetWindowsDirectory(void)
1378 CHAR buffer
[MAX_PATH
+ 4];
1382 SetLastError(0xdeadbeef);
1383 res
= GetWindowsDirectoryA(NULL
, 0);
1384 /* res includes the terminating Zero */
1385 ok(res
> 0, "returned %d with %d (expected '>0')\n", res
, GetLastError());
1388 /* this crashes on XP */
1390 GetWindowsDirectoryA(NULL
, total
);
1392 SetLastError(0xdeadbeef);
1393 res
= GetWindowsDirectoryA(NULL
, total
-1);
1394 /* 95+NT: total (includes the terminating Zero)
1395 98+ME: 0 with ERROR_INVALID_PARAMETER */
1396 ok( (res
== total
) || (!res
&& (GetLastError() == ERROR_INVALID_PARAMETER
)),
1397 "returned %d with %d (expected '%d' or: '0' with "
1398 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError(), total
);
1400 if (total
> MAX_PATH
) return;
1403 SetLastError(0xdeadbeef);
1404 res
= GetWindowsDirectoryA(buffer
, total
);
1405 /* res does not include the terminating Zero */
1406 ok( (res
== (total
-1)) && (buffer
[0]),
1407 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1408 res
, GetLastError(), buffer
, total
-1);
1411 SetLastError(0xdeadbeef);
1412 res
= GetWindowsDirectoryA(buffer
, total
+ 1);
1413 /* res does not include the terminating Zero */
1414 ok( (res
== (total
-1)) && (buffer
[0]),
1415 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1416 res
, GetLastError(), buffer
, total
-1);
1418 memset(buffer
, '#', total
+ 1);
1419 buffer
[total
+ 2] = '\0';
1420 SetLastError(0xdeadbeef);
1421 res
= GetWindowsDirectoryA(buffer
, total
-1);
1422 /* res includes the terminating Zero) */
1423 ok( res
== total
, "returned %d with %d and '%s' (expected '%d')\n",
1424 res
, GetLastError(), buffer
, total
);
1426 memset(buffer
, '#', total
+ 1);
1427 buffer
[total
+ 2] = '\0';
1428 SetLastError(0xdeadbeef);
1429 res
= GetWindowsDirectoryA(buffer
, total
-2);
1430 /* res includes the terminating Zero) */
1431 ok( res
== total
, "returned %d with %d and '%s' (expected '%d')\n",
1432 res
, GetLastError(), buffer
, total
);
1435 static void test_NeedCurrentDirectoryForExePathA(void)
1437 if (!pNeedCurrentDirectoryForExePathA
)
1439 win_skip("NeedCurrentDirectoryForExePathA is not available\n");
1443 /* Crashes in Windows */
1445 pNeedCurrentDirectoryForExePathA(NULL
);
1447 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL
);
1448 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1449 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1450 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1452 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1453 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1454 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1455 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1458 static void test_NeedCurrentDirectoryForExePathW(void)
1460 const WCHAR thispath
[] = {'.', 0};
1461 const WCHAR fullpath
[] = {'c', ':', '\\', 0};
1462 const WCHAR cmdname
[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1464 if (!pNeedCurrentDirectoryForExePathW
)
1466 win_skip("NeedCurrentDirectoryForExePathW is not available\n");
1470 /* Crashes in Windows */
1472 pNeedCurrentDirectoryForExePathW(NULL
);
1474 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL
);
1475 ok(pNeedCurrentDirectoryForExePathW(thispath
), "returned FALSE for \".\"\n");
1476 ok(pNeedCurrentDirectoryForExePathW(fullpath
), "returned FALSE for \"c:\\\"\n");
1477 ok(pNeedCurrentDirectoryForExePathW(cmdname
), "returned FALSE for \"cmd.exe\"\n");
1479 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1480 ok(!pNeedCurrentDirectoryForExePathW(thispath
), "returned TRUE for \".\"\n");
1481 ok(pNeedCurrentDirectoryForExePathW(fullpath
), "returned FALSE for \"c:\\\"\n");
1482 ok(!pNeedCurrentDirectoryForExePathW(cmdname
), "returned TRUE for \"cmd.exe\"\n");
1485 /* Call various path/file name retrieving APIs and check the case of
1486 * the returned drive letter. Some apps (for instance Adobe Photoshop CS3
1487 * installer) depend on the drive letter being in upper case.
1489 static void test_drive_letter_case(void)
1494 #define is_upper_case_letter(a) ((a) >= 'A' && (a) <= 'Z')
1496 memset(buf
, 0, sizeof(buf
));
1497 SetLastError(0xdeadbeef);
1498 ret
= GetWindowsDirectoryA(buf
, sizeof(buf
));
1499 ok(ret
, "GetWindowsDirectory error %u\n", GetLastError());
1500 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1501 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1502 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1504 /* re-use the buffer returned by GetFullPathName */
1506 SetLastError(0xdeadbeef);
1507 ret
= GetFullPathNameA(buf
+ 2, sizeof(buf
), buf
, NULL
);
1508 ok(ret
, "GetFullPathName error %u\n", GetLastError());
1509 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1510 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1511 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1513 memset(buf
, 0, sizeof(buf
));
1514 SetLastError(0xdeadbeef);
1515 ret
= GetSystemDirectoryA(buf
, sizeof(buf
));
1516 ok(ret
, "GetSystemDirectory error %u\n", GetLastError());
1517 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1518 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1519 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1521 memset(buf
, 0, sizeof(buf
));
1522 SetLastError(0xdeadbeef);
1523 ret
= GetCurrentDirectoryA(sizeof(buf
), buf
);
1524 ok(ret
, "GetCurrentDirectory error %u\n", GetLastError());
1525 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1526 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1527 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1529 /* TEMP is an environment variable, so it can't be tested for case-sensitivity */
1530 memset(buf
, 0, sizeof(buf
));
1531 SetLastError(0xdeadbeef);
1532 ret
= GetTempPathA(sizeof(buf
), buf
);
1533 ok(ret
, "GetTempPath error %u\n", GetLastError());
1534 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1537 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1538 ok(buf
[strlen(buf
)-1] == '\\', "Temporary path (%s) doesn't end in a slash\n", buf
);
1541 memset(buf
, 0, sizeof(buf
));
1542 SetLastError(0xdeadbeef);
1543 ret
= GetFullPathNameA(".", sizeof(buf
), buf
, NULL
);
1544 ok(ret
, "GetFullPathName error %u\n", GetLastError());
1545 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1546 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1547 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1549 /* re-use the buffer returned by GetFullPathName */
1550 SetLastError(0xdeadbeef);
1551 ret
= GetShortPathNameA(buf
, buf
, sizeof(buf
));
1552 ok(ret
, "GetShortPathName error %u\n", GetLastError());
1553 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1554 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1555 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1557 if (pGetLongPathNameA
)
1559 /* re-use the buffer returned by GetShortPathName */
1560 SetLastError(0xdeadbeef);
1561 ret
= pGetLongPathNameA(buf
, buf
, sizeof(buf
));
1562 ok(ret
, "GetLongPathNameA error %u\n", GetLastError());
1563 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1564 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1565 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1567 #undef is_upper_case_letter
1570 static const char manifest_dep
[] =
1571 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1572 "<assemblyIdentity version=\"1.2.3.4\" name=\"testdep1\" type=\"win32\" processorArchitecture=\"" ARCH
"\"/>"
1573 " <file name=\"testdep.dll\" />"
1574 " <file name=\"ole32\" />"
1575 " <file name=\"kernel32.dll\" />"
1578 static const char manifest_main
[] =
1579 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1580 "<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
1582 " <dependentAssembly>"
1583 " <assemblyIdentity type=\"win32\" name=\"testdep1\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH
"\" />"
1584 " </dependentAssembly>"
1588 static void create_manifest_file(const char *filename
, const char *manifest
)
1590 WCHAR path
[MAX_PATH
], manifest_path
[MAX_PATH
];
1594 MultiByteToWideChar( CP_ACP
, 0, filename
, -1, path
, MAX_PATH
);
1596 GetTempPathW(sizeof(manifest_path
)/sizeof(WCHAR
), manifest_path
);
1597 lstrcatW(manifest_path
, path
);
1599 file
= CreateFileW(manifest_path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1600 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %u\n", GetLastError());
1601 WriteFile(file
, manifest
, strlen(manifest
), &size
, NULL
);
1605 static void delete_manifest_file(const char *filename
)
1607 CHAR path
[MAX_PATH
];
1609 GetTempPathA(sizeof(path
), path
);
1610 strcat(path
, filename
);
1614 static HANDLE
test_create(const char *file
)
1616 WCHAR path
[MAX_PATH
], manifest_path
[MAX_PATH
];
1620 MultiByteToWideChar(CP_ACP
, 0, file
, -1, path
, MAX_PATH
);
1621 GetTempPathW(sizeof(manifest_path
)/sizeof(WCHAR
), manifest_path
);
1622 lstrcatW(manifest_path
, path
);
1624 memset(&actctx
, 0, sizeof(ACTCTXW
));
1625 actctx
.cbSize
= sizeof(ACTCTXW
);
1626 actctx
.lpSource
= manifest_path
;
1628 handle
= pCreateActCtxW(&actctx
);
1629 ok(handle
!= INVALID_HANDLE_VALUE
, "failed to create context, error %u\n", GetLastError());
1631 ok(actctx
.cbSize
== sizeof(actctx
), "cbSize=%d\n", actctx
.cbSize
);
1632 ok(actctx
.dwFlags
== 0, "dwFlags=%d\n", actctx
.dwFlags
);
1633 ok(actctx
.lpSource
== manifest_path
, "lpSource=%p\n", actctx
.lpSource
);
1634 ok(actctx
.wProcessorArchitecture
== 0, "wProcessorArchitecture=%d\n", actctx
.wProcessorArchitecture
);
1635 ok(actctx
.wLangId
== 0, "wLangId=%d\n", actctx
.wLangId
);
1636 ok(actctx
.lpAssemblyDirectory
== NULL
, "lpAssemblyDirectory=%p\n", actctx
.lpAssemblyDirectory
);
1637 ok(actctx
.lpResourceName
== NULL
, "lpResourceName=%p\n", actctx
.lpResourceName
);
1638 ok(actctx
.lpApplicationName
== NULL
, "lpApplicationName=%p\n", actctx
.lpApplicationName
);
1639 ok(actctx
.hModule
== NULL
, "hModule=%p\n", actctx
.hModule
);
1644 static void test_SearchPathA(void)
1646 static const CHAR testdepA
[] = "testdep.dll";
1647 static const CHAR testdeprelA
[] = "./testdep.dll";
1648 static const CHAR kernel32A
[] = "kernel32.dll";
1649 static const CHAR fileA
[] = "";
1650 CHAR pathA
[MAX_PATH
], buffA
[MAX_PATH
], path2A
[MAX_PATH
], path3A
[MAX_PATH
], curdirA
[MAX_PATH
];
1651 CHAR tmpdirA
[MAX_PATH
], *ptrA
= NULL
;
1659 win_skip("SearchPathA isn't available\n");
1663 GetWindowsDirectoryA(pathA
, sizeof(pathA
)/sizeof(CHAR
));
1666 SetLastError(0xdeadbeef);
1667 ret
= pSearchPathA(pathA
, NULL
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, &ptrA
);
1668 ok(ret
== 0, "Expected failure, got %d\n", ret
);
1669 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1670 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1672 /* empty filename */
1673 SetLastError(0xdeadbeef);
1674 ret
= pSearchPathA(pathA
, fileA
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, &ptrA
);
1675 ok(ret
== 0, "Expected failure, got %d\n", ret
);
1676 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1677 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1679 if (!pActivateActCtx
)
1682 create_manifest_file("testdep1.manifest", manifest_dep
);
1683 create_manifest_file("main.manifest", manifest_main
);
1685 handle
= test_create("main.manifest");
1686 delete_manifest_file("testdep1.manifest");
1687 delete_manifest_file("main.manifest");
1689 /* search fails without active context */
1690 ret
= pSearchPathA(NULL
, testdepA
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1691 ok(ret
== 0, "got %d\n", ret
);
1693 ret
= pSearchPathA(NULL
, kernel32A
, NULL
, sizeof(path2A
)/sizeof(CHAR
), path2A
, NULL
);
1694 ok(ret
&& ret
== strlen(path2A
), "got %d\n", ret
);
1696 ret
= pActivateActCtx(handle
, &cookie
);
1697 ok(ret
, "failed to activate context, %u\n", GetLastError());
1699 /* works when activated */
1700 ret
= pSearchPathA(NULL
, testdepA
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1701 ok(ret
&& ret
== strlen(buffA
), "got %d\n", ret
);
1703 ret
= pSearchPathA(NULL
, "testdep.dll", ".ext", sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1704 ok(ret
&& ret
== strlen(buffA
), "got %d\n", ret
);
1706 ret
= pSearchPathA(NULL
, "testdep", ".dll", sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1707 ok(ret
&& ret
== strlen(buffA
), "got %d\n", ret
);
1709 ret
= pSearchPathA(NULL
, "testdep", ".ext", sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1710 ok(!ret
, "got %d\n", ret
);
1712 /* name contains path */
1713 ret
= pSearchPathA(NULL
, testdeprelA
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1714 ok(!ret
, "got %d\n", ret
);
1716 /* fails with specified path that doesn't contain this file */
1717 ret
= pSearchPathA(pathA
, testdepA
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1718 ok(!ret
, "got %d\n", ret
);
1720 /* path is redirected for wellknown names too */
1721 ret
= pSearchPathA(NULL
, kernel32A
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1722 ok(ret
&& ret
== strlen(buffA
), "got %d\n", ret
);
1723 ok(strcmp(buffA
, path2A
), "got wrong path %s, %s\n", buffA
, path2A
);
1725 ret
= pDeactivateActCtx(0, cookie
);
1726 ok(ret
, "failed to deactivate context, %u\n", GetLastError());
1727 pReleaseActCtx(handle
);
1729 /* test the search path priority of the working directory */
1730 GetTempPathA(sizeof(tmpdirA
), tmpdirA
);
1731 ret
= GetCurrentDirectoryA(MAX_PATH
, curdirA
);
1732 ok(ret
, "failed to obtain working directory.\n");
1733 sprintf(pathA
, "%s\\%s", tmpdirA
, kernel32A
);
1734 ret
= pSearchPathA(NULL
, kernel32A
, NULL
, sizeof(path2A
)/sizeof(CHAR
), path2A
, NULL
);
1735 ok(ret
&& ret
== strlen(path2A
), "got %d\n", ret
);
1736 bret
= CopyFileA(path2A
, pathA
, FALSE
);
1737 ok(bret
!= 0, "failed to copy test executable to temp directory, %u\n", GetLastError());
1738 sprintf(path3A
, "%s%s%s", curdirA
, curdirA
[strlen(curdirA
)-1] != '\\' ? "\\" : "", kernel32A
);
1739 bret
= CopyFileA(path2A
, path3A
, FALSE
);
1740 ok(bret
!= 0, "failed to copy test executable to launch directory, %u\n", GetLastError());
1741 bret
= SetCurrentDirectoryA(tmpdirA
);
1742 ok(bret
, "failed to change working directory\n");
1743 ret
= pSearchPathA(NULL
, kernel32A
, ".exe", sizeof(buffA
), buffA
, NULL
);
1744 ok(ret
&& ret
== strlen(buffA
), "got %d\n", ret
);
1745 ok(strcmp(buffA
, path3A
) == 0, "expected %s, got %s\n", path3A
, buffA
);
1746 bret
= SetCurrentDirectoryA(curdirA
);
1747 ok(bret
, "failed to reset working directory\n");
1748 DeleteFileA(path3A
);
1752 static void test_SearchPathW(void)
1754 static const WCHAR testdeprelW
[] = {'.','/','t','e','s','t','d','e','p','.','d','l','l',0};
1755 static const WCHAR testdepW
[] = {'t','e','s','t','d','e','p','.','d','l','l',0};
1756 static const WCHAR testdep1W
[] = {'t','e','s','t','d','e','p',0};
1757 static const WCHAR kernel32dllW
[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
1758 static const WCHAR kernel32W
[] = {'k','e','r','n','e','l','3','2',0};
1759 static const WCHAR ole32W
[] = {'o','l','e','3','2',0};
1760 static const WCHAR extW
[] = {'.','e','x','t',0};
1761 static const WCHAR dllW
[] = {'.','d','l','l',0};
1762 static const WCHAR fileW
[] = { 0 };
1763 WCHAR pathW
[MAX_PATH
], buffW
[MAX_PATH
], path2W
[MAX_PATH
];
1771 win_skip("SearchPathW isn't available\n");
1777 /* NULL filename, crashes on nt4 */
1778 pSearchPathW(pathW
, NULL
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, &ptrW
);
1781 GetWindowsDirectoryW(pathW
, sizeof(pathW
)/sizeof(WCHAR
));
1783 /* empty filename */
1784 SetLastError(0xdeadbeef);
1785 ret
= pSearchPathW(pathW
, fileW
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, &ptrW
);
1786 ok(ret
== 0, "Expected failure, got %d\n", ret
);
1787 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1788 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1790 if (!pActivateActCtx
)
1793 create_manifest_file("testdep1.manifest", manifest_dep
);
1794 create_manifest_file("main.manifest", manifest_main
);
1796 handle
= test_create("main.manifest");
1797 delete_manifest_file("testdep1.manifest");
1798 delete_manifest_file("main.manifest");
1800 /* search fails without active context */
1801 ret
= pSearchPathW(NULL
, testdepW
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
1802 ok(ret
== 0, "got %d\n", ret
);
1804 ret
= pSearchPathW(NULL
, kernel32dllW
, NULL
, sizeof(path2W
)/sizeof(WCHAR
), path2W
, NULL
);
1805 ok(ret
&& ret
== lstrlenW(path2W
), "got %d\n", ret
);
1807 /* full path, name without 'dll' extension */
1808 GetSystemDirectoryW(pathW
, sizeof(pathW
)/sizeof(WCHAR
));
1809 ret
= pSearchPathW(pathW
, kernel32W
, NULL
, sizeof(path2W
)/sizeof(WCHAR
), path2W
, NULL
);
1810 ok(ret
== 0, "got %d\n", ret
);
1812 GetWindowsDirectoryW(pathW
, sizeof(pathW
)/sizeof(WCHAR
));
1814 ret
= pActivateActCtx(handle
, &cookie
);
1815 ok(ret
, "failed to activate context, %u\n", GetLastError());
1817 /* works when activated */
1818 ret
= pSearchPathW(NULL
, testdepW
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
1819 ok(ret
&& ret
== lstrlenW(buffW
), "got %d\n", ret
);
1821 ret
= pSearchPathW(NULL
, testdepW
, extW
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
1822 ok(ret
&& ret
== lstrlenW(buffW
), "got %d\n", ret
);
1824 ret
= pSearchPathW(NULL
, testdep1W
, dllW
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
1825 ok(ret
&& ret
== lstrlenW(buffW
), "got %d\n", ret
);
1827 ret
= pSearchPathW(NULL
, testdep1W
, extW
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
1828 ok(!ret
, "got %d\n", ret
);
1830 /* name contains path */
1831 ret
= pSearchPathW(NULL
, testdeprelW
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
1832 ok(!ret
, "got %d\n", ret
);
1834 /* fails with specified path that doesn't contain this file */
1835 ret
= pSearchPathW(pathW
, testdepW
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
1836 ok(!ret
, "got %d\n", ret
);
1838 /* path is redirected for wellknown names too, meaning it takes precedence over normal search order */
1839 ret
= pSearchPathW(NULL
, kernel32dllW
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
1840 ok(ret
&& ret
== lstrlenW(buffW
), "got %d\n", ret
);
1841 ok(lstrcmpW(buffW
, path2W
), "got wrong path %s, %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(path2W
));
1843 /* path is built using on manifest file name */
1844 ret
= pSearchPathW(NULL
, ole32W
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
1845 ok(ret
&& ret
== lstrlenW(buffW
), "got %d\n", ret
);
1847 ret
= pDeactivateActCtx(0, cookie
);
1848 ok(ret
, "failed to deactivate context, %u\n", GetLastError());
1849 pReleaseActCtx(handle
);
1852 static void test_GetFullPathNameA(void)
1854 char output
[MAX_PATH
], *filepart
;
1865 } invalid_parameters
[] =
1867 {NULL
, 0, NULL
, NULL
},
1868 {NULL
, MAX_PATH
, NULL
, NULL
},
1869 {NULL
, MAX_PATH
, output
, NULL
},
1870 {NULL
, MAX_PATH
, output
, &filepart
},
1871 {"", 0, NULL
, NULL
},
1872 {"", MAX_PATH
, NULL
, NULL
},
1873 {"", MAX_PATH
, output
, NULL
},
1874 {"", MAX_PATH
, output
, &filepart
},
1877 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
1879 SetLastError(0xdeadbeef);
1880 strcpy(output
, "deadbeef");
1881 filepart
= (char *)0xdeadbeef;
1882 ret
= GetFullPathNameA(invalid_parameters
[i
].name
,
1883 invalid_parameters
[i
].len
,
1884 invalid_parameters
[i
].buffer
,
1885 invalid_parameters
[i
].lastpart
);
1886 ok(!ret
, "[%d] Expected GetFullPathNameA to return 0, got %u\n", i
, ret
);
1887 ok(!strcmp(output
, "deadbeef"), "[%d] Expected the output buffer to be unchanged, got \"%s\"\n", i
, output
);
1888 ok(filepart
== (char *)0xdeadbeef, "[%d] Expected output file part pointer to be untouched, got %p\n", i
, filepart
);
1889 ok(GetLastError() == 0xdeadbeef ||
1890 GetLastError() == ERROR_INVALID_NAME
, /* Win7 */
1891 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
1897 skip("Skipping DBCS(Japanese) GetFullPathNameA test in this codepage (%d)\n", acp
);
1899 const struct dbcs_case
{
1901 const char *expected
;
1903 { "c:\\a\\\x95\x5c\x97\xa0.txt", "\x95\x5c\x97\xa0.txt" },
1904 { "c:\\\x83\x8f\x83\x43\x83\x93\\wine.c", "wine.c" },
1905 { "c:\\demo\\\x97\xa0\x95\x5c", "\x97\xa0\x95\x5c" }
1907 for (i
= 0; i
< sizeof(testset
)/sizeof(testset
[0]); i
++) {
1908 ret
= GetFullPathNameA(testset
[i
].input
, sizeof(output
),
1910 ok(ret
, "[%d] GetFullPathName error %u\n", i
, GetLastError());
1911 ok(!lstrcmpA(filepart
, testset
[i
].expected
),
1912 "[%d] expected %s got %s\n", i
, testset
[i
].expected
, filepart
);
1917 static void test_GetFullPathNameW(void)
1919 static const WCHAR emptyW
[] = {0};
1920 static const WCHAR deadbeefW
[] = {'d','e','a','d','b','e','e','f',0};
1922 WCHAR output
[MAX_PATH
], *filepart
;
1933 } invalid_parameters
[] =
1935 {NULL
, 0, NULL
, NULL
},
1936 {NULL
, 0, NULL
, &filepart
, 1},
1937 {NULL
, MAX_PATH
, NULL
, NULL
},
1938 {NULL
, MAX_PATH
, output
, NULL
},
1939 {NULL
, MAX_PATH
, output
, &filepart
, 1},
1940 {emptyW
, 0, NULL
, NULL
},
1941 {emptyW
, 0, NULL
, &filepart
, 1},
1942 {emptyW
, MAX_PATH
, NULL
, NULL
},
1943 {emptyW
, MAX_PATH
, output
, NULL
},
1944 {emptyW
, MAX_PATH
, output
, &filepart
, 1},
1947 SetLastError(0xdeadbeef);
1948 ret
= GetFullPathNameW(NULL
, 0, NULL
, NULL
);
1949 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1951 win_skip("GetFullPathNameW is not available\n");
1955 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
1957 SetLastError(0xdeadbeef);
1958 lstrcpyW(output
, deadbeefW
);
1959 filepart
= (WCHAR
*)0xdeadbeef;
1960 ret
= GetFullPathNameW(invalid_parameters
[i
].name
,
1961 invalid_parameters
[i
].len
,
1962 invalid_parameters
[i
].buffer
,
1963 invalid_parameters
[i
].lastpart
);
1964 ok(!ret
, "[%d] Expected GetFullPathNameW to return 0, got %u\n", i
, ret
);
1965 ok(!lstrcmpW(output
, deadbeefW
), "[%d] Expected the output buffer to be unchanged, got %s\n", i
, wine_dbgstr_w(output
));
1966 ok(filepart
== (WCHAR
*)0xdeadbeef ||
1967 (invalid_parameters
[i
].win7_expect
&& filepart
== NULL
),
1968 "[%d] Expected output file part pointer to be untouched, got %p\n", i
, filepart
);
1969 ok(GetLastError() == 0xdeadbeef ||
1970 GetLastError() == ERROR_INVALID_NAME
, /* Win7 */
1971 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
1976 static void init_pointers(void)
1978 HMODULE hKernel32
= GetModuleHandleA("kernel32.dll");
1980 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hKernel32, #f))
1981 MAKEFUNC(GetLongPathNameA
);
1982 MAKEFUNC(GetLongPathNameW
);
1983 MAKEFUNC(NeedCurrentDirectoryForExePathA
);
1984 MAKEFUNC(NeedCurrentDirectoryForExePathW
);
1985 MAKEFUNC(SearchPathA
);
1986 MAKEFUNC(SearchPathW
);
1987 MAKEFUNC(ActivateActCtx
);
1988 MAKEFUNC(CreateActCtxW
);
1989 MAKEFUNC(DeactivateActCtx
);
1990 MAKEFUNC(GetCurrentActCtx
);
1991 MAKEFUNC(ReleaseActCtx
);
1995 static void test_relative_path(void)
1997 char path
[MAX_PATH
], buf
[MAX_PATH
];
2001 if (!pGetLongPathNameA
) return;
2003 GetTempPathA(MAX_PATH
, path
);
2004 ret
= SetCurrentDirectoryA(path
);
2005 ok(ret
, "SetCurrentDirectory error %d\n", GetLastError());
2007 ret
= CreateDirectoryA("foo", NULL
);
2008 ok(ret
, "CreateDirectory error %d\n", GetLastError());
2009 file
= CreateFileA("foo\\file", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2010 ok(file
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n");
2012 ret
= CreateDirectoryA("bar", NULL
);
2013 ok(ret
, "CreateDirectory error %d\n", GetLastError());
2014 ret
= SetCurrentDirectoryA("bar");
2015 ok(ret
, "SetCurrentDirectory error %d\n", GetLastError());
2017 ret
= GetFileAttributesA("..\\foo\\file");
2018 ok(ret
!= INVALID_FILE_ATTRIBUTES
, "GetFileAttributes error %d\n", GetLastError());
2020 strcpy(buf
, "deadbeef");
2021 ret
= pGetLongPathNameA(".", buf
, MAX_PATH
);
2022 ok(ret
, "GetLongPathName error %d\n", GetLastError());
2023 ok(!strcmp(buf
, "."), "expected ., got %s\n", buf
);
2024 strcpy(buf
, "deadbeef");
2025 ret
= GetShortPathNameA(".", buf
, MAX_PATH
);
2026 ok(ret
, "GetShortPathName error %d\n", GetLastError());
2027 ok(!strcmp(buf
, "."), "expected ., got %s\n", buf
);
2029 strcpy(buf
, "deadbeef");
2030 ret
= pGetLongPathNameA("..", buf
, MAX_PATH
);
2031 ok(ret
, "GetLongPathName error %d\n", GetLastError());
2032 ok(!strcmp(buf
, ".."), "expected .., got %s\n", buf
);
2033 strcpy(buf
, "deadbeef");
2034 ret
= GetShortPathNameA("..", buf
, MAX_PATH
);
2035 ok(ret
, "GetShortPathName error %d\n", GetLastError());
2036 ok(!strcmp(buf
, ".."), "expected .., got %s\n", buf
);
2038 strcpy(buf
, "deadbeef");
2039 ret
= pGetLongPathNameA("..\\foo\\file", buf
, MAX_PATH
);
2040 ok(ret
, "GetLongPathName error %d\n", GetLastError());
2041 ok(!strcmp(buf
, "..\\foo\\file"), "expected ..\\foo\\file, got %s\n", buf
);
2042 strcpy(buf
, "deadbeef");
2043 ret
= GetShortPathNameA("..\\foo\\file", buf
, MAX_PATH
);
2044 ok(ret
, "GetShortPathName error %d\n", GetLastError());
2045 ok(!strcmp(buf
, "..\\foo\\file"), "expected ..\\foo\\file, got %s\n", buf
);
2047 SetCurrentDirectoryA("..");
2048 DeleteFileA("foo\\file");
2049 RemoveDirectoryA("foo");
2050 RemoveDirectoryA("bar");
2055 CHAR origdir
[MAX_PATH
],curdir
[MAX_PATH
], curDrive
, otherDrive
;
2059 /* Report only once */
2060 if (!pGetLongPathNameA
)
2061 win_skip("GetLongPathNameA is not available\n");
2062 if (!pGetLongPathNameW
)
2063 win_skip("GetLongPathNameW is not available\n");
2064 if (!pActivateActCtx
)
2065 win_skip("Activation contexts not supported, some tests will be skipped\n");
2067 test_relative_path();
2068 test_InitPathA(curdir
, &curDrive
, &otherDrive
);
2069 test_CurrentDirectoryA(origdir
,curdir
);
2070 test_PathNameA(curdir
, curDrive
, otherDrive
);
2071 test_CleanupPathA(origdir
,curdir
);
2073 test_GetLongPathNameA();
2074 test_GetLongPathNameW();
2075 test_GetShortPathNameW();
2076 test_GetSystemDirectory();
2077 test_GetWindowsDirectory();
2078 test_NeedCurrentDirectoryForExePathA();
2079 test_NeedCurrentDirectoryForExePathW();
2080 test_drive_letter_case();
2083 test_GetFullPathNameA();
2084 test_GetFullPathNameW();