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__
51 #elif defined __aarch64__
57 /* the following characters don't work well with GetFullPathNameA
58 in Win98. I don't know if this is a FAT thing, or if it is an OS thing
59 but I don't test these characters now.
60 NOTE: Win2k allows GetFullPathNameA to work with them though
63 static const CHAR funny_chars
[]="!@#$%^&*()=+{}[],?'`";
64 static const CHAR is_char_ok
[] ="11111110111111111011";
66 static DWORD (WINAPI
*pGetLongPathNameA
)(LPCSTR
,LPSTR
,DWORD
);
67 static DWORD (WINAPI
*pGetLongPathNameW
)(LPWSTR
,LPWSTR
,DWORD
);
69 /* Present in Win2003+ */
70 static BOOL (WINAPI
*pNeedCurrentDirectoryForExePathA
)(LPCSTR
);
71 static BOOL (WINAPI
*pNeedCurrentDirectoryForExePathW
)(LPCWSTR
);
73 static DWORD (WINAPI
*pSearchPathA
)(LPCSTR
,LPCSTR
,LPCSTR
,DWORD
,LPSTR
,LPSTR
*);
74 static DWORD (WINAPI
*pSearchPathW
)(LPCWSTR
,LPCWSTR
,LPCWSTR
,DWORD
,LPWSTR
,LPWSTR
*);
76 static BOOL (WINAPI
*pActivateActCtx
)(HANDLE
,ULONG_PTR
*);
77 static HANDLE (WINAPI
*pCreateActCtxW
)(PCACTCTXW
);
78 static BOOL (WINAPI
*pDeactivateActCtx
)(DWORD
,ULONG_PTR
);
79 static BOOL (WINAPI
*pGetCurrentActCtx
)(HANDLE
*);
80 static void (WINAPI
*pReleaseActCtx
)(HANDLE
);
82 static BOOL (WINAPI
*pCheckNameLegalDOS8Dot3W
)(const WCHAR
*, char *, DWORD
, BOOL
*, BOOL
*);
83 static BOOL (WINAPI
*pCheckNameLegalDOS8Dot3A
)(const char *, char *, DWORD
, BOOL
*, BOOL
*);
85 /* a structure to deal with wine todos somewhat cleanly */
95 /* function that tests GetFullPathNameA, GetShortPathNameA,GetLongPathNameA */
96 /* NOTE: the passfail structure is used to allow customizable todo checking
97 for wine. It is not very pretty, but it sure beats duplicating this
98 function lots of times
100 static void test_ValidPathA(const CHAR
*curdir
, const CHAR
*subdir
, const CHAR
*filename
,
101 CHAR
*shortstr
, SLpassfail
*passfail
, const CHAR
*errstr
)
103 CHAR tmpstr
[MAX_PATH
],
104 fullpath
[MAX_PATH
], /*full path to the file (not short/long) */
105 subpath
[MAX_PATH
], /*relative path to the file */
106 fullpathshort
[MAX_PATH
], /*absolute path to the file (short format) */
107 fullpathlong
[MAX_PATH
], /*absolute path to the file (long format) */
108 curdirshort
[MAX_PATH
], /*absolute path to the current dir (short) */
109 curdirlong
[MAX_PATH
]; /*absolute path to the current dir (long) */
110 LPSTR strptr
; /*ptr to the filename portion of the path */
112 /* if passfail is NULL, we can perform all checks within this function,
113 otherwise, we will return the relevant data in the passfail struct, so
114 we must initialize it first
117 passfail
->shortlen
=-1;passfail
->s2llen
=-1;passfail
->longlen
=-1;
118 passfail
->shorterror
=0;passfail
->s2lerror
=0;passfail
->longerror
=0;
120 /* GetLongPathNameA is only supported on Win2k+ and Win98+ */
121 if(pGetLongPathNameA
) {
122 ok((len
=pGetLongPathNameA(curdir
,curdirlong
,MAX_PATH
)),
123 "%s: GetLongPathNameA failed\n",errstr
);
124 /*GetLongPathNameA can return a trailing '\\' but shouldn't do so here */
125 ok(! HAS_TRAIL_SLASH_A(curdirlong
),
126 "%s: GetLongPathNameA should not have a trailing \\\n",errstr
);
128 ok((len
=GetShortPathNameA(curdir
,curdirshort
,MAX_PATH
)),
129 "%s: GetShortPathNameA failed\n",errstr
);
130 /*GetShortPathNameA can return a trailing '\\' but shouldn't do so here */
131 ok(! HAS_TRAIL_SLASH_A(curdirshort
),
132 "%s: GetShortPathNameA should not have a trailing \\\n",errstr
);
133 /* build relative and absolute paths from inputs */
134 if(lstrlenA(subdir
)) {
135 sprintf(subpath
,"%s\\%s",subdir
,filename
);
137 lstrcpyA(subpath
,filename
);
139 sprintf(fullpath
,"%s\\%s",curdir
,subpath
);
140 sprintf(fullpathshort
,"%s\\%s",curdirshort
,subpath
);
141 sprintf(fullpathlong
,"%s\\%s",curdirlong
,subpath
);
142 /* Test GetFullPathNameA functionality */
143 len
=GetFullPathNameA(subpath
,MAX_PATH
,tmpstr
,&strptr
);
144 ok(len
, "GetFullPathNameA failed for: '%s'\n",subpath
);
145 if(HAS_TRAIL_SLASH_A(subpath
)) {
147 "%s: GetFullPathNameA should not return a filename ptr\n",errstr
);
148 ok(lstrcmpiA(fullpath
,tmpstr
)==0,
149 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
150 errstr
,tmpstr
,fullpath
);
152 ok(lstrcmpiA(strptr
,filename
)==0,
153 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
154 errstr
,strptr
,filename
);
155 ok(lstrcmpiA(fullpath
,tmpstr
)==0,
156 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
157 errstr
,tmpstr
,fullpath
);
159 /* Test GetShortPathNameA functionality */
161 len
=GetShortPathNameA(fullpathshort
,shortstr
,MAX_PATH
);
163 ok(len
, "%s: GetShortPathNameA failed\n",errstr
);
165 passfail
->shortlen
=len
;
166 passfail
->shorterror
=GetLastError();
168 /* Test GetLongPathNameA functionality
169 We test both conversion from GetFullPathNameA and from GetShortPathNameA
171 if(pGetLongPathNameA
) {
174 len
=pGetLongPathNameA(shortstr
,tmpstr
,MAX_PATH
);
177 "%s: GetLongPathNameA failed during Short->Long conversion\n", errstr
);
178 ok(lstrcmpiA(fullpathlong
,tmpstr
)==0,
179 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
180 errstr
,tmpstr
,fullpathlong
);
182 passfail
->s2llen
=len
;
183 passfail
->s2lerror
=GetLastError();
187 len
=pGetLongPathNameA(fullpath
,tmpstr
,MAX_PATH
);
189 ok(len
, "%s: GetLongPathNameA failed\n",errstr
);
190 ok(!lstrcmpiA(fullpathlong
, tmpstr
), "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
191 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
);
854 /* Don't Starve relies on GetLongPathName returning the passed in filename,
855 even if the actual file on disk has a different case or separator */
856 if (pGetLongPathNameA
) {
857 int len
= lstrlenA(LONGDIR
) + 1;
858 sprintf(tmpstr
,"%s/%s",LONGDIR
,LONGFILE
);
859 ok(GetLongPathNameA(tmpstr
,tmpstr1
,MAX_PATH
),"GetLongPathNameA failed\n");
860 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
861 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
862 tmpstr
[len
] = tolower(tmpstr
[len
]);
863 ok(GetLongPathNameA(tmpstr
,tmpstr1
,MAX_PATH
),"GetLongPathNameA failed\n");
864 ok(lstrcmpA(tmpstr
,tmpstr1
)==0,
865 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
866 sprintf(tmpstr
,"%s/%s",SHORTDIR
,SHORTFILE
);
867 ok(GetLongPathNameA(tmpstr
,tmpstr1
,MAX_PATH
),"GetLongPathNameA failed\n");
868 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
869 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
870 len
= lstrlenA(SHORTDIR
) + 1;
871 tmpstr
[len
] = toupper(tmpstr
[len
]);
872 ok(GetLongPathNameA(tmpstr
,tmpstr1
,MAX_PATH
),"GetLongPathNameA failed\n");
873 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0 && lstrcmpA(tmpstr
,tmpstr1
) != 0,
874 "GetLongPathNameA returned '%s' instead of '%s/%s'\n",tmpstr1
,SHORTDIR
,SHORTFILE
);
876 sprintf(tmpstr
,"%s/%s",SHORTDIR
,SHORTFILE
);
877 ok(GetShortPathNameA(tmpstr
,tmpstr1
,MAX_PATH
),"GetShortPathNameA failed\n");
878 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
879 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
882 sprintf(tmpstr
,"%c:%s/%s",curdir
[0],SHORTDIR
,SHORTFILE
);
883 ok(GetFullPathNameA(tmpstr
,MAX_PATH
,tmpstr1
,&strptr
),"GetFullPathNameA failed\n");
884 sprintf(tmpstr
,"%s\\%s\\%s",curdir
,SHORTDIR
,SHORTFILE
);
885 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
886 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
887 ok(lstrcmpiA(SHORTFILE
,strptr
)==0,
888 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr
,SHORTFILE
);
889 /* Windows will insert a drive letter in front of an absolute UNIX path */
890 sprintf(tmpstr
,"/%s/%s",SHORTDIR
,SHORTFILE
);
891 ok(GetFullPathNameA(tmpstr
,MAX_PATH
,tmpstr1
,&strptr
),"GetFullPathNameA failed\n");
892 sprintf(tmpstr
,"%c:\\%s\\%s",*tmpstr1
,SHORTDIR
,SHORTFILE
);
893 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
894 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
895 /* This passes in Wine because it still contains the pointer from the previous test */
896 ok(lstrcmpiA(SHORTFILE
,strptr
)==0,
897 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr
,SHORTFILE
);
899 /* Now try some relative paths */
900 ok(GetShortPathNameA(LONGDIR
,tmpstr
,MAX_PATH
),"GetShortPathNameA failed\n");
901 test_SplitShortPathA(tmpstr
,dir
,eight
,three
);
902 if(pGetLongPathNameA
) {
903 ok(pGetLongPathNameA(tmpstr
,tmpstr1
,MAX_PATH
),"GetLongPathNameA failed\n");
904 ok(lstrcmpiA(tmpstr1
,LONGDIR
)==0,
905 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1
,LONGDIR
);
907 sprintf(tmpstr
,".\\%s",LONGDIR
);
908 ok(GetShortPathNameA(tmpstr
,tmpstr1
,MAX_PATH
),"GetShortPathNameA failed\n");
909 test_SplitShortPathA(tmpstr1
,dir
,eight
,three
);
910 ok(lstrcmpiA(dir
,".")==0 || dir
[0]=='\0',
911 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1
);
912 if(pGetLongPathNameA
) {
913 ok(pGetLongPathNameA(tmpstr1
,tmpstr1
,MAX_PATH
),"GetLongPathNameA failed %s\n",
915 ok(lstrcmpiA(tmpstr1
,tmpstr
)==0,
916 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
918 /* Check out Get*PathNameA on some funny characters */
919 for(i
=0;i
<lstrlenA(funny_chars
);i
++) {
921 valid
=(is_char_ok
[i
]=='0') ? 0 : 1;
922 sprintf(tmpstr1
,"check%d-1",i
);
923 sprintf(tmpstr
,"file%c000.ext",funny_chars
[i
]);
924 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
925 sprintf(tmpstr1
,"check%d-2",i
);
926 sprintf(tmpstr
,"file000.e%ct",funny_chars
[i
]);
927 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
928 sprintf(tmpstr1
,"check%d-3",i
);
929 sprintf(tmpstr
,"%cfile000.ext",funny_chars
[i
]);
930 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
931 sprintf(tmpstr1
,"check%d-4",i
);
932 sprintf(tmpstr
,"file000%c.ext",funny_chars
[i
]);
933 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
934 sprintf(tmpstr1
,"check%d-5",i
);
935 sprintf(tmpstr
,"Long %c File",funny_chars
[i
]);
936 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
937 sprintf(tmpstr1
,"check%d-6",i
);
938 sprintf(tmpstr
,"%c Long File",funny_chars
[i
]);
939 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
940 sprintf(tmpstr1
,"check%d-7",i
);
941 sprintf(tmpstr
,"Long File %c",funny_chars
[i
]);
942 test_FunnyChars(curdir
,curdir_short
,tmpstr
,valid
,tmpstr1
);
944 /* Now try it on mixed case short names */
945 test_ShortPathCase(curdir
,SHORTDIR
,LONGFILE
);
946 test_ShortPathCase(curdir
,LONGDIR
,SHORTFILE
);
947 test_ShortPathCase(curdir
,LONGDIR
,LONGFILE
);
949 /* test double delimiters */
950 sprintf(tmpstr
,"%s\\\\%s", SHORTDIR
,SHORTFILE
);
951 ok(GetShortPathNameA(tmpstr
,tmpstr1
,MAX_PATH
),"GetShortPathNameA failed\n");
952 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
953 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
954 sprintf(tmpstr
,".\\\\%s\\\\%s", SHORTDIR
,SHORTFILE
);
955 ok(GetShortPathNameA(tmpstr
,tmpstr1
,MAX_PATH
),"GetShortPathNameA failed\n");
956 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
957 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
959 if (pGetLongPathNameA
) {
960 sprintf(tmpstr
,"%s\\\\%s",LONGDIR
,LONGFILE
);
961 ok(pGetLongPathNameA(tmpstr
,tmpstr1
,MAX_PATH
),"GetLongPathNameA failed\n");
962 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
963 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
965 sprintf(tmpstr
,".\\\\%s\\\\%s",LONGDIR
,LONGFILE
);
966 ok(pGetLongPathNameA(tmpstr
,tmpstr1
,MAX_PATH
),"GetLongPathNameA failed\n");
967 ok(lstrcmpiA(tmpstr
,tmpstr1
)==0,
968 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1
,tmpstr
);
972 static void test_GetTempPathA(char* tmp_dir
)
974 DWORD len
, slen
, len_with_null
;
977 len_with_null
= strlen(tmp_dir
) + 1;
979 lstrcpyA(buf
, "foo");
980 len
= GetTempPathA(MAX_PATH
, buf
);
981 ok(len
<= MAX_PATH
, "should fit into MAX_PATH\n");
982 ok(lstrcmpiA(buf
, tmp_dir
) == 0, "expected [%s], got [%s]\n",tmp_dir
,buf
);
983 ok(len
== strlen(buf
), "returned length should be equal to the length of string\n");
985 /* Some versions of Windows touch the buffer, some don't so we don't
986 * test that. Also, NT sometimes exaggerates the required buffer size
987 * so we cannot test for an exact match. Finally, the
988 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
989 * For instance in some cases Win98 returns len_with_null - 1 instead
992 len
= GetTempPathA(1, buf
);
993 ok(len
>= len_with_null
, "Expected >= %u, got %u\n", len_with_null
, len
);
995 len
= GetTempPathA(0, NULL
);
996 ok(len
>= len_with_null
, "Expected >= %u, got %u\n", len_with_null
, len
);
998 /* The call above gave us the buffer size that Windows thinks is needed
999 * so the next call should work
1001 lstrcpyA(buf
, "foo");
1002 len
= GetTempPathA(len
, buf
);
1003 ok(lstrcmpiA(buf
, tmp_dir
) == 0, "expected [%s], got [%s]\n",tmp_dir
,buf
);
1004 ok(len
== strlen(buf
), "returned length should be equal to the length of string\n");
1006 memset(buf
, 'a', sizeof(buf
));
1007 len
= GetTempPathA(sizeof(buf
), buf
);
1008 ok(lstrcmpiA(buf
, tmp_dir
) == 0, "expected [%s], got [%s]\n",tmp_dir
,buf
);
1009 ok(len
== strlen(buf
), "returned length should be equal to the length of string\n");
1010 /* The rest of the buffer remains untouched */
1012 for(len
++; len
< sizeof(buf
); len
++)
1013 ok(buf
[len
] == 'a', "expected 'a' at [%d], got 0x%x\n", len
, buf
[len
]);
1015 /* When the buffer is not long enough it remains untouched */
1016 memset(buf
, 'a', sizeof(buf
));
1017 len
= GetTempPathA(slen
/ 2, buf
);
1018 ok(len
== slen
|| broken(len
== slen
+ 1) /* read the big comment above */ ,
1019 "expected %d, got %d\n", slen
, len
);
1020 for(len
= 0; len
< sizeof(buf
) / sizeof(buf
[0]); len
++)
1021 ok(buf
[len
] == 'a', "expected 'a' at [%d], got 0x%x\n", len
, buf
[len
]);
1024 static void test_GetTempPathW(char* tmp_dir
)
1026 DWORD len
, slen
, len_with_null
;
1027 WCHAR buf
[MAX_PATH
], *long_buf
;
1028 WCHAR tmp_dirW
[MAX_PATH
];
1029 static const WCHAR fooW
[] = {'f','o','o',0};
1031 MultiByteToWideChar(CP_ACP
,0,tmp_dir
,-1,tmp_dirW
,sizeof(tmp_dirW
)/sizeof(*tmp_dirW
));
1032 len_with_null
= lstrlenW(tmp_dirW
) + 1;
1034 /* This one is different from ANSI version: ANSI version doesn't
1035 * touch the buffer, unicode version usually truncates the buffer
1036 * to zero size. NT still exaggerates the required buffer size
1037 * sometimes so we cannot test for an exact match. Finally, the
1038 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
1039 * For instance on NT4 it will sometimes return a path without the
1040 * trailing '\\' and sometimes return an error.
1043 lstrcpyW(buf
, fooW
);
1044 len
= GetTempPathW(MAX_PATH
, buf
);
1045 if (len
== 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1047 win_skip("GetTempPathW is not available\n");
1050 ok(lstrcmpiW(buf
, tmp_dirW
) == 0, "GetTempPathW returned an incorrect temporary path\n");
1051 ok(len
== lstrlenW(buf
), "returned length should be equal to the length of string\n");
1053 lstrcpyW(buf
, fooW
);
1054 len
= GetTempPathW(1, buf
);
1055 ok(buf
[0] == 0, "unicode version should truncate the buffer to zero size\n");
1056 ok(len
>= len_with_null
, "Expected >= %u, got %u\n", len_with_null
, len
);
1058 len
= GetTempPathW(0, NULL
);
1059 ok(len
>= len_with_null
, "Expected >= %u, got %u\n", len_with_null
, len
);
1061 lstrcpyW(buf
, fooW
);
1062 len
= GetTempPathW(len
, buf
);
1063 ok(lstrcmpiW(buf
, tmp_dirW
) == 0, "GetTempPathW returned an incorrect temporary path\n");
1064 ok(len
== lstrlenW(buf
), "returned length should be equal to the length of string\n");
1066 for(len
= 0; len
< sizeof(buf
) / sizeof(buf
[0]); len
++)
1068 len
= GetTempPathW(len
, buf
);
1069 ok(lstrcmpiW(buf
, tmp_dirW
) == 0, "GetTempPathW returned an incorrect temporary path\n");
1070 ok(len
== lstrlenW(buf
), "returned length should be equal to the length of string\n");
1071 /* The rest of the buffer must be zeroed */
1073 for(len
++; len
< sizeof(buf
) / sizeof(buf
[0]); len
++)
1074 ok(buf
[len
] == '\0', "expected NULL at [%d], got 0x%x\n", len
, buf
[len
]);
1076 /* When the buffer is not long enough the length passed is zeroed */
1077 for(len
= 0; len
< sizeof(buf
) / sizeof(buf
[0]); len
++)
1079 len
= GetTempPathW(slen
/ 2, buf
);
1080 ok(len
== slen
|| broken(len
== slen
+ 1) /* read the big comment above */ ,
1081 "expected %d, got %d\n", slen
, len
);
1084 /* In Windows 8 when TMP var points to a drive only (like C:) instead of a
1085 * full directory the behavior changes. It will start filling the path but
1086 * will later truncate the buffer before returning. So the generic test
1087 * below will fail for this Windows 8 corner case.
1090 DWORD version
= GetVersion();
1091 GetEnvironmentVariableA("TMP", tmp_var
, sizeof(tmp_var
));
1092 if (strlen(tmp_var
) == 2 && version
>= 0x00060002)
1096 for(len
= 0; len
< slen
/ 2; len
++)
1097 ok(buf
[len
] == '\0', "expected NULL at [%d], got 0x%x\n", len
, buf
[len
]);
1098 for(; len
< sizeof(buf
) / sizeof(buf
[0]); len
++)
1099 ok(buf
[len
] == 'a', "expected 'a' at [%d], got 0x%x\n", len
, buf
[len
]);
1101 /* bogus application from bug 38220 passes the count value in sizeof(buffer)
1102 * instead the correct count of WCHAR, this test catches this case. */
1104 long_buf
= HeapAlloc(GetProcessHeap(), 0, slen
* sizeof(WCHAR
));
1107 skip("Could not allocate memory for the test\n");
1110 for(len
= 0; len
< slen
; len
++)
1111 long_buf
[len
] = 0xCC;
1112 len
= GetTempPathW(slen
, long_buf
);
1113 ok(lstrcmpiW(long_buf
, tmp_dirW
) == 0, "GetTempPathW returned an incorrect temporary path\n");
1114 ok(len
== lstrlenW(long_buf
), "returned length should be equal to the length of string\n");
1115 /* the remaining buffer must be zeroed up to different values in different OS versions.
1118 * to simplify testing we will test only until XP.
1120 for(; len
< 32767; len
++)
1121 ok(long_buf
[len
] == '\0', "expected NULL at [%d], got 0x%x\n", len
, long_buf
[len
]);
1122 /* we will know skip the test that is in the middle of the OS difference by
1123 * incrementing len and then resume the test for the untouched part. */
1124 for(len
++; len
< slen
; len
++)
1125 ok(long_buf
[len
] == 0xcc, "expected 0xcc at [%d], got 0x%x\n", len
, long_buf
[len
]);
1127 HeapFree(GetProcessHeap(), 0, long_buf
);
1130 static void test_GetTempPath(void)
1132 char save_TMP
[MAX_PATH
];
1133 char windir
[MAX_PATH
];
1135 WCHAR curdir
[MAX_PATH
];
1137 if (!GetEnvironmentVariableA("TMP", save_TMP
, sizeof(save_TMP
))) save_TMP
[0] = 0;
1139 /* test default configuration */
1140 trace("TMP=%s\n", save_TMP
);
1143 strcpy(buf
,save_TMP
);
1144 if (buf
[strlen(buf
)-1]!='\\')
1146 test_GetTempPathA(buf
);
1147 test_GetTempPathW(buf
);
1150 /* TMP=C:\WINDOWS */
1151 GetWindowsDirectoryA(windir
, sizeof(windir
));
1152 SetEnvironmentVariableA("TMP", windir
);
1153 GetEnvironmentVariableA("TMP", buf
, sizeof(buf
));
1154 trace("TMP=%s\n", buf
);
1155 strcat(windir
,"\\");
1156 test_GetTempPathA(windir
);
1157 test_GetTempPathW(windir
);
1160 GetWindowsDirectoryA(windir
, sizeof(windir
));
1162 SetEnvironmentVariableA("TMP", windir
);
1163 GetEnvironmentVariableA("TMP", buf
, sizeof(buf
));
1164 trace("TMP=%s\n", buf
);
1165 test_GetTempPathA(windir
);
1166 test_GetTempPathW(windir
);
1168 GetCurrentDirectoryW(MAX_PATH
, curdir
);
1169 /* TMP=C: i.e. use current working directory of the specified drive */
1170 GetWindowsDirectoryA(windir
, sizeof(windir
));
1171 SetCurrentDirectoryA(windir
);
1173 SetEnvironmentVariableA("TMP", windir
);
1174 GetEnvironmentVariableA("TMP", buf
, sizeof(buf
));
1175 trace("TMP=%s\n", buf
);
1176 GetWindowsDirectoryA(windir
, sizeof(windir
));
1177 strcat(windir
,"\\");
1178 test_GetTempPathA(windir
);
1179 test_GetTempPathW(windir
);
1181 SetEnvironmentVariableA("TMP", save_TMP
);
1182 SetCurrentDirectoryW(curdir
);
1185 static void test_GetLongPathNameA(void)
1187 DWORD length
, explength
, hostsize
;
1188 char tempfile
[MAX_PATH
], *name
;
1189 char longpath
[MAX_PATH
];
1190 char unc_prefix
[MAX_PATH
];
1191 char unc_short
[MAX_PATH
], unc_long
[MAX_PATH
];
1192 char temppath
[MAX_PATH
], temppath2
[MAX_PATH
];
1195 if (!pGetLongPathNameA
)
1198 GetTempPathA(MAX_PATH
, tempfile
);
1199 name
= tempfile
+ strlen(tempfile
);
1202 SetLastError(0xdeadbeef);
1203 length
= pGetLongPathNameA(tempfile
, temppath
, MAX_PATH
);
1204 ok(!length
, "GetLongPathNameA should fail\n");
1205 ok(GetLastError() == ERROR_INVALID_NAME
, "wrong error %d\n", GetLastError());
1207 strcpy(name
, "longfilename.longext");
1209 file
= CreateFileA(tempfile
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1212 /* Test a normal path with a small buffer size */
1213 memset(temppath
, 0, MAX_PATH
);
1214 length
= pGetLongPathNameA(tempfile
, temppath
, 4);
1215 /* We have a failure so length should be the minimum plus the terminating '0' */
1216 ok(length
>= strlen(tempfile
) + 1, "Wrong length\n");
1217 ok(temppath
[0] == 0, "Buffer should not have been touched\n");
1219 /* Some UNC syntax tests */
1221 memset(temppath
, 0, MAX_PATH
);
1222 memset(temppath2
, 0, MAX_PATH
);
1223 lstrcpyA(temppath2
, "\\\\?\\");
1224 lstrcatA(temppath2
, tempfile
);
1225 explength
= length
+ 4;
1227 SetLastError(0xdeadbeef);
1228 length
= pGetLongPathNameA(temppath2
, NULL
, 0);
1229 if (length
== 0 && GetLastError() == ERROR_BAD_NET_NAME
)
1231 win_skip("UNC syntax tests don't work on Win98/WinMe\n");
1232 DeleteFileA(tempfile
);
1235 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1237 length
= pGetLongPathNameA(temppath2
, NULL
, MAX_PATH
);
1238 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1240 length
= pGetLongPathNameA(temppath2
, temppath
, 4);
1241 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1242 ok(temppath
[0] == 0, "Buffer should not have been touched\n");
1244 /* Now an UNC path with the computername */
1245 lstrcpyA(unc_prefix
, "\\\\");
1246 hostsize
= sizeof(unc_prefix
) - 2;
1247 GetComputerNameA(unc_prefix
+ 2, &hostsize
);
1248 lstrcatA(unc_prefix
, "\\");
1250 /* Create a short syntax for the whole unc path */
1251 memset(unc_short
, 0, MAX_PATH
);
1252 GetShortPathNameA(tempfile
, temppath
, MAX_PATH
);
1253 lstrcpyA(unc_short
, unc_prefix
);
1254 unc_short
[lstrlenA(unc_short
)] = temppath
[0];
1255 lstrcatA(unc_short
, "$\\");
1256 lstrcatA(unc_short
, strchr(temppath
, '\\') + 1);
1258 /* Create a long syntax for reference */
1259 memset(longpath
, 0, MAX_PATH
);
1260 pGetLongPathNameA(tempfile
, temppath
, MAX_PATH
);
1261 lstrcpyA(longpath
, unc_prefix
);
1262 longpath
[lstrlenA(longpath
)] = temppath
[0];
1263 lstrcatA(longpath
, "$\\");
1264 lstrcatA(longpath
, strchr(temppath
, '\\') + 1);
1267 SetLastError(0xdeadbeef);
1268 length
= pGetLongPathNameA(unc_short
, NULL
, 0);
1269 if (length
== 0 && GetLastError() == ERROR_BAD_NETPATH
)
1271 /* Seen on Window XP Home */
1272 win_skip("UNC with computername is not supported\n");
1273 DeleteFileA(tempfile
);
1276 explength
= lstrlenA(longpath
) + 1;
1278 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1280 length
= pGetLongPathNameA(unc_short
, NULL
, MAX_PATH
);
1282 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1284 memset(unc_long
, 0, MAX_PATH
);
1285 length
= pGetLongPathNameA(unc_short
, unc_long
, lstrlenA(unc_short
));
1286 /* length will include terminating '0' on failure */
1288 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1289 ok(unc_long
[0] == 0, "Buffer should not have been touched\n");
1291 memset(unc_long
, 0, MAX_PATH
);
1292 length
= pGetLongPathNameA(unc_short
, unc_long
, length
);
1293 /* length doesn't include terminating '0' on success */
1297 ok(length
== explength
, "Wrong length %d, expected %d\n", length
, explength
);
1298 ok(!lstrcmpiA(unc_long
, longpath
), "Expected (%s), got (%s)\n", longpath
, unc_long
);
1301 DeleteFileA(tempfile
);
1304 static void test_GetLongPathNameW(void)
1306 DWORD length
, expanded
;
1309 WCHAR empty
[MAX_PATH
];
1310 WCHAR tempdir
[MAX_PATH
], name
[200];
1311 WCHAR dirpath
[4 + MAX_PATH
+ 200]; /* To ease removal */
1312 WCHAR shortpath
[4 + MAX_PATH
+ 200 + 1 + 200];
1313 static const WCHAR prefix
[] = { '\\','\\','?','\\', 0};
1314 static const WCHAR backslash
[] = { '\\', 0};
1315 static const WCHAR letterX
[] = { 'X', 0};
1317 if (!pGetLongPathNameW
)
1320 SetLastError(0xdeadbeef);
1321 length
= pGetLongPathNameW(NULL
,NULL
,0);
1322 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1324 win_skip("GetLongPathNameW is not implemented\n");
1327 ok(0==length
,"GetLongPathNameW returned %d but expected 0\n",length
);
1328 ok(GetLastError()==ERROR_INVALID_PARAMETER
,"GetLastError returned %d but expected ERROR_INVALID_PARAMETER\n",GetLastError());
1330 SetLastError(0xdeadbeef);
1332 length
= pGetLongPathNameW(empty
,NULL
,0);
1333 ok(0==length
,"GetLongPathNameW returned %d but expected 0\n",length
);
1334 ok(GetLastError()==ERROR_PATH_NOT_FOUND
,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
1336 /* Create a long path name. The path needs to exist for these tests to
1337 * succeed so we need the "\\?\" prefix when creating directories and
1341 while (lstrlenW(name
) < (sizeof(name
)/sizeof(WCHAR
) - 1))
1342 lstrcatW(name
, letterX
);
1344 GetTempPathW(MAX_PATH
, tempdir
);
1346 lstrcpyW(shortpath
, prefix
);
1347 lstrcatW(shortpath
, tempdir
);
1348 lstrcatW(shortpath
, name
);
1349 lstrcpyW(dirpath
, shortpath
);
1350 ret
= CreateDirectoryW(shortpath
, NULL
);
1351 ok(ret
, "Could not create the temporary directory : %d\n", GetLastError());
1352 lstrcatW(shortpath
, backslash
);
1353 lstrcatW(shortpath
, name
);
1355 /* Path does not exist yet and we know it overruns MAX_PATH */
1358 SetLastError(0xdeadbeef);
1359 length
= pGetLongPathNameW(shortpath
+ 4, NULL
, 0);
1360 ok(length
== 0, "Expected 0, got %d\n", length
);
1362 ok(GetLastError() == ERROR_PATH_NOT_FOUND
,
1363 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1365 SetLastError(0xdeadbeef);
1366 length
= pGetLongPathNameW(shortpath
, NULL
, 0);
1369 ok(length
== 0, "Expected 0, got %d\n", length
);
1370 ok(GetLastError() == ERROR_FILE_NOT_FOUND
,
1371 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1374 file
= CreateFileW(shortpath
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
1375 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1376 ok(file
!= INVALID_HANDLE_VALUE
,
1377 "Could not create the temporary file : %d.\n", GetLastError());
1383 SetLastError(0xdeadbeef);
1384 length
= pGetLongPathNameW(shortpath
+ 4, NULL
, 0);
1387 ok(length
== 0, "Expected 0, got %d\n", length
);
1388 ok(GetLastError() == ERROR_PATH_NOT_FOUND
, "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1391 expanded
= 4 + (pGetLongPathNameW(tempdir
, NULL
, 0) - 1) + lstrlenW(name
) + 1 + lstrlenW(name
) + 1;
1392 SetLastError(0xdeadbeef);
1393 length
= pGetLongPathNameW(shortpath
, NULL
, 0);
1394 ok(length
== expanded
, "Expected %d, got %d\n", expanded
, length
);
1396 /* NULL buffer with length crashes on Windows */
1398 pGetLongPathNameW(shortpath
, NULL
, 20);
1400 ok(DeleteFileW(shortpath
), "Could not delete temporary file\n");
1401 ok(RemoveDirectoryW(dirpath
), "Could not delete temporary directory\n");
1404 static void test_GetShortPathNameW(void)
1406 static const WCHAR extended_prefix
[] = {'\\','\\','?','\\',0};
1407 static const WCHAR test_path
[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
1408 static const WCHAR name
[] = { 't', 'e', 's', 't', 0 };
1409 static const WCHAR backSlash
[] = { '\\', 0 };
1410 static const WCHAR a_bcdeW
[] = {'a','.','b','c','d','e',0};
1411 static const WCHAR wildW
[] = { '*',0 };
1412 WCHAR path
[MAX_PATH
], tmppath
[MAX_PATH
], *ptr
;
1413 WCHAR short_path
[MAX_PATH
];
1418 SetLastError(0xdeadbeef);
1419 GetTempPathW( MAX_PATH
, tmppath
);
1420 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1422 win_skip("GetTempPathW is not implemented\n");
1426 lstrcpyW( path
, tmppath
);
1427 lstrcatW( path
, test_path
);
1428 lstrcatW( path
, backSlash
);
1429 ret
= CreateDirectoryW( path
, NULL
);
1430 ok( ret
, "Directory was not created. LastError = %d\n", GetLastError() );
1432 /* Starting a main part of test */
1434 /* extended path \\?\C:\path\ */
1435 lstrcpyW( path
, extended_prefix
);
1436 lstrcatW( path
, tmppath
);
1437 lstrcatW( path
, test_path
);
1438 lstrcatW( path
, backSlash
);
1440 length
= GetShortPathNameW( path
, short_path
, sizeof(short_path
) / sizeof(*short_path
) );
1441 ok( length
, "GetShortPathNameW returned 0.\n" );
1443 lstrcpyW( path
, tmppath
);
1444 lstrcatW( path
, test_path
);
1445 lstrcatW( path
, backSlash
);
1446 length
= GetShortPathNameW( path
, short_path
, 0 );
1447 ok( length
, "GetShortPathNameW returned 0.\n" );
1448 ret
= GetShortPathNameW( path
, short_path
, length
);
1449 ok( ret
&& ret
== length
-1, "GetShortPathNameW returned 0.\n" );
1451 lstrcatW( short_path
, name
);
1453 /* GetShortPathName for a non-existent short file name should fail */
1454 SetLastError(0xdeadbeef);
1455 length
= GetShortPathNameW( short_path
, path
, 0 );
1456 ok(!length
, "GetShortPathNameW should fail\n");
1457 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
1459 file
= CreateFileW( short_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1460 ok( file
!= INVALID_HANDLE_VALUE
, "File was not created.\n" );
1461 CloseHandle( file
);
1462 ret
= DeleteFileW( short_path
);
1463 ok( ret
, "Cannot delete file.\n" );
1465 ptr
= path
+ lstrlenW(path
);
1466 lstrcpyW( ptr
, a_bcdeW
);
1467 file
= CreateFileW( path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1468 ok( file
!= INVALID_HANDLE_VALUE
, "File was not created.\n" );
1469 CloseHandle( file
);
1471 length
= GetShortPathNameW( path
, short_path
, sizeof(short_path
)/sizeof(*short_path
) );
1472 ok( length
, "GetShortPathNameW failed: %u.\n", GetLastError() );
1474 lstrcpyW(ptr
, wildW
);
1475 SetLastError(0xdeadbeef);
1476 length
= GetShortPathNameW( path
, short_path
, sizeof(short_path
)/sizeof(*short_path
) );
1477 ok(!length
, "GetShortPathNameW should fail\n");
1478 ok(GetLastError() == ERROR_INVALID_NAME
, "wrong error %d\n", GetLastError());
1480 lstrcpyW(ptr
, a_bcdeW
);
1481 ret
= DeleteFileW( path
);
1482 ok( ret
, "Cannot delete file.\n" );
1486 ret
= RemoveDirectoryW( path
);
1487 ok( ret
, "Cannot delete directory.\n" );
1490 static void test_GetSystemDirectory(void)
1492 CHAR buffer
[MAX_PATH
+ 4];
1496 SetLastError(0xdeadbeef);
1497 res
= GetSystemDirectoryA(NULL
, 0);
1498 /* res includes the terminating Zero */
1499 ok(res
> 0, "returned %d with %d (expected '>0')\n", res
, GetLastError());
1503 /* this crashes on XP */
1505 GetSystemDirectoryA(NULL
, total
);
1507 SetLastError(0xdeadbeef);
1508 res
= GetSystemDirectoryA(NULL
, total
-1);
1509 /* 95+NT: total (includes the terminating Zero)
1510 98+ME: 0 with ERROR_INVALID_PARAMETER */
1511 ok( (res
== total
) || (!res
&& (GetLastError() == ERROR_INVALID_PARAMETER
)),
1512 "returned %d with %d (expected '%d' or: '0' with "
1513 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError(), total
);
1515 if (total
> MAX_PATH
) return;
1518 SetLastError(0xdeadbeef);
1519 res
= GetSystemDirectoryA(buffer
, total
);
1520 /* res does not include the terminating Zero */
1521 ok( (res
== (total
-1)) && (buffer
[0]),
1522 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1523 res
, GetLastError(), buffer
, total
-1);
1526 SetLastError(0xdeadbeef);
1527 res
= GetSystemDirectoryA(buffer
, total
+ 1);
1528 /* res does not include the terminating Zero */
1529 ok( (res
== (total
-1)) && (buffer
[0]),
1530 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1531 res
, GetLastError(), buffer
, total
-1);
1533 memset(buffer
, '#', total
+ 1);
1534 buffer
[total
+ 2] = '\0';
1535 SetLastError(0xdeadbeef);
1536 res
= GetSystemDirectoryA(buffer
, total
-1);
1537 /* res includes the terminating Zero) */
1538 ok( res
== total
, "returned %d with %d and '%s' (expected '%d')\n",
1539 res
, GetLastError(), buffer
, total
);
1541 memset(buffer
, '#', total
+ 1);
1542 buffer
[total
+ 2] = '\0';
1543 SetLastError(0xdeadbeef);
1544 res
= GetSystemDirectoryA(buffer
, total
-2);
1545 /* res includes the terminating Zero) */
1546 ok( res
== total
, "returned %d with %d and '%s' (expected '%d')\n",
1547 res
, GetLastError(), buffer
, total
);
1550 static void test_GetWindowsDirectory(void)
1552 CHAR buffer
[MAX_PATH
+ 4];
1556 SetLastError(0xdeadbeef);
1557 res
= GetWindowsDirectoryA(NULL
, 0);
1558 /* res includes the terminating Zero */
1559 ok(res
> 0, "returned %d with %d (expected '>0')\n", res
, GetLastError());
1562 /* this crashes on XP */
1564 GetWindowsDirectoryA(NULL
, total
);
1566 SetLastError(0xdeadbeef);
1567 res
= GetWindowsDirectoryA(NULL
, total
-1);
1568 /* 95+NT: total (includes the terminating Zero)
1569 98+ME: 0 with ERROR_INVALID_PARAMETER */
1570 ok( (res
== total
) || (!res
&& (GetLastError() == ERROR_INVALID_PARAMETER
)),
1571 "returned %d with %d (expected '%d' or: '0' with "
1572 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError(), total
);
1574 if (total
> MAX_PATH
) return;
1577 SetLastError(0xdeadbeef);
1578 res
= GetWindowsDirectoryA(buffer
, total
);
1579 /* res does not include the terminating Zero */
1580 ok( (res
== (total
-1)) && (buffer
[0]),
1581 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1582 res
, GetLastError(), buffer
, total
-1);
1585 SetLastError(0xdeadbeef);
1586 res
= GetWindowsDirectoryA(buffer
, total
+ 1);
1587 /* res does not include the terminating Zero */
1588 ok( (res
== (total
-1)) && (buffer
[0]),
1589 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1590 res
, GetLastError(), buffer
, total
-1);
1592 memset(buffer
, '#', total
+ 1);
1593 buffer
[total
+ 2] = '\0';
1594 SetLastError(0xdeadbeef);
1595 res
= GetWindowsDirectoryA(buffer
, total
-1);
1596 /* res includes the terminating Zero) */
1597 ok( res
== total
, "returned %d with %d and '%s' (expected '%d')\n",
1598 res
, GetLastError(), buffer
, total
);
1600 memset(buffer
, '#', total
+ 1);
1601 buffer
[total
+ 2] = '\0';
1602 SetLastError(0xdeadbeef);
1603 res
= GetWindowsDirectoryA(buffer
, total
-2);
1604 /* res includes the terminating Zero) */
1605 ok( res
== total
, "returned %d with %d and '%s' (expected '%d')\n",
1606 res
, GetLastError(), buffer
, total
);
1609 static void test_NeedCurrentDirectoryForExePathA(void)
1611 if (!pNeedCurrentDirectoryForExePathA
)
1613 win_skip("NeedCurrentDirectoryForExePathA is not available\n");
1617 /* Crashes in Windows */
1619 pNeedCurrentDirectoryForExePathA(NULL
);
1621 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL
);
1622 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1623 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1624 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1626 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1627 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1628 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1629 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1632 static void test_NeedCurrentDirectoryForExePathW(void)
1634 const WCHAR thispath
[] = {'.', 0};
1635 const WCHAR fullpath
[] = {'c', ':', '\\', 0};
1636 const WCHAR cmdname
[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1638 if (!pNeedCurrentDirectoryForExePathW
)
1640 win_skip("NeedCurrentDirectoryForExePathW is not available\n");
1644 /* Crashes in Windows */
1646 pNeedCurrentDirectoryForExePathW(NULL
);
1648 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL
);
1649 ok(pNeedCurrentDirectoryForExePathW(thispath
), "returned FALSE for \".\"\n");
1650 ok(pNeedCurrentDirectoryForExePathW(fullpath
), "returned FALSE for \"c:\\\"\n");
1651 ok(pNeedCurrentDirectoryForExePathW(cmdname
), "returned FALSE for \"cmd.exe\"\n");
1653 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1654 ok(!pNeedCurrentDirectoryForExePathW(thispath
), "returned TRUE for \".\"\n");
1655 ok(pNeedCurrentDirectoryForExePathW(fullpath
), "returned FALSE for \"c:\\\"\n");
1656 ok(!pNeedCurrentDirectoryForExePathW(cmdname
), "returned TRUE for \"cmd.exe\"\n");
1659 /* Call various path/file name retrieving APIs and check the case of
1660 * the returned drive letter. Some apps (for instance Adobe Photoshop CS3
1661 * installer) depend on the drive letter being in upper case.
1663 static void test_drive_letter_case(void)
1668 #define is_upper_case_letter(a) ((a) >= 'A' && (a) <= 'Z')
1670 memset(buf
, 0, sizeof(buf
));
1671 SetLastError(0xdeadbeef);
1672 ret
= GetWindowsDirectoryA(buf
, sizeof(buf
));
1673 ok(ret
, "GetWindowsDirectory error %u\n", GetLastError());
1674 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1675 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1676 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1678 /* re-use the buffer returned by GetFullPathName */
1680 SetLastError(0xdeadbeef);
1681 ret
= GetFullPathNameA(buf
+ 2, sizeof(buf
), buf
, NULL
);
1682 ok(ret
, "GetFullPathName error %u\n", GetLastError());
1683 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1684 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1685 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1687 memset(buf
, 0, sizeof(buf
));
1688 SetLastError(0xdeadbeef);
1689 ret
= GetSystemDirectoryA(buf
, sizeof(buf
));
1690 ok(ret
, "GetSystemDirectory error %u\n", GetLastError());
1691 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1692 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1693 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1695 memset(buf
, 0, sizeof(buf
));
1696 SetLastError(0xdeadbeef);
1697 ret
= GetCurrentDirectoryA(sizeof(buf
), buf
);
1698 ok(ret
, "GetCurrentDirectory error %u\n", GetLastError());
1699 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1700 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1701 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1703 /* TEMP is an environment variable, so it can't be tested for case-sensitivity */
1704 memset(buf
, 0, sizeof(buf
));
1705 SetLastError(0xdeadbeef);
1706 ret
= GetTempPathA(sizeof(buf
), buf
);
1707 ok(ret
, "GetTempPath error %u\n", GetLastError());
1708 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1711 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1712 ok(buf
[strlen(buf
)-1] == '\\', "Temporary path (%s) doesn't end in a slash\n", buf
);
1715 memset(buf
, 0, sizeof(buf
));
1716 SetLastError(0xdeadbeef);
1717 ret
= GetFullPathNameA(".", sizeof(buf
), buf
, NULL
);
1718 ok(ret
, "GetFullPathName error %u\n", GetLastError());
1719 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1720 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1721 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1723 /* re-use the buffer returned by GetFullPathName */
1724 SetLastError(0xdeadbeef);
1725 ret
= GetShortPathNameA(buf
, buf
, sizeof(buf
));
1726 ok(ret
, "GetShortPathName error %u\n", GetLastError());
1727 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1728 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1729 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1731 if (pGetLongPathNameA
)
1733 /* re-use the buffer returned by GetShortPathName */
1734 SetLastError(0xdeadbeef);
1735 ret
= pGetLongPathNameA(buf
, buf
, sizeof(buf
));
1736 ok(ret
, "GetLongPathNameA error %u\n", GetLastError());
1737 ok(ret
< sizeof(buf
), "buffer should be %u bytes\n", ret
);
1738 ok(buf
[1] == ':', "expected buf[1] == ':' got %c\n", buf
[1]);
1739 ok(is_upper_case_letter(buf
[0]), "expected buf[0] upper case letter got %c\n", buf
[0]);
1741 #undef is_upper_case_letter
1744 static const char manifest_dep
[] =
1745 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1746 "<assemblyIdentity version=\"1.2.3.4\" name=\"testdep1\" type=\"win32\" processorArchitecture=\"" ARCH
"\"/>"
1747 " <file name=\"testdep.dll\" />"
1748 " <file name=\"ole32\" />"
1749 " <file name=\"kernel32.dll\" />"
1752 static const char manifest_main
[] =
1753 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1754 "<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
1756 " <dependentAssembly>"
1757 " <assemblyIdentity type=\"win32\" name=\"testdep1\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH
"\" />"
1758 " </dependentAssembly>"
1762 static void create_manifest_file(const char *filename
, const char *manifest
)
1764 WCHAR path
[MAX_PATH
], manifest_path
[MAX_PATH
];
1768 MultiByteToWideChar( CP_ACP
, 0, filename
, -1, path
, MAX_PATH
);
1770 GetTempPathW(sizeof(manifest_path
)/sizeof(WCHAR
), manifest_path
);
1771 lstrcatW(manifest_path
, path
);
1773 file
= CreateFileW(manifest_path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1774 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %u\n", GetLastError());
1775 WriteFile(file
, manifest
, strlen(manifest
), &size
, NULL
);
1779 static void delete_manifest_file(const char *filename
)
1781 CHAR path
[MAX_PATH
];
1783 GetTempPathA(sizeof(path
), path
);
1784 strcat(path
, filename
);
1788 static HANDLE
test_create(const char *file
)
1790 WCHAR path
[MAX_PATH
], manifest_path
[MAX_PATH
];
1794 MultiByteToWideChar(CP_ACP
, 0, file
, -1, path
, MAX_PATH
);
1795 GetTempPathW(sizeof(manifest_path
)/sizeof(WCHAR
), manifest_path
);
1796 lstrcatW(manifest_path
, path
);
1798 memset(&actctx
, 0, sizeof(ACTCTXW
));
1799 actctx
.cbSize
= sizeof(ACTCTXW
);
1800 actctx
.lpSource
= manifest_path
;
1802 handle
= pCreateActCtxW(&actctx
);
1803 ok(handle
!= INVALID_HANDLE_VALUE
, "failed to create context, error %u\n", GetLastError());
1805 ok(actctx
.cbSize
== sizeof(actctx
), "cbSize=%d\n", actctx
.cbSize
);
1806 ok(actctx
.dwFlags
== 0, "dwFlags=%d\n", actctx
.dwFlags
);
1807 ok(actctx
.lpSource
== manifest_path
, "lpSource=%p\n", actctx
.lpSource
);
1808 ok(actctx
.wProcessorArchitecture
== 0, "wProcessorArchitecture=%d\n", actctx
.wProcessorArchitecture
);
1809 ok(actctx
.wLangId
== 0, "wLangId=%d\n", actctx
.wLangId
);
1810 ok(actctx
.lpAssemblyDirectory
== NULL
, "lpAssemblyDirectory=%p\n", actctx
.lpAssemblyDirectory
);
1811 ok(actctx
.lpResourceName
== NULL
, "lpResourceName=%p\n", actctx
.lpResourceName
);
1812 ok(actctx
.lpApplicationName
== NULL
, "lpApplicationName=%p\n", actctx
.lpApplicationName
);
1813 ok(actctx
.hModule
== NULL
, "hModule=%p\n", actctx
.hModule
);
1818 static void test_SearchPathA(void)
1820 static const CHAR testdepA
[] = "testdep.dll";
1821 static const CHAR testdeprelA
[] = "./testdep.dll";
1822 static const CHAR kernel32A
[] = "kernel32.dll";
1823 static const CHAR fileA
[] = "";
1824 CHAR pathA
[MAX_PATH
], buffA
[MAX_PATH
], path2A
[MAX_PATH
], path3A
[MAX_PATH
], curdirA
[MAX_PATH
];
1825 CHAR tmpdirA
[MAX_PATH
], *ptrA
= NULL
;
1833 win_skip("SearchPathA isn't available\n");
1837 GetWindowsDirectoryA(pathA
, sizeof(pathA
)/sizeof(CHAR
));
1840 SetLastError(0xdeadbeef);
1841 ret
= pSearchPathA(pathA
, NULL
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, &ptrA
);
1842 ok(ret
== 0, "Expected failure, got %d\n", ret
);
1843 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1844 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1846 /* empty filename */
1847 SetLastError(0xdeadbeef);
1848 ret
= pSearchPathA(pathA
, fileA
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, &ptrA
);
1849 ok(ret
== 0, "Expected failure, got %d\n", ret
);
1850 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1851 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1853 if (!pActivateActCtx
)
1856 create_manifest_file("testdep1.manifest", manifest_dep
);
1857 create_manifest_file("main.manifest", manifest_main
);
1859 handle
= test_create("main.manifest");
1860 delete_manifest_file("testdep1.manifest");
1861 delete_manifest_file("main.manifest");
1863 /* search fails without active context */
1864 ret
= pSearchPathA(NULL
, testdepA
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1865 ok(ret
== 0, "got %d\n", ret
);
1867 ret
= pSearchPathA(NULL
, kernel32A
, NULL
, sizeof(path2A
)/sizeof(CHAR
), path2A
, NULL
);
1868 ok(ret
&& ret
== strlen(path2A
), "got %d\n", ret
);
1870 ret
= pActivateActCtx(handle
, &cookie
);
1871 ok(ret
, "failed to activate context, %u\n", GetLastError());
1873 /* works when activated */
1874 ret
= pSearchPathA(NULL
, testdepA
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1875 ok(ret
&& ret
== strlen(buffA
), "got %d\n", ret
);
1877 ret
= pSearchPathA(NULL
, "testdep.dll", ".ext", sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1878 ok(ret
&& ret
== strlen(buffA
), "got %d\n", ret
);
1880 ret
= pSearchPathA(NULL
, "testdep", ".dll", sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1881 ok(ret
&& ret
== strlen(buffA
), "got %d\n", ret
);
1883 ret
= pSearchPathA(NULL
, "testdep", ".ext", sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1884 ok(!ret
, "got %d\n", ret
);
1886 /* name contains path */
1887 ret
= pSearchPathA(NULL
, testdeprelA
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1888 ok(!ret
, "got %d\n", ret
);
1890 /* fails with specified path that doesn't contain this file */
1891 ret
= pSearchPathA(pathA
, testdepA
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1892 ok(!ret
, "got %d\n", ret
);
1894 /* path is redirected for wellknown names too */
1895 ret
= pSearchPathA(NULL
, kernel32A
, NULL
, sizeof(buffA
)/sizeof(CHAR
), buffA
, NULL
);
1896 ok(ret
&& ret
== strlen(buffA
), "got %d\n", ret
);
1897 ok(strcmp(buffA
, path2A
), "got wrong path %s, %s\n", buffA
, path2A
);
1899 ret
= pDeactivateActCtx(0, cookie
);
1900 ok(ret
, "failed to deactivate context, %u\n", GetLastError());
1901 pReleaseActCtx(handle
);
1903 /* test the search path priority of the working directory */
1904 GetTempPathA(sizeof(tmpdirA
), tmpdirA
);
1905 ret
= GetCurrentDirectoryA(MAX_PATH
, curdirA
);
1906 ok(ret
, "failed to obtain working directory.\n");
1907 sprintf(pathA
, "%s\\%s", tmpdirA
, kernel32A
);
1908 ret
= pSearchPathA(NULL
, kernel32A
, NULL
, sizeof(path2A
)/sizeof(CHAR
), path2A
, NULL
);
1909 ok(ret
&& ret
== strlen(path2A
), "got %d\n", ret
);
1910 bret
= CopyFileA(path2A
, pathA
, FALSE
);
1911 ok(bret
!= 0, "failed to copy test executable to temp directory, %u\n", GetLastError());
1912 sprintf(path3A
, "%s%s%s", curdirA
, curdirA
[strlen(curdirA
)-1] != '\\' ? "\\" : "", kernel32A
);
1913 bret
= CopyFileA(path2A
, path3A
, FALSE
);
1914 ok(bret
!= 0, "failed to copy test executable to launch directory, %u\n", GetLastError());
1915 bret
= SetCurrentDirectoryA(tmpdirA
);
1916 ok(bret
, "failed to change working directory\n");
1917 ret
= pSearchPathA(NULL
, kernel32A
, ".exe", sizeof(buffA
), buffA
, NULL
);
1918 ok(ret
&& ret
== strlen(buffA
), "got %d\n", ret
);
1919 ok(strcmp(buffA
, path3A
) == 0, "expected %s, got %s\n", path3A
, buffA
);
1920 bret
= SetCurrentDirectoryA(curdirA
);
1921 ok(bret
, "failed to reset working directory\n");
1922 DeleteFileA(path3A
);
1926 static void test_SearchPathW(void)
1928 static const WCHAR testdeprelW
[] = {'.','/','t','e','s','t','d','e','p','.','d','l','l',0};
1929 static const WCHAR testdepW
[] = {'t','e','s','t','d','e','p','.','d','l','l',0};
1930 static const WCHAR testdep1W
[] = {'t','e','s','t','d','e','p',0};
1931 static const WCHAR kernel32dllW
[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
1932 static const WCHAR kernel32W
[] = {'k','e','r','n','e','l','3','2',0};
1933 static const WCHAR ole32W
[] = {'o','l','e','3','2',0};
1934 static const WCHAR extW
[] = {'.','e','x','t',0};
1935 static const WCHAR dllW
[] = {'.','d','l','l',0};
1936 static const WCHAR fileW
[] = { 0 };
1937 WCHAR pathW
[MAX_PATH
], buffW
[MAX_PATH
], path2W
[MAX_PATH
];
1945 win_skip("SearchPathW isn't available\n");
1951 /* NULL filename, crashes on nt4 */
1952 pSearchPathW(pathW
, NULL
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, &ptrW
);
1955 GetWindowsDirectoryW(pathW
, sizeof(pathW
)/sizeof(WCHAR
));
1957 /* empty filename */
1958 SetLastError(0xdeadbeef);
1959 ret
= pSearchPathW(pathW
, fileW
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, &ptrW
);
1960 ok(ret
== 0, "Expected failure, got %d\n", ret
);
1961 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1962 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1964 if (!pActivateActCtx
)
1967 create_manifest_file("testdep1.manifest", manifest_dep
);
1968 create_manifest_file("main.manifest", manifest_main
);
1970 handle
= test_create("main.manifest");
1971 delete_manifest_file("testdep1.manifest");
1972 delete_manifest_file("main.manifest");
1974 /* search fails without active context */
1975 ret
= pSearchPathW(NULL
, testdepW
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
1976 ok(ret
== 0, "got %d\n", ret
);
1978 ret
= pSearchPathW(NULL
, kernel32dllW
, NULL
, sizeof(path2W
)/sizeof(WCHAR
), path2W
, NULL
);
1979 ok(ret
&& ret
== lstrlenW(path2W
), "got %d\n", ret
);
1981 /* full path, name without 'dll' extension */
1982 GetSystemDirectoryW(pathW
, sizeof(pathW
)/sizeof(WCHAR
));
1983 ret
= pSearchPathW(pathW
, kernel32W
, NULL
, sizeof(path2W
)/sizeof(WCHAR
), path2W
, NULL
);
1984 ok(ret
== 0, "got %d\n", ret
);
1986 GetWindowsDirectoryW(pathW
, sizeof(pathW
)/sizeof(WCHAR
));
1988 ret
= pActivateActCtx(handle
, &cookie
);
1989 ok(ret
, "failed to activate context, %u\n", GetLastError());
1991 /* works when activated */
1992 ret
= pSearchPathW(NULL
, testdepW
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
1993 ok(ret
&& ret
== lstrlenW(buffW
), "got %d\n", ret
);
1995 ret
= pSearchPathW(NULL
, testdepW
, extW
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
1996 ok(ret
&& ret
== lstrlenW(buffW
), "got %d\n", ret
);
1998 ret
= pSearchPathW(NULL
, testdep1W
, dllW
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
1999 ok(ret
&& ret
== lstrlenW(buffW
), "got %d\n", ret
);
2001 ret
= pSearchPathW(NULL
, testdep1W
, extW
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
2002 ok(!ret
, "got %d\n", ret
);
2004 /* name contains path */
2005 ret
= pSearchPathW(NULL
, testdeprelW
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
2006 ok(!ret
, "got %d\n", ret
);
2008 /* fails with specified path that doesn't contain this file */
2009 ret
= pSearchPathW(pathW
, testdepW
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
2010 ok(!ret
, "got %d\n", ret
);
2012 /* path is redirected for wellknown names too, meaning it takes precedence over normal search order */
2013 ret
= pSearchPathW(NULL
, kernel32dllW
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
2014 ok(ret
&& ret
== lstrlenW(buffW
), "got %d\n", ret
);
2015 ok(lstrcmpW(buffW
, path2W
), "got wrong path %s, %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(path2W
));
2017 /* path is built using on manifest file name */
2018 ret
= pSearchPathW(NULL
, ole32W
, NULL
, sizeof(buffW
)/sizeof(WCHAR
), buffW
, NULL
);
2019 ok(ret
&& ret
== lstrlenW(buffW
), "got %d\n", ret
);
2021 ret
= pDeactivateActCtx(0, cookie
);
2022 ok(ret
, "failed to deactivate context, %u\n", GetLastError());
2023 pReleaseActCtx(handle
);
2026 static void test_GetFullPathNameA(void)
2028 char output
[MAX_PATH
], *filepart
;
2039 } invalid_parameters
[] =
2041 {NULL
, 0, NULL
, NULL
},
2042 {NULL
, MAX_PATH
, NULL
, NULL
},
2043 {NULL
, MAX_PATH
, output
, NULL
},
2044 {NULL
, MAX_PATH
, output
, &filepart
},
2045 {"", 0, NULL
, NULL
},
2046 {"", MAX_PATH
, NULL
, NULL
},
2047 {"", MAX_PATH
, output
, NULL
},
2048 {"", MAX_PATH
, output
, &filepart
},
2051 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
2053 SetLastError(0xdeadbeef);
2054 strcpy(output
, "deadbeef");
2055 filepart
= (char *)0xdeadbeef;
2056 ret
= GetFullPathNameA(invalid_parameters
[i
].name
,
2057 invalid_parameters
[i
].len
,
2058 invalid_parameters
[i
].buffer
,
2059 invalid_parameters
[i
].lastpart
);
2060 ok(!ret
, "[%d] Expected GetFullPathNameA to return 0, got %u\n", i
, ret
);
2061 ok(!strcmp(output
, "deadbeef"), "[%d] Expected the output buffer to be unchanged, got \"%s\"\n", i
, output
);
2062 ok(filepart
== (char *)0xdeadbeef, "[%d] Expected output file part pointer to be untouched, got %p\n", i
, filepart
);
2063 ok(GetLastError() == 0xdeadbeef ||
2064 GetLastError() == ERROR_INVALID_NAME
, /* Win7 */
2065 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
2071 skip("Skipping DBCS(Japanese) GetFullPathNameA test in this codepage (%d)\n", acp
);
2073 const struct dbcs_case
{
2075 const char *expected
;
2077 { "c:\\a\\\x95\x5c\x97\xa0.txt", "\x95\x5c\x97\xa0.txt" },
2078 { "c:\\\x83\x8f\x83\x43\x83\x93\\wine.c", "wine.c" },
2079 { "c:\\demo\\\x97\xa0\x95\x5c", "\x97\xa0\x95\x5c" }
2081 for (i
= 0; i
< sizeof(testset
)/sizeof(testset
[0]); i
++) {
2082 ret
= GetFullPathNameA(testset
[i
].input
, sizeof(output
),
2084 ok(ret
, "[%d] GetFullPathName error %u\n", i
, GetLastError());
2085 ok(!lstrcmpA(filepart
, testset
[i
].expected
),
2086 "[%d] expected %s got %s\n", i
, testset
[i
].expected
, filepart
);
2091 static void test_GetFullPathNameW(void)
2093 static const WCHAR emptyW
[] = {0};
2094 static const WCHAR deadbeefW
[] = {'d','e','a','d','b','e','e','f',0};
2096 WCHAR output
[MAX_PATH
], *filepart
;
2107 } invalid_parameters
[] =
2109 {NULL
, 0, NULL
, NULL
},
2110 {NULL
, 0, NULL
, &filepart
, 1},
2111 {NULL
, MAX_PATH
, NULL
, NULL
},
2112 {NULL
, MAX_PATH
, output
, NULL
},
2113 {NULL
, MAX_PATH
, output
, &filepart
, 1},
2114 {emptyW
, 0, NULL
, NULL
},
2115 {emptyW
, 0, NULL
, &filepart
, 1},
2116 {emptyW
, MAX_PATH
, NULL
, NULL
},
2117 {emptyW
, MAX_PATH
, output
, NULL
},
2118 {emptyW
, MAX_PATH
, output
, &filepart
, 1},
2121 SetLastError(0xdeadbeef);
2122 ret
= GetFullPathNameW(NULL
, 0, NULL
, NULL
);
2123 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
2125 win_skip("GetFullPathNameW is not available\n");
2129 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
2131 SetLastError(0xdeadbeef);
2132 lstrcpyW(output
, deadbeefW
);
2133 filepart
= (WCHAR
*)0xdeadbeef;
2134 ret
= GetFullPathNameW(invalid_parameters
[i
].name
,
2135 invalid_parameters
[i
].len
,
2136 invalid_parameters
[i
].buffer
,
2137 invalid_parameters
[i
].lastpart
);
2138 ok(!ret
, "[%d] Expected GetFullPathNameW to return 0, got %u\n", i
, ret
);
2139 ok(!lstrcmpW(output
, deadbeefW
), "[%d] Expected the output buffer to be unchanged, got %s\n", i
, wine_dbgstr_w(output
));
2140 ok(filepart
== (WCHAR
*)0xdeadbeef ||
2141 (invalid_parameters
[i
].win7_expect
&& filepart
== NULL
),
2142 "[%d] Expected output file part pointer to be untouched, got %p\n", i
, filepart
);
2143 ok(GetLastError() == 0xdeadbeef ||
2144 GetLastError() == ERROR_INVALID_NAME
, /* Win7 */
2145 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
2150 static void init_pointers(void)
2152 HMODULE hKernel32
= GetModuleHandleA("kernel32.dll");
2154 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hKernel32, #f))
2155 MAKEFUNC(GetLongPathNameA
);
2156 MAKEFUNC(GetLongPathNameW
);
2157 MAKEFUNC(NeedCurrentDirectoryForExePathA
);
2158 MAKEFUNC(NeedCurrentDirectoryForExePathW
);
2159 MAKEFUNC(SearchPathA
);
2160 MAKEFUNC(SearchPathW
);
2161 MAKEFUNC(ActivateActCtx
);
2162 MAKEFUNC(CreateActCtxW
);
2163 MAKEFUNC(DeactivateActCtx
);
2164 MAKEFUNC(GetCurrentActCtx
);
2165 MAKEFUNC(ReleaseActCtx
);
2166 MAKEFUNC(CheckNameLegalDOS8Dot3W
);
2167 MAKEFUNC(CheckNameLegalDOS8Dot3A
);
2171 static void test_relative_path(void)
2173 char path
[MAX_PATH
], buf
[MAX_PATH
];
2176 WCHAR curdir
[MAX_PATH
];
2178 if (!pGetLongPathNameA
) return;
2180 GetCurrentDirectoryW(MAX_PATH
, curdir
);
2181 GetTempPathA(MAX_PATH
, path
);
2182 ret
= SetCurrentDirectoryA(path
);
2183 ok(ret
, "SetCurrentDirectory error %d\n", GetLastError());
2185 ret
= CreateDirectoryA("foo", NULL
);
2186 ok(ret
, "CreateDirectory error %d\n", GetLastError());
2187 file
= CreateFileA("foo\\file", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2188 ok(file
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n");
2190 ret
= CreateDirectoryA("bar", NULL
);
2191 ok(ret
, "CreateDirectory error %d\n", GetLastError());
2192 ret
= SetCurrentDirectoryA("bar");
2193 ok(ret
, "SetCurrentDirectory error %d\n", GetLastError());
2195 ret
= GetFileAttributesA("..\\foo\\file");
2196 ok(ret
!= INVALID_FILE_ATTRIBUTES
, "GetFileAttributes error %d\n", GetLastError());
2198 strcpy(buf
, "deadbeef");
2199 ret
= pGetLongPathNameA(".", buf
, MAX_PATH
);
2200 ok(ret
, "GetLongPathName error %d\n", GetLastError());
2201 ok(!strcmp(buf
, "."), "expected ., got %s\n", buf
);
2202 strcpy(buf
, "deadbeef");
2203 ret
= GetShortPathNameA(".", buf
, MAX_PATH
);
2204 ok(ret
, "GetShortPathName error %d\n", GetLastError());
2205 ok(!strcmp(buf
, "."), "expected ., got %s\n", buf
);
2207 strcpy(buf
, "deadbeef");
2208 ret
= pGetLongPathNameA("..", buf
, MAX_PATH
);
2209 ok(ret
, "GetLongPathName error %d\n", GetLastError());
2210 ok(!strcmp(buf
, ".."), "expected .., got %s\n", buf
);
2211 strcpy(buf
, "deadbeef");
2212 ret
= GetShortPathNameA("..", buf
, MAX_PATH
);
2213 ok(ret
, "GetShortPathName error %d\n", GetLastError());
2214 ok(!strcmp(buf
, ".."), "expected .., got %s\n", buf
);
2216 strcpy(buf
, "deadbeef");
2217 ret
= pGetLongPathNameA("..\\foo\\file", buf
, MAX_PATH
);
2218 ok(ret
, "GetLongPathName error %d\n", GetLastError());
2219 ok(!strcmp(buf
, "..\\foo\\file"), "expected ..\\foo\\file, got %s\n", buf
);
2220 strcpy(buf
, "deadbeef");
2221 ret
= GetShortPathNameA("..\\foo\\file", buf
, MAX_PATH
);
2222 ok(ret
, "GetShortPathName error %d\n", GetLastError());
2223 ok(!strcmp(buf
, "..\\foo\\file"), "expected ..\\foo\\file, got %s\n", buf
);
2225 strcpy(buf
, "deadbeef");
2226 ret
= pGetLongPathNameA(".\\..\\foo\\file", buf
, MAX_PATH
);
2227 ok(ret
, "GetLongPathName error %d\n", GetLastError());
2228 ok(!strcmp(buf
, ".\\..\\foo\\file"), "expected .\\..\\foo\\file, got %s\n", buf
);
2229 strcpy(buf
, "deadbeef");
2230 ret
= GetShortPathNameA(".\\..\\foo\\file", buf
, MAX_PATH
);
2231 ok(ret
, "GetShortPathName error %d\n", GetLastError());
2232 ok(!strcmp(buf
, ".\\..\\foo\\file"), "expected .\\..\\foo\\file, got %s\n", buf
);
2234 /* test double delimiters */
2235 strcpy(buf
, "deadbeef");
2236 ret
= pGetLongPathNameA("..\\\\foo\\file", buf
, MAX_PATH
);
2237 ok(ret
, "GetLongPathName error %d\n", GetLastError());
2238 ok(!strcmp(buf
, "..\\\\foo\\file"), "expected ..\\\\foo\\file, got %s\n", buf
);
2239 strcpy(buf
, "deadbeef");
2240 ret
= GetShortPathNameA("..\\\\foo\\file", buf
, MAX_PATH
);
2241 ok(ret
, "GetShortPathName error %d\n", GetLastError());
2242 ok(!strcmp(buf
, "..\\\\foo\\file"), "expected ..\\\\foo\\file, got %s\n", buf
);
2244 SetCurrentDirectoryA("..");
2245 DeleteFileA("foo\\file");
2246 RemoveDirectoryA("foo");
2247 RemoveDirectoryA("bar");
2248 SetCurrentDirectoryW(curdir
);
2251 static void test_CheckNameLegalDOS8Dot3(void)
2253 static const WCHAR has_driveW
[] = {'C',':','\\','a','.','t','x','t',0};
2254 static const WCHAR has_pathW
[] = {'b','\\','a','.','t','x','t',0};
2255 static const WCHAR too_longW
[] = {'a','l','o','n','g','f','i','l','e','n','a','m','e','.','t','x','t',0};
2256 static const WCHAR twodotsW
[] = {'t','e','s','t','.','e','s','t','.','t','x','t',0};
2257 static const WCHAR longextW
[] = {'t','e','s','t','.','t','x','t','t','x','t',0};
2258 static const WCHAR emptyW
[] = {0};
2259 static const WCHAR funnycharsW
[] = {'!','#','$','%','&','\'','(',')','.','-','@','^',0};
2260 static const WCHAR length8W
[] = {'t','e','s','t','t','e','s','t','.','t','x','t',0};
2261 static const WCHAR length1W
[] = {'t',0};
2262 static const WCHAR withspaceW
[] = {'t','e','s','t',' ','e','s','t','.','t','x','t',0};
2264 static const struct {
2266 BOOL should_be_legal
, has_space
;
2268 {has_driveW
, FALSE
, FALSE
},
2269 {has_pathW
, FALSE
, FALSE
},
2270 {too_longW
, FALSE
, FALSE
},
2271 {twodotsW
, FALSE
, FALSE
},
2272 {longextW
, FALSE
, FALSE
},
2273 {emptyW
, TRUE
/* ! */, FALSE
},
2274 {funnycharsW
, TRUE
, FALSE
},
2275 {length8W
, TRUE
, FALSE
},
2276 {length1W
, TRUE
, FALSE
},
2277 {withspaceW
, TRUE
, TRUE
},
2280 BOOL br
, is_legal
, has_space
;
2284 if(!pCheckNameLegalDOS8Dot3W
){
2285 win_skip("Missing CheckNameLegalDOS8Dot3, skipping tests\n");
2289 br
= pCheckNameLegalDOS8Dot3W(NULL
, NULL
, 0, NULL
, &is_legal
);
2290 ok(br
== FALSE
, "CheckNameLegalDOS8Dot3W should have failed\n");
2292 br
= pCheckNameLegalDOS8Dot3A(NULL
, NULL
, 0, NULL
, &is_legal
);
2293 ok(br
== FALSE
, "CheckNameLegalDOS8Dot3A should have failed\n");
2295 br
= pCheckNameLegalDOS8Dot3W(length8W
, NULL
, 0, NULL
, NULL
);
2296 ok(br
== FALSE
, "CheckNameLegalDOS8Dot3W should have failed\n");
2298 br
= pCheckNameLegalDOS8Dot3A("testtest.txt", NULL
, 0, NULL
, NULL
);
2299 ok(br
== FALSE
, "CheckNameLegalDOS8Dot3A should have failed\n");
2301 for(i
= 0; i
< sizeof(cases
)/sizeof(*cases
); ++i
){
2302 br
= pCheckNameLegalDOS8Dot3W(cases
[i
].name
, NULL
, 0, &has_space
, &is_legal
);
2303 ok(br
== TRUE
, "CheckNameLegalDOS8Dot3W failed for %s\n", wine_dbgstr_w(cases
[i
].name
));
2304 ok(is_legal
== cases
[i
].should_be_legal
, "Got wrong legality for %s\n", wine_dbgstr_w(cases
[i
].name
));
2306 ok(has_space
== cases
[i
].has_space
, "Got wrong space for %s\n", wine_dbgstr_w(cases
[i
].name
));
2308 WideCharToMultiByte(CP_ACP
, 0, cases
[i
].name
, -1, astr
, sizeof(astr
), NULL
, NULL
);
2310 br
= pCheckNameLegalDOS8Dot3A(astr
, NULL
, 0, &has_space
, &is_legal
);
2311 ok(br
== TRUE
, "CheckNameLegalDOS8Dot3W failed for %s\n", astr
);
2312 ok(is_legal
== cases
[i
].should_be_legal
, "Got wrong legality for %s\n", astr
);
2314 ok(has_space
== cases
[i
].has_space
, "Got wrong space for %s\n", wine_dbgstr_w(cases
[i
].name
));
2320 CHAR origdir
[MAX_PATH
],curdir
[MAX_PATH
], curDrive
, otherDrive
;
2324 /* Report only once */
2325 if (!pGetLongPathNameA
)
2326 win_skip("GetLongPathNameA is not available\n");
2327 if (!pGetLongPathNameW
)
2328 win_skip("GetLongPathNameW is not available\n");
2329 if (!pActivateActCtx
)
2330 win_skip("Activation contexts not supported, some tests will be skipped\n");
2332 test_relative_path();
2333 test_InitPathA(curdir
, &curDrive
, &otherDrive
);
2334 test_CurrentDirectoryA(origdir
,curdir
);
2335 test_PathNameA(curdir
, curDrive
, otherDrive
);
2336 test_CleanupPathA(origdir
,curdir
);
2338 test_GetLongPathNameA();
2339 test_GetLongPathNameW();
2340 test_GetShortPathNameW();
2341 test_GetSystemDirectory();
2342 test_GetWindowsDirectory();
2343 test_NeedCurrentDirectoryForExePathA();
2344 test_NeedCurrentDirectoryForExePathW();
2345 test_drive_letter_case();
2348 test_GetFullPathNameA();
2349 test_GetFullPathNameW();
2350 test_CheckNameLegalDOS8Dot3();