1 /* Unit test suite for Path functions
3 * Copyright 2002 Matthew Mastracci
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define WIN32_NO_STATUS
22 #define COM_NO_WINDOWS_H
27 #include <wine/test.h>
29 //#include "winbase.h"
35 static BOOL (WINAPI
*pPathIsValidCharA
)(char,DWORD
);
36 static BOOL (WINAPI
*pPathIsValidCharW
)(WCHAR
,DWORD
);
37 static LPWSTR (WINAPI
*pPathCombineW
)(LPWSTR
, LPCWSTR
, LPCWSTR
);
38 static HRESULT (WINAPI
*pPathCreateFromUrlA
)(LPCSTR
, LPSTR
, LPDWORD
, DWORD
);
39 static HRESULT (WINAPI
*pPathCreateFromUrlW
)(LPCWSTR
, LPWSTR
, LPDWORD
, DWORD
);
40 static HRESULT (WINAPI
*pPathCreateFromUrlAlloc
)(LPCWSTR
, LPWSTR
*, DWORD
);
41 static BOOL (WINAPI
*pPathAppendA
)(LPSTR
, LPCSTR
);
42 static BOOL (WINAPI
*pPathUnExpandEnvStringsA
)(LPCSTR
, LPSTR
, UINT
);
43 static BOOL (WINAPI
*pPathUnExpandEnvStringsW
)(LPCWSTR
, LPWSTR
, UINT
);
44 static BOOL (WINAPI
*pPathIsRelativeA
)(LPCSTR
);
45 static BOOL (WINAPI
*pPathIsRelativeW
)(LPCWSTR
);
47 /* ################ */
53 } TEST_PATHFROMURL
[] = {
55 {"file:c:/foo/bar", "c:\\foo\\bar", S_OK
, 0},
56 {"file:c|/foo/bar", "c:\\foo\\bar", S_OK
, 0},
57 {"file:cx|/foo/bar", "cx|\\foo\\bar", S_OK
, 0},
58 {"file:c:foo/bar", "c:foo\\bar", S_OK
, 0},
59 {"file:c|foo/bar", "c:foo\\bar", S_OK
, 0},
60 {"file:c:/foo%20ba%2fr", "c:\\foo ba/r", S_OK
, 0},
61 {"file:foo%20ba%2fr", "foo ba/r", S_OK
, 0},
62 {"file:foo/bar/", "foo\\bar\\", S_OK
, 0},
64 /* 1 leading (back)slash */
65 {"file:/c:/foo/bar", "c:\\foo\\bar", S_OK
, 0},
66 {"file:\\c:/foo/bar", "c:\\foo\\bar", S_OK
, 0},
67 {"file:/c|/foo/bar", "c:\\foo\\bar", S_OK
, 0},
68 {"file:/cx|/foo/bar", "\\cx|\\foo\\bar", S_OK
, 0},
69 {"file:/c:foo/bar", "c:foo\\bar", S_OK
, 0},
70 {"file:/c|foo/bar", "c:foo\\bar", S_OK
, 0},
71 {"file:/c:/foo%20ba%2fr", "c:\\foo ba/r", S_OK
, 0},
72 {"file:/foo%20ba%2fr", "\\foo ba/r", S_OK
, 0},
73 {"file:/foo/bar/", "\\foo\\bar\\", S_OK
, 0},
75 /* 2 leading (back)slashes */
76 {"file://c:/foo/bar", "c:\\foo\\bar", S_OK
, 0},
77 {"file://c:/d:/foo/bar", "c:\\d:\\foo\\bar", S_OK
, 0},
78 {"file://c|/d|/foo/bar", "c:\\d|\\foo\\bar", S_OK
, 0},
79 {"file://cx|/foo/bar", "\\\\cx|\\foo\\bar", S_OK
, 0},
80 {"file://c:foo/bar", "c:foo\\bar", S_OK
, 0},
81 {"file://c|foo/bar", "c:foo\\bar", S_OK
, 0},
82 {"file://c:/foo%20ba%2fr", "c:\\foo%20ba%2fr", S_OK
, 0},
83 {"file://c%3a/foo/../bar", "\\\\c:\\foo\\..\\bar", S_OK
, 0},
84 {"file://c%7c/foo/../bar", "\\\\c|\\foo\\..\\bar", S_OK
, 0},
85 {"file://foo%20ba%2fr", "\\\\foo ba/r", S_OK
, 0},
86 {"file://localhost/c:/foo/bar", "c:\\foo\\bar", S_OK
, 0},
87 {"file://localhost/c:/foo%20ba%5Cr", "c:\\foo ba\\r", S_OK
, 0},
88 {"file://LocalHost/c:/foo/bar", "c:\\foo\\bar", S_OK
, 0},
89 {"file:\\\\localhost\\c:\\foo\\bar", "c:\\foo\\bar", S_OK
, 0},
90 {"file://incomplete", "\\\\incomplete", S_OK
, 0},
92 /* 3 leading (back)slashes (omitting hostname) */
93 {"file:///c:/foo/bar", "c:\\foo\\bar", S_OK
, 0},
94 {"File:///c:/foo/bar", "c:\\foo\\bar", S_OK
, 0},
95 {"file:///c:/foo%20ba%2fr", "c:\\foo ba/r", S_OK
, 0},
96 {"file:///foo%20ba%2fr", "\\foo ba/r", S_OK
, 0},
97 {"file:///foo/bar/", "\\foo\\bar\\", S_OK
, 0},
98 {"file:///localhost/c:/foo/bar", "\\localhost\\c:\\foo\\bar", S_OK
, 0},
100 /* 4 leading (back)slashes */
101 {"file:////c:/foo/bar", "c:\\foo\\bar", S_OK
, 0},
102 {"file:////c:/foo%20ba%2fr", "c:\\foo%20ba%2fr", S_OK
, 0},
103 {"file:////foo%20ba%2fr", "\\\\foo%20ba%2fr", S_OK
, 0},
105 /* 5 and more leading (back)slashes */
106 {"file://///c:/foo/bar", "\\\\c:\\foo\\bar", S_OK
, 0},
107 {"file://///c:/foo%20ba%2fr", "\\\\c:\\foo ba/r", S_OK
, 0},
108 {"file://///foo%20ba%2fr", "\\\\foo ba/r", S_OK
, 0},
109 {"file://////c:/foo/bar", "\\\\c:\\foo\\bar", S_OK
, 0},
111 /* Leading (back)slashes cannot be escaped */
112 {"file:%2f%2flocalhost%2fc:/foo/bar", "//localhost/c:\\foo\\bar", S_OK
, 0},
113 {"file:%5C%5Clocalhost%5Cc:/foo/bar", "\\\\localhost\\c:\\foo\\bar", S_OK
, 0},
115 /* Hostname handling */
116 {"file://l%6fcalhost/c:/foo/bar", "\\\\localhostc:\\foo\\bar", S_OK
, 0},
117 {"file://localhost:80/c:/foo/bar", "\\\\localhost:80c:\\foo\\bar", S_OK
, 0},
118 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK
, 0},
119 {"file://host//c:/foo/bar", "\\\\host\\\\c:\\foo\\bar", S_OK
, 0},
120 {"file://host/\\c:/foo/bar", "\\\\host\\\\c:\\foo\\bar", S_OK
, 0},
121 {"file://host/c:foo/bar", "\\\\hostc:foo\\bar", S_OK
, 0},
122 {"file://host/foo/bar", "\\\\host\\foo\\bar", S_OK
, 0},
123 {"file:\\\\host\\c:\\foo\\bar", "\\\\hostc:\\foo\\bar", S_OK
, 0},
124 {"file:\\\\host\\ca\\foo\\bar", "\\\\host\\ca\\foo\\bar", S_OK
, 0},
125 {"file:\\\\host\\c|\\foo\\bar", "\\\\hostc|\\foo\\bar", S_OK
, 0},
126 {"file:\\%5Chost\\c:\\foo\\bar", "\\\\host\\c:\\foo\\bar", S_OK
, 0},
127 {"file:\\\\host\\cx:\\foo\\bar", "\\\\host\\cx:\\foo\\bar", S_OK
, 0},
128 {"file:///host/c:/foo/bar", "\\host\\c:\\foo\\bar", S_OK
, 0},
131 {"c:\\foo\\bar", NULL
, E_INVALIDARG
, 0},
132 {"foo/bar", NULL
, E_INVALIDARG
, 0},
133 {"http://foo/bar", NULL
, E_INVALIDARG
, 0},
141 } TEST_PATH_IS_URL
[] = {
142 {"http://foo/bar", TRUE
},
143 {"c:\\foo\\bar", FALSE
},
144 {"c:/foo/bar", FALSE
},
145 {"foo://foo/bar", TRUE
},
148 {"bogusscheme:", TRUE
},
149 {"http:partial", TRUE
},
150 {"www.winehq.org", FALSE
},
151 /* More examples that the user might enter as the browser start page */
152 {"winehq.org", FALSE
},
153 {"ftp.winehq.org", FALSE
},
154 {"http://winehq.org", TRUE
},
155 {"http://www.winehq.org", TRUE
},
156 {"https://winehq.org", TRUE
},
157 {"https://www.winehq.org", TRUE
},
158 {"ftp://winehq.org", TRUE
},
159 {"ftp://ftp.winehq.org", TRUE
},
160 {"file://does_not_exist.txt", TRUE
},
161 {"about:blank", TRUE
},
162 {"about:home", TRUE
},
163 {"about:mozilla", TRUE
},
164 /* scheme is case independent */
165 {"HTTP://www.winehq.org", TRUE
},
166 /* a space at the start is not allowed */
167 {" http://www.winehq.org", FALSE
},
172 static const struct {
175 } TEST_PATH_UNQUOTE_SPACES
[] = {
176 { "abcdef", "abcdef" },
177 { "\"abcdef\"", "abcdef" },
178 { "\"abcdef", "\"abcdef" },
179 { "abcdef\"", "abcdef\"" },
180 { "\"\"abcdef\"\"", "\"abcdef\"" },
181 { "abc\"def", "abc\"def" },
182 { "\"abc\"def", "\"abc\"def" },
183 { "\"abc\"def\"", "abc\"def" },
184 { "\'abcdef\'", "\'abcdef\'" },
189 /* ################ */
191 static LPWSTR
GetWideString(const char *src
)
198 ret
= HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH
) * sizeof(WCHAR
));
200 MultiByteToWideChar(CP_ACP
, 0, src
, -1, ret
, INTERNET_MAX_URL_LENGTH
);
205 static void FreeWideString(LPWSTR wszString
)
207 HeapFree(GetProcessHeap(), 0, wszString
);
210 static LPSTR
strdupA(LPCSTR p
)
213 DWORD len
= (strlen(p
) + 1);
214 ret
= HeapAlloc(GetProcessHeap(), 0, len
);
219 /* ################ */
221 static void test_PathSearchAndQualify(void)
223 WCHAR path1
[] = {'c',':','\\','f','o','o',0};
224 WCHAR expect1
[] = {'c',':','\\','f','o','o',0};
225 WCHAR path2
[] = {'c',':','f','o','o',0};
226 WCHAR c_drive
[] = {'c',':',0};
227 WCHAR foo
[] = {'f','o','o',0};
228 WCHAR path3
[] = {'\\','f','o','o',0};
229 WCHAR winini
[] = {'w','i','n','.','i','n','i',0};
231 WCHAR cur_dir
[MAX_PATH
];
232 WCHAR dot
[] = {'.',0};
235 ok(PathSearchAndQualifyW(path1
, out
, MAX_PATH
) != 0,
236 "PathSearchAndQualify rets 0\n");
237 ok(!lstrcmpiW(out
, expect1
), "strings don't match\n");
240 ok(PathSearchAndQualifyW(path2
, out
, MAX_PATH
) != 0,
241 "PathSearchAndQualify rets 0\n");
242 GetFullPathNameW(c_drive
, MAX_PATH
, cur_dir
, NULL
);
243 PathAddBackslashW(cur_dir
);
244 lstrcatW(cur_dir
, foo
);
245 ok(!lstrcmpiW(out
, cur_dir
), "strings don't match\n");
248 ok(PathSearchAndQualifyW(foo
, out
, MAX_PATH
) != 0,
249 "PathSearchAndQualify rets 0\n");
250 GetFullPathNameW(dot
, MAX_PATH
, cur_dir
, NULL
);
251 PathAddBackslashW(cur_dir
);
252 lstrcatW(cur_dir
, foo
);
253 ok(!lstrcmpiW(out
, cur_dir
), "strings don't match\n");
256 ok(PathSearchAndQualifyW(path3
, out
, MAX_PATH
) != 0,
257 "PathSearchAndQualify rets 0\n");
258 GetFullPathNameW(dot
, MAX_PATH
, cur_dir
, NULL
);
259 lstrcpyW(cur_dir
+ 2, path3
);
260 ok(!lstrcmpiW(out
, cur_dir
), "strings don't match\n");
263 ok(PathSearchAndQualifyW(winini
, out
, MAX_PATH
) != 0,
264 "PathSearchAndQualify rets 0\n");
265 if(!SearchPathW(NULL
, winini
, NULL
, MAX_PATH
, cur_dir
, NULL
))
266 GetFullPathNameW(winini
, MAX_PATH
, cur_dir
, NULL
);
267 ok(!lstrcmpiW(out
, cur_dir
), "strings don't match\n");
271 static void test_PathCreateFromUrl(void)
274 char ret_path
[INTERNET_MAX_URL_LENGTH
];
275 DWORD len
, len2
, ret
;
276 WCHAR ret_pathW
[INTERNET_MAX_URL_LENGTH
];
279 if (!pPathCreateFromUrlA
) {
280 win_skip("PathCreateFromUrlA not found\n");
284 /* Won't say how much is needed without a buffer */
286 ret
= pPathCreateFromUrlA("file://foo", NULL
, &len
, 0);
287 ok(ret
== E_INVALIDARG
, "got 0x%08x expected E_INVALIDARG\n", ret
);
288 ok(len
== 0xdeca, "got %x expected 0xdeca\n", len
);
290 /* Test the decoding itself */
291 for(i
= 0; i
< sizeof(TEST_PATHFROMURL
) / sizeof(TEST_PATHFROMURL
[0]); i
++) {
292 len
= INTERNET_MAX_URL_LENGTH
;
293 ret
= pPathCreateFromUrlA(TEST_PATHFROMURL
[i
].url
, ret_path
, &len
, 0);
294 todo_wine_if (TEST_PATHFROMURL
[i
].todo
& 0x1)
295 ok(ret
== TEST_PATHFROMURL
[i
].ret
, "ret %08x from url %s\n", ret
, TEST_PATHFROMURL
[i
].url
);
296 if(SUCCEEDED(ret
) && TEST_PATHFROMURL
[i
].path
) {
297 if(!(TEST_PATHFROMURL
[i
].todo
& 0x2)) {
298 ok(!lstrcmpiA(ret_path
, TEST_PATHFROMURL
[i
].path
), "got %s expected %s from url %s\n", ret_path
, TEST_PATHFROMURL
[i
].path
, TEST_PATHFROMURL
[i
].url
);
299 ok(len
== strlen(ret_path
), "ret len %d from url %s\n", len
, TEST_PATHFROMURL
[i
].url
);
301 /* Wrong string, don't bother checking the length */
302 ok(!lstrcmpiA(ret_path
, TEST_PATHFROMURL
[i
].path
), "got %s expected %s from url %s\n", ret_path
, TEST_PATHFROMURL
[i
].path
, TEST_PATHFROMURL
[i
].url
);
305 if (pPathCreateFromUrlW
) {
306 len
= INTERNET_MAX_URL_LENGTH
;
307 pathW
= GetWideString(TEST_PATHFROMURL
[i
].path
);
308 urlW
= GetWideString(TEST_PATHFROMURL
[i
].url
);
309 ret
= pPathCreateFromUrlW(urlW
, ret_pathW
, &len
, 0);
310 WideCharToMultiByte(CP_ACP
, 0, ret_pathW
, -1, ret_path
, sizeof(ret_path
),NULL
,NULL
);
311 todo_wine_if (TEST_PATHFROMURL
[i
].todo
& 0x1)
312 ok(ret
== TEST_PATHFROMURL
[i
].ret
, "ret %08x from url L\"%s\"\n", ret
, TEST_PATHFROMURL
[i
].url
);
313 if(SUCCEEDED(ret
) && TEST_PATHFROMURL
[i
].path
) {
314 if(!(TEST_PATHFROMURL
[i
].todo
& 0x2)) {
315 ok(!lstrcmpiW(ret_pathW
, pathW
), "got %s expected %s from url L\"%s\"\n",
316 ret_path
, TEST_PATHFROMURL
[i
].path
, TEST_PATHFROMURL
[i
].url
);
317 ok(len
== lstrlenW(ret_pathW
), "ret len %d from url L\"%s\"\n", len
, TEST_PATHFROMURL
[i
].url
);
319 /* Wrong string, don't bother checking the length */
320 ok(!lstrcmpiW(ret_pathW
, pathW
), "got %s expected %s from url L\"%s\"\n",
321 ret_path
, TEST_PATHFROMURL
[i
].path
, TEST_PATHFROMURL
[i
].url
);
326 /* Check what happens if the buffer is too small */
328 ret
= pPathCreateFromUrlW(urlW
, ret_pathW
, &len2
, 0);
329 ok(ret
== E_POINTER
, "ret %08x, expected E_POINTER from url %s\n", ret
, TEST_PATHFROMURL
[i
].url
);
330 todo_wine_if (TEST_PATHFROMURL
[i
].todo
& 0x4)
331 ok(len2
== len
+ 1, "got len = %d expected %d from url %s\n", len2
, len
+ 1, TEST_PATHFROMURL
[i
].url
);
334 FreeWideString(urlW
);
335 FreeWideString(pathW
);
339 if (pPathCreateFromUrlAlloc
)
341 static const WCHAR fileW
[] = {'f','i','l','e',':','/','/','f','o','o',0};
342 static const WCHAR fooW
[] = {'\\','\\','f','o','o',0};
345 ret
= pPathCreateFromUrlAlloc(fileW
, &pathW
, 0);
346 ok(ret
== S_OK
, "got 0x%08x expected S_OK\n", ret
);
347 ok(lstrcmpiW(pathW
, fooW
) == 0, "got %s expected %s\n", wine_dbgstr_w(pathW
), wine_dbgstr_w(fooW
));
348 HeapFree(GetProcessHeap(), 0, pathW
);
353 static void test_PathIsUrl(void)
358 for(i
= 0; i
< sizeof(TEST_PATH_IS_URL
)/sizeof(TEST_PATH_IS_URL
[0]); i
++) {
359 ret
= PathIsURLA(TEST_PATH_IS_URL
[i
].path
);
360 ok(ret
== TEST_PATH_IS_URL
[i
].expect
,
361 "returned %d from path %s, expected %d\n", ret
, TEST_PATH_IS_URL
[i
].path
,
362 TEST_PATH_IS_URL
[i
].expect
);
366 static const DWORD SHELL_charclass
[] =
368 0x00000000, 0x00000000, 0x00000000, 0x00000000,
369 0x00000000, 0x00000000, 0x00000000, 0x00000000,
370 0x00000000, 0x00000000, 0x00000000, 0x00000000,
371 0x00000000, 0x00000000, 0x00000000, 0x00000000,
372 0x00000000, 0x00000000, 0x00000000, 0x00000000,
373 0x00000000, 0x00000000, 0x00000000, 0x00000000,
374 0x00000000, 0x00000000, 0x00000000, 0x00000000,
375 0x00000000, 0x00000000, 0x00000000, 0x00000000,
376 0x00000080, 0x00000100, 0x00000200, 0x00000100,
377 0x00000100, 0x00000100, 0x00000100, 0x00000100,
378 0x00000100, 0x00000100, 0x00000002, 0x00000100,
379 0x00000040, 0x00000100, 0x00000004, 0x00000000,
380 0x00000100, 0x00000100, 0x00000100, 0x00000100,
381 0x00000100, 0x00000100, 0x00000100, 0x00000100,
382 0x00000100, 0x00000100, 0x00000010, 0x00000020,
383 0x00000000, 0x00000100, 0x00000000, 0x00000001,
384 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
385 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
386 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
387 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
388 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
389 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
390 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
391 0x00000008, 0x00000100, 0x00000100, 0x00000100,
392 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
393 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
394 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
395 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
396 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
397 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
398 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
399 0x00000000, 0x00000100, 0x00000100
402 static void test_PathIsValidCharA(void)
407 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
408 * ordinal number in some native versions. Check this to prevent a crash.
410 if (!pPathIsValidCharA
|| pPathIsValidCharA
== (void*)pPathAppendA
)
412 win_skip("PathIsValidCharA isn't available\n");
416 for (c
= 0; c
< 0x7f; c
++)
418 ret
= pPathIsValidCharA( c
, ~0U );
419 ok ( ret
|| !SHELL_charclass
[c
], "PathIsValidCharA failed: 0x%02x got 0x%08x\n", c
, ret
);
422 for (c
= 0x7f; c
<= 0xff; c
++)
424 ret
= pPathIsValidCharA( c
, ~0U );
425 ok ( ret
, "PathIsValidCharA failed: 0x%02x got 0x%08x\n", c
, ret
);
429 static void test_PathIsValidCharW(void)
434 if (!pPathIsValidCharW
)
436 win_skip("PathIsValidCharW isn't available\n");
440 for (c
= 0; c
< 0x7f; c
++)
442 ret
= pPathIsValidCharW( c
, ~0U );
443 ok ( ret
|| !SHELL_charclass
[c
], "PathIsValidCharW failed: 0x%02x got 0x%08x\n", c
, ret
);
446 for (c
= 0x007f; c
<= 0xffff; c
++)
448 ret
= pPathIsValidCharW( c
, ~0U );
449 ok ( ret
, "PathIsValidCharW failed: 0x%02x got 0x%08x\n", c
, ret
);
453 static void test_PathMakePretty(void)
457 ok (PathMakePrettyA(NULL
) == FALSE
, "PathMakePretty: NULL path succeeded\n");
459 ok (PathMakePrettyA(buff
) == TRUE
, "PathMakePretty: Empty path failed\n");
461 strcpy(buff
, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
462 ok (PathMakePrettyA(buff
) == TRUE
, "PathMakePretty: Long UC name failed\n");
463 ok (strcmp(buff
, "C:\\a long file name with \\spaces.txt") == 0,
464 "PathMakePretty: Long UC name not changed\n");
466 strcpy(buff
, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
467 ok (PathMakePrettyA(buff
) == FALSE
, "PathMakePretty: Long MC name succeeded\n");
468 ok (strcmp(buff
, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
469 "PathMakePretty: Failed but modified path\n");
471 strcpy(buff
, "TEST");
472 ok (PathMakePrettyA(buff
) == TRUE
, "PathMakePretty: Short name failed\n");
473 ok (strcmp(buff
, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff
);
476 static void test_PathMatchSpec(void)
478 static const char file
[] = "c:\\foo\\bar\\filename.ext";
479 static const char spec1
[] = ".ext";
480 static const char spec2
[] = "*.ext";
481 static const char spec3
[] = "*.ext ";
482 static const char spec4
[] = " *.ext";
483 static const char spec5
[] = "* .ext";
484 static const char spec6
[] = "*. ext";
485 static const char spec7
[] = "* . ext";
486 static const char spec8
[] = "*.e?t";
487 static const char spec9
[] = "filename.ext";
488 static const char spec10
[] = "*bar\\filename.ext";
489 static const char spec11
[] = " foo; *.ext";
490 static const char spec12
[] = "*.ext;*.bar";
491 static const char spec13
[] = "*bar*";
493 ok (PathMatchSpecA(file
, spec1
) == FALSE
, "PathMatchSpec: Spec1 failed\n");
494 ok (PathMatchSpecA(file
, spec2
) == TRUE
, "PathMatchSpec: Spec2 failed\n");
495 ok (PathMatchSpecA(file
, spec3
) == FALSE
, "PathMatchSpec: Spec3 failed\n");
496 ok (PathMatchSpecA(file
, spec4
) == TRUE
, "PathMatchSpec: Spec4 failed\n");
497 todo_wine
ok (PathMatchSpecA(file
, spec5
) == TRUE
, "PathMatchSpec: Spec5 failed\n");
498 todo_wine
ok (PathMatchSpecA(file
, spec6
) == TRUE
, "PathMatchSpec: Spec6 failed\n");
499 ok (PathMatchSpecA(file
, spec7
) == FALSE
, "PathMatchSpec: Spec7 failed\n");
500 ok (PathMatchSpecA(file
, spec8
) == TRUE
, "PathMatchSpec: Spec8 failed\n");
501 ok (PathMatchSpecA(file
, spec9
) == FALSE
, "PathMatchSpec: Spec9 failed\n");
502 ok (PathMatchSpecA(file
, spec10
) == TRUE
, "PathMatchSpec: Spec10 failed\n");
503 ok (PathMatchSpecA(file
, spec11
) == TRUE
, "PathMatchSpec: Spec11 failed\n");
504 ok (PathMatchSpecA(file
, spec12
) == TRUE
, "PathMatchSpec: Spec12 failed\n");
505 ok (PathMatchSpecA(file
, spec13
) == TRUE
, "PathMatchSpec: Spec13 failed\n");
508 static void test_PathCombineW(void)
510 LPWSTR wszString
, wszString2
;
511 WCHAR wbuf
[MAX_PATH
+1], wstr1
[MAX_PATH
] = {'C',':','\\',0}, wstr2
[MAX_PATH
];
512 static const WCHAR expout
[] = {'C',':','\\','A','A',0};
517 win_skip("PathCombineW isn't available\n");
521 wszString2
= HeapAlloc(GetProcessHeap(), 0, MAX_PATH
* sizeof(WCHAR
));
524 wszString
= pPathCombineW(NULL
, NULL
, NULL
);
525 ok (wszString
== NULL
, "Expected a NULL return\n");
529 wszString
= pPathCombineW(wszString2
, NULL
, NULL
);
530 ok (wszString
== NULL
||
531 broken(wszString
[0] == 'a'), /* Win95 and some W2K */
532 "Expected a NULL return\n");
533 ok (wszString2
[0] == 0 ||
534 broken(wszString2
[0] == 'a'), /* Win95 and some W2K */
535 "Destination string not empty\n");
537 HeapFree(GetProcessHeap(), 0, wszString2
);
540 wstr2
[0] = wstr2
[1] = wstr2
[2] = 'A';
541 for (i
=3; i
<MAX_PATH
/2; i
++)
542 wstr1
[i
] = wstr2
[i
] = 'A';
543 wstr1
[(MAX_PATH
/2) - 1] = wstr2
[MAX_PATH
/2] = 0;
544 memset(wbuf
, 0xbf, sizeof(wbuf
));
546 wszString
= pPathCombineW(wbuf
, wstr1
, wstr2
);
547 ok(wszString
== NULL
, "Expected a NULL return\n");
549 broken(wbuf
[0] == 0xbfbf), /* Win95 and some W2K */
550 "Buffer contains data\n");
552 /* PathCombineW can be used in place */
555 ok(PathCombineW(wstr1
, wstr1
, wstr2
) == wstr1
, "Expected a wstr1 return\n");
556 ok(StrCmpW(wstr1
, expout
) == 0, "Unexpected PathCombine output\n");
560 #define LONG_LEN (MAX_PATH * 2)
561 #define HALF_LEN (MAX_PATH / 2 + 1)
563 static void test_PathCombineA(void)
567 char too_long
[LONG_LEN
];
568 char one
[HALF_LEN
], two
[HALF_LEN
];
571 SetLastError(0xdeadbeef);
572 str
= PathCombineA(NULL
, "C:\\", "one\\two\\three");
573 ok(str
== NULL
, "Expected NULL, got %p\n", str
);
574 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
576 /* try NULL dest and NULL directory */
577 SetLastError(0xdeadbeef);
578 str
= PathCombineA(NULL
, NULL
, "one\\two\\three");
579 ok(str
== NULL
, "Expected NULL, got %p\n", str
);
580 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
583 SetLastError(0xdeadbeef);
584 str
= PathCombineA(NULL
, NULL
, NULL
);
585 ok(str
== NULL
, "Expected NULL, got %p\n", str
);
586 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
588 /* try NULL file part */
589 SetLastError(0xdeadbeef);
590 lstrcpyA(dest
, "control");
591 str
= PathCombineA(dest
, "C:\\", NULL
);
592 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
593 ok(!lstrcmpA(str
, "C:\\"), "Expected C:\\, got %s\n", str
);
594 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
596 /* try empty file part */
597 SetLastError(0xdeadbeef);
598 lstrcpyA(dest
, "control");
599 str
= PathCombineA(dest
, "C:\\", "");
600 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
601 ok(!lstrcmpA(str
, "C:\\"), "Expected C:\\, got %s\n", str
);
602 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
604 /* try empty directory and file part */
605 SetLastError(0xdeadbeef);
606 lstrcpyA(dest
, "control");
607 str
= PathCombineA(dest
, "", "");
608 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
609 ok(!lstrcmpA(str
, "\\") ||
610 broken(!lstrcmpA(str
, "control")), /* Win95 and some W2K */
611 "Expected \\, got %s\n", str
);
612 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
614 /* try NULL directory */
615 SetLastError(0xdeadbeef);
616 lstrcpyA(dest
, "control");
617 str
= PathCombineA(dest
, NULL
, "one\\two\\three");
618 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
619 ok(!lstrcmpA(str
, "one\\two\\three"), "Expected one\\two\\three, got %s\n", str
);
620 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
622 /* try NULL directory and empty file part */
623 SetLastError(0xdeadbeef);
624 lstrcpyA(dest
, "control");
625 str
= PathCombineA(dest
, NULL
, "");
626 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
627 ok(!lstrcmpA(str
, "\\") ||
628 broken(!lstrcmpA(str
, "one\\two\\three")), /* Win95 and some W2K */
629 "Expected \\, got %s\n", str
);
630 ok(GetLastError() == 0xdeadbeef ||
631 broken(GetLastError() == ERROR_INVALID_PARAMETER
), /* Win95 */
632 "Expected 0xdeadbeef, got %d\n", GetLastError());
634 /* try NULL directory and file part */
635 SetLastError(0xdeadbeef);
636 lstrcpyA(dest
, "control");
637 str
= PathCombineA(dest
, NULL
, NULL
);
639 broken(str
!= NULL
), /* Win95 and some W2K */
640 "Expected str == NULL, got %p\n", str
);
641 ok(!dest
[0] || broken(!lstrcmpA(dest
, "control")), /* Win95 and some W2K */
642 "Expected 0 length, got %i\n", lstrlenA(dest
));
643 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
645 /* try directory without backslash */
646 SetLastError(0xdeadbeef);
647 lstrcpyA(dest
, "control");
648 str
= PathCombineA(dest
, "C:", "one\\two\\three");
649 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
650 ok(!lstrcmpA(str
, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str
);
651 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
653 /* try directory with backslash */
654 SetLastError(0xdeadbeef);
655 lstrcpyA(dest
, "control");
656 str
= PathCombineA(dest
, "C:\\", "one\\two\\three");
657 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
658 ok(!lstrcmpA(str
, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str
);
659 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
661 /* try directory with backslash and file with prepended backslash */
662 SetLastError(0xdeadbeef);
663 lstrcpyA(dest
, "control");
664 str
= PathCombineA(dest
, "C:\\", "\\one\\two\\three");
665 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
666 ok(!lstrcmpA(str
, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str
);
667 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
669 /* try previous test, with backslash appended as well */
670 SetLastError(0xdeadbeef);
671 lstrcpyA(dest
, "control");
672 str
= PathCombineA(dest
, "C:\\", "\\one\\two\\three\\");
673 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
674 ok(!lstrcmpA(str
, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str
);
675 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
677 /* try a relative directory */
678 SetLastError(0xdeadbeef);
679 lstrcpyA(dest
, "control");
680 str
= PathCombineA(dest
, "relative\\dir", "\\one\\two\\three\\");
681 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
682 /* Vista fails which probably makes sense as PathCombineA expects an absolute dir */
685 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
686 ok(!lstrcmpA(str
, "one\\two\\three\\"), "Expected one\\two\\three\\, got %s\n", str
);
689 /* try forward slashes */
690 SetLastError(0xdeadbeef);
691 lstrcpyA(dest
, "control");
692 str
= PathCombineA(dest
, "C:\\", "one/two/three\\");
693 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
694 ok(!lstrcmpA(str
, "C:\\one/two/three\\"), "Expected one/two/three\\, got %s\n", str
);
695 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
697 /* try a really weird directory */
698 SetLastError(0xdeadbeef);
699 lstrcpyA(dest
, "control");
700 str
= PathCombineA(dest
, "C:\\/\\/", "\\one\\two\\three\\");
701 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
702 ok(!lstrcmpA(str
, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str
);
703 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
706 SetLastError(0xdeadbeef);
707 lstrcpyA(dest
, "control");
708 str
= PathCombineA(dest
, "C:\\", "one\\..\\two\\.\\three");
709 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
710 ok(!lstrcmpA(str
, "C:\\two\\three"), "Expected C:\\two\\three, got %s\n", str
);
711 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
714 /* try forward slashes */
715 SetLastError(0xdeadbeef);
716 lstrcpyA(dest
, "control");
717 str
= PathCombineA(dest
, "C:\\", "..");
718 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
719 ok(!lstrcmpA(str
, "C:\\"), "Expected C:\\, got %s\n", str
);
720 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
722 memset(too_long
, 'a', LONG_LEN
);
723 too_long
[LONG_LEN
- 1] = '\0';
725 /* try a file longer than MAX_PATH */
726 SetLastError(0xdeadbeef);
727 lstrcpyA(dest
, "control");
728 str
= PathCombineA(dest
, "C:\\", too_long
);
729 ok(str
== NULL
, "Expected str == NULL, got %p\n", str
);
730 ok(!dest
[0] || broken(!lstrcmpA(dest
, "control")), /* Win95 and some W2K */
731 "Expected 0 length, got %i\n", lstrlenA(dest
));
732 todo_wine
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
734 /* try a directory longer than MAX_PATH */
735 SetLastError(0xdeadbeef);
736 lstrcpyA(dest
, "control");
737 str
= PathCombineA(dest
, too_long
, "one\\two\\three");
738 ok(str
== NULL
, "Expected str == NULL, got %p\n", str
);
739 ok(!dest
[0] || broken(!lstrcmpA(dest
, "control")), /* Win95 and some W2K */
740 "Expected 0 length, got %i\n", lstrlenA(dest
));
741 todo_wine
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
743 memset(one
, 'b', HALF_LEN
);
744 memset(two
, 'c', HALF_LEN
);
745 one
[HALF_LEN
- 1] = '\0';
746 two
[HALF_LEN
- 1] = '\0';
748 /* destination string is longer than MAX_PATH, but not the constituent parts */
749 SetLastError(0xdeadbeef);
750 lstrcpyA(dest
, "control");
751 str
= PathCombineA(dest
, one
, two
);
752 ok(str
== NULL
, "Expected str == NULL, got %p\n", str
);
753 ok(!dest
[0] || broken(!lstrcmpA(dest
, "control")), /* Win95 and some W2K */
754 "Expected 0 length, got %i\n", lstrlenA(dest
));
755 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
758 static void test_PathAddBackslash(void)
762 char too_long
[LONG_LEN
];
764 /* try a NULL path */
765 SetLastError(0xdeadbeef);
766 str
= PathAddBackslashA(NULL
);
767 ok(str
== NULL
, "Expected str == NULL, got %p\n", str
);
768 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
770 /* try an empty path */
772 SetLastError(0xdeadbeef);
773 str
= PathAddBackslashA(path
);
774 ok(str
== (path
+ lstrlenA(path
)), "Expected str to point to end of path, got %p\n", str
);
775 ok(!path
[0], "Expected empty string, got %i\n", lstrlenA(path
));
776 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
778 /* try a relative path */
779 lstrcpyA(path
, "one\\two");
780 SetLastError(0xdeadbeef);
781 str
= PathAddBackslashA(path
);
782 ok(str
== (path
+ lstrlenA(path
)), "Expected str to point to end of path, got %p\n", str
);
783 ok(!lstrcmpA(path
, "one\\two\\"), "Expected one\\two\\, got %s\n", path
);
784 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
787 lstrcpyA(path
, "one\\..\\two");
788 SetLastError(0xdeadbeef);
789 str
= PathAddBackslashA(path
);
790 ok(str
== (path
+ lstrlenA(path
)), "Expected str to point to end of path, got %p\n", str
);
791 ok(!lstrcmpA(path
, "one\\..\\two\\"), "Expected one\\..\\two\\, got %s\n", path
);
792 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
794 /* try just a space */
796 SetLastError(0xdeadbeef);
797 str
= PathAddBackslashA(path
);
798 ok(str
== (path
+ lstrlenA(path
)), "Expected str to point to end of path, got %p\n", str
);
799 ok(!lstrcmpA(path
, " \\"), "Expected \\, got %s\n", path
);
800 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
802 /* path already has backslash */
803 lstrcpyA(path
, "C:\\one\\");
804 SetLastError(0xdeadbeef);
805 str
= PathAddBackslashA(path
);
806 ok(str
== (path
+ lstrlenA(path
)), "Expected str to point to end of path, got %p\n", str
);
807 ok(!lstrcmpA(path
, "C:\\one\\"), "Expected C:\\one\\, got %s\n", path
);
808 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
810 memset(too_long
, 'a', LONG_LEN
);
811 too_long
[LONG_LEN
- 1] = '\0';
813 /* path is longer than MAX_PATH */
814 SetLastError(0xdeadbeef);
815 str
= PathAddBackslashA(too_long
);
816 ok(str
== NULL
, "Expected str == NULL, got %p\n", str
);
817 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
820 static void test_PathAppendA(void)
823 char too_long
[LONG_LEN
];
827 lstrcpyA(path
, "C:\\one");
829 /* try NULL pszMore */
830 SetLastError(0xdeadbeef);
831 res
= PathAppendA(path
, NULL
);
832 ok(!res
, "Expected failure\n");
833 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
834 ok(!lstrcmpA(path
, "C:\\one"), "Expected C:\\one, got %s\n", path
);
836 /* try empty pszMore */
837 SetLastError(0xdeadbeef);
838 res
= PathAppendA(path
, "");
839 ok(res
, "Expected success\n");
840 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
841 ok(!lstrcmpA(path
, "C:\\one"), "Expected C:\\one, got %s\n", path
);
843 /* try NULL pszPath */
844 SetLastError(0xdeadbeef);
845 res
= PathAppendA(NULL
, "two\\three");
846 ok(!res
, "Expected failure\n");
847 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
849 /* try empty pszPath */
851 SetLastError(0xdeadbeef);
852 res
= PathAppendA(path
, "two\\three");
853 ok(res
, "Expected success\n");
854 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
855 ok(!lstrcmpA(path
, "two\\three"), "Expected \\two\\three, got %s\n", path
);
857 /* try empty pszPath and empty pszMore */
859 SetLastError(0xdeadbeef);
860 res
= PathAppendA(path
, "");
861 ok(res
, "Expected success\n");
862 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
863 ok(!lstrcmpA(path
, "\\"), "Expected \\, got %s\n", path
);
865 /* try legit params */
866 lstrcpyA(path
, "C:\\one");
867 SetLastError(0xdeadbeef);
868 res
= PathAppendA(path
, "two\\three");
869 ok(res
, "Expected success\n");
870 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
871 ok(!lstrcmpA(path
, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path
);
873 /* try pszPath with backslash after it */
874 lstrcpyA(path
, "C:\\one\\");
875 SetLastError(0xdeadbeef);
876 res
= PathAppendA(path
, "two\\three");
877 ok(res
, "Expected success\n");
878 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
879 ok(!lstrcmpA(path
, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path
);
881 /* try pszMore with backslash before it */
882 lstrcpyA(path
, "C:\\one");
883 SetLastError(0xdeadbeef);
884 res
= PathAppendA(path
, "\\two\\three");
885 ok(res
, "Expected success\n");
886 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
887 ok(!lstrcmpA(path
, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path
);
889 /* try pszMore with backslash after it */
890 lstrcpyA(path
, "C:\\one");
891 SetLastError(0xdeadbeef);
892 res
= PathAppendA(path
, "two\\three\\");
893 ok(res
, "Expected success\n");
894 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
895 ok(!lstrcmpA(path
, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", path
);
897 /* try spaces in pszPath */
898 lstrcpyA(path
, "C: \\ one ");
899 SetLastError(0xdeadbeef);
900 res
= PathAppendA(path
, "two\\three");
901 ok(res
, "Expected success\n");
902 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
903 ok(!lstrcmpA(path
, "C: \\ one \\two\\three"), "Expected C: \\ one \\two\\three, got %s\n", path
);
905 /* try spaces in pszMore */
906 lstrcpyA(path
, "C:\\one");
907 SetLastError(0xdeadbeef);
908 res
= PathAppendA(path
, " two \\ three ");
909 ok(res
, "Expected success\n");
910 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
911 ok(!lstrcmpA(path
, "C:\\one\\ two \\ three "), "Expected 'C:\\one\\ two \\ three ', got %s\n", path
);
913 /* pszPath is too long */
914 memset(too_long
, 'a', LONG_LEN
);
915 too_long
[LONG_LEN
- 1] = '\0';
916 SetLastError(0xdeadbeef);
917 res
= PathAppendA(too_long
, "two\\three");
918 ok(!res
, "Expected failure\n");
919 todo_wine
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
920 ok(!too_long
[0] || broken(lstrlenA(too_long
) == (LONG_LEN
- 1)), /* Win95 and some W2K */
921 "Expected length of too_long to be zero, got %i\n", lstrlenA(too_long
));
923 /* pszMore is too long */
924 lstrcpyA(path
, "C:\\one");
925 memset(too_long
, 'a', LONG_LEN
);
926 too_long
[LONG_LEN
- 1] = '\0';
927 SetLastError(0xdeadbeef);
928 res
= PathAppendA(path
, too_long
);
929 ok(!res
, "Expected failure\n");
930 todo_wine
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
931 ok(!path
[0] || broken(!lstrcmpA(path
, "C:\\one")), /* Win95 and some W2K */
932 "Expected length of path to be zero, got %i\n", lstrlenA(path
));
934 /* both params combined are too long */
935 memset(path
, 'a', HALF_LEN
);
936 path
[HALF_LEN
- 1] = '\0';
937 memset(half
, 'b', HALF_LEN
);
938 half
[HALF_LEN
- 1] = '\0';
939 SetLastError(0xdeadbeef);
940 res
= PathAppendA(path
, half
);
941 ok(!res
, "Expected failure\n");
942 ok(!path
[0] || broken(lstrlenA(path
) == (HALF_LEN
- 1)), /* Win95 and some W2K */
943 "Expected length of path to be zero, got %i\n", lstrlenA(path
));
944 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
947 static void test_PathCanonicalizeA(void)
949 char dest
[LONG_LEN
+ MAX_PATH
];
950 char too_long
[LONG_LEN
];
953 /* try a NULL source */
954 lstrcpyA(dest
, "test");
955 SetLastError(0xdeadbeef);
956 res
= PathCanonicalizeA(dest
, NULL
);
957 ok(!res
, "Expected failure\n");
958 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
959 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
960 ok(dest
[0] == 0 || !lstrcmpA(dest
, "test"),
961 "Expected either an empty string (Vista) or test, got %s\n", dest
);
963 /* try an empty source */
964 lstrcpyA(dest
, "test");
965 SetLastError(0xdeadbeef);
966 res
= PathCanonicalizeA(dest
, "");
967 ok(res
, "Expected success\n");
968 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
969 ok(!lstrcmpA(dest
, "\\") ||
970 broken(!lstrcmpA(dest
, "test")), /* Win95 and some W2K */
971 "Expected \\, got %s\n", dest
);
973 /* try a NULL dest */
974 SetLastError(0xdeadbeef);
975 res
= PathCanonicalizeA(NULL
, "C:\\");
976 ok(!res
, "Expected failure\n");
977 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
978 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
982 SetLastError(0xdeadbeef);
983 res
= PathCanonicalizeA(dest
, "C:\\");
984 ok(res
, "Expected success\n");
985 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
986 ok(!lstrcmpA(dest
, "C:\\"), "Expected C:\\, got %s\n", dest
);
988 /* try non-empty dest */
989 lstrcpyA(dest
, "test");
990 SetLastError(0xdeadbeef);
991 res
= PathCanonicalizeA(dest
, "C:\\");
992 ok(res
, "Expected success\n");
993 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
994 ok(!lstrcmpA(dest
, "C:\\"), "Expected C:\\, got %s\n", dest
);
996 /* try a space for source */
997 lstrcpyA(dest
, "test");
998 SetLastError(0xdeadbeef);
999 res
= PathCanonicalizeA(dest
, " ");
1000 ok(res
, "Expected success\n");
1001 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1002 ok(!lstrcmpA(dest
, " "), "Expected ' ', got %s\n", dest
);
1004 /* try a relative path */
1005 lstrcpyA(dest
, "test");
1006 SetLastError(0xdeadbeef);
1007 res
= PathCanonicalizeA(dest
, "one\\two");
1008 ok(res
, "Expected success\n");
1009 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1010 ok(!lstrcmpA(dest
, "one\\two"), "Expected one\\two, got %s\n", dest
);
1012 /* try current dir and previous dir */
1013 lstrcpyA(dest
, "test");
1014 SetLastError(0xdeadbeef);
1015 res
= PathCanonicalizeA(dest
, "C:\\one\\.\\..\\two\\three\\..");
1016 ok(res
, "Expected success\n");
1017 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1018 ok(!lstrcmpA(dest
, "C:\\two"), "Expected C:\\two, got %s\n", dest
);
1020 /* try simple forward slashes */
1021 lstrcpyA(dest
, "test");
1022 SetLastError(0xdeadbeef);
1023 res
= PathCanonicalizeA(dest
, "C:\\one/two/three\\four/five\\six");
1024 ok(res
, "Expected success\n");
1025 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1026 ok(!lstrcmpA(dest
, "C:\\one/two/three\\four/five\\six"),
1027 "Expected C:\\one/two/three\\four/five\\six, got %s\n", dest
);
1029 /* try simple forward slashes with same dir */
1030 lstrcpyA(dest
, "test");
1031 SetLastError(0xdeadbeef);
1032 res
= PathCanonicalizeA(dest
, "C:\\one/.\\two");
1033 ok(res
, "Expected success\n");
1034 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1035 ok(!lstrcmpA(dest
, "C:\\one/.\\two"), "Expected C:\\one/.\\two, got %s\n", dest
);
1037 /* try simple forward slashes with change dir */
1038 lstrcpyA(dest
, "test");
1039 SetLastError(0xdeadbeef);
1040 res
= PathCanonicalizeA(dest
, "C:\\one/.\\two\\..");
1041 ok(res
, "Expected success\n");
1042 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1043 ok(!lstrcmpA(dest
, "C:\\one/.") ||
1044 !lstrcmpA(dest
, "C:\\one/"), /* Vista */
1045 "Expected \"C:\\one/.\" or \"C:\\one/\", got \"%s\"\n", dest
);
1047 /* try forward slashes with change dirs
1048 * NOTE: if there is a forward slash in between two backslashes,
1049 * everything in between the two backslashes is considered on dir
1051 lstrcpyA(dest
, "test");
1052 SetLastError(0xdeadbeef);
1053 res
= PathCanonicalizeA(dest
, "C:\\one/.\\..\\two/three\\..\\four/.five");
1054 ok(res
, "Expected success\n");
1055 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1056 ok(!lstrcmpA(dest
, "C:\\four/.five"), "Expected C:\\four/.five, got %s\n", dest
);
1058 /* try src is too long */
1059 memset(too_long
, 'a', LONG_LEN
);
1060 too_long
[LONG_LEN
- 1] = '\0';
1061 lstrcpyA(dest
, "test");
1062 SetLastError(0xdeadbeef);
1063 res
= PathCanonicalizeA(dest
, too_long
);
1065 broken(res
), /* Win95, some W2K and XP-SP1 */
1066 "Expected failure\n");
1069 ok(GetLastError() == 0xdeadbeef || GetLastError() == ERROR_FILENAME_EXCED_RANGE
/* Vista */,
1070 "Expected 0xdeadbeef or ERROR_FILENAME_EXCED_RANGE, got %d\n", GetLastError());
1072 ok(lstrlenA(too_long
) == LONG_LEN
- 1, "Expected length LONG_LEN - 1, got %i\n", lstrlenA(too_long
));
1075 static void test_PathFindExtensionA(void)
1078 char path
[MAX_PATH
];
1079 char too_long
[LONG_LEN
];
1081 /* try a NULL path */
1082 SetLastError(0xdeadbeef);
1083 ext
= PathFindExtensionA(NULL
);
1084 ok(ext
== NULL
, "Expected NULL, got %p\n", ext
);
1085 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1087 /* try an empty path */
1089 SetLastError(0xdeadbeef);
1090 ext
= PathFindExtensionA(path
);
1091 ok(ext
== path
, "Expected ext == path, got %p\n", ext
);
1092 ok(!ext
[0], "Expected length 0, got %i\n", lstrlenA(ext
));
1093 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1095 /* try a path without an extension */
1096 lstrcpyA(path
, "file");
1097 SetLastError(0xdeadbeef);
1098 ext
= PathFindExtensionA(path
);
1099 ok(ext
== path
+ lstrlenA(path
), "Expected ext == path, got %p\n", ext
);
1100 ok(!ext
[0], "Expected length 0, got %i\n", lstrlenA(ext
));
1101 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1103 /* try a path with an extension */
1104 lstrcpyA(path
, "file.txt");
1105 SetLastError(0xdeadbeef);
1106 ext
= PathFindExtensionA(path
);
1107 ok(ext
== path
+ lstrlenA("file"),
1108 "Expected ext == path + lstrlenA(\"file\"), got %p\n", ext
);
1109 ok(!lstrcmpA(ext
, ".txt"), "Expected .txt, got %s\n", ext
);
1110 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1112 /* try a path with two extensions */
1113 lstrcpyA(path
, "file.txt.doc");
1114 SetLastError(0xdeadbeef);
1115 ext
= PathFindExtensionA(path
);
1116 ok(ext
== path
+ lstrlenA("file.txt"),
1117 "Expected ext == path + lstrlenA(\"file.txt\"), got %p\n", ext
);
1118 ok(!lstrcmpA(ext
, ".doc"), "Expected .txt, got %s\n", ext
);
1119 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1121 /* try a path longer than MAX_PATH without an extension*/
1122 memset(too_long
, 'a', LONG_LEN
);
1123 too_long
[LONG_LEN
- 1] = '\0';
1124 SetLastError(0xdeadbeef);
1125 ext
= PathFindExtensionA(too_long
);
1126 ok(ext
== too_long
+ LONG_LEN
- 1, "Expected ext == too_long + LONG_LEN - 1, got %p\n", ext
);
1127 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1129 /* try a path longer than MAX_PATH with an extension*/
1130 memset(too_long
, 'a', LONG_LEN
);
1131 too_long
[LONG_LEN
- 1] = '\0';
1132 lstrcpyA(too_long
+ 300, ".abcde");
1133 too_long
[lstrlenA(too_long
)] = 'a';
1134 SetLastError(0xdeadbeef);
1135 ext
= PathFindExtensionA(too_long
);
1136 ok(ext
== too_long
+ 300, "Expected ext == too_long + 300, got %p\n", ext
);
1137 ok(lstrlenA(ext
) == LONG_LEN
- 301, "Expected LONG_LEN - 301, got %i\n", lstrlenA(ext
));
1138 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1141 static void test_PathBuildRootA(void)
1145 char root_expected
[26][4];
1149 /* set up the expected paths */
1150 for (drive
= 'A'; drive
<= 'Z'; drive
++)
1151 sprintf(root_expected
[drive
- 'A'], "%c:\\", drive
);
1153 /* test the expected values */
1154 for (j
= 0; j
< 26; j
++)
1156 SetLastError(0xdeadbeef);
1157 lstrcpyA(path
, "aaaaaaaaa");
1158 root
= PathBuildRootA(path
, j
);
1159 ok(root
== path
, "Expected root == path, got %p\n", root
);
1160 ok(!lstrcmpA(root
, root_expected
[j
]), "Expected %s, got %s\n", root_expected
[j
], root
);
1161 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1164 /* test a negative drive number */
1165 SetLastError(0xdeadbeef);
1166 lstrcpyA(path
, "aaaaaaaaa");
1167 root
= PathBuildRootA(path
, -1);
1168 ok(root
== path
, "Expected root == path, got %p\n", root
);
1169 ok(!lstrcmpA(path
, "aaaaaaaaa") || !path
[0], /* Vista */
1170 "Expected aaaaaaaaa or empty string, got %s\n", path
);
1171 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1173 /* test a drive number greater than 25 */
1174 SetLastError(0xdeadbeef);
1175 lstrcpyA(path
, "aaaaaaaaa");
1176 root
= PathBuildRootA(path
, 26);
1177 ok(root
== path
, "Expected root == path, got %p\n", root
);
1178 ok(!lstrcmpA(path
, "aaaaaaaaa") || !path
[0], /* Vista */
1179 "Expected aaaaaaaaa or empty string, got %s\n", path
);
1180 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1182 /* length of path is less than 4 */
1183 SetLastError(0xdeadbeef);
1184 lstrcpyA(path
, "aa");
1185 root
= PathBuildRootA(path
, 0);
1186 ok(root
== path
, "Expected root == path, got %p\n", root
);
1187 ok(!lstrcmpA(path
, "A:\\"), "Expected A:\\, got %s\n", path
);
1188 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1191 SetLastError(0xdeadbeef);
1192 root
= PathBuildRootA(NULL
, 0);
1193 ok(root
== NULL
, "Expected root == NULL, got %p\n", root
);
1194 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1197 static void test_PathCommonPrefixA(void)
1199 char path1
[MAX_PATH
], path2
[MAX_PATH
];
1203 /* test NULL path1 */
1204 SetLastError(0xdeadbeef);
1205 lstrcpyA(path2
, "C:\\");
1206 lstrcpyA(out
, "aaa");
1207 count
= PathCommonPrefixA(NULL
, path2
, out
);
1208 ok(count
== 0, "Expected 0, got %i\n", count
);
1211 ok(!lstrcmpA(out
, "aaa"), "Expected aaa, got %s\n", out
);
1213 ok(!lstrcmpA(path2
, "C:\\"), "Expected C:\\, got %s\n", path2
);
1214 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1216 /* test NULL path2 */
1217 SetLastError(0xdeadbeef);
1218 lstrcpyA(path1
, "C:\\");
1219 lstrcpyA(out
, "aaa");
1220 count
= PathCommonPrefixA(path1
, NULL
, out
);
1221 ok(count
== 0, "Expected 0, got %i\n", count
);
1224 ok(!lstrcmpA(out
, "aaa"), "Expected aaa, got %s\n", out
);
1226 ok(!lstrcmpA(path1
, "C:\\"), "Expected C:\\, got %s\n", path1
);
1227 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1229 /* test empty path1 */
1230 SetLastError(0xdeadbeef);
1232 lstrcpyA(path2
, "C:\\");
1233 lstrcpyA(out
, "aaa");
1234 count
= PathCommonPrefixA(path1
, path2
, out
);
1235 ok(count
== 0, "Expected 0, got %i\n", count
);
1236 ok(!out
[0], "Expected 0 length out, got %i\n", lstrlenA(out
));
1237 ok(!path1
[0], "Expected 0 length path1, got %i\n", lstrlenA(path1
));
1238 ok(!lstrcmpA(path2
, "C:\\"), "Expected C:\\, got %s\n", path2
);
1239 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1241 /* test empty path1 */
1242 SetLastError(0xdeadbeef);
1244 lstrcpyA(path1
, "C:\\");
1245 lstrcpyA(out
, "aaa");
1246 count
= PathCommonPrefixA(path1
, path2
, out
);
1247 ok(count
== 0, "Expected 0, got %i\n", count
);
1248 ok(!out
[0], "Expected 0 length out, got %i\n", lstrlenA(out
));
1249 ok(!path2
[0], "Expected 0 length path2, got %i\n", lstrlenA(path2
));
1250 ok(!lstrcmpA(path1
, "C:\\"), "Expected C:\\, got %s\n", path1
);
1251 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1253 /* paths are legit, out is NULL */
1254 SetLastError(0xdeadbeef);
1255 lstrcpyA(path1
, "C:\\");
1256 lstrcpyA(path2
, "C:\\");
1257 count
= PathCommonPrefixA(path1
, path2
, NULL
);
1258 ok(count
== 3, "Expected 3, got %i\n", count
);
1259 ok(!lstrcmpA(path1
, "C:\\"), "Expected C:\\, got %s\n", path1
);
1260 ok(!lstrcmpA(path2
, "C:\\"), "Expected C:\\, got %s\n", path2
);
1261 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1263 /* all parameters legit */
1264 SetLastError(0xdeadbeef);
1265 lstrcpyA(path1
, "C:\\");
1266 lstrcpyA(path2
, "C:\\");
1267 lstrcpyA(out
, "aaa");
1268 count
= PathCommonPrefixA(path1
, path2
, out
);
1269 ok(count
== 3, "Expected 3, got %i\n", count
);
1270 ok(!lstrcmpA(path1
, "C:\\"), "Expected C:\\, got %s\n", path1
);
1271 ok(!lstrcmpA(path2
, "C:\\"), "Expected C:\\, got %s\n", path2
);
1272 ok(!lstrcmpA(out
, "C:\\"), "Expected C:\\, got %s\n", out
);
1273 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1275 /* path1 and path2 not the same, but common prefix */
1276 SetLastError(0xdeadbeef);
1277 lstrcpyA(path1
, "C:\\one\\two");
1278 lstrcpyA(path2
, "C:\\one\\three");
1279 lstrcpyA(out
, "aaa");
1280 count
= PathCommonPrefixA(path1
, path2
, out
);
1281 ok(count
== 6, "Expected 6, got %i\n", count
);
1282 ok(!lstrcmpA(path1
, "C:\\one\\two"), "Expected C:\\one\\two, got %s\n", path1
);
1283 ok(!lstrcmpA(path2
, "C:\\one\\three"), "Expected C:\\one\\three, got %s\n", path2
);
1284 ok(!lstrcmpA(out
, "C:\\one"), "Expected C:\\one, got %s\n", out
);
1285 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1288 SetLastError(0xdeadbeef);
1289 lstrcpyA(path1
, "one\\.two");
1290 lstrcpyA(path2
, "one\\.three");
1291 lstrcpyA(out
, "aaa");
1292 count
= PathCommonPrefixA(path1
, path2
, out
);
1293 ok(count
== 3, "Expected 3, got %i\n", count
);
1294 ok(!lstrcmpA(path1
, "one\\.two"), "Expected one\\.two, got %s\n", path1
);
1295 ok(!lstrcmpA(path2
, "one\\.three"), "Expected one\\.three, got %s\n", path2
);
1296 ok(!lstrcmpA(out
, "one"), "Expected one, got %s\n", out
);
1297 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1300 SetLastError(0xdeadbeef);
1301 lstrcpyA(path1
, "one\\..two");
1302 lstrcpyA(path2
, "one\\..three");
1303 lstrcpyA(out
, "aaa");
1304 count
= PathCommonPrefixA(path1
, path2
, out
);
1305 ok(count
== 3, "Expected 3, got %i\n", count
);
1306 ok(!lstrcmpA(path1
, "one\\..two"), "Expected one\\..two, got %s\n", path1
);
1307 ok(!lstrcmpA(path2
, "one\\..three"), "Expected one\\..three, got %s\n", path2
);
1308 ok(!lstrcmpA(out
, "one"), "Expected one, got %s\n", out
);
1309 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1311 /* try ... prefix */
1312 SetLastError(0xdeadbeef);
1313 lstrcpyA(path1
, "one\\...two");
1314 lstrcpyA(path2
, "one\\...three");
1315 lstrcpyA(out
, "aaa");
1316 count
= PathCommonPrefixA(path1
, path2
, out
);
1317 ok(count
== 3, "Expected 3, got %i\n", count
);
1318 ok(!lstrcmpA(path1
, "one\\...two"), "Expected one\\...two, got %s\n", path1
);
1319 ok(!lstrcmpA(path2
, "one\\...three"), "Expected one\\...three, got %s\n", path2
);
1320 ok(!lstrcmpA(out
, "one"), "Expected one, got %s\n", out
);
1321 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1324 SetLastError(0xdeadbeef);
1325 lstrcpyA(path1
, "one\\.\\two");
1326 lstrcpyA(path2
, "one\\.\\three");
1327 lstrcpyA(out
, "aaa");
1328 count
= PathCommonPrefixA(path1
, path2
, out
);
1329 ok(count
== 5, "Expected 5, got %i\n", count
);
1330 ok(!lstrcmpA(path1
, "one\\.\\two"), "Expected one\\.\\two, got %s\n", path1
);
1331 ok(!lstrcmpA(path2
, "one\\.\\three"), "Expected one\\.\\three, got %s\n", path2
);
1332 ok(!lstrcmpA(out
, "one\\."), "Expected one\\., got %s\n", out
);
1333 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1335 /* try ..\ prefix */
1336 SetLastError(0xdeadbeef);
1337 lstrcpyA(path1
, "one\\..\\two");
1338 lstrcpyA(path2
, "one\\..\\three");
1339 lstrcpyA(out
, "aaa");
1340 count
= PathCommonPrefixA(path1
, path2
, out
);
1341 ok(count
== 6, "Expected 6, got %i\n", count
);
1342 ok(!lstrcmpA(path1
, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1
);
1343 ok(!lstrcmpA(path2
, "one\\..\\three"), "Expected one\\..\\three, got %s\n", path2
);
1344 ok(!lstrcmpA(out
, "one\\.."), "Expected one\\.., got %s\n", out
);
1345 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1347 /* try ...\\ prefix */
1348 SetLastError(0xdeadbeef);
1349 lstrcpyA(path1
, "one\\...\\two");
1350 lstrcpyA(path2
, "one\\...\\three");
1351 lstrcpyA(out
, "aaa");
1352 count
= PathCommonPrefixA(path1
, path2
, out
);
1353 ok(count
== 7, "Expected 7, got %i\n", count
);
1354 ok(!lstrcmpA(path1
, "one\\...\\two"), "Expected one\\...\\two, got %s\n", path1
);
1355 ok(!lstrcmpA(path2
, "one\\...\\three"), "Expected one\\...\\three, got %s\n", path2
);
1356 ok(!lstrcmpA(out
, "one\\..."), "Expected one\\..., got %s\n", out
);
1357 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1359 /* try prefix that is not an msdn labeled prefix type */
1360 SetLastError(0xdeadbeef);
1361 lstrcpyA(path1
, "same");
1362 lstrcpyA(path2
, "same");
1363 lstrcpyA(out
, "aaa");
1364 count
= PathCommonPrefixA(path1
, path2
, out
);
1365 ok(count
== 4, "Expected 4, got %i\n", count
);
1366 ok(!lstrcmpA(path1
, "same"), "Expected same, got %s\n", path1
);
1367 ok(!lstrcmpA(path2
, "same"), "Expected same, got %s\n", path2
);
1368 ok(!lstrcmpA(out
, "same"), "Expected same, got %s\n", out
);
1369 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1371 /* try . after directory */
1372 SetLastError(0xdeadbeef);
1373 lstrcpyA(path1
, "one\\mid.\\two");
1374 lstrcpyA(path2
, "one\\mid.\\three");
1375 lstrcpyA(out
, "aaa");
1376 count
= PathCommonPrefixA(path1
, path2
, out
);
1377 ok(count
== 8, "Expected 8, got %i\n", count
);
1378 ok(!lstrcmpA(path1
, "one\\mid.\\two"), "Expected one\\mid.\\two, got %s\n", path1
);
1379 ok(!lstrcmpA(path2
, "one\\mid.\\three"), "Expected one\\mid.\\three, got %s\n", path2
);
1380 ok(!lstrcmpA(out
, "one\\mid."), "Expected one\\mid., got %s\n", out
);
1381 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1383 /* try . in the middle of a directory */
1384 SetLastError(0xdeadbeef);
1385 lstrcpyA(path1
, "one\\mid.end\\two");
1386 lstrcpyA(path2
, "one\\mid.end\\three");
1387 lstrcpyA(out
, "aaa");
1388 count
= PathCommonPrefixA(path1
, path2
, out
);
1389 ok(count
== 11, "Expected 11, got %i\n", count
);
1390 ok(!lstrcmpA(path1
, "one\\mid.end\\two"), "Expected one\\mid.end\\two, got %s\n", path1
);
1391 ok(!lstrcmpA(path2
, "one\\mid.end\\three"), "Expected one\\mid.end\\three, got %s\n", path2
);
1392 ok(!lstrcmpA(out
, "one\\mid.end"), "Expected one\\mid.end, got %s\n", out
);
1393 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1395 /* try comparing a .. with the expanded path */
1396 SetLastError(0xdeadbeef);
1397 lstrcpyA(path1
, "one\\..\\two");
1398 lstrcpyA(path2
, "two");
1399 lstrcpyA(out
, "aaa");
1400 count
= PathCommonPrefixA(path1
, path2
, out
);
1401 ok(count
== 0, "Expected 0, got %i\n", count
);
1402 ok(!lstrcmpA(path1
, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1
);
1403 ok(!lstrcmpA(path2
, "two"), "Expected two, got %s\n", path2
);
1404 ok(!out
[0], "Expected 0 length out, got %i\n", lstrlenA(out
));
1405 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1408 static void test_PathUnquoteSpaces(void)
1411 for(i
= 0; i
< sizeof(TEST_PATH_UNQUOTE_SPACES
) / sizeof(TEST_PATH_UNQUOTE_SPACES
[0]); i
++)
1413 char *path
= strdupA(TEST_PATH_UNQUOTE_SPACES
[i
].path
);
1414 WCHAR
*pathW
= GetWideString(TEST_PATH_UNQUOTE_SPACES
[i
].path
);
1415 WCHAR
*resultW
= GetWideString(TEST_PATH_UNQUOTE_SPACES
[i
].result
);
1417 PathUnquoteSpacesA(path
);
1418 ok(!strcmp(path
, TEST_PATH_UNQUOTE_SPACES
[i
].result
), "%s (A): got %s expected %s\n",
1419 TEST_PATH_UNQUOTE_SPACES
[i
].path
, path
,
1420 TEST_PATH_UNQUOTE_SPACES
[i
].result
);
1422 PathUnquoteSpacesW(pathW
);
1423 ok(!lstrcmpW(pathW
, resultW
), "%s (W): strings differ\n",
1424 TEST_PATH_UNQUOTE_SPACES
[i
].path
);
1425 FreeWideString(pathW
);
1426 FreeWideString(resultW
);
1427 HeapFree(GetProcessHeap(), 0, path
);
1431 static void test_PathGetDriveNumber(void)
1433 static const CHAR test1A
[] = "a:\\test.file";
1434 static const CHAR test2A
[] = "file:////b:\\test.file";
1435 static const CHAR test3A
[] = "file:///c:\\test.file";
1436 static const CHAR test4A
[] = "file:\\\\c:\\test.file";
1439 SetLastError(0xdeadbeef);
1440 ret
= PathGetDriveNumberA(NULL
);
1441 ok(ret
== -1, "got %d\n", ret
);
1442 ok(GetLastError() == 0xdeadbeef, "got %d\n", GetLastError());
1444 ret
= PathGetDriveNumberA(test1A
);
1445 ok(ret
== 0, "got %d\n", ret
);
1446 ret
= PathGetDriveNumberA(test2A
);
1447 ok(ret
== -1, "got %d\n", ret
);
1448 ret
= PathGetDriveNumberA(test3A
);
1449 ok(ret
== -1, "got %d\n", ret
);
1450 ret
= PathGetDriveNumberA(test4A
);
1451 ok(ret
== -1, "got %d\n", ret
);
1454 static void test_PathUnExpandEnvStrings(void)
1456 static const WCHAR sysrootW
[] = {'%','S','y','s','t','e','m','R','o','o','t','%',0};
1457 static const WCHAR sysdriveW
[] = {'%','S','y','s','t','e','m','D','r','i','v','e','%',0};
1458 static const WCHAR nonpathW
[] = {'p','a','t','h',0};
1459 static const char sysrootA
[] = "%SystemRoot%";
1460 static const char sysdriveA
[] = "%SystemDrive%";
1461 WCHAR pathW
[MAX_PATH
], buffW
[MAX_PATH
], sysdrvW
[3];
1462 char path
[MAX_PATH
], buff
[MAX_PATH
], sysdrvA
[3], envvarA
[10];
1466 if (!pPathUnExpandEnvStringsA
|| !pPathUnExpandEnvStringsW
)
1468 win_skip("PathUnExpandEnvStrings not available\n");
1472 /* something that can't be represented with env var */
1473 strcpy(path
, "somepath_name");
1475 SetLastError(0xdeadbeef);
1476 ret
= pPathUnExpandEnvStringsA(path
, buff
, sizeof(buff
));
1477 ok(!ret
&& GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret
, GetLastError());
1478 ok(buff
[0] == 'x', "wrong return string %s\n", buff
);
1480 len
= GetSystemDirectoryA(path
, MAX_PATH
);
1481 ok(len
> 0, "failed to get sysdir\n");
1483 sysdrvA
[0] = path
[0];
1484 strcpy(&sysdrvA
[1], ":");
1486 /* buffer size is not enough */
1488 SetLastError(0xdeadbeef);
1489 ret
= pPathUnExpandEnvStringsA(path
, buff
, 5);
1490 ok(!ret
&& GetLastError() == 0xdeadbeef, "got %d\n", ret
);
1491 ok(buff
[0] == 'x', "wrong return string %s\n", buff
);
1493 /* buffer size is enough to hold variable name only */
1495 SetLastError(0xdeadbeef);
1496 ret
= pPathUnExpandEnvStringsA(path
, buff
, sizeof(sysrootA
));
1497 ok(!ret
&& GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret
, GetLastError());
1498 ok(buff
[0] == 'x', "wrong return string %s\n", buff
);
1502 ret
= pPathUnExpandEnvStringsA(path
, buff
, sizeof(buff
));
1503 ok(ret
, "got %d\n", ret
);
1504 ok(!strncmp(buff
, sysrootA
, sizeof(sysrootA
)-1), "wrong return string %s\n", buff
);
1506 /* expanded value occurs multiple times */
1507 /* for drive C: it unexpands it like 'C:C:' -> '%SystemDrive%C:' */
1509 strcpy(path
, sysdrvA
);
1510 strcat(path
, sysdrvA
);
1511 ret
= pPathUnExpandEnvStringsA(path
, buff
, sizeof(buff
));
1512 ok(ret
, "got %d\n", ret
);
1513 /* expected string */
1514 strcpy(path
, sysdriveA
);
1515 strcat(path
, sysdrvA
);
1516 ok(!strcmp(buff
, path
), "wrong unexpanded string %s, expected %s\n", buff
, path
);
1518 /* now with altered variable */
1519 ret
= GetEnvironmentVariableA("SystemDrive", envvarA
, sizeof(envvarA
));
1520 ok(ret
, "got %d\n", ret
);
1522 ret
= SetEnvironmentVariableA("SystemDrive", "WW");
1523 ok(ret
, "got %d\n", ret
);
1525 /* variables are not cached */
1526 strcpy(path
, sysdrvA
);
1527 strcat(path
, sysdrvA
);
1528 SetLastError(0xdeadbeef);
1529 ret
= pPathUnExpandEnvStringsA(path
, buff
, sizeof(buff
));
1530 ok(!ret
&& GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret
, GetLastError());
1532 ret
= SetEnvironmentVariableA("SystemDrive", envvarA
);
1533 ok(ret
, "got %d\n", ret
);
1535 /* PathUnExpandEnvStringsW */
1537 /* something that can't be represented with env var */
1538 lstrcpyW(pathW
, nonpathW
);
1539 buffW
[0] = 'x'; buffW
[1] = 0;
1540 SetLastError(0xdeadbeef);
1541 ret
= pPathUnExpandEnvStringsW(pathW
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1542 ok(!ret
&& GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret
, GetLastError());
1543 ok(buffW
[0] == 'x', "wrong return string %s\n", wine_dbgstr_w(buffW
));
1545 len
= GetSystemDirectoryW(pathW
, MAX_PATH
);
1546 ok(len
> 0, "failed to get sysdir\n");
1548 sysdrvW
[0] = pathW
[0];
1552 /* buffer size is not enough */
1553 buffW
[0] = 'x'; buffW
[1] = 0;
1554 SetLastError(0xdeadbeef);
1555 ret
= pPathUnExpandEnvStringsW(pathW
, buffW
, 5);
1556 ok(!ret
&& GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret
, GetLastError());
1557 ok(buffW
[0] == 'x', "wrong return string %s\n", wine_dbgstr_w(buffW
));
1559 /* buffer size is enough to hold variable name only */
1560 buffW
[0] = 'x'; buffW
[1] = 0;
1561 SetLastError(0xdeadbeef);
1562 ret
= pPathUnExpandEnvStringsW(pathW
, buffW
, sizeof(sysrootW
)/sizeof(WCHAR
));
1563 ok(!ret
&& GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret
, GetLastError());
1564 ok(buffW
[0] == 'x', "wrong return string %s\n", wine_dbgstr_w(buffW
));
1568 ret
= pPathUnExpandEnvStringsW(pathW
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1569 ok(ret
, "got %d\n", ret
);
1570 ok(!memcmp(buffW
, sysrootW
, sizeof(sysrootW
) - sizeof(WCHAR
)), "wrong return string %s\n", wine_dbgstr_w(buffW
));
1572 /* expanded value occurs multiple times */
1573 /* for drive C: it unexpands it like 'C:C:' -> '%SystemDrive%C:' */
1575 lstrcpyW(pathW
, sysdrvW
);
1576 lstrcatW(pathW
, sysdrvW
);
1577 ret
= pPathUnExpandEnvStringsW(pathW
, buffW
, sizeof(buff
)/sizeof(WCHAR
));
1578 ok(ret
, "got %d\n", ret
);
1579 /* expected string */
1580 lstrcpyW(pathW
, sysdriveW
);
1581 lstrcatW(pathW
, sysdrvW
);
1582 ok(!lstrcmpW(buffW
, pathW
), "wrong unexpanded string %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(pathW
));
1585 static const struct {
1588 } test_path_is_relative
[] = {
1592 {"\\\\folder\\test.txt", FALSE
},
1593 {"file://folder/test.txt", TRUE
},
1594 {"C:\\test.txt", FALSE
},
1595 {"file:///C:/test.txt", TRUE
}
1598 static void test_PathIsRelativeA(void)
1603 if (!pPathIsRelativeA
) {
1604 win_skip("PathIsRelativeA not available\n");
1608 num
= sizeof(test_path_is_relative
) / sizeof(test_path_is_relative
[0]);
1609 for (i
= 0; i
< num
; i
++) {
1610 ret
= pPathIsRelativeA(test_path_is_relative
[i
].path
);
1611 ok(ret
== test_path_is_relative
[i
].expect
,
1612 "PathIsRelativeA(\"%s\") expects %d, got %d.\n",
1613 test_path_is_relative
[i
].path
, test_path_is_relative
[i
].expect
, ret
);
1617 static void test_PathIsRelativeW(void)
1623 if (!pPathIsRelativeW
) {
1624 win_skip("PathIsRelativeW not available\n");
1628 num
= sizeof(test_path_is_relative
) / sizeof(test_path_is_relative
[0]);
1629 for (i
= 0; i
< num
; i
++) {
1630 path
= GetWideString(test_path_is_relative
[i
].path
);
1632 ret
= pPathIsRelativeW(path
);
1633 ok(ret
== test_path_is_relative
[i
].expect
,
1634 "PathIsRelativeW(\"%s\") expects %d, got %d.\n",
1635 test_path_is_relative
[i
].path
, test_path_is_relative
[i
].expect
, ret
);
1637 FreeWideString(path
);
1641 static void test_PathStripPathA(void)
1643 const char const_path
[] = "test";
1644 char path
[] = "short//path\\file.txt";
1646 PathStripPathA(path
);
1647 ok(!strcmp(path
, "file.txt"), "path = %s\n", path
);
1649 /* following test should not crash */
1650 /* LavView 2013 depends on that behaviour */
1651 PathStripPathA((char*)const_path
);
1656 HMODULE hShlwapi
= GetModuleHandleA("shlwapi.dll");
1658 /* SHCreateStreamOnFileEx was introduced in shlwapi v6.0 */
1659 if(!GetProcAddress(hShlwapi
, "SHCreateStreamOnFileEx")){
1660 win_skip("Too old shlwapi version\n");
1664 pPathCreateFromUrlA
= (void*)GetProcAddress(hShlwapi
, "PathCreateFromUrlA");
1665 pPathCreateFromUrlW
= (void*)GetProcAddress(hShlwapi
, "PathCreateFromUrlW");
1666 pPathCreateFromUrlAlloc
= (void*)GetProcAddress(hShlwapi
, "PathCreateFromUrlAlloc");
1667 pPathCombineW
= (void*)GetProcAddress(hShlwapi
, "PathCombineW");
1668 pPathIsValidCharA
= (void*)GetProcAddress(hShlwapi
, (LPSTR
)455);
1669 pPathIsValidCharW
= (void*)GetProcAddress(hShlwapi
, (LPSTR
)456);
1670 pPathAppendA
= (void*)GetProcAddress(hShlwapi
, "PathAppendA");
1671 pPathUnExpandEnvStringsA
= (void*)GetProcAddress(hShlwapi
, "PathUnExpandEnvStringsA");
1672 pPathUnExpandEnvStringsW
= (void*)GetProcAddress(hShlwapi
, "PathUnExpandEnvStringsW");
1673 pPathIsRelativeA
= (void*)GetProcAddress(hShlwapi
, "PathIsRelativeA");
1674 pPathIsRelativeW
= (void*)GetProcAddress(hShlwapi
, "PathIsRelativeW");
1676 test_PathSearchAndQualify();
1677 test_PathCreateFromUrl();
1680 test_PathAddBackslash();
1681 test_PathMakePretty();
1682 test_PathMatchSpec();
1684 test_PathIsValidCharA();
1685 test_PathIsValidCharW();
1687 test_PathCombineW();
1688 test_PathCombineA();
1690 test_PathCanonicalizeA();
1691 test_PathFindExtensionA();
1692 test_PathBuildRootA();
1693 test_PathCommonPrefixA();
1694 test_PathUnquoteSpaces();
1695 test_PathGetDriveNumber();
1696 test_PathUnExpandEnvStrings();
1697 test_PathIsRelativeA();
1698 test_PathIsRelativeW();
1699 test_PathStripPathA();