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
24 #include "wine/test.h"
31 static HMODULE hShlwapi;
32 static HRESULT (WINAPI *pPathIsValidCharA)(char,DWORD);
33 static HRESULT (WINAPI *pPathIsValidCharW)(WCHAR,DWORD);
34 static LPWSTR (WINAPI *pPathCombineW)(LPWSTR, LPCWSTR, LPCWSTR);
36 /* ################ */
42 } TEST_PATHFROMURL[] = {
43 {"file:///c:/foo/ba%5Cr", "c:\\foo\\ba\\r", S_OK},
44 {"file:///c:/foo/../ba%5Cr", "c:\\foo\\..\\ba\\r", S_OK},
45 {"file:///host/c:/foo/bar", "\\host\\c:\\foo\\bar", S_OK},
46 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
47 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
48 {"file:\\\\host\\c:\\foo\\bar", "\\\\hostc:\\foo\\bar", S_OK},
49 {"file:\\\\host\\ca\\foo\\bar", "\\\\host\\ca\\foo\\bar", S_OK},
50 {"file:\\\\host\\c|\\foo\\bar", "\\\\hostc|\\foo\\bar", S_OK},
51 {"file:\\%5Chost\\c:\\foo\\bar", "\\\\host\\c:\\foo\\bar", S_OK},
52 {"file:\\\\host\\cx:\\foo\\bar", "\\\\host\\cx:\\foo\\bar", S_OK},
53 {"file://c:/foo/bar", "c:\\foo\\bar", S_OK},
54 {"file://c:/d:/foo/bar", "c:\\d:\\foo\\bar", S_OK},
55 {"file://c|/d|/foo/bar", "c:\\d|\\foo\\bar", S_OK},
56 {"file://host/foo/bar", "\\\\host\\foo\\bar", S_OK},
57 {"file:/foo/bar", "\\foo\\bar", S_OK},
58 {"file:/foo/bar/", "\\foo\\bar\\", S_OK},
59 {"file:foo/bar", "foo\\bar", S_OK},
60 {"file:c:/foo/bar", "c:\\foo\\bar", S_OK},
61 {"file:c|/foo/bar", "c:\\foo\\bar", S_OK},
62 {"file:cx|/foo/bar", "cx|\\foo\\bar", S_OK},
63 {"file:////c:/foo/bar", "c:\\foo\\bar", S_OK},
64 /* {"file:////c:/foo/foo%20bar", "c:\\foo\\foo%20bar", S_OK},*/
66 {"c:\\foo\\bar", NULL, E_INVALIDARG},
67 {"foo/bar", NULL, E_INVALIDARG},
68 {"http://foo/bar", NULL, E_INVALIDARG},
76 } TEST_PATH_IS_URL[] = {
77 {"http://foo/bar", TRUE},
78 {"c:\\foo\\bar", FALSE},
79 {"c:/foo/bar", FALSE},
80 {"foo://foo/bar", TRUE},
83 {"bogusscheme:", TRUE},
84 {"http:partial", TRUE},
85 {"www.winehq.org", FALSE}
91 } TEST_PATH_UNQUOTE_SPACES[] = {
92 { "abcdef", "abcdef" },
93 { "\"abcdef\"", "abcdef" },
94 { "\"abcdef", "\"abcdef" },
95 { "abcdef\"", "abcdef\"" },
96 { "\"\"abcdef\"\"", "\"abcdef\"" },
97 { "abc\"def", "abc\"def" },
98 { "\"abc\"def", "\"abc\"def" },
99 { "\"abc\"def\"", "abc\"def" },
100 { "\'abcdef\'", "\'abcdef\'" },
105 /* ################ */
107 static LPWSTR GetWideString(const char* szString)
109 LPWSTR wszString = HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
111 MultiByteToWideChar(0, 0, szString, -1, wszString, INTERNET_MAX_URL_LENGTH);
116 static void FreeWideString(LPWSTR wszString)
118 HeapFree(GetProcessHeap(), 0, wszString);
121 static LPSTR strdupA(LPCSTR p)
124 DWORD len = (strlen(p) + 1);
125 ret = HeapAlloc(GetProcessHeap(), 0, len);
130 /* ################ */
132 static void test_PathSearchAndQualify(void)
134 WCHAR path1[] = {'c',':','\\','f','o','o',0};
135 WCHAR expect1[] = {'c',':','\\','f','o','o',0};
136 WCHAR path2[] = {'c',':','f','o','o',0};
137 WCHAR c_drive[] = {'c',':',0};
138 WCHAR foo[] = {'f','o','o',0};
139 WCHAR path3[] = {'\\','f','o','o',0};
140 WCHAR winini[] = {'w','i','n','.','i','n','i',0};
142 WCHAR cur_dir[MAX_PATH];
143 WCHAR dot[] = {'.',0};
146 ok(PathSearchAndQualifyW(path1, out, MAX_PATH) != 0,
147 "PathSearchAndQualify rets 0\n");
148 ok(!lstrcmpiW(out, expect1), "strings don't match\n");
151 ok(PathSearchAndQualifyW(path2, out, MAX_PATH) != 0,
152 "PathSearchAndQualify rets 0\n");
153 GetFullPathNameW(c_drive, MAX_PATH, cur_dir, NULL);
154 PathAddBackslashW(cur_dir);
155 lstrcatW(cur_dir, foo);
156 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
159 ok(PathSearchAndQualifyW(foo, out, MAX_PATH) != 0,
160 "PathSearchAndQualify rets 0\n");
161 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
162 PathAddBackslashW(cur_dir);
163 lstrcatW(cur_dir, foo);
164 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
167 ok(PathSearchAndQualifyW(path3, out, MAX_PATH) != 0,
168 "PathSearchAndQualify rets 0\n");
169 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
170 lstrcpyW(cur_dir + 2, path3);
171 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
174 ok(PathSearchAndQualifyW(winini, out, MAX_PATH) != 0,
175 "PathSearchAndQualify rets 0\n");
176 if(!SearchPathW(NULL, winini, NULL, MAX_PATH, cur_dir, NULL))
177 GetFullPathNameW(winini, MAX_PATH, cur_dir, NULL);
178 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
182 static void test_PathCreateFromUrl(void)
185 char ret_path[INTERNET_MAX_URL_LENGTH];
187 WCHAR ret_pathW[INTERNET_MAX_URL_LENGTH];
189 static const char url[] = "http://www.winehq.org";
191 /* Check ret_path = NULL */
193 ret = PathCreateFromUrlA(url, NULL, &len, 0);
194 ok ( ret == E_INVALIDARG, "got 0x%08x expected E_INVALIDARG\n", ret);
196 for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
197 len = INTERNET_MAX_URL_LENGTH;
198 ret = PathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
199 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url %s\n", ret, TEST_PATHFROMURL[i].url);
200 if(TEST_PATHFROMURL[i].path) {
201 ok(!lstrcmpi(ret_path, TEST_PATHFROMURL[i].path), "got %s expected %s from url %s\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
202 ok(len == strlen(ret_path), "ret len %d from url %s\n", len, TEST_PATHFROMURL[i].url);
204 len = INTERNET_MAX_URL_LENGTH;
205 pathW = GetWideString(TEST_PATHFROMURL[i].path);
206 urlW = GetWideString(TEST_PATHFROMURL[i].url);
207 ret = PathCreateFromUrlW(urlW, ret_pathW, &len, 0);
208 WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),0,0);
209 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
210 if(TEST_PATHFROMURL[i].path) {
211 ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
212 ok(len == lstrlenW(ret_pathW), "ret len %d from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url);
214 FreeWideString(urlW);
215 FreeWideString(pathW);
220 static void test_PathIsUrl(void)
225 for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
226 ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
227 ok(ret == TEST_PATH_IS_URL[i].expect,
228 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
229 TEST_PATH_IS_URL[i].expect);
233 static const DWORD SHELL_charclass[] =
235 0x00000000, 0x00000000, 0x00000000, 0x00000000,
236 0x00000000, 0x00000000, 0x00000000, 0x00000000,
237 0x00000000, 0x00000000, 0x00000000, 0x00000000,
238 0x00000000, 0x00000000, 0x00000000, 0x00000000,
239 0x00000000, 0x00000000, 0x00000000, 0x00000000,
240 0x00000000, 0x00000000, 0x00000000, 0x00000000,
241 0x00000000, 0x00000000, 0x00000000, 0x00000000,
242 0x00000000, 0x00000000, 0x00000000, 0x00000000,
243 0x00000080, 0x00000100, 0x00000200, 0x00000100,
244 0x00000100, 0x00000100, 0x00000100, 0x00000100,
245 0x00000100, 0x00000100, 0x00000002, 0x00000100,
246 0x00000040, 0x00000100, 0x00000004, 0x00000000,
247 0x00000100, 0x00000100, 0x00000100, 0x00000100,
248 0x00000100, 0x00000100, 0x00000100, 0x00000100,
249 0x00000100, 0x00000100, 0x00000010, 0x00000020,
250 0x00000000, 0x00000100, 0x00000000, 0x00000001,
251 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
252 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
253 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
254 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
255 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
256 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
257 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
258 0x00000008, 0x00000100, 0x00000100, 0x00000100,
259 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
260 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
261 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
262 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
263 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
264 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
265 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
266 0x00000000, 0x00000100, 0x00000100
269 static void test_PathIsValidCharA(void)
274 for (c = 0; c < 0x7f; c++)
276 ret = pPathIsValidCharA( c, ~0U );
277 ok ( ret || !SHELL_charclass[c], "PathIsValidCharA failed: 0x%02x got 0x%08x\n", c, ret );
280 for (c = 0x7f; c <= 0xff; c++)
282 ret = pPathIsValidCharA( c, ~0U );
283 ok ( ret, "PathIsValidCharA failed: 0x%02x got 0x%08x\n", c, ret );
287 static void test_PathIsValidCharW(void)
292 for (c = 0; c < 0x7f; c++)
294 ret = pPathIsValidCharW( c, ~0U );
295 ok ( ret || !SHELL_charclass[c], "PathIsValidCharW failed: 0x%02x got 0x%08x\n", c, ret );
298 for (c = 0x007f; c <= 0xffff; c++)
300 ret = pPathIsValidCharW( c, ~0U );
301 ok ( ret, "PathIsValidCharW failed: 0x%02x got 0x%08x\n", c, ret );
305 static void test_PathMakePretty(void)
309 ok (PathMakePrettyA(NULL) == FALSE, "PathMakePretty: NULL path succeeded\n");
311 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Empty path failed\n");
313 strcpy(buff, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
314 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Long UC name failed\n");
315 ok (strcmp(buff, "C:\\a long file name with \\spaces.txt") == 0,
316 "PathMakePretty: Long UC name not changed\n");
318 strcpy(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
319 ok (PathMakePrettyA(buff) == FALSE, "PathMakePretty: Long MC name succeeded\n");
320 ok (strcmp(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
321 "PathMakePretty: Failed but modified path\n");
323 strcpy(buff, "TEST");
324 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Short name failed\n");
325 ok (strcmp(buff, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff);
328 static void test_PathMatchSpec(void)
330 static const char file[] = "c:\\foo\\bar\\filename.ext";
331 static const char spec1[] = ".ext";
332 static const char spec2[] = "*.ext";
333 static const char spec3[] = "*.ext ";
334 static const char spec4[] = " *.ext";
335 static const char spec5[] = "* .ext";
336 static const char spec6[] = "*. ext";
337 static const char spec7[] = "* . ext";
338 static const char spec8[] = "*.e?t";
339 static const char spec9[] = "filename.ext";
340 static const char spec10[] = "*bar\\filename.ext";
341 static const char spec11[] = " foo; *.ext";
342 static const char spec12[] = "*.ext;*.bar";
343 static const char spec13[] = "*bar*";
345 ok (PathMatchSpecA(file, spec1) == FALSE, "PathMatchSpec: Spec1 failed\n");
346 ok (PathMatchSpecA(file, spec2) == TRUE, "PathMatchSpec: Spec2 failed\n");
347 ok (PathMatchSpecA(file, spec3) == FALSE, "PathMatchSpec: Spec3 failed\n");
348 ok (PathMatchSpecA(file, spec4) == TRUE, "PathMatchSpec: Spec4 failed\n");
349 todo_wine ok (PathMatchSpecA(file, spec5) == TRUE, "PathMatchSpec: Spec5 failed\n");
350 todo_wine ok (PathMatchSpecA(file, spec6) == TRUE, "PathMatchSpec: Spec6 failed\n");
351 ok (PathMatchSpecA(file, spec7) == FALSE, "PathMatchSpec: Spec7 failed\n");
352 ok (PathMatchSpecA(file, spec8) == TRUE, "PathMatchSpec: Spec8 failed\n");
353 ok (PathMatchSpecA(file, spec9) == FALSE, "PathMatchSpec: Spec9 failed\n");
354 ok (PathMatchSpecA(file, spec10) == TRUE, "PathMatchSpec: Spec10 failed\n");
355 ok (PathMatchSpecA(file, spec11) == TRUE, "PathMatchSpec: Spec11 failed\n");
356 ok (PathMatchSpecA(file, spec12) == TRUE, "PathMatchSpec: Spec12 failed\n");
357 ok (PathMatchSpecA(file, spec13) == TRUE, "PathMatchSpec: Spec13 failed\n");
360 static void test_PathCombineW(void)
362 LPWSTR wszString, wszString2;
363 WCHAR wbuf[MAX_PATH+1], wstr1[MAX_PATH] = {'C',':','\\',0}, wstr2[MAX_PATH];
364 static const WCHAR expout[] = {'C',':','\\','A','A',0};
367 wszString2 = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
370 wszString = pPathCombineW(NULL, NULL, NULL);
371 ok (wszString == NULL, "Expected a NULL return\n");
375 wszString = pPathCombineW(wszString2, NULL, NULL);
376 ok (wszString == NULL, "Expected a NULL return\n");
377 ok (wszString2[0] == 0, "Destination string not empty\n");
379 HeapFree(GetProcessHeap(), 0, wszString2);
382 wstr2[0] = wstr2[1] = wstr2[2] = 'A';
383 for (i=3; i<MAX_PATH/2; i++)
384 wstr1[i] = wstr2[i] = 'A';
385 wstr1[(MAX_PATH/2) - 1] = wstr2[MAX_PATH/2] = 0;
386 memset(wbuf, 0xbf, sizeof(wbuf));
388 wszString = pPathCombineW(wbuf, wstr1, wstr2);
389 ok(wszString == NULL, "Expected a NULL return\n");
390 ok(wbuf[0] == 0, "Buffer contains data\n");
392 /* PathCombineW can be used in place */
395 ok(PathCombineW(wstr1, wstr1, wstr2) == wstr1, "Expected a wstr1 return\n");
396 ok(StrCmpW(wstr1, expout) == 0, "Unexpected PathCombine output\n");
400 #define LONG_LEN (MAX_PATH * 2)
401 #define HALF_LEN (MAX_PATH / 2 + 1)
403 static void test_PathCombineA(void)
407 char too_long[LONG_LEN];
408 char one[HALF_LEN], two[HALF_LEN];
411 SetLastError(0xdeadbeef);
412 str = PathCombineA(NULL, "C:\\", "one\\two\\three");
413 ok(str == NULL, "Expected NULL, got %p\n", str);
414 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
416 /* try NULL dest and NULL directory */
417 SetLastError(0xdeadbeef);
418 str = PathCombineA(NULL, NULL, "one\\two\\three");
419 ok(str == NULL, "Expected NULL, got %p\n", str);
420 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
423 SetLastError(0xdeadbeef);
424 str = PathCombineA(NULL, NULL, NULL);
425 ok(str == NULL, "Expected NULL, got %p\n", str);
426 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
428 /* try NULL file part */
429 SetLastError(0xdeadbeef);
430 lstrcpyA(dest, "control");
431 str = PathCombineA(dest, "C:\\", NULL);
432 ok(str == dest, "Expected str == dest, got %p\n", str);
433 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
434 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
436 /* try empty file part */
437 SetLastError(0xdeadbeef);
438 lstrcpyA(dest, "control");
439 str = PathCombineA(dest, "C:\\", "");
440 ok(str == dest, "Expected str == dest, got %p\n", str);
441 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
442 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
444 /* try empty directory and file part */
445 SetLastError(0xdeadbeef);
446 lstrcpyA(dest, "control");
447 str = PathCombineA(dest, "", "");
448 ok(str == dest, "Expected str == dest, got %p\n", str);
449 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
450 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
452 /* try NULL directory */
453 SetLastError(0xdeadbeef);
454 lstrcpyA(dest, "control");
455 str = PathCombineA(dest, NULL, "one\\two\\three");
456 ok(str == dest, "Expected str == dest, got %p\n", str);
457 ok(!lstrcmp(str, "one\\two\\three"), "Expected one\\two\\three, got %s\n", str);
458 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
460 /* try NULL directory and empty file part */
461 SetLastError(0xdeadbeef);
462 lstrcpyA(dest, "control");
463 str = PathCombineA(dest, NULL, "");
464 ok(str == dest, "Expected str == dest, got %p\n", str);
465 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
466 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
468 /* try NULL directory and file part */
469 SetLastError(0xdeadbeef);
470 lstrcpyA(dest, "control");
471 str = PathCombineA(dest, NULL, NULL);
472 ok(str == NULL, "Expected str == NULL, got %p\n", str);
473 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
474 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
476 /* try directory without backslash */
477 SetLastError(0xdeadbeef);
478 lstrcpyA(dest, "control");
479 str = PathCombineA(dest, "C:", "one\\two\\three");
480 ok(str == dest, "Expected str == dest, got %p\n", str);
481 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
482 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
484 /* try directory with backslash */
485 SetLastError(0xdeadbeef);
486 lstrcpyA(dest, "control");
487 str = PathCombineA(dest, "C:\\", "one\\two\\three");
488 ok(str == dest, "Expected str == dest, got %p\n", str);
489 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
490 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
492 /* try directory with backslash and file with prepended backslash */
493 SetLastError(0xdeadbeef);
494 lstrcpyA(dest, "control");
495 str = PathCombineA(dest, "C:\\", "\\one\\two\\three");
496 ok(str == dest, "Expected str == dest, got %p\n", str);
497 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
498 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
500 /* try previous test, with backslash appended as well */
501 SetLastError(0xdeadbeef);
502 lstrcpyA(dest, "control");
503 str = PathCombineA(dest, "C:\\", "\\one\\two\\three\\");
504 ok(str == dest, "Expected str == dest, got %p\n", str);
505 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
506 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
508 /* try a relative directory */
509 SetLastError(0xdeadbeef);
510 lstrcpyA(dest, "control");
511 str = PathCombineA(dest, "relative\\dir", "\\one\\two\\three\\");
512 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
513 /* Vista fails which probably makes sense as PathCombineA expects an absolute dir */
516 ok(str == dest, "Expected str == dest, got %p\n", str);
517 ok(!lstrcmp(str, "one\\two\\three\\"), "Expected one\\two\\three\\, got %s\n", str);
520 /* try forward slashes */
521 SetLastError(0xdeadbeef);
522 lstrcpyA(dest, "control");
523 str = PathCombineA(dest, "C:\\", "one/two/three\\");
524 ok(str == dest, "Expected str == dest, got %p\n", str);
525 ok(!lstrcmp(str, "C:\\one/two/three\\"), "Expected one/two/three\\, got %s\n", str);
526 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
528 /* try a really weird directory */
529 SetLastError(0xdeadbeef);
530 lstrcpyA(dest, "control");
531 str = PathCombineA(dest, "C:\\/\\/", "\\one\\two\\three\\");
532 ok(str == dest, "Expected str == dest, got %p\n", str);
533 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
534 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
537 SetLastError(0xdeadbeef);
538 lstrcpyA(dest, "control");
539 str = PathCombineA(dest, "C:\\", "one\\..\\two\\.\\three");
540 ok(str == dest, "Expected str == dest, got %p\n", str);
541 ok(!lstrcmp(str, "C:\\two\\three"), "Expected C:\\two\\three, got %s\n", str);
542 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
545 /* try forward slashes */
546 SetLastError(0xdeadbeef);
547 lstrcpyA(dest, "control");
548 str = PathCombineA(dest, "C:\\", "..");
549 ok(str == dest, "Expected str == dest, got %p\n", str);
550 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
551 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
553 memset(too_long, 'a', LONG_LEN);
554 too_long[LONG_LEN - 1] = '\0';
556 /* try a file longer than MAX_PATH */
557 SetLastError(0xdeadbeef);
558 lstrcpyA(dest, "control");
559 str = PathCombineA(dest, "C:\\", too_long);
560 ok(str == NULL, "Expected str == NULL, got %p\n", str);
561 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
562 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
564 /* try a directory longer than MAX_PATH */
565 SetLastError(0xdeadbeef);
566 lstrcpyA(dest, "control");
567 str = PathCombineA(dest, too_long, "one\\two\\three");
568 ok(str == NULL, "Expected str == NULL, got %p\n", str);
569 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
570 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
572 memset(one, 'b', HALF_LEN);
573 memset(two, 'c', HALF_LEN);
574 one[HALF_LEN - 1] = '\0';
575 two[HALF_LEN - 1] = '\0';
577 /* destination string is longer than MAX_PATH, but not the constituent parts */
578 SetLastError(0xdeadbeef);
579 lstrcpyA(dest, "control");
580 str = PathCombineA(dest, one, two);
581 ok(str == NULL, "Expected str == NULL, got %p\n", str);
582 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
583 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
586 static void test_PathAddBackslash(void)
590 char too_long[LONG_LEN];
592 /* try a NULL path */
593 SetLastError(0xdeadbeef);
594 str = PathAddBackslashA(NULL);
595 ok(str == NULL, "Expected str == NULL, got %p\n", str);
596 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
598 /* try an empty path */
600 SetLastError(0xdeadbeef);
601 str = PathAddBackslashA(path);
602 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
603 ok(lstrlenA(path) == 0, "Expected empty string, got %i\n", lstrlenA(path));
604 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
606 /* try a relative path */
607 lstrcpyA(path, "one\\two");
608 SetLastError(0xdeadbeef);
609 str = PathAddBackslashA(path);
610 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
611 ok(!lstrcmp(path, "one\\two\\"), "Expected one\\two\\, got %s\n", path);
612 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
615 lstrcpyA(path, "one\\..\\two");
616 SetLastError(0xdeadbeef);
617 str = PathAddBackslashA(path);
618 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
619 ok(!lstrcmp(path, "one\\..\\two\\"), "Expected one\\..\\two\\, got %s\n", path);
620 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
622 /* try just a space */
624 SetLastError(0xdeadbeef);
625 str = PathAddBackslashA(path);
626 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
627 ok(!lstrcmp(path, " \\"), "Expected \\, got %s\n", path);
628 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
630 /* path already has backslash */
631 lstrcpyA(path, "C:\\one\\");
632 SetLastError(0xdeadbeef);
633 str = PathAddBackslashA(path);
634 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
635 ok(!lstrcmp(path, "C:\\one\\"), "Expected C:\\one\\, got %s\n", path);
636 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
638 memset(too_long, 'a', LONG_LEN);
639 too_long[LONG_LEN - 1] = '\0';
641 /* path is longer than MAX_PATH */
642 SetLastError(0xdeadbeef);
643 str = PathAddBackslashA(too_long);
644 ok(str == NULL, "Expected str == NULL, got %p\n", str);
645 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
648 static void test_PathAppendA(void)
651 char too_long[LONG_LEN];
652 char one[HALF_LEN], two[HALF_LEN];
655 lstrcpy(path, "C:\\one");
657 /* try NULL pszMore */
658 SetLastError(0xdeadbeef);
659 res = PathAppendA(path, NULL);
660 ok(!res, "Expected failure\n");
661 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
662 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
664 /* try empty pszMore */
665 SetLastError(0xdeadbeef);
666 res = PathAppendA(path, "");
667 ok(res, "Expected success\n");
668 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
669 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
671 /* try NULL pszPath */
672 SetLastError(0xdeadbeef);
673 res = PathAppendA(NULL, "two\\three");
674 ok(!res, "Expected failure\n");
675 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
677 /* try empty pszPath */
679 SetLastError(0xdeadbeef);
680 res = PathAppendA(path, "two\\three");
681 ok(res, "Expected success\n");
682 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
683 ok(!lstrcmp(path, "two\\three"), "Expected \\two\\three, got %s\n", path);
685 /* try empty pszPath and empty pszMore */
687 SetLastError(0xdeadbeef);
688 res = PathAppendA(path, "");
689 ok(res, "Expected success\n");
690 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
691 ok(!lstrcmp(path, "\\"), "Expected \\, got %s\n", path);
693 /* try legit params */
694 lstrcpy(path, "C:\\one");
695 SetLastError(0xdeadbeef);
696 res = PathAppendA(path, "two\\three");
697 ok(res, "Expected success\n");
698 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
699 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
701 /* try pszPath with backslash after it */
702 lstrcpy(path, "C:\\one\\");
703 SetLastError(0xdeadbeef);
704 res = PathAppendA(path, "two\\three");
705 ok(res, "Expected success\n");
706 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
707 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
709 /* try pszMore with backslash before it */
710 lstrcpy(path, "C:\\one");
711 SetLastError(0xdeadbeef);
712 res = PathAppendA(path, "\\two\\three");
713 ok(res, "Expected success\n");
714 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
715 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
717 /* try pszMore with backslash after it */
718 lstrcpy(path, "C:\\one");
719 SetLastError(0xdeadbeef);
720 res = PathAppendA(path, "two\\three\\");
721 ok(res, "Expected success\n");
722 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
723 ok(!lstrcmp(path, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", path);
725 /* try spaces in pszPath */
726 lstrcpy(path, "C: \\ one ");
727 SetLastError(0xdeadbeef);
728 res = PathAppendA(path, "two\\three");
729 ok(res, "Expected success\n");
730 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
731 ok(!lstrcmp(path, "C: \\ one \\two\\three"), "Expected C: \\ one \\two\\three, got %s\n", path);
733 /* try spaces in pszMore */
734 lstrcpy(path, "C:\\one");
735 SetLastError(0xdeadbeef);
736 res = PathAppendA(path, " two \\ three ");
737 ok(res, "Expected success\n");
738 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
739 ok(!lstrcmp(path, "C:\\one\\ two \\ three "), "Expected 'C:\\one\\ two \\ three ', got %s\n", path);
741 /* pszPath is too long */
742 memset(too_long, 'a', LONG_LEN);
743 too_long[LONG_LEN - 1] = '\0';
744 SetLastError(0xdeadbeef);
745 res = PathAppendA(too_long, "two\\three");
746 ok(!res, "Expected failure\n");
747 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
748 ok(lstrlen(too_long) == 0, "Expected length of too_long to be zero, got %i\n", lstrlen(too_long));
750 /* pszMore is too long */
751 lstrcpy(path, "C:\\one");
752 memset(too_long, 'a', LONG_LEN);
753 too_long[LONG_LEN - 1] = '\0';
754 SetLastError(0xdeadbeef);
755 res = PathAppendA(path, too_long);
756 ok(!res, "Expected failure\n");
757 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
758 ok(lstrlen(path) == 0, "Expected length of path to be zero, got %i\n", lstrlen(path));
760 /* both params combined are too long */
761 memset(one, 'a', HALF_LEN);
762 one[HALF_LEN - 1] = '\0';
763 memset(two, 'b', HALF_LEN);
764 two[HALF_LEN - 1] = '\0';
765 SetLastError(0xdeadbeef);
766 res = PathAppendA(one, two);
767 ok(!res, "Expected failure\n");
768 ok(lstrlen(one) == 0, "Expected length of one to be zero, got %i\n", lstrlen(one));
769 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
772 static void test_PathCanonicalizeA(void)
774 char dest[LONG_LEN + MAX_PATH];
775 char too_long[LONG_LEN];
778 /* try a NULL source */
779 lstrcpy(dest, "test");
780 SetLastError(0xdeadbeef);
781 res = PathCanonicalizeA(dest, NULL);
782 ok(!res, "Expected failure\n");
783 ok(GetLastError() == ERROR_INVALID_PARAMETER,
784 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
785 ok(dest[0] == 0 || !lstrcmp(dest, "test"),
786 "Expected either an empty string (Vista) or test, got %s\n", dest);
788 /* try an empty source */
789 lstrcpy(dest, "test");
790 SetLastError(0xdeadbeef);
791 res = PathCanonicalizeA(dest, "");
792 ok(res, "Expected success\n");
793 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
794 ok(!lstrcmp(dest, "\\"), "Expected \\, got %s\n", dest);
796 /* try a NULL dest */
797 SetLastError(0xdeadbeef);
798 res = PathCanonicalizeA(NULL, "C:\\");
799 ok(!res, "Expected failure\n");
800 ok(GetLastError() == ERROR_INVALID_PARAMETER,
801 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
805 SetLastError(0xdeadbeef);
806 res = PathCanonicalizeA(dest, "C:\\");
807 ok(res, "Expected success\n");
808 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
809 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
811 /* try non-empty dest */
812 lstrcpy(dest, "test");
813 SetLastError(0xdeadbeef);
814 res = PathCanonicalizeA(dest, "C:\\");
815 ok(res, "Expected success\n");
816 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
817 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
819 /* try a space for source */
820 lstrcpy(dest, "test");
821 SetLastError(0xdeadbeef);
822 res = PathCanonicalizeA(dest, " ");
823 ok(res, "Expected success\n");
824 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
825 ok(!lstrcmp(dest, " "), "Expected ' ', got %s\n", dest);
827 /* try a relative path */
828 lstrcpy(dest, "test");
829 SetLastError(0xdeadbeef);
830 res = PathCanonicalizeA(dest, "one\\two");
831 ok(res, "Expected success\n");
832 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
833 ok(!lstrcmp(dest, "one\\two"), "Expected one\\two, got %s\n", dest);
835 /* try current dir and previous dir */
836 lstrcpy(dest, "test");
837 SetLastError(0xdeadbeef);
838 res = PathCanonicalizeA(dest, "C:\\one\\.\\..\\two\\three\\..");
839 ok(res, "Expected success\n");
840 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
841 ok(!lstrcmp(dest, "C:\\two"), "Expected C:\\two, got %s\n", dest);
843 /* try simple forward slashes */
844 lstrcpy(dest, "test");
845 SetLastError(0xdeadbeef);
846 res = PathCanonicalizeA(dest, "C:\\one/two/three\\four/five\\six");
847 ok(res, "Expected success\n");
848 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
849 ok(!lstrcmp(dest, "C:\\one/two/three\\four/five\\six"),
850 "Expected C:\\one/two/three\\four/five\\six, got %s\n", dest);
852 /* try simple forward slashes with same dir */
853 lstrcpy(dest, "test");
854 SetLastError(0xdeadbeef);
855 res = PathCanonicalizeA(dest, "C:\\one/.\\two");
856 ok(res, "Expected success\n");
857 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
858 ok(!lstrcmp(dest, "C:\\one/.\\two"), "Expected C:\\one/.\\two, got %s\n", dest);
860 /* try simple forward slashes with change dir */
861 lstrcpy(dest, "test");
862 SetLastError(0xdeadbeef);
863 res = PathCanonicalizeA(dest, "C:\\one/.\\two\\..");
864 ok(res, "Expected success\n");
865 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
866 ok(!lstrcmp(dest, "C:\\one/.") ||
867 !lstrcmp(dest, "C:\\one/"), /* Vista */
868 "Expected \"C:\\one/.\" or \"C:\\one/\", got \"%s\"\n", dest);
870 /* try forward slashes with change dirs
871 * NOTE: if there is a forward slash in between two backslashes,
872 * everything in between the two backslashes is considered on dir
874 lstrcpy(dest, "test");
875 SetLastError(0xdeadbeef);
876 res = PathCanonicalizeA(dest, "C:\\one/.\\..\\two/three\\..\\four/.five");
877 ok(res, "Expected success\n");
878 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
879 ok(!lstrcmp(dest, "C:\\four/.five"), "Expected C:\\four/.five, got %s\n", dest);
881 /* try src is too long */
882 memset(too_long, 'a', LONG_LEN);
883 too_long[LONG_LEN - 1] = '\0';
884 lstrcpy(dest, "test");
885 SetLastError(0xdeadbeef);
886 res = PathCanonicalizeA(dest, too_long);
887 ok(!res, "Expected failure\n");
890 ok(GetLastError() == 0xdeadbeef || GetLastError() == ERROR_FILENAME_EXCED_RANGE /* Vista */,
891 "Expected 0xdeadbeef or ERROR_FILENAME_EXCED_RANGE, got %d\n", GetLastError());
893 ok(lstrlen(too_long) == LONG_LEN - 1, "Expected length LONG_LEN - 1, got %i\n", lstrlen(too_long));
896 static void test_PathFindExtensionA(void)
900 char too_long[LONG_LEN];
902 /* try a NULL path */
903 SetLastError(0xdeadbeef);
904 ext = PathFindExtensionA(NULL);
905 ok(ext == NULL, "Expected NULL, got %p\n", ext);
906 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
908 /* try an empty path */
910 SetLastError(0xdeadbeef);
911 ext = PathFindExtensionA(path);
912 ok(ext == path, "Expected ext == path, got %p\n", ext);
913 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
914 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
916 /* try a path without an extension */
917 lstrcpy(path, "file");
918 SetLastError(0xdeadbeef);
919 ext = PathFindExtensionA(path);
920 ok(ext == path + lstrlen(path), "Expected ext == path, got %p\n", ext);
921 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
922 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
924 /* try a path with an extension */
925 lstrcpy(path, "file.txt");
926 SetLastError(0xdeadbeef);
927 ext = PathFindExtensionA(path);
928 ok(ext == path + lstrlen("file"),
929 "Expected ext == path + lstrlen(\"file\"), got %p\n", ext);
930 ok(!lstrcmp(ext, ".txt"), "Expected .txt, got %s\n", ext);
931 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
933 /* try a path with two extensions */
934 lstrcpy(path, "file.txt.doc");
935 SetLastError(0xdeadbeef);
936 ext = PathFindExtensionA(path);
937 ok(ext == path + lstrlen("file.txt"),
938 "Expected ext == path + lstrlen(\"file.txt\"), got %p\n", ext);
939 ok(!lstrcmp(ext, ".doc"), "Expected .txt, got %s\n", ext);
940 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
942 /* try a path longer than MAX_PATH without an extension*/
943 memset(too_long, 'a', LONG_LEN);
944 too_long[LONG_LEN - 1] = '\0';
945 SetLastError(0xdeadbeef);
946 ext = PathFindExtensionA(too_long);
947 ok(ext == too_long + LONG_LEN - 1, "Expected ext == too_long + LONG_LEN - 1, got %p\n", ext);
948 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
950 /* try a path longer than MAX_PATH with an extension*/
951 memset(too_long, 'a', LONG_LEN);
952 too_long[LONG_LEN - 1] = '\0';
953 lstrcpy(too_long + 300, ".abcde");
954 too_long[lstrlen(too_long)] = 'a';
955 SetLastError(0xdeadbeef);
956 ext = PathFindExtensionA(too_long);
957 ok(ext == too_long + 300, "Expected ext == too_long + 300, got %p\n", ext);
958 ok(lstrlen(ext) == LONG_LEN - 301, "Expected LONG_LEN - 301, got %i\n", lstrlen(ext));
959 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
962 static void test_PathBuildRootA(void)
966 char root_expected[26][4];
970 /* set up the expected paths */
971 for (drive = 'A'; drive <= 'Z'; drive++)
972 sprintf(root_expected[drive - 'A'], "%c:\\", drive);
974 /* test the expected values */
975 for (j = 0; j < 26; j++)
977 SetLastError(0xdeadbeef);
978 lstrcpy(path, "aaaaaaaaa");
979 root = PathBuildRootA(path, j);
980 ok(root == path, "Expected root == path, got %p\n", root);
981 ok(!lstrcmp(root, root_expected[j]), "Expected %s, got %s\n", root_expected[j], root);
982 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
985 /* test a negative drive number */
986 SetLastError(0xdeadbeef);
987 lstrcpy(path, "aaaaaaaaa");
988 root = PathBuildRootA(path, -1);
989 ok(root == path, "Expected root == path, got %p\n", root);
990 ok(!lstrcmp(path, "aaaaaaaaa") ||
991 lstrlenA(path) == 0, /* Vista */
992 "Expected aaaaaaaaa or empty string, got %s\n", path);
993 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
995 /* test a drive number greater than 25 */
996 SetLastError(0xdeadbeef);
997 lstrcpy(path, "aaaaaaaaa");
998 root = PathBuildRootA(path, 26);
999 ok(root == path, "Expected root == path, got %p\n", root);
1000 ok(!lstrcmp(path, "aaaaaaaaa") ||
1001 lstrlenA(path) == 0, /* Vista */
1002 "Expected aaaaaaaaa or empty string, got %s\n", path);
1003 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1005 /* length of path is less than 4 */
1006 SetLastError(0xdeadbeef);
1007 lstrcpy(path, "aa");
1008 root = PathBuildRootA(path, 0);
1009 ok(root == path, "Expected root == path, got %p\n", root);
1010 ok(!lstrcmp(path, "A:\\"), "Expected A:\\, got %s\n", path);
1011 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1014 SetLastError(0xdeadbeef);
1015 root = PathBuildRootA(NULL, 0);
1016 ok(root == NULL, "Expected root == NULL, got %p\n", root);
1017 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1020 static void test_PathCommonPrefixA(void)
1022 char path1[MAX_PATH], path2[MAX_PATH];
1026 /* test NULL path1 */
1027 SetLastError(0xdeadbeef);
1028 lstrcpy(path2, "C:\\");
1029 lstrcpy(out, "aaa");
1030 count = PathCommonPrefixA(NULL, path2, out);
1031 ok(count == 0, "Expected 0, got %i\n", count);
1034 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1036 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1037 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1039 /* test NULL path2 */
1040 SetLastError(0xdeadbeef);
1041 lstrcpy(path1, "C:\\");
1042 lstrcpy(out, "aaa");
1043 count = PathCommonPrefixA(path1, NULL, out);
1044 ok(count == 0, "Expected 0, got %i\n", count);
1047 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1049 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1050 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1052 /* test empty path1 */
1053 SetLastError(0xdeadbeef);
1055 lstrcpy(path2, "C:\\");
1056 lstrcpy(out, "aaa");
1057 count = PathCommonPrefixA(path1, path2, out);
1058 ok(count == 0, "Expected 0, got %i\n", count);
1059 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1060 ok(lstrlen(path1) == 0, "Expected 0 length path1, got %i\n", lstrlen(path1));
1061 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1062 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1064 /* test empty path1 */
1065 SetLastError(0xdeadbeef);
1067 lstrcpy(path1, "C:\\");
1068 lstrcpy(out, "aaa");
1069 count = PathCommonPrefixA(path1, path2, out);
1070 ok(count == 0, "Expected 0, got %i\n", count);
1071 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1072 ok(lstrlen(path2) == 0, "Expected 0 length path2, got %i\n", lstrlen(path2));
1073 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1074 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1076 /* paths are legit, out is NULL */
1077 SetLastError(0xdeadbeef);
1078 lstrcpy(path1, "C:\\");
1079 lstrcpy(path2, "C:\\");
1080 count = PathCommonPrefixA(path1, path2, NULL);
1081 ok(count == 3, "Expected 3, got %i\n", count);
1082 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1083 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1084 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1086 /* all parameters legit */
1087 SetLastError(0xdeadbeef);
1088 lstrcpy(path1, "C:\\");
1089 lstrcpy(path2, "C:\\");
1090 lstrcpy(out, "aaa");
1091 count = PathCommonPrefixA(path1, path2, out);
1092 ok(count == 3, "Expected 3, got %i\n", count);
1093 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1094 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1095 ok(!lstrcmp(out, "C:\\"), "Expected C:\\, got %s\n", out);
1096 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1098 /* path1 and path2 not the same, but common prefix */
1099 SetLastError(0xdeadbeef);
1100 lstrcpy(path1, "C:\\one\\two");
1101 lstrcpy(path2, "C:\\one\\three");
1102 lstrcpy(out, "aaa");
1103 count = PathCommonPrefixA(path1, path2, out);
1104 ok(count == 6, "Expected 6, got %i\n", count);
1105 ok(!lstrcmp(path1, "C:\\one\\two"), "Expected C:\\one\\two, got %s\n", path1);
1106 ok(!lstrcmp(path2, "C:\\one\\three"), "Expected C:\\one\\three, got %s\n", path2);
1107 ok(!lstrcmp(out, "C:\\one"), "Expected C:\\one, got %s\n", out);
1108 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1111 SetLastError(0xdeadbeef);
1112 lstrcpy(path1, "one\\.two");
1113 lstrcpy(path2, "one\\.three");
1114 lstrcpy(out, "aaa");
1115 count = PathCommonPrefixA(path1, path2, out);
1116 ok(count == 3, "Expected 3, got %i\n", count);
1117 ok(!lstrcmp(path1, "one\\.two"), "Expected one\\.two, got %s\n", path1);
1118 ok(!lstrcmp(path2, "one\\.three"), "Expected one\\.three, got %s\n", path2);
1119 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1120 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1123 SetLastError(0xdeadbeef);
1124 lstrcpy(path1, "one\\..two");
1125 lstrcpy(path2, "one\\..three");
1126 lstrcpy(out, "aaa");
1127 count = PathCommonPrefixA(path1, path2, out);
1128 ok(count == 3, "Expected 3, got %i\n", count);
1129 ok(!lstrcmp(path1, "one\\..two"), "Expected one\\..two, got %s\n", path1);
1130 ok(!lstrcmp(path2, "one\\..three"), "Expected one\\..three, got %s\n", path2);
1131 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1132 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1134 /* try ... prefix */
1135 SetLastError(0xdeadbeef);
1136 lstrcpy(path1, "one\\...two");
1137 lstrcpy(path2, "one\\...three");
1138 lstrcpy(out, "aaa");
1139 count = PathCommonPrefixA(path1, path2, out);
1140 ok(count == 3, "Expected 3, got %i\n", count);
1141 ok(!lstrcmp(path1, "one\\...two"), "Expected one\\...two, got %s\n", path1);
1142 ok(!lstrcmp(path2, "one\\...three"), "Expected one\\...three, got %s\n", path2);
1143 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1144 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1147 SetLastError(0xdeadbeef);
1148 lstrcpy(path1, "one\\.\\two");
1149 lstrcpy(path2, "one\\.\\three");
1150 lstrcpy(out, "aaa");
1151 count = PathCommonPrefixA(path1, path2, out);
1152 ok(count == 5, "Expected 5, got %i\n", count);
1153 ok(!lstrcmp(path1, "one\\.\\two"), "Expected one\\.\\two, got %s\n", path1);
1154 ok(!lstrcmp(path2, "one\\.\\three"), "Expected one\\.\\three, got %s\n", path2);
1155 ok(!lstrcmp(out, "one\\."), "Expected one\\., got %s\n", out);
1156 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1158 /* try ..\ prefix */
1159 SetLastError(0xdeadbeef);
1160 lstrcpy(path1, "one\\..\\two");
1161 lstrcpy(path2, "one\\..\\three");
1162 lstrcpy(out, "aaa");
1163 count = PathCommonPrefixA(path1, path2, out);
1164 ok(count == 6, "Expected 6, got %i\n", count);
1165 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1166 ok(!lstrcmp(path2, "one\\..\\three"), "Expected one\\..\\three, got %s\n", path2);
1167 ok(!lstrcmp(out, "one\\.."), "Expected one\\.., got %s\n", out);
1168 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1170 /* try ...\\ prefix */
1171 SetLastError(0xdeadbeef);
1172 lstrcpy(path1, "one\\...\\two");
1173 lstrcpy(path2, "one\\...\\three");
1174 lstrcpy(out, "aaa");
1175 count = PathCommonPrefixA(path1, path2, out);
1176 ok(count == 7, "Expected 7, got %i\n", count);
1177 ok(!lstrcmp(path1, "one\\...\\two"), "Expected one\\...\\two, got %s\n", path1);
1178 ok(!lstrcmp(path2, "one\\...\\three"), "Expected one\\...\\three, got %s\n", path2);
1179 ok(!lstrcmp(out, "one\\..."), "Expected one\\..., got %s\n", out);
1180 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1182 /* try prefix that is not an msdn labeled prefix type */
1183 SetLastError(0xdeadbeef);
1184 lstrcpy(path1, "same");
1185 lstrcpy(path2, "same");
1186 lstrcpy(out, "aaa");
1187 count = PathCommonPrefixA(path1, path2, out);
1188 ok(count == 4, "Expected 4, got %i\n", count);
1189 ok(!lstrcmp(path1, "same"), "Expected same, got %s\n", path1);
1190 ok(!lstrcmp(path2, "same"), "Expected same, got %s\n", path2);
1191 ok(!lstrcmp(out, "same"), "Expected same, got %s\n", out);
1192 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1194 /* try . after directory */
1195 SetLastError(0xdeadbeef);
1196 lstrcpy(path1, "one\\mid.\\two");
1197 lstrcpy(path2, "one\\mid.\\three");
1198 lstrcpy(out, "aaa");
1199 count = PathCommonPrefixA(path1, path2, out);
1200 ok(count == 8, "Expected 8, got %i\n", count);
1201 ok(!lstrcmp(path1, "one\\mid.\\two"), "Expected one\\mid.\\two, got %s\n", path1);
1202 ok(!lstrcmp(path2, "one\\mid.\\three"), "Expected one\\mid.\\three, got %s\n", path2);
1203 ok(!lstrcmp(out, "one\\mid."), "Expected one\\mid., got %s\n", out);
1204 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1206 /* try . in the middle of a directory */
1207 SetLastError(0xdeadbeef);
1208 lstrcpy(path1, "one\\mid.end\\two");
1209 lstrcpy(path2, "one\\mid.end\\three");
1210 lstrcpy(out, "aaa");
1211 count = PathCommonPrefixA(path1, path2, out);
1212 ok(count == 11, "Expected 11, got %i\n", count);
1213 ok(!lstrcmp(path1, "one\\mid.end\\two"), "Expected one\\mid.end\\two, got %s\n", path1);
1214 ok(!lstrcmp(path2, "one\\mid.end\\three"), "Expected one\\mid.end\\three, got %s\n", path2);
1215 ok(!lstrcmp(out, "one\\mid.end"), "Expected one\\mid.end, got %s\n", out);
1216 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1218 /* try comparing a .. with the expanded path */
1219 SetLastError(0xdeadbeef);
1220 lstrcpy(path1, "one\\..\\two");
1221 lstrcpy(path2, "two");
1222 lstrcpy(out, "aaa");
1223 count = PathCommonPrefixA(path1, path2, out);
1224 ok(count == 0, "Expected 0, got %i\n", count);
1225 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1226 ok(!lstrcmp(path2, "two"), "Expected two, got %s\n", path2);
1227 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1228 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1231 static void test_PathUnquoteSpaces(void)
1234 for(i = 0; i < sizeof(TEST_PATH_UNQUOTE_SPACES) / sizeof(TEST_PATH_UNQUOTE_SPACES[0]); i++)
1236 char *path = strdupA(TEST_PATH_UNQUOTE_SPACES[i].path);
1237 WCHAR *pathW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].path);
1238 WCHAR *resultW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].result);
1240 PathUnquoteSpacesA(path);
1241 ok(!strcmp(path, TEST_PATH_UNQUOTE_SPACES[i].result), "%s (A): got %s expected %s\n",
1242 TEST_PATH_UNQUOTE_SPACES[i].path, path,
1243 TEST_PATH_UNQUOTE_SPACES[i].result);
1245 PathUnquoteSpacesW(pathW);
1246 ok(!lstrcmpW(pathW, resultW), "%s (W): strings differ\n",
1247 TEST_PATH_UNQUOTE_SPACES[i].path);
1248 FreeWideString(pathW);
1249 FreeWideString(resultW);
1250 HeapFree(GetProcessHeap(), 0, path);
1254 /* ################ */
1258 hShlwapi = GetModuleHandleA("shlwapi.dll");
1260 test_PathSearchAndQualify();
1261 test_PathCreateFromUrl();
1264 test_PathAddBackslash();
1265 test_PathMakePretty();
1266 test_PathMatchSpec();
1268 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
1269 * ordinal number in some native versions. Check this to prevent a crash.
1271 pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
1272 if (pPathIsValidCharA && pPathIsValidCharA != (void*)GetProcAddress(hShlwapi, "PathAppendA"))
1274 test_PathIsValidCharA();
1276 pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
1277 if (pPathIsValidCharW) test_PathIsValidCharW();
1280 pPathCombineW = (void*)GetProcAddress(hShlwapi, "PathCombineW");
1282 test_PathCombineW();
1284 test_PathCombineA();
1286 test_PathCanonicalizeA();
1287 test_PathFindExtensionA();
1288 test_PathBuildRootA();
1289 test_PathCommonPrefixA();
1290 test_PathUnquoteSpaces();