ntdll: Implement the SectionBasicInformation class of NtQuerySection.
[wine.git] / dlls / kernel32 / tests / path.c
blob836d7eca7819e5166660944d80a0725f49b8d921
1 /*
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
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <assert.h>
25 #include "wine/test.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winerror.h"
30 #include "winnls.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 '@'
45 #ifdef __i386__
46 #define ARCH "x86"
47 #elif defined __x86_64__
48 #define ARCH "amd64"
49 #elif defined __arm__
50 #define ARCH "arm"
51 #elif defined __aarch64__
52 #define ARCH "arm64"
53 #else
54 #define ARCH "none"
55 #endif
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
61 |<>"
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 */
86 typedef struct {
87 DWORD shortlen;
88 DWORD shorterror;
89 DWORD s2llen;
90 DWORD s2lerror;
91 DWORD longlen;
92 DWORD longerror;
93 } SLpassfail;
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 */
111 DWORD len;
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
116 if(passfail!=NULL) {
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);
136 } else {
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)) {
146 ok(strptr==NULL,
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);
151 } else {
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 */
160 SetLastError(0);
161 len=GetShortPathNameA(fullpathshort,shortstr,MAX_PATH);
162 if(passfail==NULL) {
163 ok(len, "%s: GetShortPathNameA failed\n",errstr);
164 } else {
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) {
172 if(len!=0) {
173 SetLastError(0);
174 len=pGetLongPathNameA(shortstr,tmpstr,MAX_PATH);
175 if(passfail==NULL) {
176 ok(len,
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);
181 } else {
182 passfail->s2llen=len;
183 passfail->s2lerror=GetLastError();
186 SetLastError(0);
187 len=pGetLongPathNameA(fullpath,tmpstr,MAX_PATH);
188 if(passfail==NULL) {
189 ok(len, "%s: GetLongPathNameA failed\n",errstr);
190 if(HAS_TRAIL_SLASH_A(fullpath)) {
191 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
192 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
193 errstr,tmpstr,fullpathlong);
194 } else {
195 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
196 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
197 errstr,tmpstr,fullpathlong);
199 } else {
200 passfail->longlen=len;
201 passfail->longerror=GetLastError();
206 /* split path into leading directory, and 8.3 filename */
207 static void test_SplitShortPathA(CHAR *path,CHAR *dir,CHAR *eight,CHAR *three) {
208 BOOL done = FALSE, error = FALSE;
209 int ext,fil;
210 int len,i;
211 len=lstrlenA(path);
212 ext=len;
213 fil=len;
214 /* walk backwards over path looking for '.' or '\\' separators */
215 for(i=len-1;(i>=0) && (!done);i--) {
216 if(path[i]=='.')
217 if(ext!=len) error=TRUE; else ext=i;
218 else if(path[i]=='\\') {
219 if(i==len-1) {
220 error=TRUE;
221 } else {
222 fil=i;
223 done=TRUE;
227 /* Check that we didn't find a trailing '\\' or multiple '.' */
228 ok(!error,"Illegal file found in 8.3 path '%s'\n",path);
229 /* Separate dir, root, and extension */
230 if(ext!=len) lstrcpyA(three,path+ext+1); else lstrcpyA(three,"");
231 if(fil!=len) {
232 lstrcpynA(eight,path+fil+1,ext-fil);
233 lstrcpynA(dir,path,fil+1);
234 } else {
235 lstrcpynA(eight,path,ext+1);
236 lstrcpyA(dir,"");
238 /* Validate that root and extension really are 8.3 */
239 ok(lstrlenA(eight)<=8 && lstrlenA(three)<=3,
240 "GetShortPathNAmeA did not return an 8.3 path\n");
243 /* Check that GetShortPathNameA returns a valid 8.3 path */
244 static void test_LongtoShortA(CHAR *teststr,const CHAR *goodstr,
245 const CHAR *ext,const CHAR *errstr) {
246 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
248 test_SplitShortPathA(teststr,dir,eight,three);
249 ok(lstrcmpiA(dir,goodstr)==0,
250 "GetShortPathNameA returned '%s' instead of '%s'\n",dir,goodstr);
251 ok(lstrcmpiA(three,ext)==0,
252 "GetShortPathNameA returned '%s' with incorrect extension\n",three);
255 /* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
256 characters in the filename.
257 'valid' indicates whether this would be an allowed filename
258 'todo' indicates that wine doesn't get this right yet.
259 NOTE: We always call this routine with a nonexistent filename, so
260 Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
261 should.
263 static void test_FunnyChars(CHAR *curdir,CHAR *curdir_short,CHAR *filename, INT valid,CHAR *errstr)
265 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
266 SLpassfail passfail;
268 test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
269 if(valid) {
270 sprintf(tmpstr1,"%s\\%s",curdir_short,filename);
271 ok((passfail.shortlen==0 &&
272 (passfail.shorterror==ERROR_FILE_NOT_FOUND || passfail.shorterror==ERROR_PATH_NOT_FOUND || !passfail.shorterror)) ||
273 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
274 "%s: GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
275 errstr,passfail.shortlen,passfail.shorterror,tmpstr);
276 } else {
277 ok(passfail.shortlen==0 &&
278 (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),
279 "%s: GetShortPathA should have failed len=%d, error=%d\n",
280 errstr,passfail.shortlen,passfail.shorterror);
282 if(pGetLongPathNameA) {
283 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
284 if(valid) {
285 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
286 "%s: GetLongPathA returned %d and not %d\n",
287 errstr,passfail.longerror,ERROR_FILE_NOT_FOUND);
288 } else {
289 ok(passfail.longerror==ERROR_INVALID_NAME ||
290 passfail.longerror==ERROR_FILE_NOT_FOUND,
291 "%s: GetLongPathA returned %d and not %d or %d'\n",
292 errstr, passfail.longerror,ERROR_INVALID_NAME,ERROR_FILE_NOT_FOUND);
297 /* Routine to test that SetCurrentDirectory behaves as expected. */
298 static void test_setdir(CHAR *olddir,CHAR *newdir,
299 CHAR *cmprstr, INT pass, const CHAR *errstr)
301 CHAR tmppath[MAX_PATH], *dirptr;
302 DWORD val,len,chklen;
304 val=SetCurrentDirectoryA(newdir);
305 len=GetCurrentDirectoryA(MAX_PATH,tmppath);
306 /* if 'pass' then the SetDirectoryA was supposed to pass */
307 if(pass) {
308 dirptr=(cmprstr==NULL) ? newdir : cmprstr;
309 chklen=lstrlenA(dirptr);
310 ok(val,"%s: SetCurrentDirectoryA failed\n",errstr);
311 ok(len==chklen,
312 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
313 errstr);
314 ok(lstrcmpiA(dirptr,tmppath)==0,
315 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
316 errstr);
317 ok(SetCurrentDirectoryA(olddir),
318 "%s: Couldn't set directory to its original value\n",errstr);
319 } else {
320 /* else thest that it fails correctly */
321 chklen=lstrlenA(olddir);
322 ok(val==0,
323 "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr);
324 ok(len==chklen,
325 "%s: SetCurrentDirectory changed the directory, though it failed\n",
326 errstr);
327 ok(lstrcmpiA(olddir,tmppath)==0,
328 "%s: SetCurrentDirectory changed the directory, though it failed\n",
329 errstr);
332 static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
334 CHAR tmppath[MAX_PATH], /*path to TEMP */
335 tmpstr[MAX_PATH],
336 tmpstr1[MAX_PATH],
337 invalid_dir[MAX_PATH];
339 DWORD len,len1,drives;
340 INT id;
341 HANDLE hndl;
342 BOOL bRes;
343 UINT unique;
345 *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
347 /* Get the current drive letter */
348 if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
349 *curDrive = tmpstr[0];
350 else
351 trace( "Unable to discover current drive, some tests will not be conducted.\n");
353 /* Test GetTempPathA */
354 len=GetTempPathA(MAX_PATH,tmppath);
355 ok(len!=0 && len < MAX_PATH,"GetTempPathA failed\n");
356 ok(HAS_TRAIL_SLASH_A(tmppath),
357 "GetTempPathA returned a path that did not end in '\\'\n");
358 lstrcpyA(tmpstr,"aaaaaaaa");
359 len1=GetTempPathA(len,tmpstr);
360 ok(len1==len+1 || broken(len1 == len), /* WinME */
361 "GetTempPathA should return string length %d instead of %d\n",len+1,len1);
363 /* Test GetTmpFileNameA */
364 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
365 sprintf(tmpstr,"pat%.4x.tmp",id & 0xffff);
366 sprintf(tmpstr1,"pat%x.tmp",id & 0xffff);
367 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
368 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
369 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
370 newdir,tmpstr,tmpstr1,id);
371 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
373 id=GetTempFileNameA(tmppath,NULL,0,newdir);
374 /* Windows 95, 98 return 0==id, while Windows 2000, XP return 0!=id */
375 if (id)
377 sprintf(tmpstr,"%.4x.tmp",id & 0xffff);
378 sprintf(tmpstr1,"%x.tmp",id & 0xffff);
379 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
380 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
381 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
382 newdir,tmpstr,tmpstr1,id);
383 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
386 for(unique=0;unique<3;unique++) {
387 /* Nonexistent path */
388 sprintf(invalid_dir, "%s\\%s",tmppath,"non_existent_dir_1jwj3y32nb3");
389 SetLastError(0xdeadbeef);
390 ok(!GetTempFileNameA(invalid_dir,"tfn",unique,newdir),"GetTempFileNameA should have failed\n");
391 ok(GetLastError()==ERROR_DIRECTORY || broken(GetLastError()==ERROR_PATH_NOT_FOUND)/*win98*/,
392 "got %d, expected ERROR_DIRECTORY\n", GetLastError());
394 /* Check return value for unique !=0 */
395 if(unique) {
396 ok((GetTempFileNameA(tmppath,"tfn",unique,newdir) == unique),"GetTempFileNameA unexpectedly failed\n");
397 /* if unique != 0, the actual temp files are not created: */
398 ok(!DeleteFileA(newdir) && GetLastError() == ERROR_FILE_NOT_FOUND,"Deleted a file that shouldn't exist!\n");
402 /* Find first valid drive letter that is neither newdir[0] nor curDrive */
403 drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
404 if( *curDrive != NOT_A_VALID_DRIVE)
405 drives &= ~(1<<(*curDrive-'A'));
406 if( drives)
407 for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
408 else
409 trace( "Could not find alternative drive, some tests will not be conducted.\n");
411 /* Do some CreateDirectoryA tests */
412 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
413 really understand how they work.
414 More formal tests should be done along with CreateFile tests
416 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
417 ok(CreateDirectoryA(newdir,NULL)==0,
418 "CreateDirectoryA succeeded even though a file of the same name exists\n");
419 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
420 ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
421 /* Create some files to test other functions. Note, we will test CreateFileA
422 at some later point
424 sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
425 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
426 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
427 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
428 sprintf(tmpstr,"%c:", *curDrive);
429 bRes = CreateDirectoryA(tmpstr,NULL);
430 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
431 GetLastError() == ERROR_ALREADY_EXISTS),
432 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
433 sprintf(tmpstr,"%c:\\", *curDrive);
434 bRes = CreateDirectoryA(tmpstr,NULL);
435 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
436 GetLastError() == ERROR_ALREADY_EXISTS),
437 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
438 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
439 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
440 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
441 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
442 ok(CloseHandle(hndl),"CloseHandle failed\n");
443 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
444 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
445 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
446 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
447 ok(CloseHandle(hndl),"CloseHandle failed\n");
448 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
449 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
450 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
451 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
452 ok(CloseHandle(hndl),"CloseHandle failed\n");
453 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
454 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
455 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
456 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
457 ok(CloseHandle(hndl),"CloseHandle failed\n");
460 /* Test GetCurrentDirectory & SetCurrentDirectory */
461 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
463 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
464 char *buffer;
465 DWORD len,len1;
466 /* Save the original directory, so that we can return to it at the end
467 of the test
469 len=GetCurrentDirectoryA(MAX_PATH,origdir);
470 ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
471 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
472 buffer size is too small to hold the current directory
474 lstrcpyA(tmpstr,"aaaaaaa");
475 len1=GetCurrentDirectoryA(len,tmpstr);
476 ok(len1==len+1, "GetCurrentDirectoryA returned %d instead of %d\n",len1,len+1);
477 ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
478 "GetCurrentDirectoryA should not have modified the buffer\n");
480 buffer = HeapAlloc( GetProcessHeap(), 0, 2 * 65536 );
481 SetLastError( 0xdeadbeef );
482 strcpy( buffer, "foo" );
483 len = GetCurrentDirectoryA( 32767, buffer );
484 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
485 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
486 SetLastError( 0xdeadbeef );
487 strcpy( buffer, "foo" );
488 len = GetCurrentDirectoryA( 32768, buffer );
489 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
490 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
491 SetLastError( 0xdeadbeef );
492 strcpy( buffer, "foo" );
493 len = GetCurrentDirectoryA( 65535, buffer );
494 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4, win2k, xp */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
495 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
496 SetLastError( 0xdeadbeef );
497 strcpy( buffer, "foo" );
498 len = GetCurrentDirectoryA( 65536, buffer );
499 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4 */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
500 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
501 SetLastError( 0xdeadbeef );
502 strcpy( buffer, "foo" );
503 len = GetCurrentDirectoryA( 2 * 65536, buffer );
504 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4 */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
505 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
506 HeapFree( GetProcessHeap(), 0, buffer );
508 /* Check for crash prevention on swapped args. Crashes all but Win9x.
510 if (0)
512 GetCurrentDirectoryA( 42, (LPSTR)(MAX_PATH + 42) );
515 /* SetCurrentDirectoryA shouldn't care whether the string has a
516 trailing '\\' or not
518 sprintf(tmpstr,"%s\\",newdir);
519 test_setdir(origdir,tmpstr,newdir,1,"check 1");
520 test_setdir(origdir,newdir,NULL,1,"check 2");
521 /* Set the directory to the working area. We just tested that this works,
522 so why check it again.
524 SetCurrentDirectoryA(newdir);
525 /* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
526 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
527 test_setdir(newdir,tmpstr,NULL,0,"check 3");
528 /* Check that SetCurrentDirectory fails for a nonexistent lond directory */
529 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
530 test_setdir(newdir,tmpstr,NULL,0,"check 4");
531 /* Check that SetCurrentDirectory passes with a long directory */
532 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
533 test_setdir(newdir,tmpstr,NULL,1,"check 5");
534 /* Check that SetCurrentDirectory passes with a short relative directory */
535 sprintf(tmpstr,"%s",SHORTDIR);
536 sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
537 test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
538 /* starting with a '.' */
539 sprintf(tmpstr,".\\%s",SHORTDIR);
540 test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
541 /* Check that SetCurrentDirectory passes with a short relative directory */
542 sprintf(tmpstr,"%s",LONGDIR);
543 sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
544 test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
545 /* starting with a '.' */
546 sprintf(tmpstr,".\\%s",LONGDIR);
547 test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
548 /* change to root without a trailing backslash. The function call succeeds
549 but the directory is not changed.
551 sprintf(tmpstr, "%c:", newdir[0]);
552 test_setdir(newdir,tmpstr,newdir,1,"check 10");
553 /* works however with a trailing backslash */
554 sprintf(tmpstr, "%c:\\", newdir[0]);
555 test_setdir(newdir,tmpstr,NULL,1,"check 11");
558 /* Cleanup the mess we made while executing these tests */
559 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
561 CHAR tmpstr[MAX_PATH];
562 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
563 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
564 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
565 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
566 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
567 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
568 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
569 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
570 sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
571 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
572 sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
573 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
574 ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
575 ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
578 /* test that short path name functions work regardless of case */
579 static void test_ShortPathCase(const char *tmpdir, const char *dirname,
580 const char *filename)
582 char buf[MAX_PATH], shortbuf[MAX_PATH];
583 HANDLE hndl;
584 size_t i;
586 assert(strlen(tmpdir) + strlen(dirname) + strlen(filename) + 2 < sizeof(buf));
587 sprintf(buf,"%s\\%s\\%s",tmpdir,dirname,filename);
588 GetShortPathNameA(buf,shortbuf,sizeof(shortbuf));
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());
591 CloseHandle(hndl);
592 /* Now for the real test */
593 for(i=0;i<strlen(shortbuf);i++)
594 if (i % 2)
595 shortbuf[i] = tolower(shortbuf[i]);
596 hndl = CreateFileA(shortbuf,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
597 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed (%d)\n",GetLastError());
598 CloseHandle(hndl);
601 /* This routine will test Get(Full|Short|Long)PathNameA */
602 static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
604 CHAR curdir_short[MAX_PATH],
605 longdir_short[MAX_PATH];
606 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH],tmpstr2[MAX_PATH];
607 LPSTR strptr; /*ptr to the filename portion of the path */
608 DWORD len;
609 INT i;
610 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
611 SLpassfail passfail;
613 /* Get the short form of the current directory */
614 ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
615 "GetShortPathNameA failed\n");
616 ok(!HAS_TRAIL_SLASH_A(curdir_short),
617 "GetShortPathNameA should not have a trailing \\\n");
618 /* Get the short form of the absolute-path to LONGDIR */
619 sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
620 ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
621 "GetShortPathNameA failed\n");
622 ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
623 "GetShortPathNameA should not have a trailing \\\n");
625 if (pGetLongPathNameA) {
626 DWORD rc1,rc2;
627 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
628 rc1=(*pGetLongPathNameA)(tmpstr,NULL,0);
629 rc2=(*pGetLongPathNameA)(curdir,NULL,0);
630 ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
631 "GetLongPathNameA: wrong return code, %d instead of %d\n",
632 rc1, lstrlenA(tmpstr)+1);
634 sprintf(dir,"%c:",curDrive);
635 rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
636 ok(strcmp(dir,tmpstr)==0,
637 "GetLongPathNameA: returned '%s' instead of '%s' (rc=%d)\n",
638 tmpstr,dir,rc1);
641 /* Check the cases where both file and directory exist first */
642 /* Start with a 8.3 directory, 8.3 filename */
643 test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
644 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
645 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
646 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
647 /* Now try a 8.3 directory, long file name */
648 test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
649 sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
650 test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
651 /* Next is a long directory, 8.3 file */
652 test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
653 sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
654 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
655 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
656 /*Lastly a long directory, long file */
657 test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
658 test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
660 /* Now check all of the invalid file w/ valid directory combinations */
661 /* Start with a 8.3 directory, 8.3 filename */
662 test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
663 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
664 ok((passfail.shortlen==0 &&
665 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
666 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
667 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
668 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
669 passfail.shortlen,passfail.shorterror,tmpstr);
670 if(pGetLongPathNameA) {
671 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
672 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
673 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
675 /* Now try a 8.3 directory, long file name */
676 test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
677 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
678 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
679 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
680 !passfail.shorterror,
681 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
682 if(pGetLongPathNameA) {
683 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
684 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
685 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
687 /* Next is a long directory, 8.3 file */
688 test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
689 sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
690 GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
691 strcat(tmpstr1,"\\" NONFILE_SHORT);
692 ok((passfail.shortlen==0 &&
693 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
694 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
695 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
696 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
697 passfail.shortlen,passfail.shorterror,tmpstr);
698 if(pGetLongPathNameA) {
699 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
700 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
701 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
703 /*Lastly a long directory, long file */
704 test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
705 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
706 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
707 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
708 !passfail.shorterror,
709 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
710 if(pGetLongPathNameA) {
711 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
712 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
713 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
715 /* Now try again with directories that don't exist */
716 /* 8.3 directory, 8.3 filename */
717 test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
718 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
719 ok((passfail.shortlen==0 &&
720 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
721 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
722 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
723 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
724 passfail.shortlen,passfail.shorterror,tmpstr);
725 if(pGetLongPathNameA) {
726 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
727 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
728 passfail.longerror==ERROR_FILE_NOT_FOUND,
729 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
730 passfail.longerror);
732 /* Now try a 8.3 directory, long file name */
733 test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
734 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
735 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
736 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
737 !passfail.shorterror,
738 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
739 passfail.shorterror);
740 if(pGetLongPathNameA) {
741 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
742 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
743 passfail.longerror==ERROR_FILE_NOT_FOUND,
744 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
745 passfail.longerror);
747 /* Next is a long directory, 8.3 file */
748 test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
749 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
750 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
751 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
752 !passfail.shorterror,
753 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
754 passfail.shorterror);
755 if(pGetLongPathNameA) {
756 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
757 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
758 passfail.longerror==ERROR_FILE_NOT_FOUND,
759 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
760 passfail.longerror);
762 /*Lastly a long directory, long file */
763 test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
764 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
765 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
766 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
767 !passfail.shorterror,
768 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
769 passfail.shorterror);
770 if(pGetLongPathNameA) {
771 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
772 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
773 passfail.longerror==ERROR_FILE_NOT_FOUND,
774 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
775 passfail.longerror);
777 /* Next try directories ending with '\\' */
778 /* Existing Directories */
779 sprintf(tmpstr,"%s\\",SHORTDIR);
780 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
781 sprintf(tmpstr,"%s\\",LONGDIR);
782 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
783 /* Nonexistent directories */
784 sprintf(tmpstr,"%s\\",NONDIR_SHORT);
785 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
786 sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
787 ok((passfail.shortlen==0 &&
788 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
789 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
790 (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
791 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
792 passfail.shortlen,passfail.shorterror,tmpstr);
793 if(pGetLongPathNameA) {
794 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
795 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
796 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
797 passfail.longerror);
799 sprintf(tmpstr,"%s\\",NONDIR_LONG);
800 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
801 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
802 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
803 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
804 !passfail.shorterror,
805 "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
806 passfail.shorterror);
807 if(pGetLongPathNameA) {
808 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
809 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
810 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
811 passfail.longerror);
813 /* Test GetFullPathNameA with drive letters */
814 if( curDrive != NOT_A_VALID_DRIVE) {
815 sprintf(tmpstr,"%c:",curdir[0]);
816 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
817 "GetFullPathNameA(%c:) failed\n", curdir[0]);
818 GetCurrentDirectoryA(MAX_PATH,tmpstr);
819 sprintf(tmpstr1,"%s\\",tmpstr);
820 ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
821 "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
822 curdir[0],tmpstr2,tmpstr,tmpstr1);
824 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
825 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
826 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
827 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
828 ok(lstrcmpiA(SHORTFILE,strptr)==0,
829 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
831 /* Without a leading slash, insert the current directory if on the current drive */
832 sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
833 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
834 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
835 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
836 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
837 ok(lstrcmpiA(SHORTFILE,strptr)==0,
838 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
839 /* Otherwise insert the missing leading slash */
840 if( otherDrive != NOT_A_VALID_DRIVE) {
841 /* FIXME: this test assumes that current directory on other drive is root */
842 sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
843 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
844 sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
845 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
846 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
847 ok(lstrcmpiA(SHORTFILE,strptr)==0,
848 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
850 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
851 So test for them. */
852 if( curDrive != NOT_A_VALID_DRIVE) {
853 sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
854 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
855 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
856 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
857 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
858 ok(lstrcmpiA(SHORTFILE,strptr)==0,
859 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
861 /* Don't Starve relies on GetLongPathName returning the passed in filename,
862 even if the actual file on disk has a different case or separator */
863 if (pGetLongPathNameA) {
864 int len = lstrlenA(LONGDIR) + 1;
865 sprintf(tmpstr,"%s/%s",LONGDIR,LONGFILE);
866 ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
867 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
868 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
869 tmpstr[len] = tolower(tmpstr[len]);
870 ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
871 ok(lstrcmpA(tmpstr,tmpstr1)==0,
872 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
873 sprintf(tmpstr,"%s/%s",SHORTDIR,SHORTFILE);
874 ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
875 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
876 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
877 len = lstrlenA(SHORTDIR) + 1;
878 tmpstr[len] = toupper(tmpstr[len]);
879 ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
880 ok(lstrcmpiA(tmpstr,tmpstr1)==0 && lstrcmpA(tmpstr,tmpstr1) != 0,
881 "GetLongPathNameA returned '%s' instead of '%s/%s'\n",tmpstr1,SHORTDIR,SHORTFILE);
883 sprintf(tmpstr,"%s/%s",SHORTDIR,SHORTFILE);
884 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
885 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
886 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
888 /**/
889 sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
890 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
891 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
892 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
893 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
894 ok(lstrcmpiA(SHORTFILE,strptr)==0,
895 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
896 /* Windows will insert a drive letter in front of an absolute UNIX path */
897 sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
898 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
899 sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
900 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
901 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
902 /* This passes in Wine because it still contains the pointer from the previous test */
903 ok(lstrcmpiA(SHORTFILE,strptr)==0,
904 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
906 /* Now try some relative paths */
907 ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
908 test_SplitShortPathA(tmpstr,dir,eight,three);
909 if(pGetLongPathNameA) {
910 ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
911 ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
912 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
914 sprintf(tmpstr,".\\%s",LONGDIR);
915 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
916 test_SplitShortPathA(tmpstr1,dir,eight,three);
917 ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
918 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
919 if(pGetLongPathNameA) {
920 ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
921 tmpstr);
922 ok(lstrcmpiA(tmpstr1,tmpstr)==0,
923 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
925 /* Check out Get*PathNameA on some funny characters */
926 for(i=0;i<lstrlenA(funny_chars);i++) {
927 INT valid;
928 valid=(is_char_ok[i]=='0') ? 0 : 1;
929 sprintf(tmpstr1,"check%d-1",i);
930 sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
931 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
932 sprintf(tmpstr1,"check%d-2",i);
933 sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
934 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
935 sprintf(tmpstr1,"check%d-3",i);
936 sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
937 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
938 sprintf(tmpstr1,"check%d-4",i);
939 sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
940 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
941 sprintf(tmpstr1,"check%d-5",i);
942 sprintf(tmpstr,"Long %c File",funny_chars[i]);
943 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
944 sprintf(tmpstr1,"check%d-6",i);
945 sprintf(tmpstr,"%c Long File",funny_chars[i]);
946 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
947 sprintf(tmpstr1,"check%d-7",i);
948 sprintf(tmpstr,"Long File %c",funny_chars[i]);
949 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
951 /* Now try it on mixed case short names */
952 test_ShortPathCase(curdir,SHORTDIR,LONGFILE);
953 test_ShortPathCase(curdir,LONGDIR,SHORTFILE);
954 test_ShortPathCase(curdir,LONGDIR,LONGFILE);
957 static void test_GetTempPathA(char* tmp_dir)
959 DWORD len, slen, len_with_null;
960 char buf[MAX_PATH];
962 len_with_null = strlen(tmp_dir) + 1;
964 lstrcpyA(buf, "foo");
965 len = GetTempPathA(MAX_PATH, buf);
966 ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
967 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
968 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
970 /* Some versions of Windows touch the buffer, some don't so we don't
971 * test that. Also, NT sometimes exaggerates the required buffer size
972 * so we cannot test for an exact match. Finally, the
973 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
974 * For instance in some cases Win98 returns len_with_null - 1 instead
975 * of len_with_null.
977 len = GetTempPathA(1, buf);
978 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
980 len = GetTempPathA(0, NULL);
981 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
983 /* The call above gave us the buffer size that Windows thinks is needed
984 * so the next call should work
986 lstrcpyA(buf, "foo");
987 len = GetTempPathA(len, buf);
988 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
989 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
991 memset(buf, 'a', sizeof(buf));
992 len = GetTempPathA(sizeof(buf), buf);
993 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
994 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
995 /* The rest of the buffer remains untouched */
996 slen = len + 1;
997 for(len++; len < sizeof(buf); len++)
998 ok(buf[len] == 'a', "expected 'a' at [%d], got 0x%x\n", len, buf[len]);
1000 /* When the buffer is not long enough it remains untouched */
1001 memset(buf, 'a', sizeof(buf));
1002 len = GetTempPathA(slen / 2, buf);
1003 ok(len == slen || broken(len == slen + 1) /* read the big comment above */ ,
1004 "expected %d, got %d\n", slen, len);
1005 for(len = 0; len < sizeof(buf) / sizeof(buf[0]); len++)
1006 ok(buf[len] == 'a', "expected 'a' at [%d], got 0x%x\n", len, buf[len]);
1009 static void test_GetTempPathW(char* tmp_dir)
1011 DWORD len, slen, len_with_null;
1012 WCHAR buf[MAX_PATH], *long_buf;
1013 WCHAR tmp_dirW[MAX_PATH];
1014 static const WCHAR fooW[] = {'f','o','o',0};
1016 MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
1017 len_with_null = lstrlenW(tmp_dirW) + 1;
1019 /* This one is different from ANSI version: ANSI version doesn't
1020 * touch the buffer, unicode version usually truncates the buffer
1021 * to zero size. NT still exaggerates the required buffer size
1022 * sometimes so we cannot test for an exact match. Finally, the
1023 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
1024 * For instance on NT4 it will sometimes return a path without the
1025 * trailing '\\' and sometimes return an error.
1028 lstrcpyW(buf, fooW);
1029 len = GetTempPathW(MAX_PATH, buf);
1030 if (len == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1032 win_skip("GetTempPathW is not available\n");
1033 return;
1035 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
1036 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
1038 lstrcpyW(buf, fooW);
1039 len = GetTempPathW(1, buf);
1040 ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
1041 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
1043 len = GetTempPathW(0, NULL);
1044 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
1046 lstrcpyW(buf, fooW);
1047 len = GetTempPathW(len, buf);
1048 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
1049 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
1051 for(len = 0; len < sizeof(buf) / sizeof(buf[0]); len++)
1052 buf[len] = 'a';
1053 len = GetTempPathW(len, buf);
1054 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
1055 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
1056 /* The rest of the buffer must be zeroed */
1057 slen = len + 1;
1058 for(len++; len < sizeof(buf) / sizeof(buf[0]); len++)
1059 ok(buf[len] == '\0', "expected NULL at [%d], got 0x%x\n", len, buf[len]);
1061 /* When the buffer is not long enough the length passed is zeroed */
1062 for(len = 0; len < sizeof(buf) / sizeof(buf[0]); len++)
1063 buf[len] = 'a';
1064 len = GetTempPathW(slen / 2, buf);
1065 ok(len == slen || broken(len == slen + 1) /* read the big comment above */ ,
1066 "expected %d, got %d\n", slen, len);
1069 /* In Windows 8 when TMP var points to a drive only (like C:) instead of a
1070 * full directory the behavior changes. It will start filling the path but
1071 * will later truncate the buffer before returning. So the generic test
1072 * below will fail for this Windows 8 corner case.
1074 char tmp_var[64];
1075 DWORD version = GetVersion();
1076 GetEnvironmentVariableA("TMP", tmp_var, sizeof(tmp_var));
1077 if (strlen(tmp_var) == 2 && version >= 0x00060002)
1078 return;
1081 for(len = 0; len < slen / 2; len++)
1082 ok(buf[len] == '\0', "expected NULL at [%d], got 0x%x\n", len, buf[len]);
1083 for(; len < sizeof(buf) / sizeof(buf[0]); len++)
1084 ok(buf[len] == 'a', "expected 'a' at [%d], got 0x%x\n", len, buf[len]);
1086 /* bogus application from bug 38220 passes the count value in sizeof(buffer)
1087 * instead the correct count of WCHAR, this test catches this case. */
1088 slen = 65534;
1089 long_buf = HeapAlloc(GetProcessHeap(), 0, slen * sizeof(WCHAR));
1090 if (!long_buf)
1092 skip("Could not allocate memory for the test\n");
1093 return;
1095 for(len = 0; len < slen; len++)
1096 long_buf[len] = 0xCC;
1097 len = GetTempPathW(slen, long_buf);
1098 ok(lstrcmpiW(long_buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
1099 ok(len == lstrlenW(long_buf), "returned length should be equal to the length of string\n");
1100 /* the remaining buffer must be zeroed up to different values in different OS versions.
1101 * <= XP - 32766
1102 * > XP - 32767
1103 * to simplify testing we will test only until XP.
1105 for(; len < 32767; len++)
1106 ok(long_buf[len] == '\0', "expected NULL at [%d], got 0x%x\n", len, long_buf[len]);
1107 /* we will know skip the test that is in the middle of the OS difference by
1108 * incrementing len and then resume the test for the untouched part. */
1109 for(len++; len < slen; len++)
1110 ok(long_buf[len] == 0xcc, "expected 0xcc at [%d], got 0x%x\n", len, long_buf[len]);
1112 HeapFree(GetProcessHeap(), 0, long_buf);
1115 static void test_GetTempPath(void)
1117 char save_TMP[MAX_PATH];
1118 char windir[MAX_PATH];
1119 char buf[MAX_PATH];
1120 WCHAR curdir[MAX_PATH];
1122 if (!GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP))) save_TMP[0] = 0;
1124 /* test default configuration */
1125 trace("TMP=%s\n", save_TMP);
1126 if (save_TMP[0])
1128 strcpy(buf,save_TMP);
1129 if (buf[strlen(buf)-1]!='\\')
1130 strcat(buf,"\\");
1131 test_GetTempPathA(buf);
1132 test_GetTempPathW(buf);
1135 /* TMP=C:\WINDOWS */
1136 GetWindowsDirectoryA(windir, sizeof(windir));
1137 SetEnvironmentVariableA("TMP", windir);
1138 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1139 trace("TMP=%s\n", buf);
1140 strcat(windir,"\\");
1141 test_GetTempPathA(windir);
1142 test_GetTempPathW(windir);
1144 /* TMP=C:\ */
1145 GetWindowsDirectoryA(windir, sizeof(windir));
1146 windir[3] = 0;
1147 SetEnvironmentVariableA("TMP", windir);
1148 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1149 trace("TMP=%s\n", buf);
1150 test_GetTempPathA(windir);
1151 test_GetTempPathW(windir);
1153 GetCurrentDirectoryW(MAX_PATH, curdir);
1154 /* TMP=C: i.e. use current working directory of the specified drive */
1155 GetWindowsDirectoryA(windir, sizeof(windir));
1156 SetCurrentDirectoryA(windir);
1157 windir[2] = 0;
1158 SetEnvironmentVariableA("TMP", windir);
1159 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1160 trace("TMP=%s\n", buf);
1161 GetWindowsDirectoryA(windir, sizeof(windir));
1162 strcat(windir,"\\");
1163 test_GetTempPathA(windir);
1164 test_GetTempPathW(windir);
1166 SetEnvironmentVariableA("TMP", save_TMP);
1167 SetCurrentDirectoryW(curdir);
1170 static void test_GetLongPathNameA(void)
1172 DWORD length, explength, hostsize;
1173 char tempfile[MAX_PATH];
1174 char longpath[MAX_PATH];
1175 char unc_prefix[MAX_PATH];
1176 char unc_short[MAX_PATH], unc_long[MAX_PATH];
1177 char temppath[MAX_PATH], temppath2[MAX_PATH];
1178 HANDLE file;
1180 if (!pGetLongPathNameA)
1181 return;
1183 GetTempPathA(MAX_PATH, tempfile);
1184 lstrcatA(tempfile, "longfilename.longext");
1186 file = CreateFileA(tempfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1187 CloseHandle(file);
1189 /* Test a normal path with a small buffer size */
1190 memset(temppath, 0, MAX_PATH);
1191 length = pGetLongPathNameA(tempfile, temppath, 4);
1192 /* We have a failure so length should be the minimum plus the terminating '0' */
1193 ok(length >= strlen(tempfile) + 1, "Wrong length\n");
1194 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1196 /* Some UNC syntax tests */
1198 memset(temppath, 0, MAX_PATH);
1199 memset(temppath2, 0, MAX_PATH);
1200 lstrcpyA(temppath2, "\\\\?\\");
1201 lstrcatA(temppath2, tempfile);
1202 explength = length + 4;
1204 SetLastError(0xdeadbeef);
1205 length = pGetLongPathNameA(temppath2, NULL, 0);
1206 if (length == 0 && GetLastError() == ERROR_BAD_NET_NAME)
1208 win_skip("UNC syntax tests don't work on Win98/WinMe\n");
1209 DeleteFileA(tempfile);
1210 return;
1212 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1214 length = pGetLongPathNameA(temppath2, NULL, MAX_PATH);
1215 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1217 length = pGetLongPathNameA(temppath2, temppath, 4);
1218 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1219 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1221 /* Now an UNC path with the computername */
1222 lstrcpyA(unc_prefix, "\\\\");
1223 hostsize = sizeof(unc_prefix) - 2;
1224 GetComputerNameA(unc_prefix + 2, &hostsize);
1225 lstrcatA(unc_prefix, "\\");
1227 /* Create a short syntax for the whole unc path */
1228 memset(unc_short, 0, MAX_PATH);
1229 GetShortPathNameA(tempfile, temppath, MAX_PATH);
1230 lstrcpyA(unc_short, unc_prefix);
1231 unc_short[lstrlenA(unc_short)] = temppath[0];
1232 lstrcatA(unc_short, "$\\");
1233 lstrcatA(unc_short, strchr(temppath, '\\') + 1);
1235 /* Create a long syntax for reference */
1236 memset(longpath, 0, MAX_PATH);
1237 pGetLongPathNameA(tempfile, temppath, MAX_PATH);
1238 lstrcpyA(longpath, unc_prefix);
1239 longpath[lstrlenA(longpath)] = temppath[0];
1240 lstrcatA(longpath, "$\\");
1241 lstrcatA(longpath, strchr(temppath, '\\') + 1);
1243 /* NULL test */
1244 SetLastError(0xdeadbeef);
1245 length = pGetLongPathNameA(unc_short, NULL, 0);
1246 if (length == 0 && GetLastError() == ERROR_BAD_NETPATH)
1248 /* Seen on Window XP Home */
1249 win_skip("UNC with computername is not supported\n");
1250 DeleteFileA(tempfile);
1251 return;
1253 explength = lstrlenA(longpath) + 1;
1254 todo_wine
1255 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1257 length = pGetLongPathNameA(unc_short, NULL, MAX_PATH);
1258 todo_wine
1259 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1261 memset(unc_long, 0, MAX_PATH);
1262 length = pGetLongPathNameA(unc_short, unc_long, lstrlenA(unc_short));
1263 /* length will include terminating '0' on failure */
1264 todo_wine
1265 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1266 ok(unc_long[0] == 0, "Buffer should not have been touched\n");
1268 memset(unc_long, 0, MAX_PATH);
1269 length = pGetLongPathNameA(unc_short, unc_long, length);
1270 /* length doesn't include terminating '0' on success */
1271 explength--;
1272 todo_wine
1274 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1275 ok(!lstrcmpiA(unc_long, longpath), "Expected (%s), got (%s)\n", longpath, unc_long);
1278 DeleteFileA(tempfile);
1281 static void test_GetLongPathNameW(void)
1283 DWORD length, expanded;
1284 BOOL ret;
1285 HANDLE file;
1286 WCHAR empty[MAX_PATH];
1287 WCHAR tempdir[MAX_PATH], name[200];
1288 WCHAR dirpath[4 + MAX_PATH + 200]; /* To ease removal */
1289 WCHAR shortpath[4 + MAX_PATH + 200 + 1 + 200];
1290 static const WCHAR prefix[] = { '\\','\\','?','\\', 0};
1291 static const WCHAR backslash[] = { '\\', 0};
1292 static const WCHAR letterX[] = { 'X', 0};
1294 if (!pGetLongPathNameW)
1295 return;
1297 SetLastError(0xdeadbeef);
1298 length = pGetLongPathNameW(NULL,NULL,0);
1299 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1301 win_skip("GetLongPathNameW is not implemented\n");
1302 return;
1304 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1305 ok(GetLastError()==ERROR_INVALID_PARAMETER,"GetLastError returned %d but expected ERROR_INVALID_PARAMETER\n",GetLastError());
1307 SetLastError(0xdeadbeef);
1308 empty[0]=0;
1309 length = pGetLongPathNameW(empty,NULL,0);
1310 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1311 ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
1313 /* Create a long path name. The path needs to exist for these tests to
1314 * succeed so we need the "\\?\" prefix when creating directories and
1315 * files.
1317 name[0] = 0;
1318 while (lstrlenW(name) < (sizeof(name)/sizeof(WCHAR) - 1))
1319 lstrcatW(name, letterX);
1321 GetTempPathW(MAX_PATH, tempdir);
1323 lstrcpyW(shortpath, prefix);
1324 lstrcatW(shortpath, tempdir);
1325 lstrcatW(shortpath, name);
1326 lstrcpyW(dirpath, shortpath);
1327 ret = CreateDirectoryW(shortpath, NULL);
1328 ok(ret, "Could not create the temporary directory : %d\n", GetLastError());
1329 lstrcatW(shortpath, backslash);
1330 lstrcatW(shortpath, name);
1332 /* Path does not exist yet and we know it overruns MAX_PATH */
1334 /* No prefix */
1335 SetLastError(0xdeadbeef);
1336 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1337 ok(length == 0, "Expected 0, got %d\n", length);
1338 todo_wine
1339 ok(GetLastError() == ERROR_PATH_NOT_FOUND,
1340 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1341 /* With prefix */
1342 SetLastError(0xdeadbeef);
1343 length = pGetLongPathNameW(shortpath, NULL, 0);
1344 todo_wine
1346 ok(length == 0, "Expected 0, got %d\n", length);
1347 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
1348 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1351 file = CreateFileW(shortpath, GENERIC_READ|GENERIC_WRITE, 0, NULL,
1352 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1353 ok(file != INVALID_HANDLE_VALUE,
1354 "Could not create the temporary file : %d.\n", GetLastError());
1355 CloseHandle(file);
1357 /* Path exists */
1359 /* No prefix */
1360 SetLastError(0xdeadbeef);
1361 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1362 todo_wine
1364 ok(length == 0, "Expected 0, got %d\n", length);
1365 ok(GetLastError() == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1367 /* With prefix */
1368 expanded = 4 + (pGetLongPathNameW(tempdir, NULL, 0) - 1) + lstrlenW(name) + 1 + lstrlenW(name) + 1;
1369 SetLastError(0xdeadbeef);
1370 length = pGetLongPathNameW(shortpath, NULL, 0);
1371 ok(length == expanded, "Expected %d, got %d\n", expanded, length);
1373 /* NULL buffer with length crashes on Windows */
1374 if (0)
1375 pGetLongPathNameW(shortpath, NULL, 20);
1377 ok(DeleteFileW(shortpath), "Could not delete temporary file\n");
1378 ok(RemoveDirectoryW(dirpath), "Could not delete temporary directory\n");
1381 static void test_GetShortPathNameW(void)
1383 static const WCHAR extended_prefix[] = {'\\','\\','?','\\',0};
1384 static const WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
1385 static const WCHAR name[] = { 't', 'e', 's', 't', 0 };
1386 static const WCHAR backSlash[] = { '\\', 0 };
1387 static const WCHAR a_bcdeW[] = {'a','.','b','c','d','e',0};
1388 WCHAR path[MAX_PATH], tmppath[MAX_PATH], *ptr;
1389 WCHAR short_path[MAX_PATH];
1390 DWORD length;
1391 HANDLE file;
1392 int ret;
1394 SetLastError(0xdeadbeef);
1395 GetTempPathW( MAX_PATH, tmppath );
1396 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1398 win_skip("GetTempPathW is not implemented\n");
1399 return;
1402 lstrcpyW( path, tmppath );
1403 lstrcatW( path, test_path );
1404 lstrcatW( path, backSlash );
1405 ret = CreateDirectoryW( path, NULL );
1406 ok( ret, "Directory was not created. LastError = %d\n", GetLastError() );
1408 /* Starting a main part of test */
1410 /* extended path \\?\C:\path\ */
1411 lstrcpyW( path, extended_prefix );
1412 lstrcatW( path, tmppath );
1413 lstrcatW( path, test_path );
1414 lstrcatW( path, backSlash );
1415 short_path[0] = 0;
1416 length = GetShortPathNameW( path, short_path, sizeof(short_path) / sizeof(*short_path) );
1417 ok( length, "GetShortPathNameW returned 0.\n" );
1419 lstrcpyW( path, tmppath );
1420 lstrcatW( path, test_path );
1421 lstrcatW( path, backSlash );
1422 length = GetShortPathNameW( path, short_path, 0 );
1423 ok( length, "GetShortPathNameW returned 0.\n" );
1424 ret = GetShortPathNameW( path, short_path, length );
1425 ok( ret && ret == length-1, "GetShortPathNameW returned 0.\n" );
1427 lstrcatW( short_path, name );
1429 /* GetShortPathName for a non-existent short file name should fail */
1430 SetLastError(0xdeadbeef);
1431 length = GetShortPathNameW( short_path, path, 0 );
1432 ok(!length, "GetShortPathNameW should fail\n");
1433 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
1435 file = CreateFileW( short_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1436 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
1437 CloseHandle( file );
1438 ret = DeleteFileW( short_path );
1439 ok( ret, "Cannot delete file.\n" );
1441 ptr = path + lstrlenW(path);
1442 lstrcpyW( ptr, a_bcdeW);
1443 file = CreateFileW( path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1444 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
1445 CloseHandle( file );
1447 length = GetShortPathNameW( path, short_path, sizeof(short_path)/sizeof(*short_path) );
1448 ok( length, "GetShortPathNameW failed: %u.\n", GetLastError() );
1450 ret = DeleteFileW( path );
1451 ok( ret, "Cannot delete file.\n" );
1452 *ptr = 0;
1454 /* End test */
1455 ret = RemoveDirectoryW( path );
1456 ok( ret, "Cannot delete directory.\n" );
1459 static void test_GetSystemDirectory(void)
1461 CHAR buffer[MAX_PATH + 4];
1462 DWORD res;
1463 DWORD total;
1465 SetLastError(0xdeadbeef);
1466 res = GetSystemDirectoryA(NULL, 0);
1467 /* res includes the terminating Zero */
1468 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1470 total = res;
1472 /* this crashes on XP */
1473 if (0)
1474 GetSystemDirectoryA(NULL, total);
1476 SetLastError(0xdeadbeef);
1477 res = GetSystemDirectoryA(NULL, total-1);
1478 /* 95+NT: total (includes the terminating Zero)
1479 98+ME: 0 with ERROR_INVALID_PARAMETER */
1480 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1481 "returned %d with %d (expected '%d' or: '0' with "
1482 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1484 if (total > MAX_PATH) return;
1486 buffer[0] = '\0';
1487 SetLastError(0xdeadbeef);
1488 res = GetSystemDirectoryA(buffer, total);
1489 /* res does not include the terminating Zero */
1490 ok( (res == (total-1)) && (buffer[0]),
1491 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1492 res, GetLastError(), buffer, total-1);
1494 buffer[0] = '\0';
1495 SetLastError(0xdeadbeef);
1496 res = GetSystemDirectoryA(buffer, total + 1);
1497 /* res does not include the terminating Zero */
1498 ok( (res == (total-1)) && (buffer[0]),
1499 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1500 res, GetLastError(), buffer, total-1);
1502 memset(buffer, '#', total + 1);
1503 buffer[total + 2] = '\0';
1504 SetLastError(0xdeadbeef);
1505 res = GetSystemDirectoryA(buffer, total-1);
1506 /* res includes the terminating Zero) */
1507 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1508 res, GetLastError(), buffer, total);
1510 memset(buffer, '#', total + 1);
1511 buffer[total + 2] = '\0';
1512 SetLastError(0xdeadbeef);
1513 res = GetSystemDirectoryA(buffer, total-2);
1514 /* res includes the terminating Zero) */
1515 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1516 res, GetLastError(), buffer, total);
1519 static void test_GetWindowsDirectory(void)
1521 CHAR buffer[MAX_PATH + 4];
1522 DWORD res;
1523 DWORD total;
1525 SetLastError(0xdeadbeef);
1526 res = GetWindowsDirectoryA(NULL, 0);
1527 /* res includes the terminating Zero */
1528 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1530 total = res;
1531 /* this crashes on XP */
1532 if (0)
1533 GetWindowsDirectoryA(NULL, total);
1535 SetLastError(0xdeadbeef);
1536 res = GetWindowsDirectoryA(NULL, total-1);
1537 /* 95+NT: total (includes the terminating Zero)
1538 98+ME: 0 with ERROR_INVALID_PARAMETER */
1539 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1540 "returned %d with %d (expected '%d' or: '0' with "
1541 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1543 if (total > MAX_PATH) return;
1545 buffer[0] = '\0';
1546 SetLastError(0xdeadbeef);
1547 res = GetWindowsDirectoryA(buffer, total);
1548 /* res does not include the terminating Zero */
1549 ok( (res == (total-1)) && (buffer[0]),
1550 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1551 res, GetLastError(), buffer, total-1);
1553 buffer[0] = '\0';
1554 SetLastError(0xdeadbeef);
1555 res = GetWindowsDirectoryA(buffer, total + 1);
1556 /* res does not include the terminating Zero */
1557 ok( (res == (total-1)) && (buffer[0]),
1558 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1559 res, GetLastError(), buffer, total-1);
1561 memset(buffer, '#', total + 1);
1562 buffer[total + 2] = '\0';
1563 SetLastError(0xdeadbeef);
1564 res = GetWindowsDirectoryA(buffer, total-1);
1565 /* res includes the terminating Zero) */
1566 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1567 res, GetLastError(), buffer, total);
1569 memset(buffer, '#', total + 1);
1570 buffer[total + 2] = '\0';
1571 SetLastError(0xdeadbeef);
1572 res = GetWindowsDirectoryA(buffer, total-2);
1573 /* res includes the terminating Zero) */
1574 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1575 res, GetLastError(), buffer, total);
1578 static void test_NeedCurrentDirectoryForExePathA(void)
1580 if (!pNeedCurrentDirectoryForExePathA)
1582 win_skip("NeedCurrentDirectoryForExePathA is not available\n");
1583 return;
1586 /* Crashes in Windows */
1587 if (0)
1588 pNeedCurrentDirectoryForExePathA(NULL);
1590 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1591 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1592 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1593 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1595 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1596 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1597 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1598 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1601 static void test_NeedCurrentDirectoryForExePathW(void)
1603 const WCHAR thispath[] = {'.', 0};
1604 const WCHAR fullpath[] = {'c', ':', '\\', 0};
1605 const WCHAR cmdname[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1607 if (!pNeedCurrentDirectoryForExePathW)
1609 win_skip("NeedCurrentDirectoryForExePathW is not available\n");
1610 return;
1613 /* Crashes in Windows */
1614 if (0)
1615 pNeedCurrentDirectoryForExePathW(NULL);
1617 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1618 ok(pNeedCurrentDirectoryForExePathW(thispath), "returned FALSE for \".\"\n");
1619 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1620 ok(pNeedCurrentDirectoryForExePathW(cmdname), "returned FALSE for \"cmd.exe\"\n");
1622 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1623 ok(!pNeedCurrentDirectoryForExePathW(thispath), "returned TRUE for \".\"\n");
1624 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1625 ok(!pNeedCurrentDirectoryForExePathW(cmdname), "returned TRUE for \"cmd.exe\"\n");
1628 /* Call various path/file name retrieving APIs and check the case of
1629 * the returned drive letter. Some apps (for instance Adobe Photoshop CS3
1630 * installer) depend on the drive letter being in upper case.
1632 static void test_drive_letter_case(void)
1634 UINT ret;
1635 char buf[MAX_PATH];
1637 #define is_upper_case_letter(a) ((a) >= 'A' && (a) <= 'Z')
1639 memset(buf, 0, sizeof(buf));
1640 SetLastError(0xdeadbeef);
1641 ret = GetWindowsDirectoryA(buf, sizeof(buf));
1642 ok(ret, "GetWindowsDirectory error %u\n", GetLastError());
1643 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1644 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1645 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1647 /* re-use the buffer returned by GetFullPathName */
1648 buf[2] = '/';
1649 SetLastError(0xdeadbeef);
1650 ret = GetFullPathNameA(buf + 2, sizeof(buf), buf, NULL);
1651 ok(ret, "GetFullPathName error %u\n", GetLastError());
1652 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1653 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1654 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1656 memset(buf, 0, sizeof(buf));
1657 SetLastError(0xdeadbeef);
1658 ret = GetSystemDirectoryA(buf, sizeof(buf));
1659 ok(ret, "GetSystemDirectory error %u\n", GetLastError());
1660 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1661 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1662 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1664 memset(buf, 0, sizeof(buf));
1665 SetLastError(0xdeadbeef);
1666 ret = GetCurrentDirectoryA(sizeof(buf), buf);
1667 ok(ret, "GetCurrentDirectory error %u\n", GetLastError());
1668 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1669 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1670 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1672 /* TEMP is an environment variable, so it can't be tested for case-sensitivity */
1673 memset(buf, 0, sizeof(buf));
1674 SetLastError(0xdeadbeef);
1675 ret = GetTempPathA(sizeof(buf), buf);
1676 ok(ret, "GetTempPath error %u\n", GetLastError());
1677 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1678 if (buf[0])
1680 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1681 ok(buf[strlen(buf)-1] == '\\', "Temporary path (%s) doesn't end in a slash\n", buf);
1684 memset(buf, 0, sizeof(buf));
1685 SetLastError(0xdeadbeef);
1686 ret = GetFullPathNameA(".", sizeof(buf), buf, NULL);
1687 ok(ret, "GetFullPathName error %u\n", GetLastError());
1688 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1689 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1690 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1692 /* re-use the buffer returned by GetFullPathName */
1693 SetLastError(0xdeadbeef);
1694 ret = GetShortPathNameA(buf, buf, sizeof(buf));
1695 ok(ret, "GetShortPathName error %u\n", GetLastError());
1696 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1697 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1698 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1700 if (pGetLongPathNameA)
1702 /* re-use the buffer returned by GetShortPathName */
1703 SetLastError(0xdeadbeef);
1704 ret = pGetLongPathNameA(buf, buf, sizeof(buf));
1705 ok(ret, "GetLongPathNameA error %u\n", GetLastError());
1706 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1707 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1708 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1710 #undef is_upper_case_letter
1713 static const char manifest_dep[] =
1714 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1715 "<assemblyIdentity version=\"1.2.3.4\" name=\"testdep1\" type=\"win32\" processorArchitecture=\"" ARCH "\"/>"
1716 " <file name=\"testdep.dll\" />"
1717 " <file name=\"ole32\" />"
1718 " <file name=\"kernel32.dll\" />"
1719 "</assembly>";
1721 static const char manifest_main[] =
1722 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1723 "<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
1724 "<dependency>"
1725 " <dependentAssembly>"
1726 " <assemblyIdentity type=\"win32\" name=\"testdep1\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH "\" />"
1727 " </dependentAssembly>"
1728 "</dependency>"
1729 "</assembly>";
1731 static void create_manifest_file(const char *filename, const char *manifest)
1733 WCHAR path[MAX_PATH], manifest_path[MAX_PATH];
1734 HANDLE file;
1735 DWORD size;
1737 MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH );
1739 GetTempPathW(sizeof(manifest_path)/sizeof(WCHAR), manifest_path);
1740 lstrcatW(manifest_path, path);
1742 file = CreateFileW(manifest_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1743 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
1744 WriteFile(file, manifest, strlen(manifest), &size, NULL);
1745 CloseHandle(file);
1748 static void delete_manifest_file(const char *filename)
1750 CHAR path[MAX_PATH];
1752 GetTempPathA(sizeof(path), path);
1753 strcat(path, filename);
1754 DeleteFileA(path);
1757 static HANDLE test_create(const char *file)
1759 WCHAR path[MAX_PATH], manifest_path[MAX_PATH];
1760 ACTCTXW actctx;
1761 HANDLE handle;
1763 MultiByteToWideChar(CP_ACP, 0, file, -1, path, MAX_PATH);
1764 GetTempPathW(sizeof(manifest_path)/sizeof(WCHAR), manifest_path);
1765 lstrcatW(manifest_path, path);
1767 memset(&actctx, 0, sizeof(ACTCTXW));
1768 actctx.cbSize = sizeof(ACTCTXW);
1769 actctx.lpSource = manifest_path;
1771 handle = pCreateActCtxW(&actctx);
1772 ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError());
1774 ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize);
1775 ok(actctx.dwFlags == 0, "dwFlags=%d\n", actctx.dwFlags);
1776 ok(actctx.lpSource == manifest_path, "lpSource=%p\n", actctx.lpSource);
1777 ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
1778 ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId);
1779 ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
1780 ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName);
1781 ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName);
1782 ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule);
1784 return handle;
1787 static void test_SearchPathA(void)
1789 static const CHAR testdepA[] = "testdep.dll";
1790 static const CHAR testdeprelA[] = "./testdep.dll";
1791 static const CHAR kernel32A[] = "kernel32.dll";
1792 static const CHAR fileA[] = "";
1793 CHAR pathA[MAX_PATH], buffA[MAX_PATH], path2A[MAX_PATH];
1794 CHAR *ptrA = NULL;
1795 ULONG_PTR cookie;
1796 HANDLE handle;
1797 DWORD ret;
1799 if (!pSearchPathA)
1801 win_skip("SearchPathA isn't available\n");
1802 return;
1805 GetWindowsDirectoryA(pathA, sizeof(pathA)/sizeof(CHAR));
1807 /* NULL filename */
1808 SetLastError(0xdeadbeef);
1809 ret = pSearchPathA(pathA, NULL, NULL, sizeof(buffA)/sizeof(CHAR), buffA, &ptrA);
1810 ok(ret == 0, "Expected failure, got %d\n", ret);
1811 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1812 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1814 /* empty filename */
1815 SetLastError(0xdeadbeef);
1816 ret = pSearchPathA(pathA, fileA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, &ptrA);
1817 ok(ret == 0, "Expected failure, got %d\n", ret);
1818 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1819 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1821 if (!pActivateActCtx)
1822 return;
1824 create_manifest_file("testdep1.manifest", manifest_dep);
1825 create_manifest_file("main.manifest", manifest_main);
1827 handle = test_create("main.manifest");
1828 delete_manifest_file("testdep1.manifest");
1829 delete_manifest_file("main.manifest");
1831 /* search fails without active context */
1832 ret = pSearchPathA(NULL, testdepA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, NULL);
1833 ok(ret == 0, "got %d\n", ret);
1835 ret = pSearchPathA(NULL, kernel32A, NULL, sizeof(path2A)/sizeof(CHAR), path2A, NULL);
1836 ok(ret && ret == strlen(path2A), "got %d\n", ret);
1838 ret = pActivateActCtx(handle, &cookie);
1839 ok(ret, "failed to activate context, %u\n", GetLastError());
1841 /* works when activated */
1842 ret = pSearchPathA(NULL, testdepA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, NULL);
1843 ok(ret && ret == strlen(buffA), "got %d\n", ret);
1845 ret = pSearchPathA(NULL, "testdep.dll", ".ext", sizeof(buffA)/sizeof(CHAR), buffA, NULL);
1846 ok(ret && ret == strlen(buffA), "got %d\n", ret);
1848 ret = pSearchPathA(NULL, "testdep", ".dll", sizeof(buffA)/sizeof(CHAR), buffA, NULL);
1849 ok(ret && ret == strlen(buffA), "got %d\n", ret);
1851 ret = pSearchPathA(NULL, "testdep", ".ext", sizeof(buffA)/sizeof(CHAR), buffA, NULL);
1852 ok(!ret, "got %d\n", ret);
1854 /* name contains path */
1855 ret = pSearchPathA(NULL, testdeprelA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, NULL);
1856 ok(!ret, "got %d\n", ret);
1858 /* fails with specified path that doesn't contain this file */
1859 ret = pSearchPathA(pathA, testdepA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, NULL);
1860 ok(!ret, "got %d\n", ret);
1862 /* path is redirected for wellknown names too */
1863 ret = pSearchPathA(NULL, kernel32A, NULL, sizeof(buffA)/sizeof(CHAR), buffA, NULL);
1864 ok(ret && ret == strlen(buffA), "got %d\n", ret);
1865 ok(strcmp(buffA, path2A), "got wrong path %s, %s\n", buffA, path2A);
1867 ret = pDeactivateActCtx(0, cookie);
1868 ok(ret, "failed to deactivate context, %u\n", GetLastError());
1869 pReleaseActCtx(handle);
1872 static void test_SearchPathW(void)
1874 static const WCHAR testdeprelW[] = {'.','/','t','e','s','t','d','e','p','.','d','l','l',0};
1875 static const WCHAR testdepW[] = {'t','e','s','t','d','e','p','.','d','l','l',0};
1876 static const WCHAR testdep1W[] = {'t','e','s','t','d','e','p',0};
1877 static const WCHAR kernel32dllW[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
1878 static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2',0};
1879 static const WCHAR ole32W[] = {'o','l','e','3','2',0};
1880 static const WCHAR extW[] = {'.','e','x','t',0};
1881 static const WCHAR dllW[] = {'.','d','l','l',0};
1882 static const WCHAR fileW[] = { 0 };
1883 WCHAR pathW[MAX_PATH], buffW[MAX_PATH], path2W[MAX_PATH];
1884 WCHAR *ptrW = NULL;
1885 ULONG_PTR cookie;
1886 HANDLE handle;
1887 DWORD ret;
1889 if (!pSearchPathW)
1891 win_skip("SearchPathW isn't available\n");
1892 return;
1895 if (0)
1897 /* NULL filename, crashes on nt4 */
1898 pSearchPathW(pathW, NULL, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW);
1901 GetWindowsDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR));
1903 /* empty filename */
1904 SetLastError(0xdeadbeef);
1905 ret = pSearchPathW(pathW, fileW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW);
1906 ok(ret == 0, "Expected failure, got %d\n", ret);
1907 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1908 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1910 if (!pActivateActCtx)
1911 return;
1913 create_manifest_file("testdep1.manifest", manifest_dep);
1914 create_manifest_file("main.manifest", manifest_main);
1916 handle = test_create("main.manifest");
1917 delete_manifest_file("testdep1.manifest");
1918 delete_manifest_file("main.manifest");
1920 /* search fails without active context */
1921 ret = pSearchPathW(NULL, testdepW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL);
1922 ok(ret == 0, "got %d\n", ret);
1924 ret = pSearchPathW(NULL, kernel32dllW, NULL, sizeof(path2W)/sizeof(WCHAR), path2W, NULL);
1925 ok(ret && ret == lstrlenW(path2W), "got %d\n", ret);
1927 /* full path, name without 'dll' extension */
1928 GetSystemDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR));
1929 ret = pSearchPathW(pathW, kernel32W, NULL, sizeof(path2W)/sizeof(WCHAR), path2W, NULL);
1930 ok(ret == 0, "got %d\n", ret);
1932 GetWindowsDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR));
1934 ret = pActivateActCtx(handle, &cookie);
1935 ok(ret, "failed to activate context, %u\n", GetLastError());
1937 /* works when activated */
1938 ret = pSearchPathW(NULL, testdepW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL);
1939 ok(ret && ret == lstrlenW(buffW), "got %d\n", ret);
1941 ret = pSearchPathW(NULL, testdepW, extW, sizeof(buffW)/sizeof(WCHAR), buffW, NULL);
1942 ok(ret && ret == lstrlenW(buffW), "got %d\n", ret);
1944 ret = pSearchPathW(NULL, testdep1W, dllW, sizeof(buffW)/sizeof(WCHAR), buffW, NULL);
1945 ok(ret && ret == lstrlenW(buffW), "got %d\n", ret);
1947 ret = pSearchPathW(NULL, testdep1W, extW, sizeof(buffW)/sizeof(WCHAR), buffW, NULL);
1948 ok(!ret, "got %d\n", ret);
1950 /* name contains path */
1951 ret = pSearchPathW(NULL, testdeprelW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL);
1952 ok(!ret, "got %d\n", ret);
1954 /* fails with specified path that doesn't contain this file */
1955 ret = pSearchPathW(pathW, testdepW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL);
1956 ok(!ret, "got %d\n", ret);
1958 /* path is redirected for wellknown names too, meaning it takes precedence over normal search order */
1959 ret = pSearchPathW(NULL, kernel32dllW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL);
1960 ok(ret && ret == lstrlenW(buffW), "got %d\n", ret);
1961 ok(lstrcmpW(buffW, path2W), "got wrong path %s, %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(path2W));
1963 /* path is built using on manifest file name */
1964 ret = pSearchPathW(NULL, ole32W, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL);
1965 ok(ret && ret == lstrlenW(buffW), "got %d\n", ret);
1967 ret = pDeactivateActCtx(0, cookie);
1968 ok(ret, "failed to deactivate context, %u\n", GetLastError());
1969 pReleaseActCtx(handle);
1972 static void test_GetFullPathNameA(void)
1974 char output[MAX_PATH], *filepart;
1975 DWORD ret;
1976 int i;
1977 UINT acp;
1979 const struct
1981 LPCSTR name;
1982 DWORD len;
1983 LPSTR buffer;
1984 LPSTR *lastpart;
1985 } invalid_parameters[] =
1987 {NULL, 0, NULL, NULL},
1988 {NULL, MAX_PATH, NULL, NULL},
1989 {NULL, MAX_PATH, output, NULL},
1990 {NULL, MAX_PATH, output, &filepart},
1991 {"", 0, NULL, NULL},
1992 {"", MAX_PATH, NULL, NULL},
1993 {"", MAX_PATH, output, NULL},
1994 {"", MAX_PATH, output, &filepart},
1997 for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
1999 SetLastError(0xdeadbeef);
2000 strcpy(output, "deadbeef");
2001 filepart = (char *)0xdeadbeef;
2002 ret = GetFullPathNameA(invalid_parameters[i].name,
2003 invalid_parameters[i].len,
2004 invalid_parameters[i].buffer,
2005 invalid_parameters[i].lastpart);
2006 ok(!ret, "[%d] Expected GetFullPathNameA to return 0, got %u\n", i, ret);
2007 ok(!strcmp(output, "deadbeef"), "[%d] Expected the output buffer to be unchanged, got \"%s\"\n", i, output);
2008 ok(filepart == (char *)0xdeadbeef, "[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
2009 ok(GetLastError() == 0xdeadbeef ||
2010 GetLastError() == ERROR_INVALID_NAME, /* Win7 */
2011 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
2012 i, GetLastError());
2015 acp = GetACP();
2016 if (acp != 932)
2017 skip("Skipping DBCS(Japanese) GetFullPathNameA test in this codepage (%d)\n", acp);
2018 else {
2019 const struct dbcs_case {
2020 const char *input;
2021 const char *expected;
2022 } testset[] = {
2023 { "c:\\a\\\x95\x5c\x97\xa0.txt", "\x95\x5c\x97\xa0.txt" },
2024 { "c:\\\x83\x8f\x83\x43\x83\x93\\wine.c", "wine.c" },
2025 { "c:\\demo\\\x97\xa0\x95\x5c", "\x97\xa0\x95\x5c" }
2027 for (i = 0; i < sizeof(testset)/sizeof(testset[0]); i++) {
2028 ret = GetFullPathNameA(testset[i].input, sizeof(output),
2029 output, &filepart);
2030 ok(ret, "[%d] GetFullPathName error %u\n", i, GetLastError());
2031 ok(!lstrcmpA(filepart, testset[i].expected),
2032 "[%d] expected %s got %s\n", i, testset[i].expected, filepart);
2037 static void test_GetFullPathNameW(void)
2039 static const WCHAR emptyW[] = {0};
2040 static const WCHAR deadbeefW[] = {'d','e','a','d','b','e','e','f',0};
2042 WCHAR output[MAX_PATH], *filepart;
2043 DWORD ret;
2044 int i;
2046 const struct
2048 LPCWSTR name;
2049 DWORD len;
2050 LPWSTR buffer;
2051 LPWSTR *lastpart;
2052 int win7_expect;
2053 } invalid_parameters[] =
2055 {NULL, 0, NULL, NULL},
2056 {NULL, 0, NULL, &filepart, 1},
2057 {NULL, MAX_PATH, NULL, NULL},
2058 {NULL, MAX_PATH, output, NULL},
2059 {NULL, MAX_PATH, output, &filepart, 1},
2060 {emptyW, 0, NULL, NULL},
2061 {emptyW, 0, NULL, &filepart, 1},
2062 {emptyW, MAX_PATH, NULL, NULL},
2063 {emptyW, MAX_PATH, output, NULL},
2064 {emptyW, MAX_PATH, output, &filepart, 1},
2067 SetLastError(0xdeadbeef);
2068 ret = GetFullPathNameW(NULL, 0, NULL, NULL);
2069 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2071 win_skip("GetFullPathNameW is not available\n");
2072 return;
2075 for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
2077 SetLastError(0xdeadbeef);
2078 lstrcpyW(output, deadbeefW);
2079 filepart = (WCHAR *)0xdeadbeef;
2080 ret = GetFullPathNameW(invalid_parameters[i].name,
2081 invalid_parameters[i].len,
2082 invalid_parameters[i].buffer,
2083 invalid_parameters[i].lastpart);
2084 ok(!ret, "[%d] Expected GetFullPathNameW to return 0, got %u\n", i, ret);
2085 ok(!lstrcmpW(output, deadbeefW), "[%d] Expected the output buffer to be unchanged, got %s\n", i, wine_dbgstr_w(output));
2086 ok(filepart == (WCHAR *)0xdeadbeef ||
2087 (invalid_parameters[i].win7_expect && filepart == NULL),
2088 "[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
2089 ok(GetLastError() == 0xdeadbeef ||
2090 GetLastError() == ERROR_INVALID_NAME, /* Win7 */
2091 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
2092 i, GetLastError());
2096 static void init_pointers(void)
2098 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
2100 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hKernel32, #f))
2101 MAKEFUNC(GetLongPathNameA);
2102 MAKEFUNC(GetLongPathNameW);
2103 MAKEFUNC(NeedCurrentDirectoryForExePathA);
2104 MAKEFUNC(NeedCurrentDirectoryForExePathW);
2105 MAKEFUNC(SearchPathA);
2106 MAKEFUNC(SearchPathW);
2107 MAKEFUNC(ActivateActCtx);
2108 MAKEFUNC(CreateActCtxW);
2109 MAKEFUNC(DeactivateActCtx);
2110 MAKEFUNC(GetCurrentActCtx);
2111 MAKEFUNC(ReleaseActCtx);
2112 MAKEFUNC(CheckNameLegalDOS8Dot3W);
2113 MAKEFUNC(CheckNameLegalDOS8Dot3A);
2114 #undef MAKEFUNC
2117 static void test_relative_path(void)
2119 char path[MAX_PATH], buf[MAX_PATH];
2120 HANDLE file;
2121 int ret;
2122 WCHAR curdir[MAX_PATH];
2124 if (!pGetLongPathNameA) return;
2126 GetCurrentDirectoryW(MAX_PATH, curdir);
2127 GetTempPathA(MAX_PATH, path);
2128 ret = SetCurrentDirectoryA(path);
2129 ok(ret, "SetCurrentDirectory error %d\n", GetLastError());
2131 ret = CreateDirectoryA("foo", NULL);
2132 ok(ret, "CreateDirectory error %d\n", GetLastError());
2133 file = CreateFileA("foo\\file", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
2134 ok(file != INVALID_HANDLE_VALUE, "failed to create temp file\n");
2135 CloseHandle(file);
2136 ret = CreateDirectoryA("bar", NULL);
2137 ok(ret, "CreateDirectory error %d\n", GetLastError());
2138 ret = SetCurrentDirectoryA("bar");
2139 ok(ret, "SetCurrentDirectory error %d\n", GetLastError());
2141 ret = GetFileAttributesA("..\\foo\\file");
2142 ok(ret != INVALID_FILE_ATTRIBUTES, "GetFileAttributes error %d\n", GetLastError());
2144 strcpy(buf, "deadbeef");
2145 ret = pGetLongPathNameA(".", buf, MAX_PATH);
2146 ok(ret, "GetLongPathName error %d\n", GetLastError());
2147 ok(!strcmp(buf, "."), "expected ., got %s\n", buf);
2148 strcpy(buf, "deadbeef");
2149 ret = GetShortPathNameA(".", buf, MAX_PATH);
2150 ok(ret, "GetShortPathName error %d\n", GetLastError());
2151 ok(!strcmp(buf, "."), "expected ., got %s\n", buf);
2153 strcpy(buf, "deadbeef");
2154 ret = pGetLongPathNameA("..", buf, MAX_PATH);
2155 ok(ret, "GetLongPathName error %d\n", GetLastError());
2156 ok(!strcmp(buf, ".."), "expected .., got %s\n", buf);
2157 strcpy(buf, "deadbeef");
2158 ret = GetShortPathNameA("..", buf, MAX_PATH);
2159 ok(ret, "GetShortPathName error %d\n", GetLastError());
2160 ok(!strcmp(buf, ".."), "expected .., got %s\n", buf);
2162 strcpy(buf, "deadbeef");
2163 ret = pGetLongPathNameA("..\\foo\\file", buf, MAX_PATH);
2164 ok(ret, "GetLongPathName error %d\n", GetLastError());
2165 ok(!strcmp(buf, "..\\foo\\file"), "expected ..\\foo\\file, got %s\n", buf);
2166 strcpy(buf, "deadbeef");
2167 ret = GetShortPathNameA("..\\foo\\file", buf, MAX_PATH);
2168 ok(ret, "GetShortPathName error %d\n", GetLastError());
2169 ok(!strcmp(buf, "..\\foo\\file"), "expected ..\\foo\\file, got %s\n", buf);
2171 strcpy(buf, "deadbeef");
2172 ret = pGetLongPathNameA(".\\..\\foo\\file", buf, MAX_PATH);
2173 ok(ret, "GetLongPathName error %d\n", GetLastError());
2174 ok(!strcmp(buf, ".\\..\\foo\\file"), "expected .\\..\\foo\\file, got %s\n", buf);
2175 strcpy(buf, "deadbeef");
2176 ret = GetShortPathNameA(".\\..\\foo\\file", buf, MAX_PATH);
2177 ok(ret, "GetShortPathName error %d\n", GetLastError());
2178 ok(!strcmp(buf, ".\\..\\foo\\file"), "expected .\\..\\foo\\file, got %s\n", buf);
2180 SetCurrentDirectoryA("..");
2181 DeleteFileA("foo\\file");
2182 RemoveDirectoryA("foo");
2183 RemoveDirectoryA("bar");
2184 SetCurrentDirectoryW(curdir);
2187 static void test_CheckNameLegalDOS8Dot3(void)
2189 static const WCHAR has_driveW[] = {'C',':','\\','a','.','t','x','t',0};
2190 static const WCHAR has_pathW[] = {'b','\\','a','.','t','x','t',0};
2191 static const WCHAR too_longW[] = {'a','l','o','n','g','f','i','l','e','n','a','m','e','.','t','x','t',0};
2192 static const WCHAR twodotsW[] = {'t','e','s','t','.','e','s','t','.','t','x','t',0};
2193 static const WCHAR longextW[] = {'t','e','s','t','.','t','x','t','t','x','t',0};
2194 static const WCHAR emptyW[] = {0};
2195 static const WCHAR funnycharsW[] = {'!','#','$','%','&','\'','(',')','.','-','@','^',0};
2196 static const WCHAR length8W[] = {'t','e','s','t','t','e','s','t','.','t','x','t',0};
2197 static const WCHAR length1W[] = {'t',0};
2198 static const WCHAR withspaceW[] = {'t','e','s','t',' ','e','s','t','.','t','x','t',0};
2200 static const struct {
2201 const WCHAR *name;
2202 BOOL should_be_legal, has_space;
2203 } cases[] = {
2204 {has_driveW, FALSE, FALSE},
2205 {has_pathW, FALSE, FALSE},
2206 {too_longW, FALSE, FALSE},
2207 {twodotsW, FALSE, FALSE},
2208 {longextW, FALSE, FALSE},
2209 {emptyW, TRUE /* ! */, FALSE},
2210 {funnycharsW, TRUE, FALSE},
2211 {length8W, TRUE, FALSE},
2212 {length1W, TRUE, FALSE},
2213 {withspaceW, TRUE, TRUE},
2216 BOOL br, is_legal, has_space;
2217 char astr[64];
2218 DWORD i;
2220 if(!pCheckNameLegalDOS8Dot3W){
2221 win_skip("Missing CheckNameLegalDOS8Dot3, skipping tests\n");
2222 return;
2225 br = pCheckNameLegalDOS8Dot3W(NULL, NULL, 0, NULL, &is_legal);
2226 ok(br == FALSE, "CheckNameLegalDOS8Dot3W should have failed\n");
2228 br = pCheckNameLegalDOS8Dot3A(NULL, NULL, 0, NULL, &is_legal);
2229 ok(br == FALSE, "CheckNameLegalDOS8Dot3A should have failed\n");
2231 br = pCheckNameLegalDOS8Dot3W(length8W, NULL, 0, NULL, NULL);
2232 ok(br == FALSE, "CheckNameLegalDOS8Dot3W should have failed\n");
2234 br = pCheckNameLegalDOS8Dot3A("testtest.txt", NULL, 0, NULL, NULL);
2235 ok(br == FALSE, "CheckNameLegalDOS8Dot3A should have failed\n");
2237 for(i = 0; i < sizeof(cases)/sizeof(*cases); ++i){
2238 br = pCheckNameLegalDOS8Dot3W(cases[i].name, NULL, 0, &has_space, &is_legal);
2239 ok(br == TRUE, "CheckNameLegalDOS8Dot3W failed for %s\n", wine_dbgstr_w(cases[i].name));
2240 ok(is_legal == cases[i].should_be_legal, "Got wrong legality for %s\n", wine_dbgstr_w(cases[i].name));
2241 if(is_legal)
2242 ok(has_space == cases[i].has_space, "Got wrong space for %s\n", wine_dbgstr_w(cases[i].name));
2244 WideCharToMultiByte(CP_ACP, 0, cases[i].name, -1, astr, sizeof(astr), NULL, NULL);
2246 br = pCheckNameLegalDOS8Dot3A(astr, NULL, 0, &has_space, &is_legal);
2247 ok(br == TRUE, "CheckNameLegalDOS8Dot3W failed for %s\n", astr);
2248 ok(is_legal == cases[i].should_be_legal, "Got wrong legality for %s\n", astr);
2249 if(is_legal)
2250 ok(has_space == cases[i].has_space, "Got wrong space for %s\n", wine_dbgstr_w(cases[i].name));
2254 START_TEST(path)
2256 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
2258 init_pointers();
2260 /* Report only once */
2261 if (!pGetLongPathNameA)
2262 win_skip("GetLongPathNameA is not available\n");
2263 if (!pGetLongPathNameW)
2264 win_skip("GetLongPathNameW is not available\n");
2265 if (!pActivateActCtx)
2266 win_skip("Activation contexts not supported, some tests will be skipped\n");
2268 test_relative_path();
2269 test_InitPathA(curdir, &curDrive, &otherDrive);
2270 test_CurrentDirectoryA(origdir,curdir);
2271 test_PathNameA(curdir, curDrive, otherDrive);
2272 test_CleanupPathA(origdir,curdir);
2273 test_GetTempPath();
2274 test_GetLongPathNameA();
2275 test_GetLongPathNameW();
2276 test_GetShortPathNameW();
2277 test_GetSystemDirectory();
2278 test_GetWindowsDirectory();
2279 test_NeedCurrentDirectoryForExePathA();
2280 test_NeedCurrentDirectoryForExePathW();
2281 test_drive_letter_case();
2282 test_SearchPathA();
2283 test_SearchPathW();
2284 test_GetFullPathNameA();
2285 test_GetFullPathNameW();
2286 test_CheckNameLegalDOS8Dot3();