kernel32/tests: Added some activation context tests for SearchPath().
[wine.git] / dlls / kernel32 / tests / path.c
blobfd40547edaf1ad77a09ddadd80193f8d3e317ad6
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 #else
50 #define ARCH "none"
51 #endif
53 /* the following characters don't work well with GetFullPathNameA
54 in Win98. I don't know if this is a FAT thing, or if it is an OS thing
55 but I don't test these characters now.
56 NOTE: Win2k allows GetFullPathNameA to work with them though
57 |<>"
59 static const CHAR funny_chars[]="!@#$%^&*()=+{}[],?'`";
60 static const CHAR is_char_ok[] ="11111110111111111011";
62 static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR,LPSTR,DWORD);
63 static DWORD (WINAPI *pGetLongPathNameW)(LPWSTR,LPWSTR,DWORD);
65 /* Present in Win2003+ */
66 static BOOL (WINAPI *pNeedCurrentDirectoryForExePathA)(LPCSTR);
67 static BOOL (WINAPI *pNeedCurrentDirectoryForExePathW)(LPCWSTR);
69 static DWORD (WINAPI *pSearchPathA)(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*);
70 static DWORD (WINAPI *pSearchPathW)(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,LPWSTR,LPWSTR*);
72 static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
73 static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
74 static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
75 static BOOL (WINAPI *pGetCurrentActCtx)(HANDLE *);
76 static void (WINAPI *pReleaseActCtx)(HANDLE);
78 /* a structure to deal with wine todos somewhat cleanly */
79 typedef struct {
80 DWORD shortlen;
81 DWORD shorterror;
82 DWORD s2llen;
83 DWORD s2lerror;
84 DWORD longlen;
85 DWORD longerror;
86 } SLpassfail;
88 /* function that tests GetFullPathNameA, GetShortPathNameA,GetLongPathNameA */
89 /* NOTE: the passfail structure is used to allow customizable todo checking
90 for wine. It is not very pretty, but it sure beats duplicating this
91 function lots of times
93 static void test_ValidPathA(const CHAR *curdir, const CHAR *subdir, const CHAR *filename,
94 CHAR *shortstr, SLpassfail *passfail, const CHAR *errstr)
96 CHAR tmpstr[MAX_PATH],
97 fullpath[MAX_PATH], /*full path to the file (not short/long) */
98 subpath[MAX_PATH], /*relative path to the file */
99 fullpathshort[MAX_PATH], /*absolute path to the file (short format) */
100 fullpathlong[MAX_PATH], /*absolute path to the file (long format) */
101 curdirshort[MAX_PATH], /*absolute path to the current dir (short) */
102 curdirlong[MAX_PATH]; /*absolute path to the current dir (long) */
103 LPSTR strptr; /*ptr to the filename portion of the path */
104 DWORD len;
105 /* if passfail is NULL, we can perform all checks within this function,
106 otherwise, we will return the relevant data in the passfail struct, so
107 we must initialize it first
109 if(passfail!=NULL) {
110 passfail->shortlen=-1;passfail->s2llen=-1;passfail->longlen=-1;
111 passfail->shorterror=0;passfail->s2lerror=0;passfail->longerror=0;
113 /* GetLongPathNameA is only supported on Win2k+ and Win98+ */
114 if(pGetLongPathNameA) {
115 ok((len=pGetLongPathNameA(curdir,curdirlong,MAX_PATH)),
116 "%s: GetLongPathNameA failed\n",errstr);
117 /*GetLongPathNameA can return a trailing '\\' but shouldn't do so here */
118 ok(! HAS_TRAIL_SLASH_A(curdirlong),
119 "%s: GetLongPathNameA should not have a trailing \\\n",errstr);
121 ok((len=GetShortPathNameA(curdir,curdirshort,MAX_PATH)),
122 "%s: GetShortPathNameA failed\n",errstr);
123 /*GetShortPathNameA can return a trailing '\\' but shouldn't do so here */
124 ok(! HAS_TRAIL_SLASH_A(curdirshort),
125 "%s: GetShortPathNameA should not have a trailing \\\n",errstr);
126 /* build relative and absolute paths from inputs */
127 if(lstrlenA(subdir)) {
128 sprintf(subpath,"%s\\%s",subdir,filename);
129 } else {
130 lstrcpyA(subpath,filename);
132 sprintf(fullpath,"%s\\%s",curdir,subpath);
133 sprintf(fullpathshort,"%s\\%s",curdirshort,subpath);
134 sprintf(fullpathlong,"%s\\%s",curdirlong,subpath);
135 /* Test GetFullPathNameA functionality */
136 len=GetFullPathNameA(subpath,MAX_PATH,tmpstr,&strptr);
137 ok(len, "GetFullPathNameA failed for: '%s'\n",subpath);
138 if(HAS_TRAIL_SLASH_A(subpath)) {
139 ok(strptr==NULL,
140 "%s: GetFullPathNameA should not return a filename ptr\n",errstr);
141 ok(lstrcmpiA(fullpath,tmpstr)==0,
142 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
143 errstr,tmpstr,fullpath);
144 } else {
145 ok(lstrcmpiA(strptr,filename)==0,
146 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
147 errstr,strptr,filename);
148 ok(lstrcmpiA(fullpath,tmpstr)==0,
149 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
150 errstr,tmpstr,fullpath);
152 /* Test GetShortPathNameA functionality */
153 SetLastError(0);
154 len=GetShortPathNameA(fullpathshort,shortstr,MAX_PATH);
155 if(passfail==NULL) {
156 ok(len, "%s: GetShortPathNameA failed\n",errstr);
157 } else {
158 passfail->shortlen=len;
159 passfail->shorterror=GetLastError();
161 /* Test GetLongPathNameA functionality
162 We test both conversion from GetFullPathNameA and from GetShortPathNameA
164 if(pGetLongPathNameA) {
165 if(len!=0) {
166 SetLastError(0);
167 len=pGetLongPathNameA(shortstr,tmpstr,MAX_PATH);
168 if(passfail==NULL) {
169 ok(len,
170 "%s: GetLongPathNameA failed during Short->Long conversion\n", errstr);
171 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
172 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
173 errstr,tmpstr,fullpathlong);
174 } else {
175 passfail->s2llen=len;
176 passfail->s2lerror=GetLastError();
179 SetLastError(0);
180 len=pGetLongPathNameA(fullpath,tmpstr,MAX_PATH);
181 if(passfail==NULL) {
182 ok(len, "%s: GetLongPathNameA failed\n",errstr);
183 if(HAS_TRAIL_SLASH_A(fullpath)) {
184 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
185 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
186 errstr,tmpstr,fullpathlong);
187 } else {
188 ok(lstrcmpiA(fullpathlong,tmpstr)==0,
189 "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
190 errstr,tmpstr,fullpathlong);
192 } else {
193 passfail->longlen=len;
194 passfail->longerror=GetLastError();
199 /* split path into leading directory, and 8.3 filename */
200 static void test_SplitShortPathA(CHAR *path,CHAR *dir,CHAR *eight,CHAR *three) {
201 int done,error;
202 int ext,fil;
203 int len,i;
204 len=lstrlenA(path);
205 ext=len; fil=len; done=0; error=0;
206 /* walk backwards over path looking for '.' or '\\' separators */
207 for(i=len-1;(i>=0) && (!done);i--) {
208 if(path[i]=='.')
209 if(ext!=len) error=1; else ext=i;
210 else if(path[i]=='\\') {
211 if(i==len-1) {
212 error=1;
213 } else {
214 fil=i;
215 done=1;
219 /* Check that we didn't find a trailing '\\' or multiple '.' */
220 ok(!error,"Illegal file found in 8.3 path '%s'\n",path);
221 /* Separate dir, root, and extension */
222 if(ext!=len) lstrcpyA(three,path+ext+1); else lstrcpyA(three,"");
223 if(fil!=len) {
224 lstrcpynA(eight,path+fil+1,ext-fil);
225 lstrcpynA(dir,path,fil+1);
226 } else {
227 lstrcpynA(eight,path,ext+1);
228 lstrcpyA(dir,"");
230 /* Validate that root and extension really are 8.3 */
231 ok(lstrlenA(eight)<=8 && lstrlenA(three)<=3,
232 "GetShortPathNAmeA did not return an 8.3 path\n");
235 /* Check that GetShortPathNameA returns a valid 8.3 path */
236 static void test_LongtoShortA(CHAR *teststr,const CHAR *goodstr,
237 const CHAR *ext,const CHAR *errstr) {
238 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
240 test_SplitShortPathA(teststr,dir,eight,three);
241 ok(lstrcmpiA(dir,goodstr)==0,
242 "GetShortPathNameA returned '%s' instead of '%s'\n",dir,goodstr);
243 ok(lstrcmpiA(three,ext)==0,
244 "GetShortPathNameA returned '%s' with incorrect extension\n",three);
247 /* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
248 characters in the filename.
249 'valid' indicates whether this would be an allowed filename
250 'todo' indicates that wine doesn't get this right yet.
251 NOTE: We always call this routine with a nonexistent filename, so
252 Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
253 should.
255 static void test_FunnyChars(CHAR *curdir,CHAR *curdir_short,CHAR *filename, INT valid,CHAR *errstr)
257 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
258 SLpassfail passfail;
260 test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
261 if(valid) {
262 sprintf(tmpstr1,"%s\\%s",curdir_short,filename);
263 ok((passfail.shortlen==0 &&
264 (passfail.shorterror==ERROR_FILE_NOT_FOUND || passfail.shorterror==ERROR_PATH_NOT_FOUND || !passfail.shorterror)) ||
265 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
266 "%s: GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
267 errstr,passfail.shortlen,passfail.shorterror,tmpstr);
268 } else {
269 ok(passfail.shortlen==0 &&
270 (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),
271 "%s: GetShortPathA should have failed len=%d, error=%d\n",
272 errstr,passfail.shortlen,passfail.shorterror);
274 if(pGetLongPathNameA) {
275 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
276 if(valid) {
277 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
278 "%s: GetLongPathA returned %d and not %d\n",
279 errstr,passfail.longerror,ERROR_FILE_NOT_FOUND);
280 } else {
281 ok(passfail.longerror==ERROR_INVALID_NAME ||
282 passfail.longerror==ERROR_FILE_NOT_FOUND,
283 "%s: GetLongPathA returned %d and not %d or %d'\n",
284 errstr, passfail.longerror,ERROR_INVALID_NAME,ERROR_FILE_NOT_FOUND);
289 /* Routine to test that SetCurrentDirectory behaves as expected. */
290 static void test_setdir(CHAR *olddir,CHAR *newdir,
291 CHAR *cmprstr, INT pass, const CHAR *errstr)
293 CHAR tmppath[MAX_PATH], *dirptr;
294 DWORD val,len,chklen;
296 val=SetCurrentDirectoryA(newdir);
297 len=GetCurrentDirectoryA(MAX_PATH,tmppath);
298 /* if 'pass' then the SetDirectoryA was supposed to pass */
299 if(pass) {
300 dirptr=(cmprstr==NULL) ? newdir : cmprstr;
301 chklen=lstrlenA(dirptr);
302 ok(val,"%s: SetCurrentDirectoryA failed\n",errstr);
303 ok(len==chklen,
304 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
305 errstr);
306 ok(lstrcmpiA(dirptr,tmppath)==0,
307 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
308 errstr);
309 ok(SetCurrentDirectoryA(olddir),
310 "%s: Couldn't set directory to it's original value\n",errstr);
311 } else {
312 /* else thest that it fails correctly */
313 chklen=lstrlenA(olddir);
314 ok(val==0,
315 "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr);
316 ok(len==chklen,
317 "%s: SetCurrentDirectory changed the directory, though it failed\n",
318 errstr);
319 ok(lstrcmpiA(olddir,tmppath)==0,
320 "%s: SetCurrentDirectory changed the directory, though it failed\n",
321 errstr);
324 static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
326 CHAR tmppath[MAX_PATH], /*path to TEMP */
327 tmpstr[MAX_PATH],
328 tmpstr1[MAX_PATH],
329 invalid_dir[MAX_PATH];
331 DWORD len,len1,drives;
332 INT id;
333 HANDLE hndl;
334 BOOL bRes;
335 UINT unique;
337 *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
339 /* Get the current drive letter */
340 if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
341 *curDrive = tmpstr[0];
342 else
343 trace( "Unable to discover current drive, some tests will not be conducted.\n");
345 /* Test GetTempPathA */
346 len=GetTempPathA(MAX_PATH,tmppath);
347 ok(len!=0 && len < MAX_PATH,"GetTempPathA failed\n");
348 ok(HAS_TRAIL_SLASH_A(tmppath),
349 "GetTempPathA returned a path that did not end in '\\'\n");
350 lstrcpyA(tmpstr,"aaaaaaaa");
351 len1=GetTempPathA(len,tmpstr);
352 ok(len1==len+1 || broken(len1 == len), /* WinME */
353 "GetTempPathA should return string length %d instead of %d\n",len+1,len1);
355 /* Test GetTmpFileNameA */
356 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
357 sprintf(tmpstr,"pat%.4x.tmp",id & 0xffff);
358 sprintf(tmpstr1,"pat%x.tmp",id & 0xffff);
359 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
360 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
361 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
362 newdir,tmpstr,tmpstr1,id);
363 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
365 id=GetTempFileNameA(tmppath,NULL,0,newdir);
366 /* Windows 95, 98 return 0==id, while Windows 2000, XP return 0!=id */
367 if (id)
369 sprintf(tmpstr,"%.4x.tmp",id & 0xffff);
370 sprintf(tmpstr1,"%x.tmp",id & 0xffff);
371 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
372 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
373 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
374 newdir,tmpstr,tmpstr1,id);
375 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
378 for(unique=0;unique<3;unique++) {
379 /* Nonexistent path */
380 sprintf(invalid_dir, "%s\\%s",tmppath,"non_existent_dir_1jwj3y32nb3");
381 SetLastError(0xdeadbeef);
382 ok(!GetTempFileNameA(invalid_dir,"tfn",unique,newdir),"GetTempFileNameA should have failed\n");
383 ok(GetLastError()==ERROR_DIRECTORY || broken(GetLastError()==ERROR_PATH_NOT_FOUND)/*win98*/,
384 "got %d, expected ERROR_DIRECTORY\n", GetLastError());
386 /* Check return value for unique !=0 */
387 if(unique) {
388 ok((GetTempFileNameA(tmppath,"tfn",unique,newdir) == unique),"GetTempFileNameA unexpectedly failed\n");
389 /* if unique != 0, the actual temp files are not created: */
390 ok(!DeleteFileA(newdir) && GetLastError() == ERROR_FILE_NOT_FOUND,"Deleted a file that shouldn't exist!\n");
394 /* Find first valid drive letter that is neither newdir[0] nor curDrive */
395 drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
396 if( *curDrive != NOT_A_VALID_DRIVE)
397 drives &= ~(1<<(*curDrive-'A'));
398 if( drives)
399 for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
400 else
401 trace( "Could not find alternative drive, some tests will not be conducted.\n");
403 /* Do some CreateDirectoryA tests */
404 /* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
405 really understand how they work.
406 More formal tests should be done along with CreateFile tests
408 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
409 ok(CreateDirectoryA(newdir,NULL)==0,
410 "CreateDirectoryA succeeded even though a file of the same name exists\n");
411 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
412 ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
413 /* Create some files to test other functions. Note, we will test CreateFileA
414 at some later point
416 sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
417 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
418 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
419 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
420 sprintf(tmpstr,"%c:", *curDrive);
421 bRes = CreateDirectoryA(tmpstr,NULL);
422 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
423 GetLastError() == ERROR_ALREADY_EXISTS),
424 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
425 sprintf(tmpstr,"%c:\\", *curDrive);
426 bRes = CreateDirectoryA(tmpstr,NULL);
427 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
428 GetLastError() == ERROR_ALREADY_EXISTS),
429 "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
430 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
431 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
432 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
433 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
434 ok(CloseHandle(hndl),"CloseHandle failed\n");
435 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
436 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
437 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
438 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
439 ok(CloseHandle(hndl),"CloseHandle failed\n");
440 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
441 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
442 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
443 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
444 ok(CloseHandle(hndl),"CloseHandle failed\n");
445 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
446 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
447 CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
448 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
449 ok(CloseHandle(hndl),"CloseHandle failed\n");
452 /* Test GetCurrentDirectory & SetCurrentDirectory */
453 static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
455 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
456 char *buffer;
457 DWORD len,len1;
458 /* Save the original directory, so that we can return to it at the end
459 of the test
461 len=GetCurrentDirectoryA(MAX_PATH,origdir);
462 ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
463 /* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
464 buffer size is too small to hold the current directory
466 lstrcpyA(tmpstr,"aaaaaaa");
467 len1=GetCurrentDirectoryA(len,tmpstr);
468 ok(len1==len+1, "GetCurrentDirectoryA returned %d instead of %d\n",len1,len+1);
469 ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
470 "GetCurrentDirectoryA should not have modified the buffer\n");
472 buffer = HeapAlloc( GetProcessHeap(), 0, 2 * 65536 );
473 SetLastError( 0xdeadbeef );
474 strcpy( buffer, "foo" );
475 len = GetCurrentDirectoryA( 32767, buffer );
476 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
477 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
478 SetLastError( 0xdeadbeef );
479 strcpy( buffer, "foo" );
480 len = GetCurrentDirectoryA( 32768, buffer );
481 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
482 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
483 SetLastError( 0xdeadbeef );
484 strcpy( buffer, "foo" );
485 len = GetCurrentDirectoryA( 65535, buffer );
486 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4, win2k, xp */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
487 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
488 SetLastError( 0xdeadbeef );
489 strcpy( buffer, "foo" );
490 len = GetCurrentDirectoryA( 65536, buffer );
491 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4 */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
492 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
493 SetLastError( 0xdeadbeef );
494 strcpy( buffer, "foo" );
495 len = GetCurrentDirectoryA( 2 * 65536, buffer );
496 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4 */ "GetCurrentDirectoryA failed %u err %u\n", len, GetLastError() );
497 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
498 HeapFree( GetProcessHeap(), 0, buffer );
500 /* Check for crash prevention on swapped args. Crashes all but Win9x.
502 if (0)
504 GetCurrentDirectoryA( 42, (LPSTR)(MAX_PATH + 42) );
507 /* SetCurrentDirectoryA shouldn't care whether the string has a
508 trailing '\\' or not
510 sprintf(tmpstr,"%s\\",newdir);
511 test_setdir(origdir,tmpstr,newdir,1,"check 1");
512 test_setdir(origdir,newdir,NULL,1,"check 2");
513 /* Set the directory to the working area. We just tested that this works,
514 so why check it again.
516 SetCurrentDirectoryA(newdir);
517 /* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
518 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
519 test_setdir(newdir,tmpstr,NULL,0,"check 3");
520 /* Check that SetCurrentDirectory fails for a nonexistent lond directory */
521 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
522 test_setdir(newdir,tmpstr,NULL,0,"check 4");
523 /* Check that SetCurrentDirectory passes with a long directory */
524 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
525 test_setdir(newdir,tmpstr,NULL,1,"check 5");
526 /* Check that SetCurrentDirectory passes with a short relative directory */
527 sprintf(tmpstr,"%s",SHORTDIR);
528 sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
529 test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
530 /* starting with a '.' */
531 sprintf(tmpstr,".\\%s",SHORTDIR);
532 test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
533 /* Check that SetCurrentDirectory passes with a short relative directory */
534 sprintf(tmpstr,"%s",LONGDIR);
535 sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
536 test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
537 /* starting with a '.' */
538 sprintf(tmpstr,".\\%s",LONGDIR);
539 test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
540 /* change to root without a trailing backslash. The function call succeeds
541 but the directory is not changed.
543 sprintf(tmpstr, "%c:", newdir[0]);
544 test_setdir(newdir,tmpstr,newdir,1,"check 10");
545 /* works however with a trailing backslash */
546 sprintf(tmpstr, "%c:\\", newdir[0]);
547 test_setdir(newdir,tmpstr,NULL,1,"check 11");
550 /* Cleanup the mess we made while executing these tests */
551 static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
553 CHAR tmpstr[MAX_PATH];
554 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
555 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
556 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
557 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
558 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
559 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
560 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
561 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
562 sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
563 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
564 sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
565 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
566 ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
567 ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
570 /* test that short path name functions work regardless of case */
571 static void test_ShortPathCase(const char *tmpdir, const char *dirname,
572 const char *filename)
574 char buf[MAX_PATH], shortbuf[MAX_PATH];
575 HANDLE hndl;
576 size_t i;
578 assert(strlen(tmpdir) + strlen(dirname) + strlen(filename) + 2 < sizeof(buf));
579 sprintf(buf,"%s\\%s\\%s",tmpdir,dirname,filename);
580 GetShortPathNameA(buf,shortbuf,sizeof(shortbuf));
581 hndl = CreateFileA(shortbuf,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
582 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed (%d)\n",GetLastError());
583 CloseHandle(hndl);
584 /* Now for the real test */
585 for(i=0;i<strlen(shortbuf);i++)
586 if (i % 2)
587 shortbuf[i] = tolower(shortbuf[i]);
588 hndl = CreateFileA(shortbuf,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
589 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed (%d)\n",GetLastError());
590 CloseHandle(hndl);
593 /* This routine will test Get(Full|Short|Long)PathNameA */
594 static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
596 CHAR curdir_short[MAX_PATH],
597 longdir_short[MAX_PATH];
598 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH],tmpstr2[MAX_PATH];
599 LPSTR strptr; /*ptr to the filename portion of the path */
600 DWORD len;
601 INT i;
602 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
603 SLpassfail passfail;
605 /* Get the short form of the current directory */
606 ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
607 "GetShortPathNameA failed\n");
608 ok(!HAS_TRAIL_SLASH_A(curdir_short),
609 "GetShortPathNameA should not have a trailing \\\n");
610 /* Get the short form of the absolute-path to LONGDIR */
611 sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
612 ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
613 "GetShortPathNameA failed\n");
614 ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
615 "GetShortPathNameA should not have a trailing \\\n");
617 if (pGetLongPathNameA) {
618 DWORD rc1,rc2;
619 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
620 rc1=(*pGetLongPathNameA)(tmpstr,NULL,0);
621 rc2=(*pGetLongPathNameA)(curdir,NULL,0);
622 ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
623 "GetLongPathNameA: wrong return code, %d instead of %d\n",
624 rc1, lstrlenA(tmpstr)+1);
626 sprintf(dir,"%c:",curDrive);
627 rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
628 ok(strcmp(dir,tmpstr)==0,
629 "GetLongPathNameA: returned '%s' instead of '%s' (rc=%d)\n",
630 tmpstr,dir,rc1);
633 /* Check the cases where both file and directory exist first */
634 /* Start with a 8.3 directory, 8.3 filename */
635 test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
636 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
637 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
638 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
639 /* Now try a 8.3 directory, long file name */
640 test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
641 sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
642 test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
643 /* Next is a long directory, 8.3 file */
644 test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
645 sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
646 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
647 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
648 /*Lastly a long directory, long file */
649 test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
650 test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
652 /* Now check all of the invalid file w/ valid directory combinations */
653 /* Start with a 8.3 directory, 8.3 filename */
654 test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
655 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
656 ok((passfail.shortlen==0 &&
657 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
658 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
659 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
660 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
661 passfail.shortlen,passfail.shorterror,tmpstr);
662 if(pGetLongPathNameA) {
663 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
664 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
665 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
667 /* Now try a 8.3 directory, long file name */
668 test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
669 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
670 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
671 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
672 !passfail.shorterror,
673 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
674 if(pGetLongPathNameA) {
675 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
676 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
677 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
679 /* Next is a long directory, 8.3 file */
680 test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
681 sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
682 GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
683 strcat(tmpstr1,"\\" NONFILE_SHORT);
684 ok((passfail.shortlen==0 &&
685 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
686 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
687 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
688 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
689 passfail.shortlen,passfail.shorterror,tmpstr);
690 if(pGetLongPathNameA) {
691 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
692 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
693 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
695 /*Lastly a long directory, long file */
696 test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
697 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
698 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
699 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
700 !passfail.shorterror,
701 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
702 if(pGetLongPathNameA) {
703 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
704 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
705 "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
707 /* Now try again with directories that don't exist */
708 /* 8.3 directory, 8.3 filename */
709 test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
710 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
711 ok((passfail.shortlen==0 &&
712 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
713 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
714 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
715 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
716 passfail.shortlen,passfail.shorterror,tmpstr);
717 if(pGetLongPathNameA) {
718 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
719 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
720 passfail.longerror==ERROR_FILE_NOT_FOUND,
721 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
722 passfail.longerror);
724 /* Now try a 8.3 directory, long file name */
725 test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
726 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
727 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
728 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
729 !passfail.shorterror,
730 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
731 passfail.shorterror);
732 if(pGetLongPathNameA) {
733 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
734 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
735 passfail.longerror==ERROR_FILE_NOT_FOUND,
736 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
737 passfail.longerror);
739 /* Next is a long directory, 8.3 file */
740 test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
741 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
742 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
743 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
744 !passfail.shorterror,
745 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
746 passfail.shorterror);
747 if(pGetLongPathNameA) {
748 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
749 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
750 passfail.longerror==ERROR_FILE_NOT_FOUND,
751 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
752 passfail.longerror);
754 /*Lastly a long directory, long file */
755 test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
756 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
757 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
758 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
759 !passfail.shorterror,
760 "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
761 passfail.shorterror);
762 if(pGetLongPathNameA) {
763 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
764 ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
765 passfail.longerror==ERROR_FILE_NOT_FOUND,
766 "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'\n",
767 passfail.longerror);
769 /* Next try directories ending with '\\' */
770 /* Existing Directories */
771 sprintf(tmpstr,"%s\\",SHORTDIR);
772 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
773 sprintf(tmpstr,"%s\\",LONGDIR);
774 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
775 /* Nonexistent directories */
776 sprintf(tmpstr,"%s\\",NONDIR_SHORT);
777 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
778 sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
779 ok((passfail.shortlen==0 &&
780 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
781 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
782 (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
783 "GetShortPathNameA error: len=%d error=%d tmpstr=[%s]\n",
784 passfail.shortlen,passfail.shorterror,tmpstr);
785 if(pGetLongPathNameA) {
786 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
787 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
788 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
789 passfail.longerror);
791 sprintf(tmpstr,"%s\\",NONDIR_LONG);
792 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
793 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
794 ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
795 passfail.shorterror==ERROR_FILE_NOT_FOUND ||
796 !passfail.shorterror,
797 "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
798 passfail.shorterror);
799 if(pGetLongPathNameA) {
800 ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
801 ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
802 "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'\n",
803 passfail.longerror);
805 /* Test GetFullPathNameA with drive letters */
806 if( curDrive != NOT_A_VALID_DRIVE) {
807 sprintf(tmpstr,"%c:",curdir[0]);
808 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
809 "GetFullPathNameA(%c:) failed\n", curdir[0]);
810 GetCurrentDirectoryA(MAX_PATH,tmpstr);
811 sprintf(tmpstr1,"%s\\",tmpstr);
812 ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
813 "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
814 curdir[0],tmpstr2,tmpstr,tmpstr1);
816 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
817 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
818 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
819 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
820 ok(lstrcmpiA(SHORTFILE,strptr)==0,
821 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
823 /* Without a leading slash, insert the current directory if on the current drive */
824 sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
825 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
826 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
827 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
828 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
829 ok(lstrcmpiA(SHORTFILE,strptr)==0,
830 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
831 /* Otherwise insert the missing leading slash */
832 if( otherDrive != NOT_A_VALID_DRIVE) {
833 /* FIXME: this test assumes that current directory on other drive is root */
834 sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
835 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
836 sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
837 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
838 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
839 ok(lstrcmpiA(SHORTFILE,strptr)==0,
840 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
842 /* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
843 So test for them. */
844 if( curDrive != NOT_A_VALID_DRIVE) {
845 sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
846 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
847 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
848 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
849 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
850 ok(lstrcmpiA(SHORTFILE,strptr)==0,
851 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
853 /**/
854 sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
855 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
856 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
857 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
858 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
859 ok(lstrcmpiA(SHORTFILE,strptr)==0,
860 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
861 /* Windows will insert a drive letter in front of an absolute UNIX path */
862 sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
863 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
864 sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
865 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
866 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
867 /* This passes in Wine because it still contains the pointer from the previous test */
868 ok(lstrcmpiA(SHORTFILE,strptr)==0,
869 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
871 /* Now try some relative paths */
872 ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
873 test_SplitShortPathA(tmpstr,dir,eight,three);
874 if(pGetLongPathNameA) {
875 ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
876 ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
877 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
879 sprintf(tmpstr,".\\%s",LONGDIR);
880 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
881 test_SplitShortPathA(tmpstr1,dir,eight,three);
882 ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
883 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
884 if(pGetLongPathNameA) {
885 ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
886 tmpstr);
887 ok(lstrcmpiA(tmpstr1,tmpstr)==0,
888 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
890 /* Check out Get*PathNameA on some funny characters */
891 for(i=0;i<lstrlenA(funny_chars);i++) {
892 INT valid;
893 valid=(is_char_ok[i]=='0') ? 0 : 1;
894 sprintf(tmpstr1,"check%d-1",i);
895 sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
896 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
897 sprintf(tmpstr1,"check%d-2",i);
898 sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
899 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
900 sprintf(tmpstr1,"check%d-3",i);
901 sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
902 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
903 sprintf(tmpstr1,"check%d-4",i);
904 sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
905 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
906 sprintf(tmpstr1,"check%d-5",i);
907 sprintf(tmpstr,"Long %c File",funny_chars[i]);
908 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
909 sprintf(tmpstr1,"check%d-6",i);
910 sprintf(tmpstr,"%c Long File",funny_chars[i]);
911 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
912 sprintf(tmpstr1,"check%d-7",i);
913 sprintf(tmpstr,"Long File %c",funny_chars[i]);
914 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
916 /* Now try it on mixed case short names */
917 test_ShortPathCase(curdir,SHORTDIR,LONGFILE);
918 test_ShortPathCase(curdir,LONGDIR,SHORTFILE);
919 test_ShortPathCase(curdir,LONGDIR,LONGFILE);
922 static void test_GetTempPathA(char* tmp_dir)
924 DWORD len, len_with_null;
925 char buf[MAX_PATH];
927 len_with_null = strlen(tmp_dir) + 1;
929 lstrcpyA(buf, "foo");
930 len = GetTempPathA(MAX_PATH, buf);
931 ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
932 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
933 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
935 /* Some versions of Windows touch the buffer, some don't so we don't
936 * test that. Also, NT sometimes exaggerates the required buffer size
937 * so we cannot test for an exact match. Finally, the
938 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
939 * For instance in some cases Win98 returns len_with_null - 1 instead
940 * of len_with_null.
942 len = GetTempPathA(1, buf);
943 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
945 len = GetTempPathA(0, NULL);
946 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
948 /* The call above gave us the buffer size that Windows thinks is needed
949 * so the next call should work
951 lstrcpyA(buf, "foo");
952 len = GetTempPathA(len, buf);
953 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
954 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
957 static void test_GetTempPathW(char* tmp_dir)
959 DWORD len, len_with_null;
960 WCHAR buf[MAX_PATH];
961 WCHAR tmp_dirW[MAX_PATH];
962 static const WCHAR fooW[] = {'f','o','o',0};
964 MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
965 len_with_null = lstrlenW(tmp_dirW) + 1;
967 /* This one is different from ANSI version: ANSI version doesn't
968 * touch the buffer, unicode version usually truncates the buffer
969 * to zero size. NT still exaggerates the required buffer size
970 * sometimes so we cannot test for an exact match. Finally, the
971 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
972 * For instance on NT4 it will sometimes return a path without the
973 * trailing '\\' and sometimes return an error.
976 lstrcpyW(buf, fooW);
977 len = GetTempPathW(MAX_PATH, buf);
978 if (len == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
980 win_skip("GetTempPathW is not available\n");
981 return;
983 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
984 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
986 lstrcpyW(buf, fooW);
987 len = GetTempPathW(1, buf);
988 ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
989 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
991 len = GetTempPathW(0, NULL);
992 ok(len >= len_with_null, "Expected >= %u, got %u\n", len_with_null, len);
994 lstrcpyW(buf, fooW);
995 len = GetTempPathW(len, buf);
996 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
997 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
1000 static void test_GetTempPath(void)
1002 char save_TMP[MAX_PATH];
1003 char windir[MAX_PATH];
1004 char buf[MAX_PATH];
1006 if (!GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP))) save_TMP[0] = 0;
1008 /* test default configuration */
1009 trace("TMP=%s\n", save_TMP);
1010 if (save_TMP[0])
1012 strcpy(buf,save_TMP);
1013 if (buf[strlen(buf)-1]!='\\')
1014 strcat(buf,"\\");
1015 test_GetTempPathA(buf);
1016 test_GetTempPathW(buf);
1019 /* TMP=C:\WINDOWS */
1020 GetWindowsDirectoryA(windir, sizeof(windir));
1021 SetEnvironmentVariableA("TMP", windir);
1022 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1023 trace("TMP=%s\n", buf);
1024 strcat(windir,"\\");
1025 test_GetTempPathA(windir);
1026 test_GetTempPathW(windir);
1028 /* TMP=C:\ */
1029 GetWindowsDirectoryA(windir, sizeof(windir));
1030 windir[3] = 0;
1031 SetEnvironmentVariableA("TMP", windir);
1032 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1033 trace("TMP=%s\n", buf);
1034 test_GetTempPathA(windir);
1035 test_GetTempPathW(windir);
1037 /* TMP=C: i.e. use current working directory of the specified drive */
1038 GetWindowsDirectoryA(windir, sizeof(windir));
1039 SetCurrentDirectoryA(windir);
1040 windir[2] = 0;
1041 SetEnvironmentVariableA("TMP", windir);
1042 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1043 trace("TMP=%s\n", buf);
1044 GetWindowsDirectoryA(windir, sizeof(windir));
1045 strcat(windir,"\\");
1046 test_GetTempPathA(windir);
1047 test_GetTempPathW(windir);
1049 SetEnvironmentVariableA("TMP", save_TMP);
1052 static void test_GetLongPathNameA(void)
1054 DWORD length, explength, hostsize;
1055 char tempfile[MAX_PATH];
1056 char longpath[MAX_PATH];
1057 char unc_prefix[MAX_PATH];
1058 char unc_short[MAX_PATH], unc_long[MAX_PATH];
1059 char temppath[MAX_PATH], temppath2[MAX_PATH];
1060 HANDLE file;
1062 if (!pGetLongPathNameA)
1063 return;
1065 GetTempPathA(MAX_PATH, tempfile);
1066 lstrcatA(tempfile, "longfilename.longext");
1068 file = CreateFileA(tempfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1069 CloseHandle(file);
1071 /* Test a normal path with a small buffer size */
1072 memset(temppath, 0, MAX_PATH);
1073 length = pGetLongPathNameA(tempfile, temppath, 4);
1074 /* We have a failure so length should be the minimum plus the terminating '0' */
1075 ok(length >= lstrlen(tempfile) + 1, "Wrong length\n");
1076 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1078 /* Some UNC syntax tests */
1080 memset(temppath, 0, MAX_PATH);
1081 memset(temppath2, 0, MAX_PATH);
1082 lstrcpyA(temppath2, "\\\\?\\");
1083 lstrcatA(temppath2, tempfile);
1084 explength = length + 4;
1086 SetLastError(0xdeadbeef);
1087 length = pGetLongPathNameA(temppath2, NULL, 0);
1088 if (length == 0 && GetLastError() == ERROR_BAD_NET_NAME)
1090 win_skip("UNC syntax tests don't work on Win98/WinMe\n");
1091 DeleteFileA(tempfile);
1092 return;
1094 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1096 length = pGetLongPathNameA(temppath2, NULL, MAX_PATH);
1097 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1099 length = pGetLongPathNameA(temppath2, temppath, 4);
1100 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1101 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1103 /* Now an UNC path with the computername */
1104 lstrcpyA(unc_prefix, "\\\\");
1105 hostsize = sizeof(unc_prefix) - 2;
1106 GetComputerName(unc_prefix + 2, &hostsize);
1107 lstrcatA(unc_prefix, "\\");
1109 /* Create a short syntax for the whole unc path */
1110 memset(unc_short, 0, MAX_PATH);
1111 GetShortPathNameA(tempfile, temppath, MAX_PATH);
1112 lstrcpyA(unc_short, unc_prefix);
1113 unc_short[lstrlenA(unc_short)] = temppath[0];
1114 lstrcatA(unc_short, "$\\");
1115 lstrcatA(unc_short, strchr(temppath, '\\') + 1);
1117 /* Create a long syntax for reference */
1118 memset(longpath, 0, MAX_PATH);
1119 pGetLongPathNameA(tempfile, temppath, MAX_PATH);
1120 lstrcpyA(longpath, unc_prefix);
1121 longpath[lstrlenA(longpath)] = temppath[0];
1122 lstrcatA(longpath, "$\\");
1123 lstrcatA(longpath, strchr(temppath, '\\') + 1);
1125 /* NULL test */
1126 SetLastError(0xdeadbeef);
1127 length = pGetLongPathNameA(unc_short, NULL, 0);
1128 if (length == 0 && GetLastError() == ERROR_BAD_NETPATH)
1130 /* Seen on Window XP Home */
1131 win_skip("UNC with computername is not supported\n");
1132 DeleteFileA(tempfile);
1133 return;
1135 explength = lstrlenA(longpath) + 1;
1136 todo_wine
1137 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1139 length = pGetLongPathNameA(unc_short, NULL, MAX_PATH);
1140 todo_wine
1141 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1143 memset(unc_long, 0, MAX_PATH);
1144 length = pGetLongPathNameA(unc_short, unc_long, lstrlenA(unc_short));
1145 /* length will include terminating '0' on failure */
1146 todo_wine
1147 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1148 ok(unc_long[0] == 0, "Buffer should not have been touched\n");
1150 memset(unc_long, 0, MAX_PATH);
1151 length = pGetLongPathNameA(unc_short, unc_long, length);
1152 /* length doesn't include terminating '0' on success */
1153 explength--;
1154 todo_wine
1156 ok(length == explength, "Wrong length %d, expected %d\n", length, explength);
1157 ok(!lstrcmpiA(unc_long, longpath), "Expected (%s), got (%s)\n", longpath, unc_long);
1160 DeleteFileA(tempfile);
1163 static void test_GetLongPathNameW(void)
1165 DWORD length, expanded;
1166 BOOL ret;
1167 HANDLE file;
1168 WCHAR empty[MAX_PATH];
1169 WCHAR tempdir[MAX_PATH], name[200];
1170 WCHAR dirpath[4 + MAX_PATH + 200]; /* To ease removal */
1171 WCHAR shortpath[4 + MAX_PATH + 200 + 1 + 200];
1172 static const WCHAR prefix[] = { '\\','\\','?','\\', 0};
1173 static const WCHAR backslash[] = { '\\', 0};
1174 static const WCHAR letterX[] = { 'X', 0};
1176 if (!pGetLongPathNameW)
1177 return;
1179 SetLastError(0xdeadbeef);
1180 length = pGetLongPathNameW(NULL,NULL,0);
1181 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1183 win_skip("GetLongPathNameW is not implemented\n");
1184 return;
1186 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1187 ok(GetLastError()==ERROR_INVALID_PARAMETER,"GetLastError returned %d but expected ERROR_INVALID_PARAMETER\n",GetLastError());
1189 SetLastError(0xdeadbeef);
1190 empty[0]=0;
1191 length = pGetLongPathNameW(empty,NULL,0);
1192 ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length);
1193 ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
1195 /* Create a long path name. The path needs to exist for these tests to
1196 * succeed so we need the "\\?\" prefix when creating directories and
1197 * files.
1199 name[0] = 0;
1200 while (lstrlenW(name) < (sizeof(name)/sizeof(WCHAR) - 1))
1201 lstrcatW(name, letterX);
1203 GetTempPathW(MAX_PATH, tempdir);
1205 lstrcpyW(shortpath, prefix);
1206 lstrcatW(shortpath, tempdir);
1207 lstrcatW(shortpath, name);
1208 lstrcpyW(dirpath, shortpath);
1209 ret = CreateDirectoryW(shortpath, NULL);
1210 ok(ret, "Could not create the temporary directory : %d\n", GetLastError());
1211 lstrcatW(shortpath, backslash);
1212 lstrcatW(shortpath, name);
1214 /* Path does not exist yet and we know it overruns MAX_PATH */
1216 /* No prefix */
1217 SetLastError(0xdeadbeef);
1218 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1219 ok(length == 0, "Expected 0, got %d\n", length);
1220 todo_wine
1221 ok(GetLastError() == ERROR_PATH_NOT_FOUND,
1222 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1223 /* With prefix */
1224 SetLastError(0xdeadbeef);
1225 length = pGetLongPathNameW(shortpath, NULL, 0);
1226 todo_wine
1228 ok(length == 0, "Expected 0, got %d\n", length);
1229 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
1230 "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1233 file = CreateFileW(shortpath, GENERIC_READ|GENERIC_WRITE, 0, NULL,
1234 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1235 ok(file != INVALID_HANDLE_VALUE,
1236 "Could not create the temporary file : %d.\n", GetLastError());
1237 CloseHandle(file);
1239 /* Path exists */
1241 /* No prefix */
1242 SetLastError(0xdeadbeef);
1243 length = pGetLongPathNameW(shortpath + 4, NULL, 0);
1244 todo_wine
1246 ok(length == 0, "Expected 0, got %d\n", length);
1247 ok(GetLastError() == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
1249 /* With prefix */
1250 expanded = 4 + (pGetLongPathNameW(tempdir, NULL, 0) - 1) + lstrlenW(name) + 1 + lstrlenW(name) + 1;
1251 SetLastError(0xdeadbeef);
1252 length = pGetLongPathNameW(shortpath, NULL, 0);
1253 ok(length == expanded, "Expected %d, got %d\n", expanded, length);
1255 /* NULL buffer with length crashes on Windows */
1256 if (0)
1257 pGetLongPathNameW(shortpath, NULL, 20);
1259 ok(DeleteFileW(shortpath), "Could not delete temporary file\n");
1260 ok(RemoveDirectoryW(dirpath), "Could not delete temporary directory\n");
1263 static void test_GetShortPathNameW(void)
1265 WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
1266 WCHAR path[MAX_PATH];
1267 WCHAR short_path[MAX_PATH];
1268 DWORD length;
1269 HANDLE file;
1270 int ret;
1271 WCHAR name[] = { 't', 'e', 's', 't', 0 };
1272 WCHAR backSlash[] = { '\\', 0 };
1274 SetLastError(0xdeadbeef);
1275 GetTempPathW( MAX_PATH, path );
1276 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1278 win_skip("GetTempPathW is not implemented\n");
1279 return;
1282 lstrcatW( path, test_path );
1283 lstrcatW( path, backSlash );
1284 ret = CreateDirectoryW( path, NULL );
1285 ok( ret, "Directory was not created. LastError = %d\n", GetLastError() );
1287 /* Starting a main part of test */
1288 length = GetShortPathNameW( path, short_path, 0 );
1289 ok( length, "GetShortPathNameW returned 0.\n" );
1290 ret = GetShortPathNameW( path, short_path, length );
1291 ok( ret, "GetShortPathNameW returned 0.\n" );
1293 lstrcatW( short_path, name );
1295 /* GetShortPathName for a non-existent short file name should fail */
1296 SetLastError(0xdeadbeef);
1297 length = GetShortPathNameW( short_path, path, 0 );
1298 ok(!length, "GetShortPathNameW should fail\n");
1299 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
1301 file = CreateFileW( short_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1302 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
1304 /* End test */
1305 CloseHandle( file );
1306 ret = DeleteFileW( short_path );
1307 ok( ret, "Cannot delete file.\n" );
1308 ret = RemoveDirectoryW( path );
1309 ok( ret, "Cannot delete directory.\n" );
1312 static void test_GetSystemDirectory(void)
1314 CHAR buffer[MAX_PATH + 4];
1315 DWORD res;
1316 DWORD total;
1318 SetLastError(0xdeadbeef);
1319 res = GetSystemDirectory(NULL, 0);
1320 /* res includes the terminating Zero */
1321 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1323 total = res;
1325 /* this crashes on XP */
1326 if (0)
1327 GetSystemDirectory(NULL, total);
1329 SetLastError(0xdeadbeef);
1330 res = GetSystemDirectory(NULL, total-1);
1331 /* 95+NT: total (includes the terminating Zero)
1332 98+ME: 0 with ERROR_INVALID_PARAMETER */
1333 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1334 "returned %d with %d (expected '%d' or: '0' with "
1335 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1337 if (total > MAX_PATH) return;
1339 buffer[0] = '\0';
1340 SetLastError(0xdeadbeef);
1341 res = GetSystemDirectory(buffer, total);
1342 /* res does not include the terminating Zero */
1343 ok( (res == (total-1)) && (buffer[0]),
1344 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1345 res, GetLastError(), buffer, total-1);
1347 buffer[0] = '\0';
1348 SetLastError(0xdeadbeef);
1349 res = GetSystemDirectory(buffer, total + 1);
1350 /* res does not include the terminating Zero */
1351 ok( (res == (total-1)) && (buffer[0]),
1352 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1353 res, GetLastError(), buffer, total-1);
1355 memset(buffer, '#', total + 1);
1356 buffer[total + 2] = '\0';
1357 SetLastError(0xdeadbeef);
1358 res = GetSystemDirectory(buffer, total-1);
1359 /* res includes the terminating Zero) */
1360 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1361 res, GetLastError(), buffer, total);
1363 memset(buffer, '#', total + 1);
1364 buffer[total + 2] = '\0';
1365 SetLastError(0xdeadbeef);
1366 res = GetSystemDirectory(buffer, total-2);
1367 /* res includes the terminating Zero) */
1368 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1369 res, GetLastError(), buffer, total);
1372 static void test_GetWindowsDirectory(void)
1374 CHAR buffer[MAX_PATH + 4];
1375 DWORD res;
1376 DWORD total;
1378 SetLastError(0xdeadbeef);
1379 res = GetWindowsDirectory(NULL, 0);
1380 /* res includes the terminating Zero */
1381 ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError());
1383 total = res;
1384 /* this crashes on XP */
1385 if (0)
1386 GetWindowsDirectory(NULL, total);
1388 SetLastError(0xdeadbeef);
1389 res = GetWindowsDirectory(NULL, total-1);
1390 /* 95+NT: total (includes the terminating Zero)
1391 98+ME: 0 with ERROR_INVALID_PARAMETER */
1392 ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)),
1393 "returned %d with %d (expected '%d' or: '0' with "
1394 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), total);
1396 if (total > MAX_PATH) return;
1398 buffer[0] = '\0';
1399 SetLastError(0xdeadbeef);
1400 res = GetWindowsDirectory(buffer, total);
1401 /* res does not include the terminating Zero */
1402 ok( (res == (total-1)) && (buffer[0]),
1403 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1404 res, GetLastError(), buffer, total-1);
1406 buffer[0] = '\0';
1407 SetLastError(0xdeadbeef);
1408 res = GetWindowsDirectory(buffer, total + 1);
1409 /* res does not include the terminating Zero */
1410 ok( (res == (total-1)) && (buffer[0]),
1411 "returned %d with %d and '%s' (expected '%d' and a string)\n",
1412 res, GetLastError(), buffer, total-1);
1414 memset(buffer, '#', total + 1);
1415 buffer[total + 2] = '\0';
1416 SetLastError(0xdeadbeef);
1417 res = GetWindowsDirectory(buffer, total-1);
1418 /* res includes the terminating Zero) */
1419 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1420 res, GetLastError(), buffer, total);
1422 memset(buffer, '#', total + 1);
1423 buffer[total + 2] = '\0';
1424 SetLastError(0xdeadbeef);
1425 res = GetWindowsDirectory(buffer, total-2);
1426 /* res includes the terminating Zero) */
1427 ok( res == total, "returned %d with %d and '%s' (expected '%d')\n",
1428 res, GetLastError(), buffer, total);
1431 static void test_NeedCurrentDirectoryForExePathA(void)
1433 if (!pNeedCurrentDirectoryForExePathA)
1435 win_skip("NeedCurrentDirectoryForExePathA is not available\n");
1436 return;
1439 /* Crashes in Windows */
1440 if (0)
1441 pNeedCurrentDirectoryForExePathA(NULL);
1443 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1444 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1445 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1446 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1448 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1449 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1450 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1451 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1454 static void test_NeedCurrentDirectoryForExePathW(void)
1456 const WCHAR thispath[] = {'.', 0};
1457 const WCHAR fullpath[] = {'c', ':', '\\', 0};
1458 const WCHAR cmdname[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1460 if (!pNeedCurrentDirectoryForExePathW)
1462 win_skip("NeedCurrentDirectoryForExePathW is not available\n");
1463 return;
1466 /* Crashes in Windows */
1467 if (0)
1468 pNeedCurrentDirectoryForExePathW(NULL);
1470 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1471 ok(pNeedCurrentDirectoryForExePathW(thispath), "returned FALSE for \".\"\n");
1472 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1473 ok(pNeedCurrentDirectoryForExePathW(cmdname), "returned FALSE for \"cmd.exe\"\n");
1475 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1476 ok(!pNeedCurrentDirectoryForExePathW(thispath), "returned TRUE for \".\"\n");
1477 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1478 ok(!pNeedCurrentDirectoryForExePathW(cmdname), "returned TRUE for \"cmd.exe\"\n");
1481 /* Call various path/file name retrieving APIs and check the case of
1482 * the returned drive letter. Some apps (for instance Adobe Photoshop CS3
1483 * installer) depend on the drive letter being in upper case.
1485 static void test_drive_letter_case(void)
1487 UINT ret;
1488 char buf[MAX_PATH];
1490 #define is_upper_case_letter(a) ((a) >= 'A' && (a) <= 'Z')
1492 memset(buf, 0, sizeof(buf));
1493 SetLastError(0xdeadbeef);
1494 ret = GetWindowsDirectory(buf, sizeof(buf));
1495 ok(ret, "GetWindowsDirectory error %u\n", GetLastError());
1496 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1497 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1498 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1500 /* re-use the buffer returned by GetFullPathName */
1501 buf[2] = '/';
1502 SetLastError(0xdeadbeef);
1503 ret = GetFullPathName(buf + 2, sizeof(buf), buf, NULL);
1504 ok(ret, "GetFullPathName error %u\n", GetLastError());
1505 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1506 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1507 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1509 memset(buf, 0, sizeof(buf));
1510 SetLastError(0xdeadbeef);
1511 ret = GetSystemDirectory(buf, sizeof(buf));
1512 ok(ret, "GetSystemDirectory error %u\n", GetLastError());
1513 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1514 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1515 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1517 memset(buf, 0, sizeof(buf));
1518 SetLastError(0xdeadbeef);
1519 ret = GetCurrentDirectory(sizeof(buf), buf);
1520 ok(ret, "GetCurrentDirectory error %u\n", GetLastError());
1521 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1522 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1523 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1525 /* TEMP is an environment variable, so it can't be tested for case-sensitivity */
1526 memset(buf, 0, sizeof(buf));
1527 SetLastError(0xdeadbeef);
1528 ret = GetTempPath(sizeof(buf), buf);
1529 ok(ret, "GetTempPath error %u\n", GetLastError());
1530 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1531 if (buf[0])
1533 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1534 ok(buf[strlen(buf)-1] == '\\', "Temporary path (%s) doesn't end in a slash\n", buf);
1537 memset(buf, 0, sizeof(buf));
1538 SetLastError(0xdeadbeef);
1539 ret = GetFullPathName(".", sizeof(buf), buf, NULL);
1540 ok(ret, "GetFullPathName error %u\n", GetLastError());
1541 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1542 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1543 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1545 /* re-use the buffer returned by GetFullPathName */
1546 SetLastError(0xdeadbeef);
1547 ret = GetShortPathName(buf, buf, sizeof(buf));
1548 ok(ret, "GetShortPathName error %u\n", GetLastError());
1549 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1550 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1551 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1553 if (pGetLongPathNameA)
1555 /* re-use the buffer returned by GetShortPathName */
1556 SetLastError(0xdeadbeef);
1557 ret = pGetLongPathNameA(buf, buf, sizeof(buf));
1558 ok(ret, "GetLongPathNameA error %u\n", GetLastError());
1559 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1560 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1561 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1563 #undef is_upper_case_letter
1566 static const char manifest_dep[] =
1567 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1568 "<assemblyIdentity version=\"1.2.3.4\" name=\"testdep1\" type=\"win32\" processorArchitecture=\"" ARCH "\"/>"
1569 " <file name=\"testdep.dll\" />"
1570 " <file name=\"kernel32.dll\" />"
1571 "</assembly>";
1573 static const char manifest_main[] =
1574 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1575 "<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
1576 "<dependency>"
1577 " <dependentAssembly>"
1578 " <assemblyIdentity type=\"win32\" name=\"testdep1\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH "\" />"
1579 " </dependentAssembly>"
1580 "</dependency>"
1581 "</assembly>";
1583 static void create_manifest_file(const char *filename, const char *manifest)
1585 WCHAR path[MAX_PATH], manifest_path[MAX_PATH];
1586 HANDLE file;
1587 DWORD size;
1589 MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH );
1591 GetTempPathW(sizeof(manifest_path)/sizeof(WCHAR), manifest_path);
1592 lstrcatW(manifest_path, path);
1594 file = CreateFileW(manifest_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1595 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
1596 WriteFile(file, manifest, strlen(manifest), &size, NULL);
1597 CloseHandle(file);
1600 static void delete_manifest_file(const char *filename)
1602 CHAR path[MAX_PATH];
1604 GetTempPathA(sizeof(path), path);
1605 strcat(path, filename);
1606 DeleteFileA(path);
1609 static HANDLE test_create(const char *file)
1611 WCHAR path[MAX_PATH], manifest_path[MAX_PATH];
1612 ACTCTXW actctx;
1613 HANDLE handle;
1615 MultiByteToWideChar(CP_ACP, 0, file, -1, path, MAX_PATH);
1616 GetTempPathW(sizeof(manifest_path)/sizeof(WCHAR), manifest_path);
1617 lstrcatW(manifest_path, path);
1619 memset(&actctx, 0, sizeof(ACTCTXW));
1620 actctx.cbSize = sizeof(ACTCTXW);
1621 actctx.lpSource = manifest_path;
1623 handle = pCreateActCtxW(&actctx);
1624 todo_wine
1625 ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError());
1627 ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize);
1628 ok(actctx.dwFlags == 0, "dwFlags=%d\n", actctx.dwFlags);
1629 ok(actctx.lpSource == manifest_path, "lpSource=%p\n", actctx.lpSource);
1630 ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
1631 ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId);
1632 ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
1633 ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName);
1634 ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName);
1635 ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule);
1637 return handle;
1640 static void test_SearchPathA(void)
1642 static const CHAR testdepA[] = "testdep.dll";
1643 static const CHAR kernel32A[] = "kernel32.dll";
1644 static const CHAR fileA[] = "";
1645 CHAR pathA[MAX_PATH], buffA[MAX_PATH], path2A[MAX_PATH];
1646 CHAR *ptrA = NULL;
1647 ULONG_PTR cookie;
1648 HANDLE handle;
1649 DWORD ret;
1651 if (!pSearchPathA)
1653 win_skip("SearchPathA isn't available\n");
1654 return;
1657 GetWindowsDirectoryA(pathA, sizeof(pathA)/sizeof(CHAR));
1659 /* NULL filename */
1660 SetLastError(0xdeadbeef);
1661 ret = pSearchPathA(pathA, NULL, NULL, sizeof(buffA)/sizeof(CHAR), buffA, &ptrA);
1662 ok(ret == 0, "Expected failure, got %d\n", ret);
1663 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1664 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1666 /* empty filename */
1667 SetLastError(0xdeadbeef);
1668 ret = pSearchPathA(pathA, fileA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, &ptrA);
1669 ok(ret == 0, "Expected failure, got %d\n", ret);
1670 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1671 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1673 if (!pActivateActCtx)
1674 return;
1676 create_manifest_file("testdep1.manifest", manifest_dep);
1677 create_manifest_file("main.manifest", manifest_main);
1679 handle = test_create("main.manifest");
1680 delete_manifest_file("testdep1.manifest");
1681 delete_manifest_file("main.manifest");
1683 /* search fails without active context */
1684 ret = pSearchPathA(NULL, testdepA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, NULL);
1685 ok(ret == 0, "got %d\n", ret);
1687 ret = pSearchPathA(NULL, kernel32A, NULL, sizeof(path2A)/sizeof(CHAR), path2A, NULL);
1688 ok(ret && ret == strlen(path2A), "got %d\n", ret);
1690 ret = pActivateActCtx(handle, &cookie);
1691 ok(ret, "failed to activate context, %u\n", GetLastError());
1693 /* works when activated */
1694 ret = pSearchPathA(NULL, testdepA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, NULL);
1695 todo_wine
1696 ok(ret && ret == strlen(buffA), "got %d\n", ret);
1698 /* path is redirect for wellknown names too */
1699 ret = pSearchPathA(NULL, kernel32A, NULL, sizeof(buffA)/sizeof(CHAR), buffA, NULL);
1700 ok(ret && ret == strlen(buffA), "got %d\n", ret);
1701 todo_wine
1702 ok(strcmp(buffA, path2A), "got wrong path %s, %s\n", buffA, path2A);
1704 ret = pDeactivateActCtx(0, cookie);
1705 ok(ret, "failed to deactivate context, %u\n", GetLastError());
1706 pReleaseActCtx(handle);
1709 static void test_SearchPathW(void)
1711 static const WCHAR testdepW[] = {'t','e','s','t','d','e','p','.','d','l','l',0};
1712 static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
1713 static const WCHAR fileW[] = { 0 };
1714 WCHAR pathW[MAX_PATH], buffW[MAX_PATH], path2W[MAX_PATH];
1715 WCHAR *ptrW = NULL;
1716 ULONG_PTR cookie;
1717 HANDLE handle;
1718 DWORD ret;
1720 if (!pSearchPathW)
1722 win_skip("SearchPathW isn't available\n");
1723 return;
1726 if (0)
1728 /* NULL filename, crashes on nt4 */
1729 pSearchPathW(pathW, NULL, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW);
1732 /* empty filename */
1733 SetLastError(0xdeadbeef);
1734 ret = pSearchPathW(pathW, fileW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW);
1735 ok(ret == 0, "Expected failure, got %d\n", ret);
1736 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1737 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1739 if (!pActivateActCtx)
1740 return;
1742 create_manifest_file("testdep1.manifest", manifest_dep);
1743 create_manifest_file("main.manifest", manifest_main);
1745 handle = test_create("main.manifest");
1746 delete_manifest_file("testdep1.manifest");
1747 delete_manifest_file("main.manifest");
1749 /* search fails without active context */
1750 ret = pSearchPathW(NULL, testdepW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL);
1751 ok(ret == 0, "got %d\n", ret);
1753 ret = pSearchPathW(NULL, kernel32W, NULL, sizeof(path2W)/sizeof(WCHAR), path2W, NULL);
1754 ok(ret && ret == lstrlenW(path2W), "got %d\n", ret);
1756 ret = pActivateActCtx(handle, &cookie);
1757 ok(ret, "failed to activate context, %u\n", GetLastError());
1759 /* works when activated */
1760 ret = pSearchPathW(NULL, testdepW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL);
1761 todo_wine
1762 ok(ret && ret == lstrlenW(buffW), "got %d\n", ret);
1764 /* path is redirect for wellknown names too */
1765 ret = pSearchPathW(NULL, kernel32W, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL);
1766 ok(ret && ret == lstrlenW(buffW), "got %d\n", ret);
1767 todo_wine
1768 ok(lstrcmpW(buffW, path2W), "got wrong path %s, %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(path2W));
1770 ret = pDeactivateActCtx(0, cookie);
1771 ok(ret, "failed to deactivate context, %u\n", GetLastError());
1772 pReleaseActCtx(handle);
1775 static void test_GetFullPathNameA(void)
1777 char output[MAX_PATH], *filepart;
1778 DWORD ret;
1779 int i;
1781 const struct
1783 LPCSTR name;
1784 DWORD len;
1785 LPSTR buffer;
1786 LPSTR *lastpart;
1787 } invalid_parameters[] =
1789 {NULL, 0, NULL, NULL},
1790 {NULL, MAX_PATH, NULL, NULL},
1791 {NULL, MAX_PATH, output, NULL},
1792 {NULL, MAX_PATH, output, &filepart},
1793 {"", 0, NULL, NULL},
1794 {"", MAX_PATH, NULL, NULL},
1795 {"", MAX_PATH, output, NULL},
1796 {"", MAX_PATH, output, &filepart},
1799 for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
1801 SetLastError(0xdeadbeef);
1802 strcpy(output, "deadbeef");
1803 filepart = (char *)0xdeadbeef;
1804 ret = GetFullPathNameA(invalid_parameters[i].name,
1805 invalid_parameters[i].len,
1806 invalid_parameters[i].buffer,
1807 invalid_parameters[i].lastpart);
1808 ok(!ret, "[%d] Expected GetFullPathNameA to return 0, got %u\n", i, ret);
1809 ok(!strcmp(output, "deadbeef"), "[%d] Expected the output buffer to be unchanged, got \"%s\"\n", i, output);
1810 ok(filepart == (char *)0xdeadbeef, "[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
1811 ok(GetLastError() == 0xdeadbeef ||
1812 GetLastError() == ERROR_INVALID_NAME, /* Win7 */
1813 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
1814 i, GetLastError());
1818 static void test_GetFullPathNameW(void)
1820 static const WCHAR emptyW[] = {0};
1821 static const WCHAR deadbeefW[] = {'d','e','a','d','b','e','e','f',0};
1823 WCHAR output[MAX_PATH], *filepart;
1824 DWORD ret;
1825 int i;
1827 const struct
1829 LPCWSTR name;
1830 DWORD len;
1831 LPWSTR buffer;
1832 LPWSTR *lastpart;
1833 int win7_expect;
1834 } invalid_parameters[] =
1836 {NULL, 0, NULL, NULL},
1837 {NULL, 0, NULL, &filepart, 1},
1838 {NULL, MAX_PATH, NULL, NULL},
1839 {NULL, MAX_PATH, output, NULL},
1840 {NULL, MAX_PATH, output, &filepart, 1},
1841 {emptyW, 0, NULL, NULL},
1842 {emptyW, 0, NULL, &filepart, 1},
1843 {emptyW, MAX_PATH, NULL, NULL},
1844 {emptyW, MAX_PATH, output, NULL},
1845 {emptyW, MAX_PATH, output, &filepart, 1},
1848 SetLastError(0xdeadbeef);
1849 ret = GetFullPathNameW(NULL, 0, NULL, NULL);
1850 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1852 win_skip("GetFullPathNameW is not available\n");
1853 return;
1856 for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
1858 SetLastError(0xdeadbeef);
1859 lstrcpyW(output, deadbeefW);
1860 filepart = (WCHAR *)0xdeadbeef;
1861 ret = GetFullPathNameW(invalid_parameters[i].name,
1862 invalid_parameters[i].len,
1863 invalid_parameters[i].buffer,
1864 invalid_parameters[i].lastpart);
1865 ok(!ret, "[%d] Expected GetFullPathNameW to return 0, got %u\n", i, ret);
1866 ok(!lstrcmpW(output, deadbeefW), "[%d] Expected the output buffer to be unchanged, got %s\n", i, wine_dbgstr_w(output));
1867 ok(filepart == (WCHAR *)0xdeadbeef ||
1868 (invalid_parameters[i].win7_expect && filepart == NULL),
1869 "[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
1870 ok(GetLastError() == 0xdeadbeef ||
1871 GetLastError() == ERROR_INVALID_NAME, /* Win7 */
1872 "[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
1873 i, GetLastError());
1877 static void init_pointers(void)
1879 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
1881 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hKernel32, #f))
1882 MAKEFUNC(GetLongPathNameA);
1883 MAKEFUNC(GetLongPathNameW);
1884 MAKEFUNC(NeedCurrentDirectoryForExePathA);
1885 MAKEFUNC(NeedCurrentDirectoryForExePathW);
1886 MAKEFUNC(SearchPathA);
1887 MAKEFUNC(SearchPathW);
1888 MAKEFUNC(ActivateActCtx);
1889 MAKEFUNC(CreateActCtxW);
1890 MAKEFUNC(DeactivateActCtx);
1891 MAKEFUNC(GetCurrentActCtx);
1892 MAKEFUNC(ReleaseActCtx);
1893 #undef MAKEFUNC
1896 START_TEST(path)
1898 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
1900 init_pointers();
1902 /* Report only once */
1903 if (!pGetLongPathNameA)
1904 win_skip("GetLongPathNameA is not available\n");
1905 if (!pGetLongPathNameW)
1906 win_skip("GetLongPathNameW is not available\n");
1907 if (!pActivateActCtx)
1908 win_skip("Activation contexts not supported, some tests will be skipped\n");
1910 test_InitPathA(curdir, &curDrive, &otherDrive);
1911 test_CurrentDirectoryA(origdir,curdir);
1912 test_PathNameA(curdir, curDrive, otherDrive);
1913 test_CleanupPathA(origdir,curdir);
1914 test_GetTempPath();
1915 test_GetLongPathNameA();
1916 test_GetLongPathNameW();
1917 test_GetShortPathNameW();
1918 test_GetSystemDirectory();
1919 test_GetWindowsDirectory();
1920 test_NeedCurrentDirectoryForExePathA();
1921 test_NeedCurrentDirectoryForExePathW();
1922 test_drive_letter_case();
1923 test_SearchPathA();
1924 test_SearchPathW();
1925 test_GetFullPathNameA();
1926 test_GetFullPathNameW();