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 {"foo://foo/bar", TRUE},
82 {"bogusscheme:", TRUE},
83 {"http:partial", TRUE}
89 } TEST_PATH_UNQUOTE_SPACES[] = {
90 { "abcdef", "abcdef" },
91 { "\"abcdef\"", "abcdef" },
92 { "\"abcdef", "\"abcdef" },
93 { "abcdef\"", "abcdef\"" },
94 { "\"\"abcdef\"\"", "\"abcdef\"" },
95 { "abc\"def", "abc\"def" },
96 { "\"abc\"def", "\"abc\"def" },
97 { "\"abc\"def\"", "abc\"def" },
98 { "\'abcdef\'", "\'abcdef\'" },
103 /* ################ */
105 static LPWSTR GetWideString(const char* szString)
107 LPWSTR wszString = HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
109 MultiByteToWideChar(0, 0, szString, -1, wszString, INTERNET_MAX_URL_LENGTH);
114 static void FreeWideString(LPWSTR wszString)
116 HeapFree(GetProcessHeap(), 0, wszString);
119 static LPSTR strdupA(LPCSTR p)
122 DWORD len = (strlen(p) + 1);
123 ret = HeapAlloc(GetProcessHeap(), 0, len);
128 /* ################ */
130 static void test_PathSearchAndQualify(void)
132 WCHAR path1[] = {'c',':','\\','f','o','o',0};
133 WCHAR expect1[] = {'c',':','\\','f','o','o',0};
134 WCHAR path2[] = {'c',':','f','o','o',0};
135 WCHAR c_drive[] = {'c',':',0};
136 WCHAR foo[] = {'f','o','o',0};
137 WCHAR path3[] = {'\\','f','o','o',0};
138 WCHAR winini[] = {'w','i','n','.','i','n','i',0};
140 WCHAR cur_dir[MAX_PATH];
141 WCHAR dot[] = {'.',0};
144 ok(PathSearchAndQualifyW(path1, out, MAX_PATH) != 0,
145 "PathSearchAndQualify rets 0\n");
146 ok(!lstrcmpiW(out, expect1), "strings don't match\n");
149 ok(PathSearchAndQualifyW(path2, out, MAX_PATH) != 0,
150 "PathSearchAndQualify rets 0\n");
151 GetFullPathNameW(c_drive, MAX_PATH, cur_dir, NULL);
152 PathAddBackslashW(cur_dir);
153 lstrcatW(cur_dir, foo);
154 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
157 ok(PathSearchAndQualifyW(foo, out, MAX_PATH) != 0,
158 "PathSearchAndQualify rets 0\n");
159 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
160 PathAddBackslashW(cur_dir);
161 lstrcatW(cur_dir, foo);
162 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
165 ok(PathSearchAndQualifyW(path3, out, MAX_PATH) != 0,
166 "PathSearchAndQualify rets 0\n");
167 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
168 lstrcpyW(cur_dir + 2, path3);
169 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
172 ok(PathSearchAndQualifyW(winini, out, MAX_PATH) != 0,
173 "PathSearchAndQualify rets 0\n");
174 if(!SearchPathW(NULL, winini, NULL, MAX_PATH, cur_dir, NULL))
175 GetFullPathNameW(winini, MAX_PATH, cur_dir, NULL);
176 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
180 static void test_PathCreateFromUrl(void)
183 char ret_path[INTERNET_MAX_URL_LENGTH];
185 WCHAR ret_pathW[INTERNET_MAX_URL_LENGTH];
187 static const char url[] = "http://www.winehq.org";
189 /* Check ret_path = NULL */
191 ret = PathCreateFromUrlA(url, NULL, &len, 0);
192 ok ( ret == E_INVALIDARG, "got 0x%08x expected E_INVALIDARG\n", ret);
194 for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
195 len = INTERNET_MAX_URL_LENGTH;
196 ret = PathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
197 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url %s\n", ret, TEST_PATHFROMURL[i].url);
198 if(TEST_PATHFROMURL[i].path) {
199 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);
200 ok(len == strlen(ret_path), "ret len %d from url %s\n", len, TEST_PATHFROMURL[i].url);
202 len = INTERNET_MAX_URL_LENGTH;
203 pathW = GetWideString(TEST_PATHFROMURL[i].path);
204 urlW = GetWideString(TEST_PATHFROMURL[i].url);
205 ret = PathCreateFromUrlW(urlW, ret_pathW, &len, 0);
206 WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),0,0);
207 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
208 if(TEST_PATHFROMURL[i].path) {
209 ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
210 ok(len == lstrlenW(ret_pathW), "ret len %d from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url);
212 FreeWideString(urlW);
213 FreeWideString(pathW);
218 static void test_PathIsUrl(void)
223 for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
224 ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
225 ok(ret == TEST_PATH_IS_URL[i].expect,
226 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
227 TEST_PATH_IS_URL[i].expect);
231 static const DWORD SHELL_charclass[] =
233 0x00000000, 0x00000000, 0x00000000, 0x00000000,
234 0x00000000, 0x00000000, 0x00000000, 0x00000000,
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 0x00000080, 0x00000100, 0x00000200, 0x00000100,
242 0x00000100, 0x00000100, 0x00000100, 0x00000100,
243 0x00000100, 0x00000100, 0x00000002, 0x00000100,
244 0x00000040, 0x00000100, 0x00000004, 0x00000000,
245 0x00000100, 0x00000100, 0x00000100, 0x00000100,
246 0x00000100, 0x00000100, 0x00000100, 0x00000100,
247 0x00000100, 0x00000100, 0x00000010, 0x00000020,
248 0x00000000, 0x00000100, 0x00000000, 0x00000001,
249 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
250 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
251 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
252 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
253 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
254 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
255 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
256 0x00000008, 0x00000100, 0x00000100, 0x00000100,
257 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
258 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
259 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
260 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
261 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
262 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
263 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
264 0x00000000, 0x00000100, 0x00000100
267 static void test_PathIsValidCharA(void)
272 ret = pPathIsValidCharA( 0x7f, 0 );
273 ok ( !ret, "PathIsValidCharA succeeded: 0x%08x\n", (DWORD)ret );
275 ret = pPathIsValidCharA( 0x7f, 1 );
276 ok ( !ret, "PathIsValidCharA succeeded: 0x%08x\n", (DWORD)ret );
278 for (c = 0; c < 0x7f; c++)
280 ret = pPathIsValidCharA( c, ~0U );
281 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
282 "PathIsValidCharA failed: 0x%02x got 0x%08x expected 0x%08x\n",
283 c, (DWORD)ret, SHELL_charclass[c] );
286 for (c = 0x7f; c <= 0xff; c++)
288 ret = pPathIsValidCharA( c, ~0U );
289 ok ( ret == 0x00000100,
290 "PathIsValidCharA failed: 0x%02x got 0x%08x expected 0x00000100\n",
295 static void test_PathIsValidCharW(void)
298 unsigned int c, err_count = 0;
300 ret = pPathIsValidCharW( 0x7f, 0 );
301 ok ( !ret, "PathIsValidCharW succeeded: 0x%08x\n", (DWORD)ret );
303 ret = pPathIsValidCharW( 0x7f, 1 );
304 ok ( !ret, "PathIsValidCharW succeeded: 0x%08x\n", (DWORD)ret );
306 for (c = 0; c < 0x7f; c++)
308 ret = pPathIsValidCharW( c, ~0U );
309 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
310 "PathIsValidCharW failed: 0x%02x got 0x%08x expected 0x%08x\n",
311 c, (DWORD)ret, SHELL_charclass[c] );
314 for (c = 0x007f; c <= 0xffff; c++)
316 ret = pPathIsValidCharW( c, ~0U );
317 ok ( ret == 0x00000100,
318 "PathIsValidCharW failed: 0x%02x got 0x%08x expected 0x00000100\n",
320 if (ret != 0x00000100)
322 if(++err_count > 100 ) {
323 trace("skipping rest of PathIsValidCharW tests "
324 "because of the current number of errors\n");
331 static void test_PathMakePretty(void)
335 ok (PathMakePrettyA(NULL) == FALSE, "PathMakePretty: NULL path succeeded\n");
337 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Empty path failed\n");
339 strcpy(buff, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
340 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Long UC name failed\n");
341 ok (strcmp(buff, "C:\\a long file name with \\spaces.txt") == 0,
342 "PathMakePretty: Long UC name not changed\n");
344 strcpy(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
345 ok (PathMakePrettyA(buff) == FALSE, "PathMakePretty: Long MC name succeeded\n");
346 ok (strcmp(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
347 "PathMakePretty: Failed but modified path\n");
349 strcpy(buff, "TEST");
350 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Short name failed\n");
351 ok (strcmp(buff, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff);
354 static void test_PathMatchSpec(void)
356 static const char file[] = "c:\\foo\\bar\\filename.ext";
357 static const char spec1[] = ".ext";
358 static const char spec2[] = "*.ext";
359 static const char spec3[] = "*.ext ";
360 static const char spec4[] = " *.ext";
361 static const char spec5[] = "* .ext";
362 static const char spec6[] = "*. ext";
363 static const char spec7[] = "* . ext";
364 static const char spec8[] = "*.e?t";
365 static const char spec9[] = "filename.ext";
366 static const char spec10[] = "*bar\\filename.ext";
367 static const char spec11[] = " foo; *.ext";
368 static const char spec12[] = "*.ext;*.bar";
369 static const char spec13[] = "*bar*";
371 ok (PathMatchSpecA(file, spec1) == FALSE, "PathMatchSpec: Spec1 failed\n");
372 ok (PathMatchSpecA(file, spec2) == TRUE, "PathMatchSpec: Spec2 failed\n");
373 ok (PathMatchSpecA(file, spec3) == FALSE, "PathMatchSpec: Spec3 failed\n");
374 ok (PathMatchSpecA(file, spec4) == TRUE, "PathMatchSpec: Spec4 failed\n");
375 todo_wine ok (PathMatchSpecA(file, spec5) == TRUE, "PathMatchSpec: Spec5 failed\n");
376 todo_wine ok (PathMatchSpecA(file, spec6) == TRUE, "PathMatchSpec: Spec6 failed\n");
377 ok (PathMatchSpecA(file, spec7) == FALSE, "PathMatchSpec: Spec7 failed\n");
378 ok (PathMatchSpecA(file, spec8) == TRUE, "PathMatchSpec: Spec8 failed\n");
379 ok (PathMatchSpecA(file, spec9) == FALSE, "PathMatchSpec: Spec9 failed\n");
380 ok (PathMatchSpecA(file, spec10) == TRUE, "PathMatchSpec: Spec10 failed\n");
381 ok (PathMatchSpecA(file, spec11) == TRUE, "PathMatchSpec: Spec11 failed\n");
382 ok (PathMatchSpecA(file, spec12) == TRUE, "PathMatchSpec: Spec12 failed\n");
383 ok (PathMatchSpecA(file, spec13) == TRUE, "PathMatchSpec: Spec13 failed\n");
386 static void test_PathCombineW(void)
388 LPWSTR wszString, wszString2;
389 WCHAR wbuf[MAX_PATH+1], wstr1[MAX_PATH] = {'C',':','\\',0}, wstr2[MAX_PATH];
390 static const WCHAR expout[] = {'C',':','\\','A','A',0};
393 wszString2 = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
396 wszString = pPathCombineW(NULL, NULL, NULL);
397 ok (wszString == NULL, "Expected a NULL return\n");
401 wszString = pPathCombineW(wszString2, NULL, NULL);
402 ok (wszString == NULL, "Expected a NULL return\n");
403 ok (wszString2[0] == 0, "Destination string not empty\n");
405 HeapFree(GetProcessHeap(), 0, wszString2);
408 wstr2[0] = wstr2[1] = wstr2[2] = 'A';
409 for (i=3; i<MAX_PATH/2; i++)
410 wstr1[i] = wstr2[i] = 'A';
411 wstr1[(MAX_PATH/2) - 1] = wstr2[MAX_PATH/2] = 0;
412 memset(wbuf, 0xbf, sizeof(wbuf));
414 wszString = pPathCombineW(wbuf, wstr1, wstr2);
415 ok(wszString == NULL, "Expected a NULL return\n");
416 ok(wbuf[0] == 0, "Buffer contains data\n");
418 /* PathCombineW can be used in place */
421 ok(PathCombineW(wstr1, wstr1, wstr2) == wstr1, "Expected a wstr1 return\n");
422 ok(StrCmpW(wstr1, expout) == 0, "Unexpected PathCombine output\n");
426 #define LONG_LEN (MAX_PATH * 2)
427 #define HALF_LEN (MAX_PATH / 2 + 1)
429 static void test_PathCombineA(void)
433 char too_long[LONG_LEN];
434 char one[HALF_LEN], two[HALF_LEN];
437 SetLastError(0xdeadbeef);
438 str = PathCombineA(NULL, "C:\\", "one\\two\\three");
439 ok(str == NULL, "Expected NULL, got %p\n", str);
440 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
442 /* try NULL dest and NULL directory */
443 SetLastError(0xdeadbeef);
444 str = PathCombineA(NULL, NULL, "one\\two\\three");
445 ok(str == NULL, "Expected NULL, got %p\n", str);
446 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
449 SetLastError(0xdeadbeef);
450 str = PathCombineA(NULL, NULL, NULL);
451 ok(str == NULL, "Expected NULL, got %p\n", str);
452 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
454 /* try NULL file part */
455 SetLastError(0xdeadbeef);
456 lstrcpyA(dest, "control");
457 str = PathCombineA(dest, "C:\\", NULL);
458 ok(str == dest, "Expected str == dest, got %p\n", str);
459 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
460 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
462 /* try empty file part */
463 SetLastError(0xdeadbeef);
464 lstrcpyA(dest, "control");
465 str = PathCombineA(dest, "C:\\", "");
466 ok(str == dest, "Expected str == dest, got %p\n", str);
467 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
468 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
470 /* try empty directory and file part */
471 SetLastError(0xdeadbeef);
472 lstrcpyA(dest, "control");
473 str = PathCombineA(dest, "", "");
474 ok(str == dest, "Expected str == dest, got %p\n", str);
475 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
476 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
478 /* try NULL directory */
479 SetLastError(0xdeadbeef);
480 lstrcpyA(dest, "control");
481 str = PathCombineA(dest, NULL, "one\\two\\three");
482 ok(str == dest, "Expected str == dest, got %p\n", str);
483 ok(!lstrcmp(str, "one\\two\\three"), "Expected one\\two\\three, got %s\n", str);
484 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
486 /* try NULL directory and empty file part */
487 SetLastError(0xdeadbeef);
488 lstrcpyA(dest, "control");
489 str = PathCombineA(dest, NULL, "");
490 ok(str == dest, "Expected str == dest, got %p\n", str);
491 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
492 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
494 /* try NULL directory and file part */
495 SetLastError(0xdeadbeef);
496 lstrcpyA(dest, "control");
497 str = PathCombineA(dest, NULL, NULL);
498 ok(str == NULL, "Expected str == NULL, got %p\n", str);
499 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
500 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
502 /* try directory without backslash */
503 SetLastError(0xdeadbeef);
504 lstrcpyA(dest, "control");
505 str = PathCombineA(dest, "C:", "one\\two\\three");
506 ok(str == dest, "Expected str == dest, got %p\n", str);
507 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
508 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
510 /* try directory with backslash */
511 SetLastError(0xdeadbeef);
512 lstrcpyA(dest, "control");
513 str = PathCombineA(dest, "C:\\", "one\\two\\three");
514 ok(str == dest, "Expected str == dest, got %p\n", str);
515 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
516 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
518 /* try directory with backslash and file with prepended backslash */
519 SetLastError(0xdeadbeef);
520 lstrcpyA(dest, "control");
521 str = PathCombineA(dest, "C:\\", "\\one\\two\\three");
522 ok(str == dest, "Expected str == dest, got %p\n", str);
523 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
524 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
526 /* try previous test, with backslash appended as well */
527 SetLastError(0xdeadbeef);
528 lstrcpyA(dest, "control");
529 str = PathCombineA(dest, "C:\\", "\\one\\two\\three\\");
530 ok(str == dest, "Expected str == dest, got %p\n", str);
531 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
532 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
534 /* try a relative directory */
535 SetLastError(0xdeadbeef);
536 lstrcpyA(dest, "control");
537 str = PathCombineA(dest, "relative\\dir", "\\one\\two\\three\\");
538 ok(str == dest, "Expected str == dest, got %p\n", str);
539 ok(!lstrcmp(str, "one\\two\\three\\"), "Expected one\\two\\three\\, got %s\n", str);
540 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
542 /* try forward slashes */
543 SetLastError(0xdeadbeef);
544 lstrcpyA(dest, "control");
545 str = PathCombineA(dest, "C:\\", "one/two/three\\");
546 ok(str == dest, "Expected str == dest, got %p\n", str);
547 ok(!lstrcmp(str, "C:\\one/two/three\\"), "Expected one/two/three\\, got %s\n", str);
548 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
550 /* try a really weird directory */
551 SetLastError(0xdeadbeef);
552 lstrcpyA(dest, "control");
553 str = PathCombineA(dest, "C:\\/\\/", "\\one\\two\\three\\");
554 ok(str == dest, "Expected str == dest, got %p\n", str);
555 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
556 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
559 SetLastError(0xdeadbeef);
560 lstrcpyA(dest, "control");
561 str = PathCombineA(dest, "C:\\", "one\\..\\two\\.\\three");
562 ok(str == dest, "Expected str == dest, got %p\n", str);
563 ok(!lstrcmp(str, "C:\\two\\three"), "Expected C:\\two\\three, got %s\n", str);
564 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
567 /* try forward slashes */
568 SetLastError(0xdeadbeef);
569 lstrcpyA(dest, "control");
570 str = PathCombineA(dest, "C:\\", "..");
571 ok(str == dest, "Expected str == dest, got %p\n", str);
572 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
573 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
575 memset(too_long, 'a', LONG_LEN);
576 too_long[LONG_LEN - 1] = '\0';
578 /* try a file longer than MAX_PATH */
579 SetLastError(0xdeadbeef);
580 lstrcpyA(dest, "control");
581 str = PathCombineA(dest, "C:\\", too_long);
582 ok(str == NULL, "Expected str == NULL, got %p\n", str);
583 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
584 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
586 /* try a directory longer than MAX_PATH */
587 SetLastError(0xdeadbeef);
588 lstrcpyA(dest, "control");
589 str = PathCombineA(dest, too_long, "one\\two\\three");
590 ok(str == NULL, "Expected str == NULL, got %p\n", str);
591 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
592 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
594 memset(one, 'b', HALF_LEN);
595 memset(two, 'c', HALF_LEN);
596 one[HALF_LEN - 1] = '\0';
597 two[HALF_LEN - 1] = '\0';
599 /* destination string is longer than MAX_PATH, but not the constituent parts */
600 SetLastError(0xdeadbeef);
601 lstrcpyA(dest, "control");
602 str = PathCombineA(dest, one, two);
603 ok(str == NULL, "Expected str == NULL, got %p\n", str);
604 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
605 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
608 static void test_PathAddBackslash(void)
612 char too_long[LONG_LEN];
614 /* try a NULL path */
615 SetLastError(0xdeadbeef);
616 str = PathAddBackslashA(NULL);
617 ok(str == NULL, "Expected str == NULL, got %p\n", str);
618 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
620 /* try an empty path */
622 SetLastError(0xdeadbeef);
623 str = PathAddBackslashA(path);
624 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
625 ok(lstrlenA(path) == 0, "Expected empty string, got %i\n", lstrlenA(path));
626 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
628 /* try a relative path */
629 lstrcpyA(path, "one\\two");
630 SetLastError(0xdeadbeef);
631 str = PathAddBackslashA(path);
632 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
633 ok(!lstrcmp(path, "one\\two\\"), "Expected one\\two\\, got %s\n", path);
634 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
637 lstrcpyA(path, "one\\..\\two");
638 SetLastError(0xdeadbeef);
639 str = PathAddBackslashA(path);
640 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
641 ok(!lstrcmp(path, "one\\..\\two\\"), "Expected one\\..\\two\\, got %s\n", path);
642 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
644 /* try just a space */
646 SetLastError(0xdeadbeef);
647 str = PathAddBackslashA(path);
648 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
649 ok(!lstrcmp(path, " \\"), "Expected \\, got %s\n", path);
650 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
652 /* path already has backslash */
653 lstrcpyA(path, "C:\\one\\");
654 SetLastError(0xdeadbeef);
655 str = PathAddBackslashA(path);
656 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
657 ok(!lstrcmp(path, "C:\\one\\"), "Expected C:\\one\\, got %s\n", path);
658 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
660 memset(too_long, 'a', LONG_LEN);
661 too_long[LONG_LEN - 1] = '\0';
663 /* path is longer than MAX_PATH */
664 SetLastError(0xdeadbeef);
665 str = PathAddBackslashA(too_long);
666 ok(str == NULL, "Expected str == NULL, got %p\n", str);
667 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
670 static void test_PathAppendA(void)
673 char too_long[LONG_LEN];
674 char one[HALF_LEN], two[HALF_LEN];
677 lstrcpy(path, "C:\\one");
679 /* try NULL pszMore */
680 SetLastError(0xdeadbeef);
681 res = PathAppendA(path, NULL);
682 ok(!res, "Expected failure\n");
683 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
684 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
686 /* try 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, "C:\\one"), "Expected C:\\one, got %s\n", path);
693 /* try NULL pszPath */
694 SetLastError(0xdeadbeef);
695 res = PathAppendA(NULL, "two\\three");
696 ok(!res, "Expected failure\n");
697 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
699 /* try empty pszPath */
701 SetLastError(0xdeadbeef);
702 res = PathAppendA(path, "two\\three");
703 ok(res, "Expected success\n");
704 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
705 ok(!lstrcmp(path, "two\\three"), "Expected \\two\\three, got %s\n", path);
707 /* try empty pszPath and empty pszMore */
709 SetLastError(0xdeadbeef);
710 res = PathAppendA(path, "");
711 ok(res, "Expected success\n");
712 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
713 ok(!lstrcmp(path, "\\"), "Expected \\, got %s\n", path);
715 /* try legit params */
716 lstrcpy(path, "C:\\one");
717 SetLastError(0xdeadbeef);
718 res = PathAppendA(path, "two\\three");
719 ok(res, "Expected success\n");
720 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
721 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
723 /* try pszPath with backslash after it */
724 lstrcpy(path, "C:\\one\\");
725 SetLastError(0xdeadbeef);
726 res = PathAppendA(path, "two\\three");
727 ok(res, "Expected success\n");
728 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
729 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
731 /* try pszMore with backslash before it */
732 lstrcpy(path, "C:\\one");
733 SetLastError(0xdeadbeef);
734 res = PathAppendA(path, "\\two\\three");
735 ok(res, "Expected success\n");
736 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
737 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
739 /* try pszMore with backslash after it */
740 lstrcpy(path, "C:\\one");
741 SetLastError(0xdeadbeef);
742 res = PathAppendA(path, "two\\three\\");
743 ok(res, "Expected success\n");
744 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
745 ok(!lstrcmp(path, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", path);
747 /* try spaces in pszPath */
748 lstrcpy(path, "C: \\ one ");
749 SetLastError(0xdeadbeef);
750 res = PathAppendA(path, "two\\three");
751 ok(res, "Expected success\n");
752 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
753 ok(!lstrcmp(path, "C: \\ one \\two\\three"), "Expected C: \\ one \\two\\three, got %s\n", path);
755 /* try spaces in pszMore */
756 lstrcpy(path, "C:\\one");
757 SetLastError(0xdeadbeef);
758 res = PathAppendA(path, " two \\ three ");
759 ok(res, "Expected success\n");
760 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
761 ok(!lstrcmp(path, "C:\\one\\ two \\ three "), "Expected 'C:\\one\\ two \\ three ', got %s\n", path);
763 /* pszPath is too long */
764 memset(too_long, 'a', LONG_LEN);
765 too_long[LONG_LEN - 1] = '\0';
766 SetLastError(0xdeadbeef);
767 res = PathAppendA(too_long, "two\\three");
768 ok(!res, "Expected failure\n");
769 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
770 ok(lstrlen(too_long) == 0, "Expected length of too_long to be zero, got %i\n", lstrlen(too_long));
772 /* pszMore is too long */
773 lstrcpy(path, "C:\\one");
774 memset(too_long, 'a', LONG_LEN);
775 too_long[LONG_LEN - 1] = '\0';
776 SetLastError(0xdeadbeef);
777 res = PathAppendA(path, too_long);
778 ok(!res, "Expected failure\n");
779 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
780 ok(lstrlen(path) == 0, "Expected length of path to be zero, got %i\n", lstrlen(path));
782 /* both params combined are too long */
783 memset(one, 'a', HALF_LEN);
784 one[HALF_LEN - 1] = '\0';
785 memset(two, 'b', HALF_LEN);
786 two[HALF_LEN - 1] = '\0';
787 SetLastError(0xdeadbeef);
788 res = PathAppendA(one, two);
789 ok(!res, "Expected failure\n");
790 ok(lstrlen(one) == 0, "Expected length of one to be zero, got %i\n", lstrlen(one));
791 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
794 static void test_PathCanonicalizeA(void)
797 char too_long[LONG_LEN];
800 /* try a NULL source */
801 lstrcpy(dest, "test");
802 SetLastError(0xdeadbeef);
803 res = PathCanonicalizeA(dest, NULL);
804 ok(!res, "Expected failure\n");
805 ok(GetLastError() == ERROR_INVALID_PARAMETER,
806 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
809 ok(!lstrcmp(dest, "test"), "Expected test, got %s\n", dest);
812 /* try an empty source */
813 lstrcpy(dest, "test");
814 SetLastError(0xdeadbeef);
815 res = PathCanonicalizeA(dest, "");
816 ok(res, "Expected success\n");
817 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
818 ok(!lstrcmp(dest, "\\"), "Expected \\, got %s\n", dest);
820 /* try a NULL dest */
821 SetLastError(0xdeadbeef);
822 res = PathCanonicalizeA(NULL, "C:\\");
823 ok(!res, "Expected failure\n");
824 ok(GetLastError() == ERROR_INVALID_PARAMETER,
825 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
829 SetLastError(0xdeadbeef);
830 res = PathCanonicalizeA(dest, "C:\\");
831 ok(res, "Expected success\n");
832 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
833 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
835 /* try non-empty dest */
836 lstrcpy(dest, "test");
837 SetLastError(0xdeadbeef);
838 res = PathCanonicalizeA(dest, "C:\\");
839 ok(res, "Expected success\n");
840 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
841 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
843 /* try a space for source */
844 lstrcpy(dest, "test");
845 SetLastError(0xdeadbeef);
846 res = PathCanonicalizeA(dest, " ");
847 ok(res, "Expected success\n");
848 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
849 ok(!lstrcmp(dest, " "), "Expected ' ', got %s\n", dest);
851 /* try a relative path */
852 lstrcpy(dest, "test");
853 SetLastError(0xdeadbeef);
854 res = PathCanonicalizeA(dest, "one\\two");
855 ok(res, "Expected success\n");
856 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
857 ok(!lstrcmp(dest, "one\\two"), "Expected one\\two, got %s\n", dest);
859 /* try current dir and previous dir */
860 lstrcpy(dest, "test");
861 SetLastError(0xdeadbeef);
862 res = PathCanonicalizeA(dest, "C:\\one\\.\\..\\two\\three\\..");
863 ok(res, "Expected success\n");
864 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
865 ok(!lstrcmp(dest, "C:\\two"), "Expected C:\\two, got %s\n", dest);
867 /* try simple forward slashes */
868 lstrcpy(dest, "test");
869 SetLastError(0xdeadbeef);
870 res = PathCanonicalizeA(dest, "C:\\one/two/three\\four/five\\six");
871 ok(res, "Expected success\n");
872 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
873 ok(!lstrcmp(dest, "C:\\one/two/three\\four/five\\six"),
874 "Expected C:\\one/two/three\\four/five\\six, got %s\n", dest);
876 /* try simple forward slashes with same dir */
877 lstrcpy(dest, "test");
878 SetLastError(0xdeadbeef);
879 res = PathCanonicalizeA(dest, "C:\\one/.\\two");
880 ok(res, "Expected success\n");
881 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
882 ok(!lstrcmp(dest, "C:\\one/.\\two"), "Expected C:\\one/.\\two, got %s\n", dest);
884 /* try simple forward slashes with change dir */
885 lstrcpy(dest, "test");
886 SetLastError(0xdeadbeef);
887 res = PathCanonicalizeA(dest, "C:\\one/.\\two\\..");
888 ok(res, "Expected success\n");
889 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
890 ok(!lstrcmp(dest, "C:\\one/."), "Expected C:\\one/., got %s\n", dest);
892 /* try forward slashes with change dirs
893 * NOTE: if there is a forward slash in between two backslashes,
894 * everything in between the two backslashes is considered on dir
896 lstrcpy(dest, "test");
897 SetLastError(0xdeadbeef);
898 res = PathCanonicalizeA(dest, "C:\\one/.\\..\\two/three\\..\\four/.five");
899 ok(res, "Expected success\n");
900 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
901 ok(!lstrcmp(dest, "C:\\four/.five"), "Expected C:\\four/.five, got %s\n", dest);
903 /* try src is too long */
904 memset(too_long, 'a', LONG_LEN);
905 too_long[LONG_LEN - 1] = '\0';
906 lstrcpy(dest, "test");
907 SetLastError(0xdeadbeef);
908 res = PathCanonicalizeA(dest, too_long);
911 ok(!res, "Expected failure\n");
912 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
914 ok(lstrlen(too_long) == LONG_LEN - 1, "Expected length LONG_LEN - 1, got %i\n", lstrlen(too_long));
917 static void test_PathFindExtensionA(void)
921 char too_long[LONG_LEN];
923 /* try a NULL path */
924 SetLastError(0xdeadbeef);
925 ext = PathFindExtensionA(NULL);
926 ok(ext == NULL, "Expected NULL, got %p\n", ext);
927 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
929 /* try an empty path */
931 SetLastError(0xdeadbeef);
932 ext = PathFindExtensionA(path);
933 ok(ext == path, "Expected ext == path, got %p\n", ext);
934 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
935 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
937 /* try a path without an extension */
938 lstrcpy(path, "file");
939 SetLastError(0xdeadbeef);
940 ext = PathFindExtensionA(path);
941 ok(ext == path + lstrlen(path), "Expected ext == path, got %p\n", ext);
942 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
943 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
945 /* try a path with an extension */
946 lstrcpy(path, "file.txt");
947 SetLastError(0xdeadbeef);
948 ext = PathFindExtensionA(path);
949 ok(ext == path + lstrlen("file"),
950 "Expected ext == path + lstrlen(\"file\"), got %p\n", ext);
951 ok(!lstrcmp(ext, ".txt"), "Expected .txt, got %s\n", ext);
952 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
954 /* try a path with two extensions */
955 lstrcpy(path, "file.txt.doc");
956 SetLastError(0xdeadbeef);
957 ext = PathFindExtensionA(path);
958 ok(ext == path + lstrlen("file.txt"),
959 "Expected ext == path + lstrlen(\"file.txt\"), got %p\n", ext);
960 ok(!lstrcmp(ext, ".doc"), "Expected .txt, got %s\n", ext);
961 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
963 /* try a path longer than MAX_PATH without an extension*/
964 memset(too_long, 'a', LONG_LEN);
965 too_long[LONG_LEN - 1] = '\0';
966 SetLastError(0xdeadbeef);
967 ext = PathFindExtensionA(too_long);
968 ok(ext == too_long + LONG_LEN - 1, "Expected ext == too_long + LONG_LEN - 1, got %p\n", ext);
969 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
971 /* try a path longer than MAX_PATH with an extension*/
972 memset(too_long, 'a', LONG_LEN);
973 too_long[LONG_LEN - 1] = '\0';
974 lstrcpy(too_long + 300, ".abcde");
975 too_long[lstrlen(too_long)] = 'a';
976 SetLastError(0xdeadbeef);
977 ext = PathFindExtensionA(too_long);
978 ok(ext == too_long + 300, "Expected ext == too_long + 300, got %p\n", ext);
979 ok(lstrlen(ext) == LONG_LEN - 301, "Expected LONG_LEN - 301, got %i\n", lstrlen(ext));
980 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
983 static void test_PathBuildRootA(void)
987 char root_expected[26][4];
991 /* set up the expected paths */
992 for (drive = 'A'; drive <= 'Z'; drive++)
993 sprintf(root_expected[drive - 'A'], "%c:\\", drive);
995 /* test the expected values */
996 for (j = 0; j < 26; j++)
998 SetLastError(0xdeadbeef);
999 lstrcpy(path, "aaaaaaaaa");
1000 root = PathBuildRootA(path, j);
1001 ok(root == path, "Expected root == path, got %p\n", root);
1002 ok(!lstrcmp(root, root_expected[j]), "Expected %s, got %s\n", root_expected[j], root);
1003 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1006 /* test a negative drive number */
1007 SetLastError(0xdeadbeef);
1008 lstrcpy(path, "aaaaaaaaa");
1009 root = PathBuildRootA(path, -1);
1010 ok(root == path, "Expected root == path, got %p\n", root);
1011 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1012 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1014 /* test a drive number greater than 25 */
1015 SetLastError(0xdeadbeef);
1016 lstrcpy(path, "aaaaaaaaa");
1017 root = PathBuildRootA(path, 26);
1018 ok(root == path, "Expected root == path, got %p\n", root);
1019 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1020 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1022 /* length of path is less than 4 */
1023 SetLastError(0xdeadbeef);
1024 lstrcpy(path, "aa");
1025 root = PathBuildRootA(path, 0);
1026 ok(root == path, "Expected root == path, got %p\n", root);
1027 ok(!lstrcmp(path, "A:\\"), "Expected A:\\, got %s\n", path);
1028 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1031 SetLastError(0xdeadbeef);
1032 root = PathBuildRootA(NULL, 0);
1033 ok(root == NULL, "Expected root == NULL, got %p\n", root);
1034 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1037 static void test_PathCommonPrefixA(void)
1039 char path1[MAX_PATH], path2[MAX_PATH];
1043 /* test NULL path1 */
1044 SetLastError(0xdeadbeef);
1045 lstrcpy(path2, "C:\\");
1046 lstrcpy(out, "aaa");
1047 count = PathCommonPrefixA(NULL, path2, out);
1048 ok(count == 0, "Expected 0, got %i\n", count);
1051 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1053 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1054 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1056 /* test NULL path2 */
1057 SetLastError(0xdeadbeef);
1058 lstrcpy(path1, "C:\\");
1059 lstrcpy(out, "aaa");
1060 count = PathCommonPrefixA(path1, NULL, out);
1061 ok(count == 0, "Expected 0, got %i\n", count);
1064 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1066 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1067 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1069 /* test empty path1 */
1070 SetLastError(0xdeadbeef);
1072 lstrcpy(path2, "C:\\");
1073 lstrcpy(out, "aaa");
1074 count = PathCommonPrefixA(path1, path2, out);
1075 ok(count == 0, "Expected 0, got %i\n", count);
1076 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1077 ok(lstrlen(path1) == 0, "Expected 0 length path1, got %i\n", lstrlen(path1));
1078 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1079 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1081 /* test empty path1 */
1082 SetLastError(0xdeadbeef);
1084 lstrcpy(path1, "C:\\");
1085 lstrcpy(out, "aaa");
1086 count = PathCommonPrefixA(path1, path2, out);
1087 ok(count == 0, "Expected 0, got %i\n", count);
1088 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1089 ok(lstrlen(path2) == 0, "Expected 0 length path2, got %i\n", lstrlen(path2));
1090 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1091 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1093 /* paths are legit, out is NULL */
1094 SetLastError(0xdeadbeef);
1095 lstrcpy(path1, "C:\\");
1096 lstrcpy(path2, "C:\\");
1097 count = PathCommonPrefixA(path1, path2, NULL);
1098 ok(count == 3, "Expected 3, got %i\n", count);
1099 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1100 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1101 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1103 /* all parameters legit */
1104 SetLastError(0xdeadbeef);
1105 lstrcpy(path1, "C:\\");
1106 lstrcpy(path2, "C:\\");
1107 lstrcpy(out, "aaa");
1108 count = PathCommonPrefixA(path1, path2, out);
1109 ok(count == 3, "Expected 3, got %i\n", count);
1110 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1111 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1112 ok(!lstrcmp(out, "C:\\"), "Expected C:\\, got %s\n", out);
1113 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1115 /* path1 and path2 not the same, but common prefix */
1116 SetLastError(0xdeadbeef);
1117 lstrcpy(path1, "C:\\one\\two");
1118 lstrcpy(path2, "C:\\one\\three");
1119 lstrcpy(out, "aaa");
1120 count = PathCommonPrefixA(path1, path2, out);
1121 ok(count == 6, "Expected 6, got %i\n", count);
1122 ok(!lstrcmp(path1, "C:\\one\\two"), "Expected C:\\one\\two, got %s\n", path1);
1123 ok(!lstrcmp(path2, "C:\\one\\three"), "Expected C:\\one\\three, got %s\n", path2);
1124 ok(!lstrcmp(out, "C:\\one"), "Expected C:\\one, got %s\n", out);
1125 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1128 SetLastError(0xdeadbeef);
1129 lstrcpy(path1, "one\\.two");
1130 lstrcpy(path2, "one\\.three");
1131 lstrcpy(out, "aaa");
1132 count = PathCommonPrefixA(path1, path2, out);
1133 ok(count == 3, "Expected 3, got %i\n", count);
1134 ok(!lstrcmp(path1, "one\\.two"), "Expected one\\.two, got %s\n", path1);
1135 ok(!lstrcmp(path2, "one\\.three"), "Expected one\\.three, got %s\n", path2);
1136 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1137 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1140 SetLastError(0xdeadbeef);
1141 lstrcpy(path1, "one\\..two");
1142 lstrcpy(path2, "one\\..three");
1143 lstrcpy(out, "aaa");
1144 count = PathCommonPrefixA(path1, path2, out);
1145 ok(count == 3, "Expected 3, got %i\n", count);
1146 ok(!lstrcmp(path1, "one\\..two"), "Expected one\\..two, got %s\n", path1);
1147 ok(!lstrcmp(path2, "one\\..three"), "Expected one\\..three, got %s\n", path2);
1148 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1149 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1151 /* try ... prefix */
1152 SetLastError(0xdeadbeef);
1153 lstrcpy(path1, "one\\...two");
1154 lstrcpy(path2, "one\\...three");
1155 lstrcpy(out, "aaa");
1156 count = PathCommonPrefixA(path1, path2, out);
1157 ok(count == 3, "Expected 3, got %i\n", count);
1158 ok(!lstrcmp(path1, "one\\...two"), "Expected one\\...two, got %s\n", path1);
1159 ok(!lstrcmp(path2, "one\\...three"), "Expected one\\...three, got %s\n", path2);
1160 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1161 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1164 SetLastError(0xdeadbeef);
1165 lstrcpy(path1, "one\\.\\two");
1166 lstrcpy(path2, "one\\.\\three");
1167 lstrcpy(out, "aaa");
1168 count = PathCommonPrefixA(path1, path2, out);
1169 ok(count == 5, "Expected 5, got %i\n", count);
1170 ok(!lstrcmp(path1, "one\\.\\two"), "Expected one\\.\\two, got %s\n", path1);
1171 ok(!lstrcmp(path2, "one\\.\\three"), "Expected one\\.\\three, got %s\n", path2);
1172 ok(!lstrcmp(out, "one\\."), "Expected one\\., got %s\n", out);
1173 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1175 /* try ..\ prefix */
1176 SetLastError(0xdeadbeef);
1177 lstrcpy(path1, "one\\..\\two");
1178 lstrcpy(path2, "one\\..\\three");
1179 lstrcpy(out, "aaa");
1180 count = PathCommonPrefixA(path1, path2, out);
1181 ok(count == 6, "Expected 6, got %i\n", count);
1182 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1183 ok(!lstrcmp(path2, "one\\..\\three"), "Expected one\\..\\three, got %s\n", path2);
1184 ok(!lstrcmp(out, "one\\.."), "Expected one\\.., got %s\n", out);
1185 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1187 /* try ...\\ prefix */
1188 SetLastError(0xdeadbeef);
1189 lstrcpy(path1, "one\\...\\two");
1190 lstrcpy(path2, "one\\...\\three");
1191 lstrcpy(out, "aaa");
1192 count = PathCommonPrefixA(path1, path2, out);
1193 ok(count == 7, "Expected 7, got %i\n", count);
1194 ok(!lstrcmp(path1, "one\\...\\two"), "Expected one\\...\\two, got %s\n", path1);
1195 ok(!lstrcmp(path2, "one\\...\\three"), "Expected one\\...\\three, got %s\n", path2);
1196 ok(!lstrcmp(out, "one\\..."), "Expected one\\..., got %s\n", out);
1197 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1199 /* try prefix that is not an msdn labeled prefix type */
1200 SetLastError(0xdeadbeef);
1201 lstrcpy(path1, "same");
1202 lstrcpy(path2, "same");
1203 lstrcpy(out, "aaa");
1204 count = PathCommonPrefixA(path1, path2, out);
1205 ok(count == 4, "Expected 4, got %i\n", count);
1206 ok(!lstrcmp(path1, "same"), "Expected same, got %s\n", path1);
1207 ok(!lstrcmp(path2, "same"), "Expected same, got %s\n", path2);
1208 ok(!lstrcmp(out, "same"), "Expected same, got %s\n", out);
1209 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1211 /* try . after directory */
1212 SetLastError(0xdeadbeef);
1213 lstrcpy(path1, "one\\mid.\\two");
1214 lstrcpy(path2, "one\\mid.\\three");
1215 lstrcpy(out, "aaa");
1216 count = PathCommonPrefixA(path1, path2, out);
1217 ok(count == 8, "Expected 8, got %i\n", count);
1218 ok(!lstrcmp(path1, "one\\mid.\\two"), "Expected one\\mid.\\two, got %s\n", path1);
1219 ok(!lstrcmp(path2, "one\\mid.\\three"), "Expected one\\mid.\\three, got %s\n", path2);
1220 ok(!lstrcmp(out, "one\\mid."), "Expected one\\mid., got %s\n", out);
1221 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1223 /* try . in the middle of a directory */
1224 SetLastError(0xdeadbeef);
1225 lstrcpy(path1, "one\\mid.end\\two");
1226 lstrcpy(path2, "one\\mid.end\\three");
1227 lstrcpy(out, "aaa");
1228 count = PathCommonPrefixA(path1, path2, out);
1229 ok(count == 11, "Expected 11, got %i\n", count);
1230 ok(!lstrcmp(path1, "one\\mid.end\\two"), "Expected one\\mid.end\\two, got %s\n", path1);
1231 ok(!lstrcmp(path2, "one\\mid.end\\three"), "Expected one\\mid.end\\three, got %s\n", path2);
1232 ok(!lstrcmp(out, "one\\mid.end"), "Expected one\\mid.end, got %s\n", out);
1233 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1235 /* try comparing a .. with the expanded path */
1236 SetLastError(0xdeadbeef);
1237 lstrcpy(path1, "one\\..\\two");
1238 lstrcpy(path2, "two");
1239 lstrcpy(out, "aaa");
1240 count = PathCommonPrefixA(path1, path2, out);
1241 ok(count == 0, "Expected 0, got %i\n", count);
1242 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1243 ok(!lstrcmp(path2, "two"), "Expected two, got %s\n", path2);
1244 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1245 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1248 static void test_PathUnquoteSpaces(void)
1251 for(i = 0; i < sizeof(TEST_PATH_UNQUOTE_SPACES) / sizeof(TEST_PATH_UNQUOTE_SPACES[0]); i++)
1253 char *path = strdupA(TEST_PATH_UNQUOTE_SPACES[i].path);
1254 WCHAR *pathW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].path);
1255 WCHAR *resultW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].result);
1257 PathUnquoteSpacesA(path);
1258 ok(!strcmp(path, TEST_PATH_UNQUOTE_SPACES[i].result), "%s (A): got %s expected %s\n",
1259 TEST_PATH_UNQUOTE_SPACES[i].path, path,
1260 TEST_PATH_UNQUOTE_SPACES[i].result);
1262 PathUnquoteSpacesW(pathW);
1263 ok(!lstrcmpW(pathW, resultW), "%s (W): strings differ\n",
1264 TEST_PATH_UNQUOTE_SPACES[i].path);
1265 FreeWideString(pathW);
1266 FreeWideString(resultW);
1267 HeapFree(GetProcessHeap(), 0, path);
1271 /* ################ */
1275 hShlwapi = GetModuleHandleA("shlwapi.dll");
1277 test_PathSearchAndQualify();
1278 test_PathCreateFromUrl();
1281 test_PathAddBackslash();
1282 test_PathMakePretty();
1283 test_PathMatchSpec();
1285 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
1286 * ordinal number in some native versions. Check this to prevent a crash.
1288 pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
1289 if (pPathIsValidCharA && pPathIsValidCharA != (void*)GetProcAddress(hShlwapi, "PathAppendA"))
1291 test_PathIsValidCharA();
1293 pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
1294 if (pPathIsValidCharW) test_PathIsValidCharW();
1297 pPathCombineW = (void*)GetProcAddress(hShlwapi, "PathCombineW");
1299 test_PathCombineW();
1301 test_PathCombineA();
1303 test_PathCanonicalizeA();
1304 test_PathFindExtensionA();
1305 test_PathBuildRootA();
1306 test_PathCommonPrefixA();
1307 test_PathUnquoteSpaces();