ReactOS 0.4.16-dev-2206-gc56950d
path.c
Go to the documentation of this file.
1/*
2 * Unit test suite for various Path and Directory Functions
3 *
4 * Copyright 2002 Geoffrey Hausheer
5 * Copyright 2006 Detlef Riekenberg
6 *
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.
11 *
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.
16 *
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
20 */
21
22#include <stdarg.h>
23#include <stdio.h>
24#include <assert.h>
25#include "ntstatus.h"
26#define WIN32_NO_STATUS
27#include "windef.h"
28#include "winbase.h"
29#include "winternl.h"
30#include "winuser.h"
31#include "winerror.h"
32#include "winnls.h"
33#include "wine/test.h"
34
35#define HAS_TRAIL_SLASH_A(string) (string[lstrlenA(string)-1]=='\\')
36
37#define LONGFILE "Long File test.path"
38#define SHORTFILE "pathtest.pth"
39#define SHORTDIR "shortdir"
40#define LONGDIR "Long Directory"
41#define NONFILE_SHORT "noexist.pth"
42#define NONFILE_LONG "NonExistent File"
43#define NONDIR_SHORT "notadir"
44#define NONDIR_LONG "NonExistent Directory"
45
46#define NOT_A_VALID_DRIVE '@'
47
48#ifdef __i386__
49#define ARCH "x86"
50#elif defined __aarch64__ || defined__arm64ec__
51#define ARCH "arm64"
52#elif defined __x86_64__
53#define ARCH "amd64"
54#elif defined __arm__
55#define ARCH "arm"
56#else
57#define ARCH "none"
58#endif
59
60/* the following characters don't work well with GetFullPathNameA
61 in Win98. I don't know if this is a FAT thing, or if it is an OS thing
62 but I don't test these characters now.
63 NOTE: Win2k allows GetFullPathNameA to work with them though
64 |<>"
65*/
66static const CHAR funny_chars[]="!@#$%^&*()=+{}[],?'`";
67static const CHAR is_char_ok[] ="11111110111111111011";
68
69/* Present in Win2003+ */
70static BOOL (WINAPI *pNeedCurrentDirectoryForExePathA)(LPCSTR);
71static BOOL (WINAPI *pNeedCurrentDirectoryForExePathW)(LPCWSTR);
72
73static DLL_DIRECTORY_COOKIE (WINAPI *pAddDllDirectory)(const WCHAR*);
74static BOOL (WINAPI *pRemoveDllDirectory)(DLL_DIRECTORY_COOKIE);
75static BOOL (WINAPI *pSetSearchPathMode)(DWORD);
76static BOOL (WINAPI *pSetDllDirectoryW)(LPCWSTR);
77static BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD);
78static NTSTATUS (WINAPI *pRtlGetExePath)(LPCWSTR,LPWSTR*);
79static NTSTATUS (WINAPI *pRtlGetSearchPath)(LPWSTR*);
80static void (WINAPI *pRtlReleasePath)(LPWSTR);
81static NTSTATUS (WINAPI *pLdrGetDllPath)(LPCWSTR,ULONG,LPWSTR*,LPWSTR*);
82
83static BOOL (WINAPI *pCheckNameLegalDOS8Dot3W)(const WCHAR *, char *, DWORD, BOOL *, BOOL *);
84static BOOL (WINAPI *pCheckNameLegalDOS8Dot3A)(const char *, char *, DWORD, BOOL *, BOOL *);
85
86/* a structure to deal with wine todos somewhat cleanly */
87typedef struct {
95
96/* function that tests GetFullPathNameA, GetShortPathNameA,GetLongPathNameA */
97/* NOTE: the passfail structure is used to allow customizable todo checking
98 for wine. It is not very pretty, but it sure beats duplicating this
99 function lots of times
100*/
101static void test_ValidPathA(const CHAR *curdir, const CHAR *subdir, const CHAR *filename,
102 CHAR *shortstr, SLpassfail *passfail, const CHAR *errstr)
103{
104 CHAR tmpstr[MAX_PATH],
105 fullpath[MAX_PATH + 1], /*full path to the file (not short/long) */
106 subpath[MAX_PATH], /*relative path to the file */
107 fullpathshort[2 * MAX_PATH], /*absolute path to the file (short format) */
108 fullpathlong[2 * MAX_PATH], /*absolute path to the file (long format) */
109 curdirshort[MAX_PATH], /*absolute path to the current dir (short) */
110 curdirlong[MAX_PATH]; /*absolute path to the current dir (long) */
111 LPSTR strptr; /*ptr to the filename portion of the path */
112 DWORD len;
113/* if passfail is NULL, we can perform all checks within this function,
114 otherwise, we will return the relevant data in the passfail struct, so
115 we must initialize it first
116*/
117 if(passfail!=NULL) {
118 passfail->shortlen=-1;passfail->s2llen=-1;passfail->longlen=-1;
119 passfail->shorterror=0;passfail->s2lerror=0;passfail->longerror=0;
120 }
121
122 ok((len = GetLongPathNameA(curdir,curdirlong,MAX_PATH)), "%s: GetLongPathNameA failed\n", errstr);
123/*GetLongPathNameA can return a trailing '\\' but shouldn't do so here */
124 ok(!HAS_TRAIL_SLASH_A(curdirlong), "%s: GetLongPathNameA should not have a trailing \\\n", errstr);
125
126 ok((len=GetShortPathNameA(curdir,curdirshort,MAX_PATH)),
127 "%s: GetShortPathNameA failed\n",errstr);
128/*GetShortPathNameA can return a trailing '\\' but shouldn't do so here */
129 ok(! HAS_TRAIL_SLASH_A(curdirshort),
130 "%s: GetShortPathNameA should not have a trailing \\\n",errstr);
131/* build relative and absolute paths from inputs */
132 if(*subdir) {
133 sprintf(subpath,"%s\\%s",subdir,filename);
134 } else {
135 lstrcpyA(subpath,filename);
136 }
137 sprintf(fullpath,"%s\\%s",curdir,subpath);
138 sprintf(fullpathshort,"%s\\%s",curdirshort,subpath);
139 sprintf(fullpathlong,"%s\\%s",curdirlong,subpath);
140/* Test GetFullPathNameA functionality */
141 len=GetFullPathNameA(subpath,MAX_PATH,tmpstr,&strptr);
142 ok(len, "GetFullPathNameA failed for: '%s'\n",subpath);
143 if(HAS_TRAIL_SLASH_A(subpath)) {
144 ok(strptr==NULL,
145 "%s: GetFullPathNameA should not return a filename ptr\n",errstr);
146 ok(lstrcmpiA(fullpath,tmpstr)==0,
147 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
148 errstr,tmpstr,fullpath);
149 } else {
150 ok(lstrcmpiA(strptr,filename)==0,
151 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
152 errstr,strptr,filename);
153 ok(lstrcmpiA(fullpath,tmpstr)==0,
154 "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
155 errstr,tmpstr,fullpath);
156 }
157/* Test GetShortPathNameA functionality */
158 SetLastError(0);
159 len=GetShortPathNameA(fullpathshort,shortstr,MAX_PATH);
160 if(passfail==NULL) {
161 ok(len, "%s: GetShortPathNameA failed\n",errstr);
162 } else {
163 passfail->shortlen=len;
164 passfail->shorterror=GetLastError();
165 }
166
167 /* Test GetLongPathNameA functionality, both conversion from GetFullPathNameA and from GetShortPathNameA */
168 if (len)
169 {
170 SetLastError(0);
171 len = GetLongPathNameA(shortstr, tmpstr, MAX_PATH);
172 if (!passfail)
173 {
174 ok(len, "%s: GetLongPathNameA failed during Short->Long conversion\n", errstr);
175 ok(!lstrcmpiA(fullpathlong, tmpstr), "%s: GetLongPathNameA returned '%s' instead of '%s'\n", errstr,
176 tmpstr, fullpathlong);
177 }
178 else
179 {
180 passfail->s2llen = len;
181 passfail->s2lerror = GetLastError();
182 }
183 }
184
185 SetLastError(0);
186 len = GetLongPathNameA(fullpath, tmpstr, MAX_PATH);
187 if (!passfail)
188 {
189 ok(len, "%s: GetLongPathNameA failed\n",errstr);
190 ok(!lstrcmpiA(fullpathlong, tmpstr), "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
191 errstr, tmpstr, fullpathlong);
192 }
193 else
194 {
195 passfail->longlen = len;
196 passfail->longerror = GetLastError();
197 }
198}
199
200/* split path into leading directory, and 8.3 filename */
201static void test_SplitShortPathA(CHAR *path,CHAR *dir,CHAR *eight,CHAR *three) {
202 BOOL done = FALSE, error = FALSE;
203 int ext,fil;
204 int len,i;
206 ext=len;
207 fil=len;
208/* walk backwards over path looking for '.' or '\\' separators */
209 for(i=len-1;(i>=0) && (!done);i--) {
210 if(path[i]=='.')
211 if(ext!=len) error=TRUE; else ext=i;
212 else if(path[i]=='\\') {
213 if(i==len-1) {
214 error=TRUE;
215 } else {
216 fil=i;
217 done=TRUE;
218 }
219 }
220 }
221/* Check that we didn't find a trailing '\\' or multiple '.' */
222 ok(!error,"Illegal file found in 8.3 path '%s'\n",path);
223/* Separate dir, root, and extension */
224 if(ext!=len) lstrcpyA(three,path+ext+1); else lstrcpyA(three,"");
225 if(fil!=len) {
226 lstrcpynA(eight,path+fil+1,ext-fil);
227 lstrcpynA(dir,path,fil+1);
228 } else {
229 lstrcpynA(eight,path,ext+1);
230 lstrcpyA(dir,"");
231 }
232/* Validate that root and extension really are 8.3 */
233 ok(lstrlenA(eight)<=8 && lstrlenA(three)<=3,
234 "GetShortPathNAmeA did not return an 8.3 path\n");
235}
236
237/* Check that GetShortPathNameA returns a valid 8.3 path */
238static void test_LongtoShortA(CHAR *teststr,const CHAR *goodstr,
239 const CHAR *ext,const CHAR *errstr) {
240 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
241
242 test_SplitShortPathA(teststr,dir,eight,three);
243 ok(lstrcmpiA(dir,goodstr)==0,
244 "GetShortPathNameA returned '%s' instead of '%s'\n",dir,goodstr);
245 ok(lstrcmpiA(three,ext)==0,
246 "GetShortPathNameA returned '%s' with incorrect extension\n",three);
247}
248
249/* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
250 characters in the filename.
251 'valid' indicates whether this would be an allowed filename
252 'todo' indicates that wine doesn't get this right yet.
253 NOTE: We always call this routine with a nonexistent filename, so
254 Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
255 should.
256*/
257static void test_FunnyChars(CHAR *curdir,CHAR *curdir_short,CHAR *filename, INT valid,CHAR *errstr)
258{
259 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
260 SLpassfail passfail;
261
262 test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
263 if(valid) {
264 sprintf(tmpstr1,"%s\\%s",curdir_short,filename);
265 ok((passfail.shortlen==0 &&
266 (passfail.shorterror==ERROR_FILE_NOT_FOUND || passfail.shorterror==ERROR_PATH_NOT_FOUND || !passfail.shorterror)) ||
267 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
268 "%s: GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
269 errstr,passfail.shortlen,passfail.shorterror,tmpstr);
270 } else {
271 ok(passfail.shortlen==0 &&
272 (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),
273 "%s: GetShortPathA should have failed len=%ld, error=%ld\n",
274 errstr,passfail.shortlen,passfail.shorterror);
275 }
276
277 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
278 if (valid)
279 {
280 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "%s: GetLongPathA unexpected error %ld.\n", errstr,
281 passfail.longerror);
282 }
283 else
284 {
286 "%s: GetLongPathA unexpected error %ld.\n", errstr, passfail.longerror);
287 }
288}
289
290/* Routine to test that SetCurrentDirectory behaves as expected. */
291static void test_setdir(CHAR *olddir,CHAR *newdir,
292 CHAR *cmprstr, INT pass, const CHAR *errstr)
293{
294 CHAR tmppath[MAX_PATH], *dirptr;
295 DWORD val,len,chklen;
296
299/* if 'pass' then the SetDirectoryA was supposed to pass */
300 if(pass) {
301 dirptr=(cmprstr==NULL) ? newdir : cmprstr;
302 chklen=lstrlenA(dirptr);
303 ok(val,"%s: SetCurrentDirectoryA failed\n",errstr);
304 ok(len==chklen,
305 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
306 errstr);
307 ok(lstrcmpiA(dirptr,tmppath)==0,
308 "%s: SetCurrentDirectory did not change the directory, though it passed\n",
309 errstr);
310 ok(SetCurrentDirectoryA(olddir),
311 "%s: Couldn't set directory to its original value\n",errstr);
312 } else {
313/* else test that it fails correctly */
314 chklen=lstrlenA(olddir);
315 ok(val==0,
316 "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr);
317 ok(len==chklen,
318 "%s: SetCurrentDirectory changed the directory, though it failed\n",
319 errstr);
320 ok(lstrcmpiA(olddir,tmppath)==0,
321 "%s: SetCurrentDirectory changed the directory, though it failed\n",
322 errstr);
323 }
324}
325static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
326{
327 CHAR tmppath[MAX_PATH], /*path to TEMP */
328 tmpstr[MAX_PATH],
329 tmpstr1[MAX_PATH],
330 invalid_dir[MAX_PATH + 29];
331
332 DWORD len,len1,drives;
333 INT id;
334 HANDLE hndl;
335 BOOL bRes;
336 UINT unique;
337
338 *curDrive = *otherDrive = NOT_A_VALID_DRIVE;
339
340/* Get the current drive letter */
341 if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
342 *curDrive = tmpstr[0];
343 else
344 trace( "Unable to discover current drive, some tests will not be conducted.\n");
345
346/* Test GetTempPathA */
347 len=GetTempPathA(MAX_PATH,tmppath);
348 ok(len!=0 && len < MAX_PATH,"GetTempPathA failed\n");
349 ok(HAS_TRAIL_SLASH_A(tmppath),
350 "GetTempPathA returned a path that did not end in '\\'\n");
351 lstrcpyA(tmpstr,"aaaaaaaa");
352 len1=GetTempPathA(len,tmpstr);
353 ok(len1==len+1,"GetTempPathA should return string length %ld instead of %ld\n",len+1,len1);
354
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");
364
365 id=GetTempFileNameA(tmppath,NULL,0,newdir);
366 sprintf(tmpstr,"%.4x.tmp",id & 0xffff);
367 sprintf(tmpstr1,"%x.tmp",id & 0xffff);
368 ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
369 lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
370 "GetTempFileNameA returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
371 newdir,tmpstr,tmpstr1,id);
372 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
373
374 for(unique=0;unique<3;unique++) {
375 /* Nonexistent path */
376 sprintf(invalid_dir, "%s\\%s",tmppath,"non_existent_dir_1jwj3y32nb3");
377 SetLastError(0xdeadbeef);
378 ok(!GetTempFileNameA(invalid_dir,"tfn",unique,newdir),"GetTempFileNameA should have failed\n");
379 ok(GetLastError()==ERROR_DIRECTORY,"got %lu, expected ERROR_DIRECTORY\n", GetLastError());
380
381 /* Check return value for unique !=0 */
382 if(unique) {
383 ok((GetTempFileNameA(tmppath,"tfn",unique,newdir) == unique),"GetTempFileNameA unexpectedly failed\n");
384 /* if unique != 0, the actual temp files are not created: */
385 ok(!DeleteFileA(newdir) && GetLastError() == ERROR_FILE_NOT_FOUND,"Deleted a file that shouldn't exist!\n");
386 }
387 }
388
389/* Find first valid drive letter that is neither newdir[0] nor curDrive */
390 drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
391 if( *curDrive != NOT_A_VALID_DRIVE)
392 drives &= ~(1<<(*curDrive-'A'));
393 if( drives)
394 for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
395 else
396 trace( "Could not find alternative drive, some tests will not be conducted.\n");
397
398/* Do some CreateDirectoryA tests */
399/* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
400 really understand how they work.
401 More formal tests should be done along with CreateFile tests
402*/
403 ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
404 ok(CreateDirectoryA(newdir,NULL)==0,
405 "CreateDirectoryA succeeded even though a file of the same name exists\n");
406 ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
407 ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
408/* Create some files to test other functions. Note, we will test CreateFileA
409 at some later point
410*/
411 sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
412 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
413 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
414 ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
415 sprintf(tmpstr,"%c:", *curDrive);
416 bRes = CreateDirectoryA(tmpstr,NULL);
417 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
419 "CreateDirectoryA(\"%s\" should have failed (%ld)\n", tmpstr, GetLastError());
420 sprintf(tmpstr,"%c:\\", *curDrive);
421 bRes = CreateDirectoryA(tmpstr,NULL);
422 ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED ||
424 "CreateDirectoryA(\"%s\" should have failed (%ld)\n", tmpstr, GetLastError());
425 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
426 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
428 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
429 ok(CloseHandle(hndl),"CloseHandle failed\n");
430 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
431 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
433 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
434 ok(CloseHandle(hndl),"CloseHandle failed\n");
435 sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
436 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,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,LONGFILE);
441 hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
443 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
444 ok(CloseHandle(hndl),"CloseHandle failed\n");
445}
446
447/* Test GetCurrentDirectory & SetCurrentDirectory */
448static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
449{
450 CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
451 char *buffer;
452 DWORD len,len1;
453/* Save the original directory, so that we can return to it at the end
454 of the test
455*/
457 ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
458/* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
459 buffer size is too small to hold the current directory
460*/
461 lstrcpyA(tmpstr,"aaaaaaa");
462 len1=GetCurrentDirectoryA(len,tmpstr);
463 ok(len1==len+1, "GetCurrentDirectoryA returned %ld instead of %ld\n",len1,len+1);
464 ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
465 "GetCurrentDirectoryA should not have modified the buffer\n");
466
467 buffer = HeapAlloc( GetProcessHeap(), 0, 2 * 65536 );
468 SetLastError( 0xdeadbeef );
469 strcpy( buffer, "foo" );
470 len = GetCurrentDirectoryA( 32767, buffer );
471 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %lu err %lu\n", len, GetLastError() );
472 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
473 SetLastError( 0xdeadbeef );
474 strcpy( buffer, "foo" );
475 len = GetCurrentDirectoryA( 32768, buffer );
476 ok( len != 0 && len < MAX_PATH, "GetCurrentDirectoryA failed %lu err %lu\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( 65535, buffer );
481 ok( (len != 0 && len < MAX_PATH) || broken(!len), /* nt4, win2k, xp */ "GetCurrentDirectoryA failed %lu err %lu\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( 65536, buffer );
486 ok( (len != 0 && len < MAX_PATH), "GetCurrentDirectoryA failed %lu err %lu\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( 2 * 65536, buffer );
491 ok( (len != 0 && len < MAX_PATH), "GetCurrentDirectoryA failed %lu err %lu\n", len, GetLastError() );
492 if (len) ok( !strcmp( buffer, origdir ), "wrong result %s\n", buffer );
494
495/* Check for crash prevention on swapped args. Crashes all but Win9x.
496*/
497 if (0)
498 {
499 GetCurrentDirectoryA( 42, (LPSTR)(MAX_PATH + 42) );
500 }
501
502/* SetCurrentDirectoryA shouldn't care whether the string has a
503 trailing '\\' or not
504*/
505 sprintf(tmpstr,"%s\\",newdir);
506 test_setdir(origdir,tmpstr,newdir,1,"check 1");
507 test_setdir(origdir,newdir,NULL,1,"check 2");
508/* Set the directory to the working area. We just tested that this works,
509 so why check it again.
510*/
511 SetCurrentDirectoryA(newdir);
512/* Check that SetCurrentDirectory fails when a nonexistent dir is specified */
513 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
514 test_setdir(newdir,tmpstr,NULL,0,"check 3");
515/* Check that SetCurrentDirectory fails for a nonexistent long directory */
516 sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
517 test_setdir(newdir,tmpstr,NULL,0,"check 4");
518/* Check that SetCurrentDirectory passes with a long directory */
519 sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
520 test_setdir(newdir,tmpstr,NULL,1,"check 5");
521/* Check that SetCurrentDirectory passes with a short relative directory */
522 sprintf(tmpstr,"%s",SHORTDIR);
523 sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
524 test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
525/* starting with a '.' */
526 sprintf(tmpstr,".\\%s",SHORTDIR);
527 test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
528/* Check that SetCurrentDirectory passes with a short relative directory */
529 sprintf(tmpstr,"%s",LONGDIR);
530 sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
531 test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
532/* starting with a '.' */
533 sprintf(tmpstr,".\\%s",LONGDIR);
534 test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
535/* change to root without a trailing backslash. The function call succeeds
536 but the directory is not changed.
537*/
538 sprintf(tmpstr, "%c:", newdir[0]);
539 test_setdir(newdir,tmpstr,newdir,1,"check 10");
540/* works however with a trailing backslash */
541 sprintf(tmpstr, "%c:\\", newdir[0]);
542 test_setdir(newdir,tmpstr,NULL,1,"check 11");
543}
544
545/* Cleanup the mess we made while executing these tests */
546static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
547{
548 CHAR tmpstr[MAX_PATH + 35];
549 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
550 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
551 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
552 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
553 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
554 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
555 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
556 ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
557 sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
558 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
559 sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
560 ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
561 ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
562 ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
563}
564
565/* test that short path name functions work regardless of case */
566static void test_ShortPathCase(const char *tmpdir, const char *dirname,
567 const char *filename)
568{
569 char buf[MAX_PATH], shortbuf[MAX_PATH];
570 HANDLE hndl;
571 size_t i;
572
573 assert(strlen(tmpdir) + strlen(dirname) + strlen(filename) + 2 < sizeof(buf));
574 sprintf(buf,"%s\\%s\\%s",tmpdir,dirname,filename);
575 GetShortPathNameA(buf,shortbuf,sizeof(shortbuf));
577 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed (%ld)\n",GetLastError());
578 CloseHandle(hndl);
579 /* Now for the real test */
580 for(i=0;i<strlen(shortbuf);i++)
581 if (i % 2)
582 shortbuf[i] = tolower(shortbuf[i]);
584 ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed (%ld)\n",GetLastError());
585 CloseHandle(hndl);
586}
587
588/* This routine will test Get(Full|Short|Long)PathNameA */
589static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
590{
591 CHAR curdir_short[MAX_PATH],
592 longdir_short[MAX_PATH];
593 CHAR tmpstr[MAX_PATH + 15],tmpstr1[MAX_PATH + 22],tmpstr2[2 * MAX_PATH + 15];
594 LPSTR strptr; /*ptr to the filename portion of the path */
595 DWORD len;
596 INT i;
597 CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
598 SLpassfail passfail;
599 DWORD rc1, rc2;
600
601/* Get the short form of the current directory */
602 ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
603 "GetShortPathNameA failed\n");
604 ok(!HAS_TRAIL_SLASH_A(curdir_short),
605 "GetShortPathNameA should not have a trailing \\\n");
606/* Get the short form of the absolute-path to LONGDIR */
607 sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
608 ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
609 "GetShortPathNameA failed\n");
610 ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
611 "GetShortPathNameA should not have a trailing \\\n");
612
613 sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
614 rc1 = GetLongPathNameA(tmpstr, NULL, 0);
615 rc2 = GetLongPathNameA(curdir, NULL, 0);
616 ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
617 "GetLongPathNameA: wrong return code, %ld instead of %d\n",
618 rc1, lstrlenA(tmpstr)+1);
619
620 sprintf(dir,"%c:",curDrive);
621 rc1= GetLongPathNameA(dir, tmpstr, sizeof(tmpstr));
622 ok(!strcmp(dir,tmpstr), "GetLongPathNameA: returned '%s' instead of '%s' (rc=%ld)\n",
623 tmpstr, dir, rc1);
624
625/* Check the cases where both file and directory exist first */
626/* Start with a 8.3 directory, 8.3 filename */
627 test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
628 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
629 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
630 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
631/* Now try a 8.3 directory, long file name */
632 test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
633 sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
634 test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
635/* Next is a long directory, 8.3 file */
636 test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
637 sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
638 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
639 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
640/*Lastly a long directory, long file */
641 test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
642 test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
643
644/* Now check all of the invalid file w/ valid directory combinations */
645/* Start with a 8.3 directory, 8.3 filename */
646 test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
647 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
648 ok((passfail.shortlen==0 &&
649 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
650 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
651 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
652 "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
653 passfail.shortlen,passfail.shorterror,tmpstr);
654
655 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
656 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "Unexpected error %ld.\n", passfail.longerror);
657
658/* Now try a 8.3 directory, long file name */
659 test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
660 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
663 !passfail.shorterror,
664 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
665 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
666 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "Unexpected error %ld.\n", passfail.longerror);
667
668/* Next is a long directory, 8.3 file */
669 test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
670 sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
671 GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
672 strcat(tmpstr1,"\\" NONFILE_SHORT);
673 ok((passfail.shortlen==0 &&
674 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
675 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
676 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
677 "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
678 passfail.shortlen,passfail.shorterror,tmpstr);
679 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
680 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "Unexpected error %ld.\n", passfail.longerror);
681
682/*Lastly a long directory, long file */
683 test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
684 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
687 !passfail.shorterror,
688 "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
689 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
690 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "Unexpected error %ld.\n", passfail.longerror);
691
692/* Now try again with directories that don't exist */
693/* 8.3 directory, 8.3 filename */
694 test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
695 sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
696 ok((passfail.shortlen==0 &&
697 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
698 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
699 (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
700 "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
701 passfail.shortlen,passfail.shorterror,tmpstr);
702 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
704 "Unexpected error %ld.\n", passfail.longerror);
705
706/* Now try a 8.3 directory, long file name */
707 test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
708 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
711 !passfail.shorterror,
712 "GetShortPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
713 passfail.shorterror);
714 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
716 "Unexpected error %ld.\n", passfail.longerror);
717
718/* Next is a long directory, 8.3 file */
719 test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
720 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
723 !passfail.shorterror,
724 "GetShortPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
725 passfail.shorterror);
726 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
728 "Unexpected error %ld.\n", passfail.longerror);
729
730/*Lastly a long directory, long file */
731 test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
732 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
735 !passfail.shorterror,
736 "GetShortPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
737 passfail.shorterror);
738 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
740 "Unexpected error %ld.\n", passfail.longerror);
741
742/* Next try directories ending with '\\' */
743/* Existing Directories */
744 sprintf(tmpstr,"%s\\",SHORTDIR);
745 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
746 sprintf(tmpstr,"%s\\",LONGDIR);
747 test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
748/* Nonexistent directories */
749 sprintf(tmpstr,"%s\\",NONDIR_SHORT);
750 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
751 sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
752 ok((passfail.shortlen==0 &&
753 (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
754 passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
755 (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
756 "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
757 passfail.shortlen,passfail.shorterror,tmpstr);
758 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
759 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "Unexpected error %ld.\n", passfail.longerror);
760
761 sprintf(tmpstr,"%s\\",NONDIR_LONG);
762 test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
763 ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
766 !passfail.shorterror,
767 "GetShortPathA returned %ld and not 'ERROR_FILE_NOT_FOUND'\n",
768 passfail.shorterror);
769 ok(!passfail.longlen, "GetLongPathNameA passed when it shouldn't have\n");
770 ok(passfail.longerror == ERROR_FILE_NOT_FOUND, "Unexpected error %ld.\n", passfail.longerror);
771
772/* Test GetFullPathNameA with drive letters */
773 if( curDrive != NOT_A_VALID_DRIVE) {
774 sprintf(tmpstr,"%c:",curdir[0]);
775 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
776 "GetFullPathNameA(%c:) failed\n", curdir[0]);
778 sprintf(tmpstr1,"%s\\",tmpstr);
779 ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
780 "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
781 curdir[0],tmpstr2,tmpstr,tmpstr1);
782
783 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
784 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
785 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
786 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
787 ok(lstrcmpiA(SHORTFILE,strptr)==0,
788 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
789 }
790/* Without a leading slash, insert the current directory if on the current drive */
791 sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
792 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
793 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
794 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
795 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
796 ok(lstrcmpiA(SHORTFILE,strptr)==0,
797 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
798/* Otherwise insert the missing leading slash */
799 if( otherDrive != NOT_A_VALID_DRIVE) {
800 /* FIXME: this test assumes that current directory on other drive is root */
801 sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
802 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
803 sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
804 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
805 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
806 ok(lstrcmpiA(SHORTFILE,strptr)==0,
807 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
808 }
809/* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
810 So test for them. */
811 if( curDrive != NOT_A_VALID_DRIVE) {
812 sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
813 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
814 sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
815 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
816 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
817 ok(lstrcmpiA(SHORTFILE,strptr)==0,
818 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
819 }
820 /* Don't Starve relies on GetLongPathName returning the passed in filename,
821 even if the actual file on disk has a different case or separator */
822 len = lstrlenA(LONGDIR) + 1;
823 sprintf(tmpstr,"%s/%s",LONGDIR,LONGFILE);
824 ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
825 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
826 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
827 tmpstr[len] = tolower(tmpstr[len]);
828 ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
829 ok(lstrcmpA(tmpstr,tmpstr1)==0,
830 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
831 sprintf(tmpstr,"%s/%s",SHORTDIR,SHORTFILE);
832 ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
833 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
834 "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
835 len = lstrlenA(SHORTDIR) + 1;
836 tmpstr[len] = toupper(tmpstr[len]);
837 ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
838 ok(lstrcmpiA(tmpstr,tmpstr1)==0 && lstrcmpA(tmpstr,tmpstr1) != 0,
839 "GetLongPathNameA returned '%s' instead of '%s/%s'\n",tmpstr1,SHORTDIR,SHORTFILE);
840
841 sprintf(tmpstr,"%s/%s",SHORTDIR,SHORTFILE);
842 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
843 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
844 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
845
846
847 sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
848 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
849 sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
850 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
851 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
852 ok(lstrcmpiA(SHORTFILE,strptr)==0,
853 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
854/* Windows will insert a drive letter in front of an absolute UNIX path */
855 sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
856 ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
857 sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
858 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
859 "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
860/* This passes in Wine because it still contains the pointer from the previous test */
861 ok(lstrcmpiA(SHORTFILE,strptr)==0,
862 "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
863
864/* Now try some relative paths */
865 ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
866 test_SplitShortPathA(tmpstr,dir,eight,three);
867 ok(GetLongPathNameA(tmpstr, tmpstr1, MAX_PATH), "GetLongPathNameA failed\n");
868 ok(!lstrcmpiA(tmpstr1, LONGDIR), "GetLongPathNameA returned '%s' instead of '%s'\n", tmpstr1, LONGDIR);
869
870 sprintf(tmpstr,".\\%s",LONGDIR);
871 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
872 test_SplitShortPathA(tmpstr1,dir,eight,three);
873 ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
874 "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
875 ok(GetLongPathNameA(tmpstr1, tmpstr1, MAX_PATH), "GetLongPathNameA failed %s\n", tmpstr);
876 ok(!lstrcmpiA(tmpstr1, tmpstr), "GetLongPathNameA returned '%s' instead of '%s'\n", tmpstr1, tmpstr);
877
878/* Check out Get*PathNameA on some funny characters */
879 for(i=0;i<lstrlenA(funny_chars);i++) {
880 INT valid;
881 valid=(is_char_ok[i]=='0') ? 0 : 1;
882 sprintf(tmpstr1,"check%d-1",i);
883 sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
884 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
885 sprintf(tmpstr1,"check%d-2",i);
886 sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
887 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
888 sprintf(tmpstr1,"check%d-3",i);
889 sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
890 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
891 sprintf(tmpstr1,"check%d-4",i);
892 sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
893 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
894 sprintf(tmpstr1,"check%d-5",i);
895 sprintf(tmpstr,"Long %c File",funny_chars[i]);
896 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
897 sprintf(tmpstr1,"check%d-6",i);
898 sprintf(tmpstr,"%c Long File",funny_chars[i]);
899 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
900 sprintf(tmpstr1,"check%d-7",i);
901 sprintf(tmpstr,"Long File %c",funny_chars[i]);
902 test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
903 }
904 /* Now try it on mixed case short names */
908
909 /* test double delimiters */
910 sprintf(tmpstr,"%s\\\\%s", SHORTDIR,SHORTFILE);
911 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
912 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
913 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
914 sprintf(tmpstr,".\\\\%s\\\\%s", SHORTDIR,SHORTFILE);
915 ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
916 ok(lstrcmpiA(tmpstr,tmpstr1)==0,
917 "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
918
919 sprintf(tmpstr,"%s\\\\%s",LONGDIR,LONGFILE);
920 ok(GetLongPathNameA(tmpstr, tmpstr1, MAX_PATH), "GetLongPathNameA failed\n");
921 ok(!lstrcmpiA(tmpstr,tmpstr1), "GetLongPathNameA returned '%s' instead of '%s'\n", tmpstr1, tmpstr);
922
923 sprintf(tmpstr,".\\\\%s\\\\%s",LONGDIR,LONGFILE);
924 ok(GetLongPathNameA(tmpstr, tmpstr1, MAX_PATH), "GetLongPathNameA failed\n");
925 ok(!lstrcmpiA(tmpstr,tmpstr1), "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
926}
927
928static void test_GetTempPathA(char* tmp_dir)
929{
930 DWORD len, slen, len_with_null;
931 char buf[MAX_PATH];
932
933 len_with_null = strlen(tmp_dir) + 1;
934
935 lstrcpyA(buf, "foo");
937 ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
938 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
939 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
940
941 /* Some versions of Windows touch the buffer, some don't so we don't
942 * test that. Also, NT sometimes exaggerates the required buffer size
943 * so we cannot test for an exact match. Finally, the
944 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
945 * For instance in some cases Win98 returns len_with_null - 1 instead
946 * of len_with_null.
947 */
948 len = GetTempPathA(1, buf);
949 ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
950
951 len = GetTempPathA(0, NULL);
952 ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
953
954 /* The call above gave us the buffer size that Windows thinks is needed
955 * so the next call should work
956 */
957 lstrcpyA(buf, "foo");
959 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
960 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
961
962 memset(buf, 'a', sizeof(buf));
963 len = GetTempPathA(sizeof(buf), buf);
964 ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
965 ok(len == strlen(buf), "returned length should be equal to the length of string\n");
966 /* The rest of the buffer remains untouched */
967 slen = len + 1;
968 for(len++; len < sizeof(buf); len++)
969 ok(buf[len] == 'a', "expected 'a' at [%ld], got 0x%x\n", len, buf[len]);
970
971 /* When the buffer is not long enough it remains untouched */
972 memset(buf, 'a', sizeof(buf));
973 len = GetTempPathA(slen / 2, buf);
974 ok(len == slen || broken(len == slen + 1) /* read the big comment above */ ,
975 "expected %ld, got %ld\n", slen, len);
976 for(len = 0; len < ARRAY_SIZE(buf); len++)
977 ok(buf[len] == 'a', "expected 'a' at [%ld], got 0x%x\n", len, buf[len]);
978}
979
980static void test_GetTempPathW(char* tmp_dir)
981{
982 DWORD len, slen, len_with_null;
983 WCHAR buf[MAX_PATH], *long_buf;
984 WCHAR tmp_dirW[MAX_PATH];
985 static const WCHAR fooW[] = {'f','o','o',0};
986
987 MultiByteToWideChar(CP_ACP, 0, tmp_dir, -1, tmp_dirW, ARRAY_SIZE(tmp_dirW));
988 len_with_null = lstrlenW(tmp_dirW) + 1;
989
990 /* This one is different from ANSI version: ANSI version doesn't
991 * touch the buffer, unicode version usually truncates the buffer
992 * to zero size. NT still exaggerates the required buffer size
993 * sometimes so we cannot test for an exact match. Finally, the
994 * 'len_with_null - 1' case is so buggy on Windows it's not testable.
995 * For instance on NT4 it will sometimes return a path without the
996 * trailing '\\' and sometimes return an error.
997 */
998
999 lstrcpyW(buf, fooW);
1001 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
1002 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
1003
1004 lstrcpyW(buf, fooW);
1005 len = GetTempPathW(1, buf);
1006 ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
1007 ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
1008
1009 len = GetTempPathW(0, NULL);
1010 ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
1011
1012 lstrcpyW(buf, fooW);
1013 len = GetTempPathW(len, buf);
1014 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
1015 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
1016
1017 for(len = 0; len < ARRAY_SIZE(buf); len++)
1018 buf[len] = 'a';
1019 len = GetTempPathW(len, buf);
1020 ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
1021 ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
1022 /* The rest of the buffer must be zeroed */
1023 slen = len + 1;
1024 for(len++; len < ARRAY_SIZE(buf); len++)
1025 ok(buf[len] == '\0', "expected NULL at [%ld], got 0x%x\n", len, buf[len]);
1026
1027 /* When the buffer is not long enough the length passed is zeroed */
1028 for(len = 0; len < ARRAY_SIZE(buf); len++)
1029 buf[len] = 'a';
1030 len = GetTempPathW(slen / 2, buf);
1031 ok(len == slen || broken(len == slen + 1) /* read the big comment above */ ,
1032 "expected %ld, got %ld\n", slen, len);
1033
1034 {
1035 /* In Windows 8 when TMP var points to a drive only (like C:) instead of a
1036 * full directory the behavior changes. It will start filling the path but
1037 * will later truncate the buffer before returning. So the generic test
1038 * below will fail for this Windows 8 corner case.
1039 */
1040 char tmp_var[64];
1042 GetEnvironmentVariableA("TMP", tmp_var, sizeof(tmp_var));
1043 if (strlen(tmp_var) == 2 && version >= 0x00060002)
1044 return;
1045 }
1046
1047 for(len = 0; len < slen / 2; len++)
1048 ok(buf[len] == '\0', "expected NULL at [%ld], got 0x%x\n", len, buf[len]);
1049 for(; len < ARRAY_SIZE(buf); len++)
1050 ok(buf[len] == 'a', "expected 'a' at [%ld], got 0x%x\n", len, buf[len]);
1051
1052 /* bogus application from bug 38220 passes the count value in sizeof(buffer)
1053 * instead the correct count of WCHAR, this test catches this case. */
1054 slen = 65534;
1055 long_buf = HeapAlloc(GetProcessHeap(), 0, slen * sizeof(WCHAR));
1056 if (!long_buf)
1057 {
1058 skip("Could not allocate memory for the test\n");
1059 return;
1060 }
1061 for(len = 0; len < slen; len++)
1062 long_buf[len] = 0xCC;
1063 len = GetTempPathW(slen, long_buf);
1064 ok(lstrcmpiW(long_buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
1065 ok(len == lstrlenW(long_buf), "returned length should be equal to the length of string\n");
1066 /* the remaining buffer must be zeroed up to different values in different OS versions.
1067 * <= XP - 32766
1068 * > XP - 32767
1069 * to simplify testing we will test only until XP.
1070 */
1071 for(; len < 32767; len++)
1072 ok(long_buf[len] == '\0', "expected NULL at [%ld], got 0x%x\n", len, long_buf[len]);
1073 /* we will know skip the test that is in the middle of the OS difference by
1074 * incrementing len and then resume the test for the untouched part. */
1075 for(len++; len < slen; len++)
1076 ok(long_buf[len] == 0xcc, "expected 0xcc at [%ld], got 0x%x\n", len, long_buf[len]);
1077
1078 HeapFree(GetProcessHeap(), 0, long_buf);
1079}
1080
1081static void test_GetTempPath(void)
1082{
1083 char save_TMP[MAX_PATH];
1084 char windir[MAX_PATH];
1085 char buf[MAX_PATH];
1086 WCHAR curdir[MAX_PATH];
1087
1088 if (!GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP))) save_TMP[0] = 0;
1089
1090 /* test default configuration */
1091 trace("TMP=%s\n", save_TMP);
1092 if (save_TMP[0])
1093 {
1094 strcpy(buf,save_TMP);
1095 if (buf[strlen(buf)-1]!='\\')
1096 strcat(buf,"\\");
1099 }
1100
1101 /* TMP=C:\WINDOWS */
1102 GetWindowsDirectoryA(windir, sizeof(windir));
1103 SetEnvironmentVariableA("TMP", windir);
1104 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1105 trace("TMP=%s\n", buf);
1106 strcat(windir,"\\");
1107 test_GetTempPathA(windir);
1108 test_GetTempPathW(windir);
1109
1110 /* TMP=C:\ */
1111 GetWindowsDirectoryA(windir, sizeof(windir));
1112 windir[3] = 0;
1113 SetEnvironmentVariableA("TMP", windir);
1114 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1115 trace("TMP=%s\n", buf);
1116 test_GetTempPathA(windir);
1117 test_GetTempPathW(windir);
1118
1120 /* TMP=C: i.e. use current working directory of the specified drive */
1121 GetWindowsDirectoryA(windir, sizeof(windir));
1122 SetCurrentDirectoryA(windir);
1123 windir[2] = 0;
1124 SetEnvironmentVariableA("TMP", windir);
1125 GetEnvironmentVariableA("TMP", buf, sizeof(buf));
1126 trace("TMP=%s\n", buf);
1127 GetWindowsDirectoryA(windir, sizeof(windir));
1128 strcat(windir,"\\");
1129 test_GetTempPathA(windir);
1130 test_GetTempPathW(windir);
1131
1132 SetEnvironmentVariableA("TMP", save_TMP);
1133 SetCurrentDirectoryW(curdir);
1134}
1135
1136static void test_GetLongPathNameA(void)
1137{
1138 DWORD length, explength, hostsize;
1139 char tempfile[MAX_PATH], *name;
1140 char longpath[MAX_PATH];
1141 char unc_prefix[MAX_PATH];
1142 char unc_short[MAX_PATH], unc_long[MAX_PATH];
1143 char temppath[MAX_PATH], temppath2[MAX_PATH];
1144 HANDLE file;
1145
1146 GetTempPathA(MAX_PATH, tempfile);
1147 name = tempfile + strlen(tempfile);
1148
1149 strcpy(name, "*");
1150 SetLastError(0xdeadbeef);
1151 length = GetLongPathNameA(tempfile, temppath, MAX_PATH);
1152 ok(!length, "GetLongPathNameA should fail\n");
1153 ok(GetLastError() == ERROR_INVALID_NAME, "wrong error %ld\n", GetLastError());
1154
1155 strcpy(name, "longfilename.longext");
1156
1159
1160 /* Test a normal path with a small buffer size */
1161 memset(temppath, 0, MAX_PATH);
1162 length = GetLongPathNameA(tempfile, temppath, 4);
1163 /* We have a failure so length should be the minimum plus the terminating '0' */
1164 ok(length >= strlen(tempfile) + 1, "Wrong length\n");
1165 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1166
1167 /* Some UNC syntax tests */
1168
1169 memset(temppath, 0, MAX_PATH);
1170 memset(temppath2, 0, MAX_PATH);
1171 lstrcpyA(temppath2, "\\\\?\\");
1172 lstrcatA(temppath2, tempfile);
1173 explength = length + 4;
1174
1175 SetLastError(0xdeadbeef);
1176 length = GetLongPathNameA(temppath2, NULL, 0);
1177 ok(length == explength, "Wrong length %ld, expected %ld\n", length, explength);
1178
1179 length = GetLongPathNameA(temppath2, NULL, MAX_PATH);
1180 ok(length == explength, "Wrong length %ld, expected %ld\n", length, explength);
1181
1182 length = GetLongPathNameA(temppath2, temppath, 4);
1183 ok(length == explength, "Wrong length %ld, expected %ld\n", length, explength);
1184 ok(temppath[0] == 0, "Buffer should not have been touched\n");
1185
1186 /* Now an UNC path with the computername */
1187 lstrcpyA(unc_prefix, "\\\\");
1188 hostsize = sizeof(unc_prefix) - 2;
1189 GetComputerNameA(unc_prefix + 2, &hostsize);
1190 lstrcatA(unc_prefix, "\\");
1191
1192 /* Create a short syntax for the whole unc path */
1193 memset(unc_short, 0, MAX_PATH);
1194 GetShortPathNameA(tempfile, temppath, MAX_PATH);
1195 lstrcpyA(unc_short, unc_prefix);
1196 unc_short[lstrlenA(unc_short)] = temppath[0];
1197 lstrcatA(unc_short, "$\\");
1198 lstrcatA(unc_short, strchr(temppath, '\\') + 1);
1199
1200 /* Create a long syntax for reference */
1201 memset(longpath, 0, MAX_PATH);
1202 GetLongPathNameA(tempfile, temppath, MAX_PATH);
1203 lstrcpyA(longpath, unc_prefix);
1204 longpath[lstrlenA(longpath)] = temppath[0];
1205 lstrcatA(longpath, "$\\");
1206 lstrcatA(longpath, strchr(temppath, '\\') + 1);
1207
1208 /* NULL test */
1209 SetLastError(0xdeadbeef);
1210 length = GetLongPathNameA(unc_short, NULL, 0);
1211 if (length == 0 && GetLastError() == ERROR_BAD_NETPATH)
1212 {
1213 /* Seen on Window XP Home */
1214 win_skip("UNC with computername is not supported\n");
1215 DeleteFileA(tempfile);
1216 return;
1217 }
1218 explength = lstrlenA(longpath) + 1;
1219 todo_wine
1220 ok(length == explength, "Wrong length %ld, expected %ld\n", length, explength);
1221
1222 length = GetLongPathNameA(unc_short, NULL, MAX_PATH);
1223 todo_wine
1224 ok(length == explength, "Wrong length %ld, expected %ld\n", length, explength);
1225
1226 memset(unc_long, 0, MAX_PATH);
1227 length = GetLongPathNameA(unc_short, unc_long, lstrlenA(unc_short));
1228 /* length will include terminating '0' on failure */
1229 todo_wine
1230 ok(length == explength, "Wrong length %ld, expected %ld\n", length, explength);
1231 ok(unc_long[0] == 0, "Buffer should not have been touched\n");
1232
1233 memset(unc_long, 0, MAX_PATH);
1234 length = GetLongPathNameA(unc_short, unc_long, length);
1235 /* length doesn't include terminating '0' on success */
1236 explength--;
1237 todo_wine
1238 {
1239 ok(length == explength, "Wrong length %ld, expected %ld\n", length, explength);
1240 ok(!lstrcmpiA(unc_long, longpath), "Expected (%s), got (%s)\n", longpath, unc_long);
1241 }
1242
1243 DeleteFileA(tempfile);
1244}
1245
1246static void test_GetLongPathNameW(void)
1247{
1248 DWORD length, expanded;
1249 BOOL ret;
1250 HANDLE file;
1252 WCHAR tempdir[MAX_PATH], name[200];
1253 WCHAR dirpath[4 + MAX_PATH + 200]; /* To ease removal */
1254 WCHAR shortpath[4 + MAX_PATH + 200 + 1 + 200];
1255 static const WCHAR prefix[] = { '\\','\\','?','\\', 0};
1256 static const WCHAR backslash[] = { '\\', 0};
1257 static const WCHAR letterX[] = { 'X', 0};
1258
1259 SetLastError(0xdeadbeef);
1261 ok(0==length,"GetLongPathNameW returned %ld but expected 0\n",length);
1262 ok(GetLastError()==ERROR_INVALID_PARAMETER,"GetLastError returned %ld but expected ERROR_INVALID_PARAMETER\n",GetLastError());
1263
1264 SetLastError(0xdeadbeef);
1265 empty[0]=0;
1267 ok(0==length,"GetLongPathNameW returned %ld but expected 0\n",length);
1268 ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %ld but expected ERROR_PATH_NOT_FOUND\n",GetLastError());
1269
1270 /* Create a long path name. The path needs to exist for these tests to
1271 * succeed so we need the "\\?\" prefix when creating directories and
1272 * files.
1273 */
1274 name[0] = 0;
1275 while (lstrlenW(name) < (ARRAY_SIZE(name) - 1))
1276 lstrcatW(name, letterX);
1277
1278 GetTempPathW(MAX_PATH, tempdir);
1279
1281 lstrcatW(shortpath, tempdir);
1283 lstrcpyW(dirpath, shortpath);
1285 ok(ret, "Could not create the temporary directory : %ld\n", GetLastError());
1286 lstrcatW(shortpath, backslash);
1288
1289 /* Path does not exist yet and we know it overruns MAX_PATH */
1290
1291 /* No prefix */
1292 SetLastError(0xdeadbeef);
1294 ok(length == 0, "Expected 0, got %ld\n", length);
1295 todo_wine
1297 "Expected ERROR_PATH_NOT_FOUND, got %ld\n", GetLastError());
1298 /* With prefix */
1299 SetLastError(0xdeadbeef);
1301 todo_wine
1302 {
1303 ok(length == 0, "Expected 0, got %ld\n", length);
1305 "Expected ERROR_PATH_NOT_FOUND, got %ld\n", GetLastError());
1306 }
1307
1311 "Could not create the temporary file : %ld.\n", GetLastError());
1313
1314 /* Path exists */
1315
1316 /* No prefix */
1317 SetLastError(0xdeadbeef);
1319 todo_wine
1320 {
1321 ok(length == 0, "Expected 0, got %ld\n", length);
1322 ok(GetLastError() == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %ld\n", GetLastError());
1323 }
1324 /* With prefix */
1325 expanded = 4 + (GetLongPathNameW(tempdir, NULL, 0) - 1) + lstrlenW(name) + 1 + lstrlenW(name) + 1;
1326 SetLastError(0xdeadbeef);
1328 ok(length == expanded, "Expected %ld, got %ld\n", expanded, length);
1329
1330 /* NULL buffer with length crashes on Windows */
1331 if (0)
1333
1334 ok(DeleteFileW(shortpath), "Could not delete temporary file\n");
1335 ok(RemoveDirectoryW(dirpath), "Could not delete temporary directory\n");
1336}
1337
1338static void test_GetShortPathNameW(void)
1339{
1340 static const WCHAR extended_prefix[] = {'\\','\\','?','\\',0};
1341 static const WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
1342 static const WCHAR name[] = { 't', 'e', 's', 't', 0 };
1343 static const WCHAR backSlash[] = { '\\', 0 };
1344 static const WCHAR a_bcdeW[] = {'a','.','b','c','d','e',0};
1345 static const WCHAR wildW[] = { '*',0 };
1346 WCHAR path[MAX_PATH], tmppath[MAX_PATH], *ptr;
1347 WCHAR short_path[MAX_PATH];
1348 DWORD length;
1349 HANDLE file;
1350 int ret;
1351
1352 GetTempPathW( MAX_PATH, tmppath );
1353
1354 lstrcpyW( path, tmppath );
1355 lstrcatW( path, test_path );
1356 lstrcatW( path, backSlash );
1358 ok( ret, "Directory was not created. LastError = %ld\n", GetLastError() );
1359
1360 /* Starting a main part of test */
1361
1362 /* extended path \\?\C:\path\ */
1363 lstrcpyW( path, extended_prefix );
1364 lstrcatW( path, tmppath );
1365 lstrcatW( path, test_path );
1366 lstrcatW( path, backSlash );
1367 short_path[0] = 0;
1368 length = GetShortPathNameW( path, short_path, ARRAY_SIZE( short_path ));
1369 ok( length, "GetShortPathNameW returned 0.\n" );
1370
1371 lstrcpyW( path, tmppath );
1372 lstrcatW( path, test_path );
1373 lstrcatW( path, backSlash );
1374 length = GetShortPathNameW( path, short_path, 0 );
1375 ok( length, "GetShortPathNameW returned 0.\n" );
1376 ret = GetShortPathNameW( path, short_path, length );
1377 ok( ret && ret == length-1, "GetShortPathNameW returned 0.\n" );
1378
1379 lstrcatW( short_path, name );
1380
1381 /* GetShortPathName for a non-existent short file name should fail */
1382 SetLastError(0xdeadbeef);
1383 length = GetShortPathNameW( short_path, path, 0 );
1384 ok(!length, "GetShortPathNameW should fail\n");
1385 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %ld\n", GetLastError());
1386
1388 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
1389 CloseHandle( file );
1390 ret = DeleteFileW( short_path );
1391 ok( ret, "Cannot delete file.\n" );
1392
1393 ptr = path + lstrlenW(path);
1394 lstrcpyW( ptr, a_bcdeW);
1396 ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
1397 CloseHandle( file );
1398
1399 length = GetShortPathNameW( path, short_path, ARRAY_SIZE( short_path ));
1400 ok( length, "GetShortPathNameW failed: %lu.\n", GetLastError() );
1401
1402 lstrcpyW(ptr, wildW);
1403 SetLastError(0xdeadbeef);
1404 length = GetShortPathNameW( path, short_path, ARRAY_SIZE( short_path ) );
1405 ok(!length, "GetShortPathNameW should fail\n");
1406 ok(GetLastError() == ERROR_INVALID_NAME, "wrong error %ld\n", GetLastError());
1407
1408 lstrcpyW(ptr, a_bcdeW);
1409 ret = DeleteFileW( path );
1410 ok( ret, "Cannot delete file.\n" );
1411 *ptr = 0;
1412
1413 /* End test */
1415 ok( ret, "Cannot delete directory.\n" );
1416}
1417
1419{
1420 CHAR buffer[MAX_PATH + 4];
1421 DWORD res;
1422 DWORD total;
1423
1424 SetLastError(0xdeadbeef);
1426 /* res includes the terminating Zero */
1427 ok(res > 0, "returned %ld with %ld (expected '>0')\n", res, GetLastError());
1428
1429 total = res;
1430
1431 /* this crashes on XP */
1432 if (0)
1434
1435 SetLastError(0xdeadbeef);
1437 ok( res == total, "returned %lu with %lu (expected '%lu')\n",
1438 res, GetLastError(), total );
1439
1440 if (total > MAX_PATH) return;
1441
1442 buffer[0] = '\0';
1443 SetLastError(0xdeadbeef);
1445 /* res does not include the terminating Zero */
1446 ok( (res == (total-1)) && (buffer[0]),
1447 "returned %ld with %ld and '%s' (expected '%ld' and a string)\n",
1448 res, GetLastError(), buffer, total-1);
1449
1450 buffer[0] = '\0';
1451 SetLastError(0xdeadbeef);
1453 /* res does not include the terminating Zero */
1454 ok( (res == (total-1)) && (buffer[0]),
1455 "returned %ld with %ld and '%s' (expected '%ld' and a string)\n",
1456 res, GetLastError(), buffer, total-1);
1457
1458 memset(buffer, '#', total + 1);
1459 buffer[total + 2] = '\0';
1460 SetLastError(0xdeadbeef);
1462 /* res includes the terminating Zero) */
1463 ok( res == total, "returned %ld with %ld and '%s' (expected '%ld')\n",
1465
1466 memset(buffer, '#', total + 1);
1467 buffer[total + 2] = '\0';
1468 SetLastError(0xdeadbeef);
1470 /* res includes the terminating Zero) */
1471 ok( res == total, "returned %ld with %ld and '%s' (expected '%ld')\n",
1473}
1474
1476{
1477 CHAR buffer[MAX_PATH + 4];
1478 DWORD res;
1479 DWORD total;
1480
1481 SetLastError(0xdeadbeef);
1483 /* res includes the terminating Zero */
1484 ok(res > 0, "returned %ld with %ld (expected '>0')\n", res, GetLastError());
1485
1486 total = res;
1487 /* this crashes on XP */
1488 if (0)
1490
1491 SetLastError(0xdeadbeef);
1493 ok( res == total, "returned %lu with %lu (expected '%lu')\n",
1494 res, GetLastError(), total );
1495
1496 if (total > MAX_PATH) return;
1497
1498 buffer[0] = '\0';
1499 SetLastError(0xdeadbeef);
1501 /* res does not include the terminating Zero */
1502 ok( (res == (total-1)) && (buffer[0]),
1503 "returned %ld with %ld and '%s' (expected '%ld' and a string)\n",
1504 res, GetLastError(), buffer, total-1);
1505
1506 buffer[0] = '\0';
1507 SetLastError(0xdeadbeef);
1509 /* res does not include the terminating Zero */
1510 ok( (res == (total-1)) && (buffer[0]),
1511 "returned %ld with %ld and '%s' (expected '%ld' and a string)\n",
1512 res, GetLastError(), buffer, total-1);
1513
1514 memset(buffer, '#', total + 1);
1515 buffer[total + 2] = '\0';
1516 SetLastError(0xdeadbeef);
1518 /* res includes the terminating Zero) */
1519 ok( res == total, "returned %ld with %ld and '%s' (expected '%ld')\n",
1521
1522 memset(buffer, '#', total + 1);
1523 buffer[total + 2] = '\0';
1524 SetLastError(0xdeadbeef);
1526 /* res includes the terminating Zero) */
1527 ok( res == total, "returned %ld with %ld and '%s' (expected '%ld')\n",
1529}
1530
1532{
1533 if (!pNeedCurrentDirectoryForExePathA)
1534 {
1535 win_skip("NeedCurrentDirectoryForExePathA is not available\n");
1536 return;
1537 }
1538
1539 /* Crashes in Windows */
1540 if (0)
1541 pNeedCurrentDirectoryForExePathA(NULL);
1542
1543 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1544 ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n");
1545 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1546 ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n");
1547
1548 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1549 ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n");
1550 ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n");
1551 ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n");
1552}
1553
1555{
1556 const WCHAR thispath[] = {'.', 0};
1557 const WCHAR fullpath[] = {'c', ':', '\\', 0};
1558 const WCHAR cmdname[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0};
1559
1560 if (!pNeedCurrentDirectoryForExePathW)
1561 {
1562 win_skip("NeedCurrentDirectoryForExePathW is not available\n");
1563 return;
1564 }
1565
1566 /* Crashes in Windows */
1567 if (0)
1568 pNeedCurrentDirectoryForExePathW(NULL);
1569
1570 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL);
1571 ok(pNeedCurrentDirectoryForExePathW(thispath), "returned FALSE for \".\"\n");
1572 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1573 ok(pNeedCurrentDirectoryForExePathW(cmdname), "returned FALSE for \"cmd.exe\"\n");
1574
1575 SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya");
1576 ok(!pNeedCurrentDirectoryForExePathW(thispath), "returned TRUE for \".\"\n");
1577 ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n");
1578 ok(!pNeedCurrentDirectoryForExePathW(cmdname), "returned TRUE for \"cmd.exe\"\n");
1579}
1580
1581/* Call various path/file name retrieving APIs and check the case of
1582 * the returned drive letter. Some apps (for instance Adobe Photoshop CS3
1583 * installer) depend on the drive letter being in upper case.
1584 */
1585static void test_drive_letter_case(void)
1586{
1587 UINT ret;
1588 char buf[MAX_PATH];
1589
1590#define is_upper_case_letter(a) ((a) >= 'A' && (a) <= 'Z')
1591
1592 memset(buf, 0, sizeof(buf));
1593 SetLastError(0xdeadbeef);
1594 ret = GetWindowsDirectoryA(buf, sizeof(buf));
1595 ok(ret, "GetWindowsDirectory error %lu\n", GetLastError());
1596 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1597 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1598 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1599
1600 /* re-use the buffer returned by GetFullPathName */
1601 buf[2] = '/';
1602 SetLastError(0xdeadbeef);
1603 ret = GetFullPathNameA(buf + 2, sizeof(buf), buf, NULL);
1604 ok(ret, "GetFullPathName error %lu\n", GetLastError());
1605 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1606 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1607 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1608
1609 memset(buf, 0, sizeof(buf));
1610 SetLastError(0xdeadbeef);
1611 ret = GetSystemDirectoryA(buf, sizeof(buf));
1612 ok(ret, "GetSystemDirectory error %lu\n", GetLastError());
1613 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1614 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1615 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1616
1617 memset(buf, 0, sizeof(buf));
1618 SetLastError(0xdeadbeef);
1619 ret = GetCurrentDirectoryA(sizeof(buf), buf);
1620 ok(ret, "GetCurrentDirectory error %lu\n", GetLastError());
1621 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1622 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1623 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1624
1625 /* TEMP is an environment variable, so it can't be tested for case-sensitivity */
1626 memset(buf, 0, sizeof(buf));
1627 SetLastError(0xdeadbeef);
1628 ret = GetTempPathA(sizeof(buf), buf);
1629 ok(ret, "GetTempPath error %lu\n", GetLastError());
1630 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1631 if (buf[0])
1632 {
1633 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1634 ok(buf[strlen(buf)-1] == '\\', "Temporary path (%s) doesn't end in a slash\n", buf);
1635 }
1636
1637 memset(buf, 0, sizeof(buf));
1638 SetLastError(0xdeadbeef);
1639 ret = GetFullPathNameA(".", sizeof(buf), buf, NULL);
1640 ok(ret, "GetFullPathName error %lu\n", GetLastError());
1641 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1642 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1643 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1644
1645 /* re-use the buffer returned by GetFullPathName */
1646 SetLastError(0xdeadbeef);
1647 ret = GetShortPathNameA(buf, buf, sizeof(buf));
1648 ok(ret, "GetShortPathName error %lu\n", GetLastError());
1649 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1650 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1651 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1652
1653 /* re-use the buffer returned by GetShortPathName */
1654 SetLastError(0xdeadbeef);
1655 ret = GetLongPathNameA(buf, buf, sizeof(buf));
1656 ok(ret, "GetLongPathNameA error %lu\n", GetLastError());
1657 ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
1658 ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
1659 ok(is_upper_case_letter(buf[0]), "expected buf[0] upper case letter got %c\n", buf[0]);
1660#undef is_upper_case_letter
1661}
1662
1663static const char manifest_dep[] =
1664"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1665"<assemblyIdentity version=\"1.2.3.4\" name=\"testdep1\" type=\"win32\" processorArchitecture=\"" ARCH "\"/>"
1666" <file name=\"testdep.dll\" />"
1667" <file name=\"ole32\" />"
1668" <file name=\"kernel32.dll\" />"
1669"</assembly>";
1670
1671static const char manifest_main[] =
1672"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1673"<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
1674"<dependency>"
1675" <dependentAssembly>"
1676" <assemblyIdentity type=\"win32\" name=\"testdep1\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH "\" />"
1677" </dependentAssembly>"
1678"</dependency>"
1679"</assembly>";
1680
1681static void create_manifest_file(const char *filename, const char *manifest)
1682{
1684 HANDLE file;
1685 DWORD size;
1686
1688
1691
1693 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError());
1696}
1697
1698static void delete_manifest_file(const char *filename)
1699{
1701
1702 GetTempPathA(sizeof(path), path);
1705}
1706
1707static HANDLE test_create(const char *file)
1708{
1710 ACTCTXW actctx;
1711 HANDLE handle;
1712
1716
1717 memset(&actctx, 0, sizeof(ACTCTXW));
1718 actctx.cbSize = sizeof(ACTCTXW);
1719 actctx.lpSource = manifest_path;
1720
1722 ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %lu\n", GetLastError());
1723
1724 ok(actctx.cbSize == sizeof(actctx), "cbSize=%ld\n", actctx.cbSize);
1725 ok(actctx.dwFlags == 0, "dwFlags=%ld\n", actctx.dwFlags);
1726 ok(actctx.lpSource == manifest_path, "lpSource=%p\n", actctx.lpSource);
1727 ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
1728 ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId);
1729 ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
1730 ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName);
1731 ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName);
1732 ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule);
1733
1734 return handle;
1735}
1736
1737static void test_SearchPathA(void)
1738{
1739 static const CHAR testdepA[] = "testdep.dll";
1740 static const CHAR testdeprelA[] = "./testdep.dll";
1741 static const CHAR kernel32A[] = "kernel32.dll";
1742 static const CHAR fileA[] = "";
1743 CHAR pathA[MAX_PATH + 13], buffA[MAX_PATH], path2A[MAX_PATH], path3A[MAX_PATH + 13], curdirA[MAX_PATH];
1744 CHAR tmpdirA[MAX_PATH], *ptrA = NULL;
1746 HANDLE handle;
1747 BOOL bret;
1748 DWORD ret;
1749
1751
1752 /* NULL filename */
1753 SetLastError(0xdeadbeef);
1754 ret = SearchPathA(pathA, NULL, NULL, ARRAY_SIZE(buffA), buffA, &ptrA);
1755 ok(ret == 0, "Expected failure, got %ld\n", ret);
1757 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1758
1759 /* empty filename */
1760 SetLastError(0xdeadbeef);
1761 ret = SearchPathA(pathA, fileA, NULL, ARRAY_SIZE(buffA), buffA, &ptrA);
1762 ok(ret == 0, "Expected failure, got %ld\n", ret);
1764 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1765
1767 strcpy(path2A, pathA);
1768 strcat(path2A, "testfile.ext.ext2");
1769
1770 handle = CreateFileA(path2A, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
1771 ok(handle != INVALID_HANDLE_VALUE, "Failed to create test file.\n");
1773
1774 buffA[0] = 0;
1775 ret = SearchPathA(pathA, "testfile.ext", NULL, ARRAY_SIZE(buffA), buffA, NULL);
1776 ok(!ret, "Unexpected return value %lu.\n", ret);
1777
1778 buffA[0] = 0;
1779 ret = SearchPathA(pathA, "testfile.ext", ".ext2", ARRAY_SIZE(buffA), buffA, NULL);
1780 ok(!ret, "Unexpected return value %lu.\n", ret);
1781
1782 buffA[0] = 0;
1783 ret = SearchPathA(pathA, "testfile.ext.ext2", NULL, ARRAY_SIZE(buffA), buffA, NULL);
1784 ok(ret && ret == strlen(path2A), "got %ld\n", ret);
1785
1786 DeleteFileA(path2A);
1787
1789
1790 create_manifest_file("testdep1.manifest", manifest_dep);
1791 create_manifest_file("main.manifest", manifest_main);
1792
1793 handle = test_create("main.manifest");
1794 delete_manifest_file("testdep1.manifest");
1795 delete_manifest_file("main.manifest");
1796
1797 /* search fails without active context */
1798 ret = SearchPathA(NULL, testdepA, NULL, ARRAY_SIZE(buffA), buffA, NULL);
1799 ok(ret == 0, "got %ld\n", ret);
1800
1801 ret = SearchPathA(NULL, kernel32A, NULL, ARRAY_SIZE(path2A), path2A, NULL);
1802 ok(ret && ret == strlen(path2A), "got %ld\n", ret);
1803
1805 ok(ret, "failed to activate context, %lu\n", GetLastError());
1806
1807 /* works when activated */
1808 ret = SearchPathA(NULL, testdepA, NULL, ARRAY_SIZE(buffA), buffA, NULL);
1809 ok(ret && ret == strlen(buffA), "got %ld\n", ret);
1810
1811 ret = SearchPathA(NULL, "testdep.dll", ".ext", ARRAY_SIZE(buffA), buffA, NULL);
1812 ok(ret && ret == strlen(buffA), "got %ld\n", ret);
1813
1814 ret = SearchPathA(NULL, "testdep", ".dll", ARRAY_SIZE(buffA), buffA, NULL);
1815 ok(ret && ret == strlen(buffA), "got %ld\n", ret);
1816
1817 ret = SearchPathA(NULL, "testdep", ".ext", ARRAY_SIZE(buffA), buffA, NULL);
1818 ok(!ret, "got %ld\n", ret);
1819
1820 /* name contains path */
1821 ret = SearchPathA(NULL, testdeprelA, NULL, ARRAY_SIZE(buffA), buffA, NULL);
1822 ok(!ret, "got %ld\n", ret);
1823
1824 /* fails with specified path that doesn't contain this file */
1825 ret = SearchPathA(pathA, testdepA, NULL, ARRAY_SIZE(buffA), buffA, NULL);
1826 ok(!ret, "got %ld\n", ret);
1827
1828 /* path is redirected for wellknown names too */
1829 ret = SearchPathA(NULL, kernel32A, NULL, ARRAY_SIZE(buffA), buffA, NULL);
1830 ok(ret && ret == strlen(buffA), "got %ld\n", ret);
1831 ok(strcmp(buffA, path2A), "got wrong path %s, %s\n", buffA, path2A);
1832
1834 ok(ret, "failed to deactivate context, %lu\n", GetLastError());
1836
1837 /* test the search path priority of the working directory */
1838 GetTempPathA(sizeof(tmpdirA), tmpdirA);
1839 ret = GetCurrentDirectoryA(MAX_PATH, curdirA);
1840 ok(ret, "failed to obtain working directory.\n");
1841 sprintf(pathA, "%s\\%s", tmpdirA, kernel32A);
1842 ret = SearchPathA(NULL, kernel32A, NULL, ARRAY_SIZE(path2A), path2A, NULL);
1843 ok(ret && ret == strlen(path2A), "got %ld\n", ret);
1844 bret = CopyFileA(path2A, pathA, FALSE);
1845 ok(bret != 0, "failed to copy test executable to temp directory, %lu\n", GetLastError());
1846 GetModuleFileNameA( GetModuleHandleA(0), path3A, sizeof(path3A) );
1847 strcpy( strrchr( path3A, '\\' ) + 1, kernel32A );
1848 bret = CopyFileA(path2A, path3A, FALSE);
1849 ok(bret != 0, "failed to copy test executable to launch directory, %lu\n", GetLastError());
1850 bret = SetCurrentDirectoryA(tmpdirA);
1851 ok(bret, "failed to change working directory\n");
1852 ret = SearchPathA(NULL, kernel32A, ".exe", sizeof(buffA), buffA, NULL);
1853 ok(ret && ret == strlen(buffA), "got %ld\n", ret);
1854 ok(strcmp(buffA, path3A) == 0, "expected %s, got %s\n", path3A, buffA);
1855 bret = SetCurrentDirectoryA(curdirA);
1856 ok(bret, "failed to reset working directory\n");
1857 DeleteFileA(path3A);
1859}
1860
1861static void test_SearchPathW(void)
1862{
1863 static const WCHAR fileext2W[] = {'t','e','s','t','f','i','l','e','.','e','x','t','.','e','x','t','2',0};
1864 static const WCHAR fileextW[] = {'t','e','s','t','f','i','l','e','.','e','x','t',0};
1865 static const WCHAR testdeprelW[] = {'.','/','t','e','s','t','d','e','p','.','d','l','l',0};
1866 static const WCHAR testdepW[] = {'t','e','s','t','d','e','p','.','d','l','l',0};
1867 static const WCHAR testdep1W[] = {'t','e','s','t','d','e','p',0};
1868 static const WCHAR kernel32dllW[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
1869 static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2',0};
1870 static const WCHAR ole32W[] = {'o','l','e','3','2',0};
1871 static const WCHAR ext2W[] = {'.','e','x','t','2',0};
1872 static const WCHAR extW[] = {'.','e','x','t',0};
1873 static const WCHAR dllW[] = {'.','d','l','l',0};
1874 static const WCHAR fileW[] = { 0 };
1875 WCHAR pathW[MAX_PATH], buffW[MAX_PATH], path2W[MAX_PATH];
1876 WCHAR *ptrW = NULL;
1878 HANDLE handle;
1879 DWORD ret;
1880
1882
1883 /* NULL filename */
1884 ret = SearchPathW(pathW, NULL, NULL, ARRAY_SIZE(buffW), buffW, &ptrW);
1885 ok(ret == 0, "Expected failure, got %ld\n", ret);
1887 "Expected ERROR_INVALID_PARAMETER, got %#lx\n", GetLastError());
1888
1889 /* empty filename */
1890 SetLastError(0xdeadbeef);
1891 ret = SearchPathW(pathW, fileW, NULL, ARRAY_SIZE(buffW), buffW, &ptrW);
1892 ok(ret == 0, "Expected failure, got %ld\n", ret);
1894 "Expected ERROR_INVALID_PARAMETER, got %lx\n", GetLastError());
1895
1897 lstrcpyW(path2W, pathW);
1898 lstrcatW(path2W, fileext2W);
1899
1900 handle = CreateFileW(path2W, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
1901 ok(handle != INVALID_HANDLE_VALUE, "Failed to create test file.\n");
1903
1904 buffW[0] = 0;
1905 ret = SearchPathW(pathW, fileextW, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1906 ok(!ret, "Unexpected return value %lu.\n", ret);
1907
1908 buffW[0] = 0;
1909 ret = SearchPathW(pathW, fileextW, ext2W, ARRAY_SIZE(buffW), buffW, NULL);
1910 ok(!ret, "Unexpected return value %lu.\n", ret);
1911
1912 buffW[0] = 0;
1913 ret = SearchPathW(pathW, fileext2W, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1914 ok(ret && ret == lstrlenW(path2W), "got %ld\n", ret);
1915
1916 DeleteFileW(path2W);
1917
1919
1920 create_manifest_file("testdep1.manifest", manifest_dep);
1921 create_manifest_file("main.manifest", manifest_main);
1922
1923 handle = test_create("main.manifest");
1924 delete_manifest_file("testdep1.manifest");
1925 delete_manifest_file("main.manifest");
1926
1927 /* search fails without active context */
1928 ret = SearchPathW(NULL, testdepW, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1929 ok(ret == 0, "got %ld\n", ret);
1930
1931 ret = SearchPathW(NULL, kernel32dllW, NULL, ARRAY_SIZE(path2W), path2W, NULL);
1932 ok(ret && ret == lstrlenW(path2W), "got %ld\n", ret);
1933
1934 /* full path, name without 'dll' extension */
1936 ret = SearchPathW(pathW, kernel32W, NULL, ARRAY_SIZE(path2W), path2W, NULL);
1937 ok(ret == 0, "got %ld\n", ret);
1938
1940
1942 ok(ret, "failed to activate context, %lu\n", GetLastError());
1943
1944 /* works when activated */
1945 ret = SearchPathW(NULL, testdepW, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1946 ok(ret && ret == lstrlenW(buffW), "got %ld\n", ret);
1947
1948 ret = SearchPathW(NULL, testdepW, extW, ARRAY_SIZE(buffW), buffW, NULL);
1949 ok(ret && ret == lstrlenW(buffW), "got %ld\n", ret);
1950
1951 ret = SearchPathW(NULL, testdep1W, dllW, ARRAY_SIZE(buffW), buffW, NULL);
1952 ok(ret && ret == lstrlenW(buffW), "got %ld\n", ret);
1953
1954 ret = SearchPathW(NULL, testdep1W, extW, ARRAY_SIZE(buffW), buffW, NULL);
1955 ok(!ret, "got %ld\n", ret);
1956
1957 /* name contains path */
1958 ret = SearchPathW(NULL, testdeprelW, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1959 ok(!ret, "got %ld\n", ret);
1960
1961 /* fails with specified path that doesn't contain this file */
1962 ret = SearchPathW(pathW, testdepW, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1963 ok(!ret, "got %ld\n", ret);
1964
1965 /* path is redirected for wellknown names too, meaning it takes precedence over normal search order */
1966 ret = SearchPathW(NULL, kernel32dllW, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1967 ok(ret && ret == lstrlenW(buffW), "got %ld\n", ret);
1968 ok(lstrcmpW(buffW, path2W), "got wrong path %s, %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(path2W));
1969
1970 /* path is built using on manifest file name */
1971 ret = SearchPathW(NULL, ole32W, NULL, ARRAY_SIZE(buffW), buffW, NULL);
1972 ok(ret && ret == lstrlenW(buffW), "got %ld\n", ret);
1973
1975 ok(ret, "failed to deactivate context, %lu\n", GetLastError());
1977}
1978
1979static void test_GetFullPathNameA(void)
1980{
1981 char output[MAX_PATH], *filepart;
1982 DWORD ret;
1983 int i;
1984 UINT acp;
1985
1986 const struct
1987 {
1988 LPCSTR name;
1989 DWORD len;
1990 LPSTR buffer;
1991 LPSTR *lastpart;
1992 } invalid_parameters[] =
1993 {
1994 {NULL, 0, NULL, NULL},
1995 {NULL, MAX_PATH, NULL, NULL},
1996 {NULL, MAX_PATH, output, NULL},
1997 {NULL, MAX_PATH, output, &filepart},
1998 {"", 0, NULL, NULL},
1999 {"", MAX_PATH, NULL, NULL},
2000 {"", MAX_PATH, output, NULL},
2001 {"", MAX_PATH, output, &filepart},
2002 };
2003
2004 for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++)
2005 {
2006 SetLastError(0xdeadbeef);
2007 strcpy(output, "deadbeef");
2008 filepart = (char *)0xdeadbeef;
2009 ret = GetFullPathNameA(invalid_parameters[i].name,
2010 invalid_parameters[i].len,
2011 invalid_parameters[i].buffer,
2012 invalid_parameters[i].lastpart);
2013 ok(!ret, "[%d] Expected GetFullPathNameA to return 0, got %lu\n", i, ret);
2014 ok(!strcmp(output, "deadbeef"), "[%d] Expected the output buffer to be unchanged, got \"%s\"\n", i, output);
2015 ok(filepart == (char *)0xdeadbeef, "[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
2016 ok(GetLastError() == 0xdeadbeef ||
2017 GetLastError() == ERROR_INVALID_NAME, /* Win7 */
2018 "[%d] Expected GetLastError() to return 0xdeadbeef, got %lu\n",
2019 i, GetLastError());
2020 }
2021
2022 acp = GetACP();
2023 if (acp != 932)
2024 skip("Skipping DBCS(Japanese) GetFullPathNameA test in this codepage (%d)\n", acp);
2025 else {
2026 const struct dbcs_case {
2027 const char *input;
2028 const char *expected;
2029 } testset[] = {
2030 { "c:\\a\\\x95\x5c\x97\xa0.txt", "\x95\x5c\x97\xa0.txt" },
2031 { "c:\\\x83\x8f\x83\x43\x83\x93\\wine.c", "wine.c" },
2032 { "c:\\demo\\\x97\xa0\x95\x5c", "\x97\xa0\x95\x5c" }
2033 };
2034 for (i = 0; i < ARRAY_SIZE(testset); i++) {
2035 ret = GetFullPathNameA(testset[i].input, sizeof(output),
2036 output, &filepart);
2037 ok(ret, "[%d] GetFullPathName error %lu\n", i, GetLastError());
2038 ok(!lstrcmpA(filepart, testset[i].expected),
2039 "[%d] expected %s got %s\n", i, testset[i].expected, filepart);
2040 }
2041 }
2042}
2043
2044static void test_GetFullPathNameW(void)
2045{
2046 static const WCHAR emptyW[] = {0};
2047 static const WCHAR deadbeefW[] = {'d','e','a','d','b','e','e','f',0};
2048
2049 WCHAR output[MAX_PATH], *filepart;
2050 DWORD ret;
2051 int i;
2052
2053 const struct
2054 {
2055 LPCWSTR name;
2056 DWORD len;
2057 LPWSTR buffer;
2058 LPWSTR *lastpart;
2059 int win7_expect;
2060 } invalid_parameters[] =
2061 {
2062 {NULL, 0, NULL, NULL},
2063 {NULL, 0, NULL, &filepart, 1},
2064 {NULL, MAX_PATH, NULL, NULL},
2065 {NULL, MAX_PATH, output, NULL},
2066 {NULL, MAX_PATH, output, &filepart, 1},
2067 {emptyW, 0, NULL, NULL},
2068 {emptyW, 0, NULL, &filepart, 1},
2069 {emptyW, MAX_PATH, NULL, NULL},
2070 {emptyW, MAX_PATH, output, NULL},
2071 {emptyW, MAX_PATH, output, &filepart, 1},
2072 };
2073
2074 for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++)
2075 {
2076 SetLastError(0xdeadbeef);
2077 lstrcpyW(output, deadbeefW);
2078 filepart = (WCHAR *)0xdeadbeef;
2079 ret = GetFullPathNameW(invalid_parameters[i].name,
2080 invalid_parameters[i].len,
2081 invalid_parameters[i].buffer,
2082 invalid_parameters[i].lastpart);
2083 ok(!ret, "[%d] Expected GetFullPathNameW to return 0, got %lu\n", i, ret);
2084 ok(!lstrcmpW(output, deadbeefW), "[%d] Expected the output buffer to be unchanged, got %s\n", i, wine_dbgstr_w(output));
2085 ok(filepart == (WCHAR *)0xdeadbeef ||
2086 (invalid_parameters[i].win7_expect && filepart == NULL),
2087 "[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
2088 ok(GetLastError() == 0xdeadbeef ||
2089 GetLastError() == ERROR_INVALID_NAME, /* Win7 */
2090 "[%d] Expected GetLastError() to return 0xdeadbeef, got %lu\n",
2091 i, GetLastError());
2092 }
2093}
2094
2095static void init_pointers(void)
2096{
2097 HMODULE mod = GetModuleHandleA("kernel32.dll");
2098
2099#define MAKEFUNC(f) (p##f = (void*)GetProcAddress(mod, #f))
2102 MAKEFUNC(SetSearchPathMode);
2109 mod = GetModuleHandleA("ntdll.dll");
2114#undef MAKEFUNC
2115}
2116
2117static void test_relative_path(void)
2118{
2119 char path[MAX_PATH], buf[MAX_PATH];
2120 HANDLE file;
2121 int ret;
2122 WCHAR curdir[MAX_PATH];
2123
2127 ok(ret, "SetCurrentDirectory error %ld\n", GetLastError());
2128
2129 ret = CreateDirectoryA("foo", NULL);
2130 ok(ret, "CreateDirectory error %ld\n", GetLastError());
2131 file = CreateFileA("foo\\file", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
2132 ok(file != INVALID_HANDLE_VALUE, "failed to create temp file\n");
2134 ret = CreateDirectoryA("bar", NULL);
2135 ok(ret, "CreateDirectory error %ld\n", GetLastError());
2136 ret = SetCurrentDirectoryA("bar");
2137 ok(ret, "SetCurrentDirectory error %ld\n", GetLastError());
2138
2139 ret = GetFileAttributesA("..\\foo\\file");
2140 ok(ret != INVALID_FILE_ATTRIBUTES, "GetFileAttributes error %ld\n", GetLastError());
2141
2142 strcpy(buf, "deadbeef");
2144 ok(ret, "GetLongPathName error %ld\n", GetLastError());
2145 ok(!strcmp(buf, "."), "expected ., got %s\n", buf);
2146 strcpy(buf, "deadbeef");
2148 ok(ret, "GetShortPathName error %ld\n", GetLastError());
2149 ok(!strcmp(buf, "."), "expected ., got %s\n", buf);
2150
2151 strcpy(buf, "deadbeef");
2152 ret = GetLongPathNameA("..", buf, MAX_PATH);
2153 ok(ret, "GetLongPathName error %ld\n", GetLastError());
2154 ok(!strcmp(buf, ".."), "expected .., got %s\n", buf);
2155 strcpy(buf, "deadbeef");
2157 ok(ret, "GetShortPathName error %ld\n", GetLastError());
2158 ok(!strcmp(buf, ".."), "expected .., got %s\n", buf);
2159
2160 strcpy(buf, "deadbeef");
2161 ret = GetLongPathNameA("..\\foo\\file", buf, MAX_PATH);
2162 ok(ret, "GetLongPathName error %ld\n", GetLastError());
2163 ok(!strcmp(buf, "..\\foo\\file"), "expected ..\\foo\\file, got %s\n", buf);
2164 strcpy(buf, "deadbeef");
2165 ret = GetShortPathNameA("..\\foo\\file", buf, MAX_PATH);
2166 ok(ret, "GetShortPathName error %ld\n", GetLastError());
2167 ok(!strcmp(buf, "..\\foo\\file"), "expected ..\\foo\\file, got %s\n", buf);
2168
2169 strcpy(buf, "deadbeef");
2170 ret = GetLongPathNameA(".\\..\\foo\\file", buf, MAX_PATH);
2171 ok(ret, "GetLongPathName error %ld\n", GetLastError());
2172 ok(!strcmp(buf, ".\\..\\foo\\file"), "expected .\\..\\foo\\file, got %s\n", buf);
2173 strcpy(buf, "deadbeef");
2174 ret = GetShortPathNameA(".\\..\\foo\\file", buf, MAX_PATH);
2175 ok(ret, "GetShortPathName error %ld\n", GetLastError());
2176 ok(!strcmp(buf, ".\\..\\foo\\file"), "expected .\\..\\foo\\file, got %s\n", buf);
2177
2178 /* test double delimiters */
2179 strcpy(buf, "deadbeef");
2180 ret = GetLongPathNameA("..\\\\foo\\file", buf, MAX_PATH);
2181 ok(ret, "GetLongPathName error %ld\n", GetLastError());
2182 ok(!strcmp(buf, "..\\\\foo\\file"), "expected ..\\\\foo\\file, got %s\n", buf);
2183 strcpy(buf, "deadbeef");
2184 ret = GetShortPathNameA("..\\\\foo\\file", buf, MAX_PATH);
2185 ok(ret, "GetShortPathName error %ld\n", GetLastError());
2186 ok(!strcmp(buf, "..\\\\foo\\file"), "expected ..\\\\foo\\file, got %s\n", buf);
2187
2189 DeleteFileA("foo\\file");
2190 RemoveDirectoryA("foo");
2191 RemoveDirectoryA("bar");
2192 SetCurrentDirectoryW(curdir);
2193}
2194
2196{
2197 static const WCHAR has_driveW[] = {'C',':','\\','a','.','t','x','t',0};
2198 static const WCHAR has_pathW[] = {'b','\\','a','.','t','x','t',0};
2199 static const WCHAR too_longW[] = {'a','l','o','n','g','f','i','l','e','n','a','m','e','.','t','x','t',0};
2200 static const WCHAR twodotsW[] = {'t','e','s','t','.','e','s','t','.','t','x','t',0};
2201 static const WCHAR longextW[] = {'t','e','s','t','.','t','x','t','t','x','t',0};
2202 static const WCHAR emptyW[] = {0};
2203 static const WCHAR funnycharsW[] = {'!','#','$','%','&','\'','(',')','.','-','@','^',0};
2204 static const WCHAR length8W[] = {'t','e','s','t','t','e','s','t','.','t','x','t',0};
2205 static const WCHAR length1W[] = {'t',0};
2206 static const WCHAR withspaceW[] = {'t','e','s','t',' ','e','s','t','.','t','x','t',0};
2207
2208 static const struct {
2209 const WCHAR *name;
2210 BOOL should_be_legal, has_space;
2211 } cases[] = {
2212 {has_driveW, FALSE, FALSE},
2213 {has_pathW, FALSE, FALSE},
2214 {too_longW, FALSE, FALSE},
2215 {twodotsW, FALSE, FALSE},
2216 {longextW, FALSE, FALSE},
2217 {emptyW, TRUE /* ! */, FALSE},
2218 {funnycharsW, TRUE, FALSE},
2219 {length8W, TRUE, FALSE},
2220 {length1W, TRUE, FALSE},
2221 {withspaceW, TRUE, TRUE},
2222 };
2223
2224 BOOL br, is_legal, has_space;
2225 char astr[64];
2226 DWORD i;
2227
2228 if(!pCheckNameLegalDOS8Dot3W){
2229 win_skip("Missing CheckNameLegalDOS8Dot3, skipping tests\n");
2230 return;
2231 }
2232
2233 br = pCheckNameLegalDOS8Dot3W(NULL, NULL, 0, NULL, &is_legal);
2234 ok(br == FALSE, "CheckNameLegalDOS8Dot3W should have failed\n");
2235
2236 br = pCheckNameLegalDOS8Dot3A(NULL, NULL, 0, NULL, &is_legal);
2237 ok(br == FALSE, "CheckNameLegalDOS8Dot3A should have failed\n");
2238
2239 br = pCheckNameLegalDOS8Dot3W(length8W, NULL, 0, NULL, NULL);
2240 ok(br == FALSE, "CheckNameLegalDOS8Dot3W should have failed\n");
2241
2242 br = pCheckNameLegalDOS8Dot3A("testtest.txt", NULL, 0, NULL, NULL);
2243 ok(br == FALSE, "CheckNameLegalDOS8Dot3A should have failed\n");
2244
2245 for(i = 0; i < ARRAY_SIZE(cases); ++i){
2246 br = pCheckNameLegalDOS8Dot3W(cases[i].name, NULL, 0, &has_space, &is_legal);
2247 ok(br == TRUE, "CheckNameLegalDOS8Dot3W failed for %s\n", wine_dbgstr_w(cases[i].name));
2248 ok(is_legal == cases[i].should_be_legal, "Got wrong legality for %s\n", wine_dbgstr_w(cases[i].name));
2249 if(is_legal)
2250 ok(has_space == cases[i].has_space, "Got wrong space for %s\n", wine_dbgstr_w(cases[i].name));
2251
2252 WideCharToMultiByte(CP_ACP, 0, cases[i].name, -1, astr, sizeof(astr), NULL, NULL);
2253
2254 br = pCheckNameLegalDOS8Dot3A(astr, NULL, 0, &has_space, &is_legal);
2255 ok(br == TRUE, "CheckNameLegalDOS8Dot3W failed for %s\n", astr);
2256 ok(is_legal == cases[i].should_be_legal, "Got wrong legality for %s\n", astr);
2257 if(is_legal)
2258 ok(has_space == cases[i].has_space, "Got wrong space for %s\n", wine_dbgstr_w(cases[i].name));
2259 }
2260}
2261
2262static void test_SetSearchPathMode(void)
2263{
2264 BOOL ret;
2265 char orig[MAX_PATH], buf[MAX_PATH], dir[MAX_PATH], expect[MAX_PATH];
2266 HANDLE handle;
2267
2268 if (!pSetSearchPathMode)
2269 {
2270 win_skip( "SetSearchPathMode isn't available\n" );
2271 return;
2272 }
2275 GetTempFileNameA( buf, "path", 0, dir );
2276 DeleteFileA( dir );
2279 ok( ret, "failed to switch to %s\n", dir );
2280 if (!ret)
2281 {
2283 return;
2284 }
2285
2286 handle = CreateFileA( "kernel32.dll", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2288
2289 SetLastError( 0xdeadbeef );
2290 ret = pSetSearchPathMode( 0 );
2291 ok( !ret, "SetSearchPathMode succeeded\n" );
2292 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
2293
2294 SetLastError( 0xdeadbeef );
2295 ret = pSetSearchPathMode( 0x80 );
2296 ok( !ret, "SetSearchPathMode succeeded\n" );
2297 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
2298
2299 SetLastError( 0xdeadbeef );
2300 ret = pSetSearchPathMode( BASE_SEARCH_PATH_PERMANENT );
2301 ok( !ret, "SetSearchPathMode succeeded\n" );
2302 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
2303
2304 SetLastError( 0xdeadbeef );
2305 ret = SearchPathA( NULL, "kernel32.dll", NULL, MAX_PATH, buf, NULL );
2306 ok( ret, "SearchPathA failed err %lu\n", GetLastError() );
2308 strcat( expect, "\\kernel32.dll" );
2309 ok( !lstrcmpiA( buf, expect ), "found %s expected %s\n", buf, expect );
2310
2311 SetLastError( 0xdeadbeef );
2312 ret = pSetSearchPathMode( BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE );
2313 ok( ret, "SetSearchPathMode failed err %lu\n", GetLastError() );
2314
2315 SetLastError( 0xdeadbeef );
2316 ret = SearchPathA( NULL, "kernel32.dll", NULL, MAX_PATH, buf, NULL );
2317 ok( ret, "SearchPathA failed err %lu\n", GetLastError() );
2319 strcat( expect, "\\kernel32.dll" );
2320 ok( !lstrcmpiA( buf, expect ), "found %s expected %s\n", buf, expect );
2321
2322 SetLastError( 0xdeadbeef );
2323 ret = pSetSearchPathMode( BASE_SEARCH_PATH_DISABLE_SAFE_SEARCHMODE );
2324 ok( ret, "SetSearchPathMode failed err %lu\n", GetLastError() );
2325
2326 SetLastError( 0xdeadbeef );
2327 ret = SearchPathA( NULL, "kernel32.dll", NULL, MAX_PATH, buf, NULL );
2328 ok( ret, "SearchPathA failed err %lu\n", GetLastError() );
2330 strcat( expect, "\\kernel32.dll" );
2331 ok( !lstrcmpiA( buf, expect ), "found %s expected %s\n", buf, expect );
2332
2333 SetLastError( 0xdeadbeef );
2335 ok( !ret, "SetSearchPathMode succeeded\n" );
2336 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
2337
2338 SetLastError( 0xdeadbeef );
2340 ok( ret, "SetSearchPathMode failed err %lu\n", GetLastError() );
2341
2342 SetLastError( 0xdeadbeef );
2343 ret = pSetSearchPathMode( BASE_SEARCH_PATH_DISABLE_SAFE_SEARCHMODE );
2344 ok( !ret, "SetSearchPathMode succeeded\n" );
2345 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError() );
2346
2347 SetLastError( 0xdeadbeef );
2348 ret = pSetSearchPathMode( BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE );
2349 ok( !ret, "SetSearchPathMode succeeded\n" );
2350 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError() );
2351
2352 SetLastError( 0xdeadbeef );
2354 ok( ret, "SetSearchPathMode failed err %lu\n", GetLastError() );
2355
2356 SetLastError( 0xdeadbeef );
2357 ret = SearchPathA( NULL, "kernel32.dll", NULL, MAX_PATH, buf, NULL );
2358 ok( ret, "SearchPathA failed err %lu\n", GetLastError() );
2360 strcat( expect, "\\kernel32.dll" );
2361 ok( !lstrcmpiA( buf, expect ), "found %s expected %s\n", buf, expect );
2362
2363 DeleteFileA( "kernel32.dll" );
2364 SetCurrentDirectoryA( orig );
2366}
2367
2368static const WCHAR pathW[] = {'P','A','T','H',0};
2369
2370static void build_search_path( WCHAR *buffer, UINT size, const WCHAR *module, const WCHAR *dlldir, BOOL safe )
2371{
2372 WCHAR *p;
2373
2374 if (module) lstrcpynW( buffer, module, size );
2376 if (!(p = wcsrchr( buffer, '\\' ))) return;
2377 *p++ = ';';
2378 if (dlldir)
2379 {
2380 lstrcpyW( p, dlldir );
2381 p += lstrlenW( p );
2382 if (*dlldir) *p++ = ';';
2383 }
2384 else if (!safe)
2385 {
2386 *p++ = '.';
2387 *p++ = ';';
2388 }
2390 p = buffer + lstrlenW(buffer);
2391 *p++ = ';';
2393 p = buffer + lstrlenW(buffer) - 2; /* remove "32" */
2394 *p++ = ';';
2396 p = buffer + lstrlenW(buffer);
2397 *p++ = ';';
2398 if (!dlldir && safe)
2399 {
2400 *p++ = '.';
2401 *p++ = ';';
2402 }
2404}
2405
2406static BOOL path_equal( const WCHAR *path1, const WCHAR *path2 )
2407{
2408 for (;;)
2409 {
2410 while (*path1 && towlower(*path1) == towlower(*path2)) { path1++; path2++; }
2411 if (*path1 && *path1 != '\\' && *path1 != ';') return FALSE;
2412 while (*path1 && (*path1 == '\\' || *path1 == ';')) path1++;
2413 while (*path2 && (*path2 == '\\' || *path2 == ';')) path2++;
2414 if (!*path1 || !*path2) return !*path1 && !*path2;
2415 }
2416}
2417
2418static void test_RtlGetSearchPath(void)
2419{
2420 NTSTATUS ret;
2421 WCHAR *path;
2422 WCHAR buffer[2048], old_path[2048], dlldir[4];
2423
2424 if (!pRtlGetSearchPath)
2425 {
2426 win_skip( "RtlGetSearchPath isn't available\n" );
2427 return;
2428 }
2429
2430 GetEnvironmentVariableW( pathW, old_path, ARRAY_SIZE(old_path) );
2432 lstrcpynW( dlldir, buffer, ARRAY_SIZE(dlldir) );
2433
2435 path = (WCHAR *)0xdeadbeef;
2436 ret = pRtlGetSearchPath( &path );
2437 ok( !ret, "RtlGetSearchPath failed %lx\n", ret );
2438 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2439 pRtlReleasePath( path );
2440
2441 SetEnvironmentVariableA( "PATH", "foo" );
2443 path = (WCHAR *)0xdeadbeef;
2444 ret = pRtlGetSearchPath( &path );
2445 ok( !ret, "RtlGetSearchPath failed %lx\n", ret );
2446 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2447 pRtlReleasePath( path );
2448
2449 if (pSetDllDirectoryW)
2450 {
2451 ok( pSetDllDirectoryW( dlldir ), "SetDllDirectoryW failed\n" );
2453 path = (WCHAR *)0xdeadbeef;
2454 ret = pRtlGetSearchPath( &path );
2455 ok( !ret, "RtlGetSearchPath failed %lx\n", ret );
2456 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2457 pRtlReleasePath( path );
2458 pSetDllDirectoryW( NULL );
2459 }
2460
2461 SetEnvironmentVariableW( pathW, old_path );
2462}
2463
2464static void test_RtlGetExePath(void)
2465{
2466 static const WCHAR fooW[] = {'\\','f','o','o',0};
2467 static const WCHAR emptyW[1];
2468 NTSTATUS ret;
2469 WCHAR *path;
2470 WCHAR buffer[2048], old_path[2048], dlldir[4];
2471
2472 if (!pRtlGetExePath)
2473 {
2474 win_skip( "RtlGetExePath isn't available\n" );
2475 return;
2476 }
2477
2478 GetEnvironmentVariableW( pathW, old_path, ARRAY_SIZE(old_path) );
2480 lstrcpynW( dlldir, buffer, ARRAY_SIZE(dlldir) );
2481 SetEnvironmentVariableA( "NoDefaultCurrentDirectoryInExePath", NULL );
2482
2484 path = (WCHAR *)0xdeadbeef;
2485 ret = pRtlGetExePath( fooW, &path );
2486 ok( !ret, "RtlGetExePath failed %lx\n", ret );
2487 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2488 pRtlReleasePath( path );
2489
2491 path = (WCHAR *)0xdeadbeef;
2492 ret = pRtlGetExePath( fooW + 1, &path );
2493 ok( !ret, "RtlGetExePath failed %lx\n", ret );
2494 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2495 pRtlReleasePath( path );
2496
2497 SetEnvironmentVariableA( "NoDefaultCurrentDirectoryInExePath", "yes" );
2498
2500 path = (WCHAR *)0xdeadbeef;
2501 ret = pRtlGetExePath( fooW, &path );
2502 ok( !ret, "RtlGetExePath failed %lx\n", ret );
2503 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2504 pRtlReleasePath( path );
2505
2507 path = (WCHAR *)0xdeadbeef;
2508 ret = pRtlGetExePath( fooW + 1, &path );
2509 ok( !ret, "RtlGetExePath failed %lx\n", ret );
2510 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2511 pRtlReleasePath( path );
2512
2513 SetEnvironmentVariableA( "PATH", "foo" );
2515 path = (WCHAR *)0xdeadbeef;
2516 ret = pRtlGetExePath( fooW, &path );
2517 ok( !ret, "RtlGetExePath failed %lx\n", ret );
2518 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2519 pRtlReleasePath( path );
2520
2521 if (pSetDllDirectoryW)
2522 {
2523 ok( pSetDllDirectoryW( dlldir ), "SetDllDirectoryW failed\n" );
2525 path = (WCHAR *)0xdeadbeef;
2526 ret = pRtlGetExePath( fooW, &path );
2527 ok( !ret, "RtlGetExePath failed %lx\n", ret );
2528 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2529 pRtlReleasePath( path );
2530 pSetDllDirectoryW( NULL );
2531 }
2532
2533 SetEnvironmentVariableW( pathW, old_path );
2534}
2535
2536static void test_LdrGetDllPath(void)
2537{
2538 static const WCHAR fooW[] = {'f','o','o',0};
2539 NTSTATUS ret;
2540 WCHAR *path, *unknown_ptr, *p;
2541 WCHAR buffer[2048], old_path[2048], dlldir[4];
2542
2543 if (!pLdrGetDllPath)
2544 {
2545 win_skip( "LdrGetDllPath isn't available\n" );
2546 return;
2547 }
2548 GetEnvironmentVariableW( pathW, old_path, ARRAY_SIZE(old_path) );
2550 lstrcpynW( dlldir, buffer, ARRAY_SIZE(dlldir) );
2551
2553
2554 path = unknown_ptr = (WCHAR *)0xdeadbeef;
2555 ret = pLdrGetDllPath( 0, 0, &path, &unknown_ptr );
2556 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2557 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2558 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2559 pRtlReleasePath( path );
2560
2561 SetEnvironmentVariableA( "PATH", "foo" );
2563 ret = pLdrGetDllPath( 0, 0, &path, &unknown_ptr );
2564 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2565 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2566 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2567 pRtlReleasePath( path );
2568
2569 if (pSetDllDirectoryW)
2570 {
2571 ok( pSetDllDirectoryW( dlldir ), "SetDllDirectoryW failed\n" );
2573 ret = pLdrGetDllPath( 0, 0, &path, &unknown_ptr );
2574 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2575 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2576 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2577 pRtlReleasePath( path );
2578 pSetDllDirectoryW( NULL );
2579 }
2580
2581 ret = pLdrGetDllPath( 0, LOAD_LIBRARY_SEARCH_SYSTEM32, &path, &unknown_ptr );
2582 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2583 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2585 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2586 pRtlReleasePath( path );
2587
2588 ret = pLdrGetDllPath( 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR, &path, &unknown_ptr );
2589 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2590 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2592 if ((p = wcsrchr( buffer, '\\' ))) *p = 0;
2593 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2594 pRtlReleasePath( path );
2595
2596 ret = pLdrGetDllPath( fooW, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, &path, &unknown_ptr );
2597 ok( ret == STATUS_INVALID_PARAMETER, "LdrGetDllPath failed %lx\n", ret );
2598
2599 lstrcpyW( buffer, L"\\\\?\\" );
2600 lstrcatW( buffer, dlldir );
2601 p = buffer + lstrlenW(buffer);
2602 *p++ = '\\';
2603 lstrcpyW( p, fooW );
2604 ret = pLdrGetDllPath( buffer, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, &path, &unknown_ptr );
2605 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2606 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2607 ok( !memcmp( path, L"\\\\?\\", 4 * sizeof(WCHAR) ) && path_equal( path + 4, dlldir ),
2608 "got %s expected \\\\?\\%s\n", wine_dbgstr_w(path), wine_dbgstr_w(dlldir));
2609 pRtlReleasePath( path );
2610
2611 ret = pLdrGetDllPath( L"\\\\?\\c:\\test.dll", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, &path, &unknown_ptr );
2612 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2613 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2614 ok( !lstrcmpW( path, L"\\\\?\\c:" ), "got %s expected \\\\?\\c:\n", wine_dbgstr_w(path));
2615 pRtlReleasePath( path );
2616
2617 ret = pLdrGetDllPath( fooW, LOAD_WITH_ALTERED_SEARCH_PATH, &path, &unknown_ptr );
2618 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2619 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2621 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2622 pRtlReleasePath( path );
2623
2624 ret = pLdrGetDllPath( L"temp/foo", LOAD_WITH_ALTERED_SEARCH_PATH, &path, &unknown_ptr );
2625 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2626 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2628 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2629 pRtlReleasePath( path );
2630
2631 ret = pLdrGetDllPath( L".\\foo\\foobar", LOAD_WITH_ALTERED_SEARCH_PATH, &path, &unknown_ptr );
2632 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2633 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2634 build_search_path( buffer, ARRAY_SIZE(buffer), L".\\foo\\foobar", NULL, TRUE );
2635 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2636 pRtlReleasePath( path );
2637
2638 ret = pLdrGetDllPath( L"temp\\foo", LOAD_WITH_ALTERED_SEARCH_PATH, &path, &unknown_ptr );
2639 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2640 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2641 build_search_path( buffer, ARRAY_SIZE(buffer), L"temp\\foo", NULL, TRUE );
2642 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2643 pRtlReleasePath( path );
2644
2645 ret = pLdrGetDllPath( L"c:\\temp\\foo", LOAD_WITH_ALTERED_SEARCH_PATH, &path, &unknown_ptr );
2646 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2647 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2648 build_search_path( buffer, ARRAY_SIZE(buffer), L"c:\\temp\\foo", NULL, TRUE );
2649 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2650 pRtlReleasePath( path );
2651
2652 lstrcpyW( buffer, fooW );
2653 ret = pLdrGetDllPath( buffer, LOAD_WITH_ALTERED_SEARCH_PATH | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, &path, &unknown_ptr );
2654 ok( ret == STATUS_INVALID_PARAMETER, "got %lx expected %lx\n", ret, STATUS_INVALID_PARAMETER );
2655 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2656
2657 lstrcpyW( buffer, dlldir );
2658 p = buffer + lstrlenW(buffer);
2659 *p++ = '\\';
2660 lstrcpyW( p, fooW );
2661 ret = pLdrGetDllPath( buffer, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, &path, &unknown_ptr );
2662 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2663 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2664 ok( path_equal( path, dlldir ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(dlldir));
2665 pRtlReleasePath( path );
2666
2667 if (pAddDllDirectory)
2668 {
2669 DLL_DIRECTORY_COOKIE cookie = pAddDllDirectory( dlldir );
2670 ok( !!cookie, "AddDllDirectory failed\n" );
2671 ret = pLdrGetDllPath( 0, LOAD_LIBRARY_SEARCH_USER_DIRS, &path, &unknown_ptr );
2672 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2673 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2674 ok( path_equal( path, dlldir ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(dlldir));
2675 pRtlReleasePath( path );
2676 pRemoveDllDirectory( cookie );
2677 }
2678
2679 if (pSetDefaultDllDirectories)
2680 {
2681 pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_SYSTEM32 );
2682 ret = pLdrGetDllPath( 0, 0, &path, &unknown_ptr );
2683 ok( !ret, "LdrGetDllPath failed %lx\n", ret );
2684 ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
2686 ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
2687 pRtlReleasePath( path );
2688 pSetDefaultDllDirectories( 0 );
2689 }
2690
2691 SetEnvironmentVariableW( pathW, old_path );
2692}
2693
2695{
2696 CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
2697
2698 init_pointers();
2699
2701 test_InitPathA(curdir, &curDrive, &otherDrive);
2702 test_CurrentDirectoryA(origdir,curdir);
2703 test_PathNameA(curdir, curDrive, otherDrive);
2704 test_CleanupPathA(origdir,curdir);
2723}
std::map< E_MODULE, HMODULE > mod
Definition: LocaleTests.cpp:66
unsigned int dir
Definition: maze.c:112
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
static const WCHAR dllW[]
Definition: axinstall.c:36
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAY_SIZE(A)
Definition: main.h:20
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NTSTATUS
Definition: precomp.h:19
static const WCHAR rc2[]
Definition: oid.c:1216
static const WCHAR empty[]
Definition: main.c:47
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define wcsrchr
Definition: compat.h:16
#define CP_ACP
Definition: compat.h:109
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:755
#define OPEN_EXISTING
Definition: compat.h:775
#define lstrcpynA
Definition: compat.h:751
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define GetEnvironmentVariableA(x, y, z)
Definition: compat.h:754
#define MultiByteToWideChar
Definition: compat.h:110
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define ERROR_INVALID_NAME
Definition: compat.h:103
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static const WCHAR *const ext[]
Definition: module.c:53
static const WCHAR version[]
Definition: asmname.c:66
VOID WINAPI ReleaseActCtx(IN HANDLE hActCtx)
Definition: actctx.c:208
BOOL WINAPI DeactivateActCtx(IN DWORD dwFlags, IN ULONG_PTR ulCookie)
Definition: actctx.c:268
BOOL WINAPI ActivateActCtx(IN HANDLE hActCtx, OUT PULONG_PTR ulCookie)
Definition: actctx.c:237
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW(IN LPCWSTR lpName, IN LPCWSTR lpValue)
Definition: environ.c:260
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableA(IN LPCSTR lpName, IN LPCSTR lpValue)
Definition: environ.c:219
BOOL WINAPI CopyFileA(IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:404
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:636
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
DWORD WINAPI GetShortPathNameA(IN LPCSTR lpszLongPath, OUT LPSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1752
DWORD WINAPI SearchPathA(IN LPCSTR lpPath OPTIONAL, IN LPCSTR lpFileName, IN LPCSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPSTR lpBuffer, OUT LPSTR *lpFilePart OPTIONAL)
Definition: path.c:1123
BOOL WINAPI SetDllDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:800
BOOL WINAPI NeedCurrentDirectoryForExePathA(IN LPCSTR ExeName)
Definition: path.c:969
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
UINT WINAPI GetWindowsDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2337
DWORD WINAPI GetLongPathNameA(IN LPCSTR lpszShortPath, OUT LPSTR lpszLongPath, IN DWORD cchBuffer)
Definition: path.c:1671
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2249
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1298
DWORD WINAPI GetFullPathNameA(IN LPCSTR lpFileName, IN DWORD nBufferLength, OUT LPSTR lpBuffer, OUT LPSTR *lpFilePart)
Definition: path.c:993
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
DWORD WINAPI GetLongPathNameW(IN LPCWSTR lpszShortPath, OUT LPWSTR lpszLongPath, IN DWORD cchBuffer)
Definition: path.c:1456
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1833
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2206
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
BOOL WINAPI NeedCurrentDirectoryForExePathW(IN LPCWSTR ExeName)
Definition: path.c:957
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2352
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2283
HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx)
Definition: actctx.c:102
UINT WINAPI GetACP(void)
Definition: locale.c:2023
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4246
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4198
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4265
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4227
DLL_DIRECTORY_COOKIE WINAPI DECLSPEC_HOTPATCH AddDllDirectory(const WCHAR *dir)
Definition: loader.c:188
BOOL WINAPI DECLSPEC_HOTPATCH SetDefaultDllDirectories(DWORD flags)
Definition: loader.c:602
BOOL WINAPI DECLSPEC_HOTPATCH RemoveDllDirectory(DLL_DIRECTORY_COOKIE cookie)
Definition: loader.c:593
DWORD WINAPI GetVersion(void)
Definition: version.c:1458
DWORD WINAPI DECLSPEC_HOTPATCH GetLogicalDrives(void)
Definition: volume.c:513
int CDECL tolower(int c)
Definition: ctype.c:572
int CDECL toupper(int c)
Definition: ctype.c:514
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP char *__cdecl strchr(const char *, int)
Definition: string.c:3286
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
_ACRTIMP char *__cdecl strrchr(const char *, int)
Definition: string.c:3298
static const WCHAR fileW[]
Definition: url.c:111
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
BOOL WINAPI CheckNameLegalDOS8Dot3W(LPCWSTR lpName, LPSTR lpOemName OPTIONAL, DWORD OemNameSize OPTIONAL, PBOOL pbNameContainsSpaces OPTIONAL, PBOOL pbNameLegal)
Definition: filename.c:321
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
BOOL WINAPI CheckNameLegalDOS8Dot3A(LPCSTR lpName, LPSTR lpOemName OPTIONAL, DWORD OemNameSize OPTIONAL, PBOOL pbNameContainsSpaces OPTIONAL, PBOOL pbNameLegal)
Definition: filename.c:365
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOLEAN valid
size_t total
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
GLuint pathA
Definition: glext.h:11719
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static const WCHAR emptyW[]
Definition: navigate.c:40
NTSYSAPI NTSTATUS WINAPI LdrGetDllPath(PCWSTR, ULONG, PWSTR *, PWSTR *)
NTSYSAPI NTSTATUS WINAPI RtlGetSearchPath(PWSTR *)
NTSYSAPI void WINAPI RtlReleasePath(PWSTR)
NTSYSAPI NTSTATUS WINAPI RtlGetExePath(PCWSTR, PWSTR *)
const char * filename
Definition: ioapi.h:137
#define actctx
Definition: kernel32.h:8
#define wine_dbgstr_w
Definition: kernel32.h:34
__cdecl __MINGW_NOTHROW char * dirname(char *)
void * DLL_DIRECTORY_COOKIE
Definition: libloaderapi.h:26
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define win_skip
Definition: minitest.h:67
#define todo_wine
Definition: minitest.h:80
#define error(str)
Definition: mkdosfs.c:1605
#define CREATE_ALWAYS
Definition: disk.h:72
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define CREATE_NEW
Definition: disk.h:69
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static PVOID ptr
Definition: dispmode.c:27
#define sprintf
Definition: sprintf.c:45
static char shortpath[MAX_PATH]
Definition: batch.c:32
static void test_create(void)
Definition: monthcal.c:1595
BOOL expected
Definition: store.c:2000
#define expect(expected, got)
Definition: path.c:34
static WCHAR manifest_path[MAX_PATH]
Definition: actctx.c:587
static const WCHAR fooW[]
Definition: locale.c:50
#define LONGDIR
Definition: path.c:40
static const CHAR is_char_ok[]
Definition: path.c:67
#define NONDIR_LONG
Definition: path.c:44
static const CHAR funny_chars[]
Definition: path.c:66
static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
Definition: path.c:589
static const char manifest_dep[]
Definition: path.c:1663
static void test_GetTempPathA(char *tmp_dir)
Definition: path.c:928
static void test_GetLongPathNameA(void)
Definition: path.c:1136
static void test_GetFullPathNameA(void)
Definition: path.c:1979
#define MAKEFUNC(f)
#define NONFILE_SHORT
Definition: path.c:41
#define HAS_TRAIL_SLASH_A(string)
Definition: path.c:35
static void test_drive_letter_case(void)
Definition: path.c:1585
static void test_GetSystemDirectory(void)
Definition: path.c:1418
static void test_ShortPathCase(const char *tmpdir, const char *dirname, const char *filename)
Definition: path.c:566
static void test_GetWindowsDirectory(void)
Definition: path.c:1475
static void test_setdir(CHAR *olddir, CHAR *newdir, CHAR *cmprstr, INT pass, const CHAR *errstr)
Definition: path.c:291
#define ARCH
Definition: path.c:57
static void test_FunnyChars(CHAR *curdir, CHAR *curdir_short, CHAR *filename, INT valid, CHAR *errstr)
Definition: path.c:257
static void test_GetTempPathW(char *tmp_dir)
Definition: path.c:980
static void test_SetSearchPathMode(void)
Definition: path.c:2262
static void create_manifest_file(const char *filename, const char *manifest)
Definition: path.c:1681
static void test_relative_path(void)
Definition: path.c:2117
static void test_GetTempPath(void)
Definition: path.c:1081
static void test_SplitShortPathA(CHAR *path, CHAR *dir, CHAR *eight, CHAR *three)
Definition: path.c:201
static void test_RtlGetSearchPath(void)
Definition: path.c:2418
static void delete_manifest_file(const char *filename)
Definition: path.c:1698
static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
Definition: path.c:448
static BOOL path_equal(const WCHAR *path1, const WCHAR *path2)
Definition: path.c:2406
static void test_GetFullPathNameW(void)
Definition: path.c:2044
static void test_LongtoShortA(CHAR *teststr, const CHAR *goodstr, const CHAR *ext, const CHAR *errstr)
Definition: path.c:238
#define SHORTFILE
Definition: path.c:38
static void test_GetLongPathNameW(void)
Definition: path.c:1246
static void test_RtlGetExePath(void)
Definition: path.c:2464
static void test_SearchPathA(void)
Definition: path.c:1737
static const WCHAR pathW[]
Definition: path.c:2368
static void test_LdrGetDllPath(void)
Definition: path.c:2536
static void test_GetShortPathNameW(void)
Definition: path.c:1338
static void test_SearchPathW(void)
Definition: path.c:1861
#define is_upper_case_letter(a)
#define LONGFILE
Definition: path.c:37
static void build_search_path(WCHAR *buffer, UINT size, const WCHAR *module, const WCHAR *dlldir, BOOL safe)
Definition: path.c:2370
static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
Definition: path.c:546
static void init_pointers(void)
Definition: path.c:2095
#define SHORTDIR
Definition: path.c:39
#define NOT_A_VALID_DRIVE
Definition: path.c:46
static void test_ValidPathA(const CHAR *curdir, const CHAR *subdir, const CHAR *filename, CHAR *shortstr, SLpassfail *passfail, const CHAR *errstr)
Definition: path.c:101
static void test_CheckNameLegalDOS8Dot3(void)
Definition: path.c:2195
#define NONFILE_LONG
Definition: path.c:42
static void test_NeedCurrentDirectoryForExePathA(void)
Definition: path.c:1531
static void test_NeedCurrentDirectoryForExePathW(void)
Definition: path.c:1554
static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
Definition: path.c:325
#define NONDIR_SHORT
Definition: path.c:43
static const char manifest_main[]
Definition: path.c:1671
static const WCHAR path1[]
Definition: path.c:28
static const WCHAR path2[]
Definition: path.c:29
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
#define GENERIC_WRITE
Definition: nt_native.h:90
strcat
Definition: string.h:92
strcpy
Definition: string.h:131
#define memset(x, y, z)
Definition: compat.h:39
#define towlower(c)
Definition: wctype.h:97
BOOL WINAPI SHIM_OBJ_NAME() GetComputerNameA(LPSTR lpBuffer, LPDWORD lpnSize)
Definition: shimtest.c:21
static char tmpdir[MAX_PATH]
Definition: shlexec.c:52
DWORD shorterror
Definition: path.c:89
DWORD s2llen
Definition: path.c:90
DWORD longerror
Definition: path.c:93
DWORD longlen
Definition: path.c:92
DWORD s2lerror
Definition: path.c:91
DWORD shortlen
Definition: path.c:88
Definition: cookie.c:34
Definition: fci.c:127
Definition: name.c:39
Character const *const prefix
Definition: tempnam.cpp:195
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
pass
Definition: typegen.h:25
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
static const CHAR manifest[]
Definition: v6util.h:41
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
const char * errstr(int errcode)
#define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
Definition: winbase.h:346
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define BASE_SEARCH_PATH_DISABLE_SAFE_SEARCHMODE
Definition: winbase.h:587
#define LOAD_LIBRARY_SEARCH_SYSTEM32
Definition: winbase.h:349
#define LOAD_WITH_ALTERED_SEARCH_PATH
Definition: winbase.h:340
#define BASE_SEARCH_PATH_PERMANENT
Definition: winbase.h:588
#define BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE
Definition: winbase.h:586
#define LOAD_LIBRARY_SEARCH_USER_DIRS
Definition: winbase.h:348
#define LOAD_LIBRARY_SEARCH_APPLICATION_DIR
Definition: winbase.h:347
#define WINAPI
Definition: msvc.h:6
#define ERROR_BAD_NETPATH
Definition: winerror.h:267
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
#define ERROR_DIRECTORY
Definition: winerror.h:416
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char * LPSTR
Definition: xmlstorage.h:182
char CHAR
Definition: xmlstorage.h:175