winemac: Don't unminimize a window for SetFocus().
[wine.git] / dlls / shlwapi / tests / path.c
blobd9209bddf3e69fe51c350828a9ab576bd837a15f
1 /* Unit test suite for Path functions
3 * Copyright 2002 Matthew Mastracci
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdarg.h>
21 #include <stdio.h>
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winreg.h"
27 #include "shlwapi.h"
28 #include "wininet.h"
30 static HRESULT (WINAPI *pPathIsValidCharA)(char,DWORD);
31 static HRESULT (WINAPI *pPathIsValidCharW)(WCHAR,DWORD);
32 static LPWSTR (WINAPI *pPathCombineW)(LPWSTR, LPCWSTR, LPCWSTR);
33 static HRESULT (WINAPI *pPathCreateFromUrlA)(LPCSTR, LPSTR, LPDWORD, DWORD);
34 static HRESULT (WINAPI *pPathCreateFromUrlW)(LPCWSTR, LPWSTR, LPDWORD, DWORD);
35 static HRESULT (WINAPI *pPathCreateFromUrlAlloc)(LPCWSTR, LPWSTR*, DWORD);
36 static BOOL (WINAPI *pPathAppendA)(LPSTR, LPCSTR);
38 /* ################ */
40 static const struct {
41 const char *url;
42 const char *path;
43 DWORD ret, todo;
44 } TEST_PATHFROMURL[] = {
45 /* 0 leading slash */
46 {"file:c:/foo/bar", "c:\\foo\\bar", S_OK, 0},
47 {"file:c|/foo/bar", "c:\\foo\\bar", S_OK, 0},
48 {"file:cx|/foo/bar", "cx|\\foo\\bar", S_OK, 0},
49 {"file:c:foo/bar", "c:foo\\bar", S_OK, 0},
50 {"file:c|foo/bar", "c:foo\\bar", S_OK, 0},
51 {"file:c:/foo%20ba%2fr", "c:\\foo ba/r", S_OK, 0},
52 {"file:foo%20ba%2fr", "foo ba/r", S_OK, 0},
53 {"file:foo/bar/", "foo\\bar\\", S_OK, 0},
55 /* 1 leading (back)slash */
56 {"file:/c:/foo/bar", "c:\\foo\\bar", S_OK, 0},
57 {"file:\\c:/foo/bar", "c:\\foo\\bar", S_OK, 0},
58 {"file:/c|/foo/bar", "c:\\foo\\bar", S_OK, 0},
59 {"file:/cx|/foo/bar", "\\cx|\\foo\\bar", S_OK, 0},
60 {"file:/c:foo/bar", "c:foo\\bar", S_OK, 0},
61 {"file:/c|foo/bar", "c:foo\\bar", S_OK, 0},
62 {"file:/c:/foo%20ba%2fr", "c:\\foo ba/r", S_OK, 0},
63 {"file:/foo%20ba%2fr", "\\foo ba/r", S_OK, 0},
64 {"file:/foo/bar/", "\\foo\\bar\\", S_OK, 0},
66 /* 2 leading (back)slashes */
67 {"file://c:/foo/bar", "c:\\foo\\bar", S_OK, 0},
68 {"file://c:/d:/foo/bar", "c:\\d:\\foo\\bar", S_OK, 0},
69 {"file://c|/d|/foo/bar", "c:\\d|\\foo\\bar", S_OK, 0},
70 {"file://cx|/foo/bar", "\\\\cx|\\foo\\bar", S_OK, 0},
71 {"file://c:foo/bar", "c:foo\\bar", S_OK, 0},
72 {"file://c|foo/bar", "c:foo\\bar", S_OK, 0},
73 {"file://c:/foo%20ba%2fr", "c:\\foo%20ba%2fr", S_OK, 0},
74 {"file://c%3a/foo/../bar", "\\\\c:\\foo\\..\\bar", S_OK, 0},
75 {"file://c%7c/foo/../bar", "\\\\c|\\foo\\..\\bar", S_OK, 0},
76 {"file://foo%20ba%2fr", "\\\\foo ba/r", S_OK, 0},
77 {"file://localhost/c:/foo/bar", "c:\\foo\\bar", S_OK, 0},
78 {"file://localhost/c:/foo%20ba%5Cr", "c:\\foo ba\\r", S_OK, 0},
79 {"file://LocalHost/c:/foo/bar", "c:\\foo\\bar", S_OK, 0},
80 {"file:\\\\localhost\\c:\\foo\\bar", "c:\\foo\\bar", S_OK, 0},
81 {"file://incomplete", "\\\\incomplete", S_OK, 0},
83 /* 3 leading (back)slashes (omitting hostname) */
84 {"file:///c:/foo/bar", "c:\\foo\\bar", S_OK, 0},
85 {"File:///c:/foo/bar", "c:\\foo\\bar", S_OK, 0},
86 {"file:///c:/foo%20ba%2fr", "c:\\foo ba/r", S_OK, 0},
87 {"file:///foo%20ba%2fr", "\\foo ba/r", S_OK, 0},
88 {"file:///foo/bar/", "\\foo\\bar\\", S_OK, 0},
89 {"file:///localhost/c:/foo/bar", "\\localhost\\c:\\foo\\bar", S_OK, 0},
91 /* 4 leading (back)slashes */
92 {"file:////c:/foo/bar", "c:\\foo\\bar", S_OK, 0},
93 {"file:////c:/foo%20ba%2fr", "c:\\foo%20ba%2fr", S_OK, 0},
94 {"file:////foo%20ba%2fr", "\\\\foo%20ba%2fr", S_OK, 0},
96 /* 5 and more leading (back)slashes */
97 {"file://///c:/foo/bar", "\\\\c:\\foo\\bar", S_OK, 0},
98 {"file://///c:/foo%20ba%2fr", "\\\\c:\\foo ba/r", S_OK, 0},
99 {"file://///foo%20ba%2fr", "\\\\foo ba/r", S_OK, 0},
100 {"file://////c:/foo/bar", "\\\\c:\\foo\\bar", S_OK, 0},
102 /* Leading (back)slashes cannot be escaped */
103 {"file:%2f%2flocalhost%2fc:/foo/bar", "//localhost/c:\\foo\\bar", S_OK, 0},
104 {"file:%5C%5Clocalhost%5Cc:/foo/bar", "\\\\localhost\\c:\\foo\\bar", S_OK, 0},
106 /* Hostname handling */
107 {"file://l%6fcalhost/c:/foo/bar", "\\\\localhostc:\\foo\\bar", S_OK, 0},
108 {"file://localhost:80/c:/foo/bar", "\\\\localhost:80c:\\foo\\bar", S_OK, 0},
109 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK, 0},
110 {"file://host//c:/foo/bar", "\\\\host\\\\c:\\foo\\bar", S_OK, 0},
111 {"file://host/\\c:/foo/bar", "\\\\host\\\\c:\\foo\\bar", S_OK, 0},
112 {"file://host/c:foo/bar", "\\\\hostc:foo\\bar", S_OK, 0},
113 {"file://host/foo/bar", "\\\\host\\foo\\bar", S_OK, 0},
114 {"file:\\\\host\\c:\\foo\\bar", "\\\\hostc:\\foo\\bar", S_OK, 0},
115 {"file:\\\\host\\ca\\foo\\bar", "\\\\host\\ca\\foo\\bar", S_OK, 0},
116 {"file:\\\\host\\c|\\foo\\bar", "\\\\hostc|\\foo\\bar", S_OK, 0},
117 {"file:\\%5Chost\\c:\\foo\\bar", "\\\\host\\c:\\foo\\bar", S_OK, 0},
118 {"file:\\\\host\\cx:\\foo\\bar", "\\\\host\\cx:\\foo\\bar", S_OK, 0},
119 {"file:///host/c:/foo/bar", "\\host\\c:\\foo\\bar", S_OK, 0},
121 /* Not file URLs */
122 {"c:\\foo\\bar", NULL, E_INVALIDARG, 0},
123 {"foo/bar", NULL, E_INVALIDARG, 0},
124 {"http://foo/bar", NULL, E_INVALIDARG, 0},
129 static struct {
130 const char *path;
131 BOOL expect;
132 } TEST_PATH_IS_URL[] = {
133 {"http://foo/bar", TRUE},
134 {"c:\\foo\\bar", FALSE},
135 {"c:/foo/bar", FALSE},
136 {"foo://foo/bar", TRUE},
137 {"foo\\bar", FALSE},
138 {"foo.bar", FALSE},
139 {"bogusscheme:", TRUE},
140 {"http:partial", TRUE},
141 {"www.winehq.org", FALSE},
142 /* More examples that the user might enter as the browser start page */
143 {"winehq.org", FALSE},
144 {"ftp.winehq.org", FALSE},
145 {"http://winehq.org", TRUE},
146 {"http://www.winehq.org", TRUE},
147 {"https://winehq.org", TRUE},
148 {"https://www.winehq.org", TRUE},
149 {"ftp://winehq.org", TRUE},
150 {"ftp://ftp.winehq.org", TRUE},
151 {"file://does_not_exist.txt", TRUE},
152 {"about:blank", TRUE},
153 {"about:home", TRUE},
154 {"about:mozilla", TRUE},
155 /* scheme is case independent */
156 {"HTTP://www.winehq.org", TRUE},
157 /* a space at the start is not allowed */
158 {" http://www.winehq.org", FALSE},
159 {"", FALSE},
160 {NULL, FALSE}
163 static const struct {
164 const char *path;
165 const char *result;
166 } TEST_PATH_UNQUOTE_SPACES[] = {
167 { "abcdef", "abcdef" },
168 { "\"abcdef\"", "abcdef" },
169 { "\"abcdef", "\"abcdef" },
170 { "abcdef\"", "abcdef\"" },
171 { "\"\"abcdef\"\"", "\"abcdef\"" },
172 { "abc\"def", "abc\"def" },
173 { "\"abc\"def", "\"abc\"def" },
174 { "\"abc\"def\"", "abc\"def" },
175 { "\'abcdef\'", "\'abcdef\'" },
176 { "\"\"", "" },
177 { "\"", "" }
180 /* ################ */
182 static LPWSTR GetWideString(const char* szString)
184 LPWSTR wszString = HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
186 MultiByteToWideChar(CP_ACP, 0, szString, -1, wszString, INTERNET_MAX_URL_LENGTH);
188 return wszString;
191 static void FreeWideString(LPWSTR wszString)
193 HeapFree(GetProcessHeap(), 0, wszString);
196 static LPSTR strdupA(LPCSTR p)
198 LPSTR ret;
199 DWORD len = (strlen(p) + 1);
200 ret = HeapAlloc(GetProcessHeap(), 0, len);
201 memcpy(ret, p, len);
202 return ret;
205 /* ################ */
207 static void test_PathSearchAndQualify(void)
209 WCHAR path1[] = {'c',':','\\','f','o','o',0};
210 WCHAR expect1[] = {'c',':','\\','f','o','o',0};
211 WCHAR path2[] = {'c',':','f','o','o',0};
212 WCHAR c_drive[] = {'c',':',0};
213 WCHAR foo[] = {'f','o','o',0};
214 WCHAR path3[] = {'\\','f','o','o',0};
215 WCHAR winini[] = {'w','i','n','.','i','n','i',0};
216 WCHAR out[MAX_PATH];
217 WCHAR cur_dir[MAX_PATH];
218 WCHAR dot[] = {'.',0};
220 /* c:\foo */
221 ok(PathSearchAndQualifyW(path1, out, MAX_PATH) != 0,
222 "PathSearchAndQualify rets 0\n");
223 ok(!lstrcmpiW(out, expect1), "strings don't match\n");
225 /* c:foo */
226 ok(PathSearchAndQualifyW(path2, out, MAX_PATH) != 0,
227 "PathSearchAndQualify rets 0\n");
228 GetFullPathNameW(c_drive, MAX_PATH, cur_dir, NULL);
229 PathAddBackslashW(cur_dir);
230 lstrcatW(cur_dir, foo);
231 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
233 /* foo */
234 ok(PathSearchAndQualifyW(foo, out, MAX_PATH) != 0,
235 "PathSearchAndQualify rets 0\n");
236 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
237 PathAddBackslashW(cur_dir);
238 lstrcatW(cur_dir, foo);
239 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
241 /* \foo */
242 ok(PathSearchAndQualifyW(path3, out, MAX_PATH) != 0,
243 "PathSearchAndQualify rets 0\n");
244 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
245 lstrcpyW(cur_dir + 2, path3);
246 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
248 /* win.ini */
249 ok(PathSearchAndQualifyW(winini, out, MAX_PATH) != 0,
250 "PathSearchAndQualify rets 0\n");
251 if(!SearchPathW(NULL, winini, NULL, MAX_PATH, cur_dir, NULL))
252 GetFullPathNameW(winini, MAX_PATH, cur_dir, NULL);
253 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
257 static void test_PathCreateFromUrl(void)
259 size_t i;
260 char ret_path[INTERNET_MAX_URL_LENGTH];
261 DWORD len, len2, ret;
262 WCHAR ret_pathW[INTERNET_MAX_URL_LENGTH];
263 WCHAR *pathW, *urlW;
265 if (!pPathCreateFromUrlA) {
266 win_skip("PathCreateFromUrlA not found\n");
267 return;
270 /* Won't say how much is needed without a buffer */
271 len = 0xdeca;
272 ret = pPathCreateFromUrlA("file://foo", NULL, &len, 0);
273 ok(ret == E_INVALIDARG, "got 0x%08x expected E_INVALIDARG\n", ret);
274 ok(len == 0xdeca, "got %x expected 0xdeca\n", len);
276 /* Test the decoding itself */
277 for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
278 len = INTERNET_MAX_URL_LENGTH;
279 ret = pPathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
280 if (!(TEST_PATHFROMURL[i].todo & 0x1))
281 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url %s\n", ret, TEST_PATHFROMURL[i].url);
282 else todo_wine
283 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url %s\n", ret, TEST_PATHFROMURL[i].url);
284 if(SUCCEEDED(ret) && TEST_PATHFROMURL[i].path) {
285 if(!(TEST_PATHFROMURL[i].todo & 0x2)) {
286 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);
287 ok(len == strlen(ret_path), "ret len %d from url %s\n", len, TEST_PATHFROMURL[i].url);
288 } else todo_wine
289 /* Wrong string, don't bother checking the length */
290 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);
293 if (pPathCreateFromUrlW) {
294 len = INTERNET_MAX_URL_LENGTH;
295 pathW = GetWideString(TEST_PATHFROMURL[i].path);
296 urlW = GetWideString(TEST_PATHFROMURL[i].url);
297 ret = pPathCreateFromUrlW(urlW, ret_pathW, &len, 0);
298 WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),NULL,NULL);
299 if (!(TEST_PATHFROMURL[i].todo & 0x1))
300 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
301 else todo_wine
302 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
303 if(SUCCEEDED(ret) && TEST_PATHFROMURL[i].path) {
304 if(!(TEST_PATHFROMURL[i].todo & 0x2)) {
305 ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n",
306 ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
307 ok(len == lstrlenW(ret_pathW), "ret len %d from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url);
308 } else todo_wine
309 /* Wrong string, don't bother checking the length */
310 ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n",
311 ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
314 if (SUCCEEDED(ret))
316 /* Check what happens if the buffer is too small */
317 len2 = 2;
318 ret = pPathCreateFromUrlW(urlW, ret_pathW, &len2, 0);
319 ok(ret == E_POINTER, "ret %08x, expected E_POINTER from url %s\n", ret, TEST_PATHFROMURL[i].url);
320 if(!(TEST_PATHFROMURL[i].todo & 0x4))
321 ok(len2 == len + 1, "got len = %d expected %d from url %s\n", len2, len + 1, TEST_PATHFROMURL[i].url);
322 else todo_wine
323 ok(len2 == len + 1, "got len = %d expected %d from url %s\n", len2, len + 1, TEST_PATHFROMURL[i].url);
326 FreeWideString(urlW);
327 FreeWideString(pathW);
331 if (pPathCreateFromUrlAlloc)
333 static const WCHAR fileW[] = {'f','i','l','e',':','/','/','f','o','o',0};
334 static const WCHAR fooW[] = {'\\','\\','f','o','o',0};
336 pathW = NULL;
337 ret = pPathCreateFromUrlAlloc(fileW, &pathW, 0);
338 ok(ret == S_OK, "got 0x%08x expected S_OK\n", ret);
339 ok(lstrcmpiW(pathW, fooW) == 0, "got %s expected %s\n", wine_dbgstr_w(pathW), wine_dbgstr_w(fooW));
340 HeapFree(GetProcessHeap(), 0, pathW);
345 static void test_PathIsUrl(void)
347 size_t i;
348 BOOL ret;
350 for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
351 ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
352 ok(ret == TEST_PATH_IS_URL[i].expect,
353 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
354 TEST_PATH_IS_URL[i].expect);
358 static const DWORD SHELL_charclass[] =
360 0x00000000, 0x00000000, 0x00000000, 0x00000000,
361 0x00000000, 0x00000000, 0x00000000, 0x00000000,
362 0x00000000, 0x00000000, 0x00000000, 0x00000000,
363 0x00000000, 0x00000000, 0x00000000, 0x00000000,
364 0x00000000, 0x00000000, 0x00000000, 0x00000000,
365 0x00000000, 0x00000000, 0x00000000, 0x00000000,
366 0x00000000, 0x00000000, 0x00000000, 0x00000000,
367 0x00000000, 0x00000000, 0x00000000, 0x00000000,
368 0x00000080, 0x00000100, 0x00000200, 0x00000100,
369 0x00000100, 0x00000100, 0x00000100, 0x00000100,
370 0x00000100, 0x00000100, 0x00000002, 0x00000100,
371 0x00000040, 0x00000100, 0x00000004, 0x00000000,
372 0x00000100, 0x00000100, 0x00000100, 0x00000100,
373 0x00000100, 0x00000100, 0x00000100, 0x00000100,
374 0x00000100, 0x00000100, 0x00000010, 0x00000020,
375 0x00000000, 0x00000100, 0x00000000, 0x00000001,
376 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
377 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
378 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
379 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
380 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
381 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
382 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
383 0x00000008, 0x00000100, 0x00000100, 0x00000100,
384 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
385 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
386 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
387 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
388 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
389 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
390 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
391 0x00000000, 0x00000100, 0x00000100
394 static void test_PathIsValidCharA(void)
396 BOOL ret;
397 unsigned int c;
399 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
400 * ordinal number in some native versions. Check this to prevent a crash.
402 if (!pPathIsValidCharA || pPathIsValidCharA == (void*)pPathAppendA)
404 win_skip("PathIsValidCharA isn't available\n");
405 return;
408 for (c = 0; c < 0x7f; c++)
410 ret = pPathIsValidCharA( c, ~0U );
411 ok ( ret || !SHELL_charclass[c], "PathIsValidCharA failed: 0x%02x got 0x%08x\n", c, ret );
414 for (c = 0x7f; c <= 0xff; c++)
416 ret = pPathIsValidCharA( c, ~0U );
417 ok ( ret, "PathIsValidCharA failed: 0x%02x got 0x%08x\n", c, ret );
421 static void test_PathIsValidCharW(void)
423 BOOL ret;
424 unsigned int c;
426 if (!pPathIsValidCharW)
428 win_skip("PathIsValidCharW isn't available\n");
429 return;
432 for (c = 0; c < 0x7f; c++)
434 ret = pPathIsValidCharW( c, ~0U );
435 ok ( ret || !SHELL_charclass[c], "PathIsValidCharW failed: 0x%02x got 0x%08x\n", c, ret );
438 for (c = 0x007f; c <= 0xffff; c++)
440 ret = pPathIsValidCharW( c, ~0U );
441 ok ( ret, "PathIsValidCharW failed: 0x%02x got 0x%08x\n", c, ret );
445 static void test_PathMakePretty(void)
447 char buff[MAX_PATH];
449 ok (PathMakePrettyA(NULL) == FALSE, "PathMakePretty: NULL path succeeded\n");
450 buff[0] = '\0';
451 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Empty path failed\n");
453 strcpy(buff, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
454 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Long UC name failed\n");
455 ok (strcmp(buff, "C:\\a long file name with \\spaces.txt") == 0,
456 "PathMakePretty: Long UC name not changed\n");
458 strcpy(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
459 ok (PathMakePrettyA(buff) == FALSE, "PathMakePretty: Long MC name succeeded\n");
460 ok (strcmp(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
461 "PathMakePretty: Failed but modified path\n");
463 strcpy(buff, "TEST");
464 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Short name failed\n");
465 ok (strcmp(buff, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff);
468 static void test_PathMatchSpec(void)
470 static const char file[] = "c:\\foo\\bar\\filename.ext";
471 static const char spec1[] = ".ext";
472 static const char spec2[] = "*.ext";
473 static const char spec3[] = "*.ext ";
474 static const char spec4[] = " *.ext";
475 static const char spec5[] = "* .ext";
476 static const char spec6[] = "*. ext";
477 static const char spec7[] = "* . ext";
478 static const char spec8[] = "*.e?t";
479 static const char spec9[] = "filename.ext";
480 static const char spec10[] = "*bar\\filename.ext";
481 static const char spec11[] = " foo; *.ext";
482 static const char spec12[] = "*.ext;*.bar";
483 static const char spec13[] = "*bar*";
485 ok (PathMatchSpecA(file, spec1) == FALSE, "PathMatchSpec: Spec1 failed\n");
486 ok (PathMatchSpecA(file, spec2) == TRUE, "PathMatchSpec: Spec2 failed\n");
487 ok (PathMatchSpecA(file, spec3) == FALSE, "PathMatchSpec: Spec3 failed\n");
488 ok (PathMatchSpecA(file, spec4) == TRUE, "PathMatchSpec: Spec4 failed\n");
489 todo_wine ok (PathMatchSpecA(file, spec5) == TRUE, "PathMatchSpec: Spec5 failed\n");
490 todo_wine ok (PathMatchSpecA(file, spec6) == TRUE, "PathMatchSpec: Spec6 failed\n");
491 ok (PathMatchSpecA(file, spec7) == FALSE, "PathMatchSpec: Spec7 failed\n");
492 ok (PathMatchSpecA(file, spec8) == TRUE, "PathMatchSpec: Spec8 failed\n");
493 ok (PathMatchSpecA(file, spec9) == FALSE, "PathMatchSpec: Spec9 failed\n");
494 ok (PathMatchSpecA(file, spec10) == TRUE, "PathMatchSpec: Spec10 failed\n");
495 ok (PathMatchSpecA(file, spec11) == TRUE, "PathMatchSpec: Spec11 failed\n");
496 ok (PathMatchSpecA(file, spec12) == TRUE, "PathMatchSpec: Spec12 failed\n");
497 ok (PathMatchSpecA(file, spec13) == TRUE, "PathMatchSpec: Spec13 failed\n");
500 static void test_PathCombineW(void)
502 LPWSTR wszString, wszString2;
503 WCHAR wbuf[MAX_PATH+1], wstr1[MAX_PATH] = {'C',':','\\',0}, wstr2[MAX_PATH];
504 static const WCHAR expout[] = {'C',':','\\','A','A',0};
505 int i;
507 if (!pPathCombineW)
509 win_skip("PathCombineW isn't available\n");
510 return;
513 wszString2 = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
515 /* NULL test */
516 wszString = pPathCombineW(NULL, NULL, NULL);
517 ok (wszString == NULL, "Expected a NULL return\n");
519 /* Some NULL */
520 wszString2[0] = 'a';
521 wszString = pPathCombineW(wszString2, NULL, NULL);
522 ok (wszString == NULL ||
523 broken(wszString[0] == 'a'), /* Win95 and some W2K */
524 "Expected a NULL return\n");
525 ok (wszString2[0] == 0 ||
526 broken(wszString2[0] == 'a'), /* Win95 and some W2K */
527 "Destination string not empty\n");
529 HeapFree(GetProcessHeap(), 0, wszString2);
531 /* overflow test */
532 wstr2[0] = wstr2[1] = wstr2[2] = 'A';
533 for (i=3; i<MAX_PATH/2; i++)
534 wstr1[i] = wstr2[i] = 'A';
535 wstr1[(MAX_PATH/2) - 1] = wstr2[MAX_PATH/2] = 0;
536 memset(wbuf, 0xbf, sizeof(wbuf));
538 wszString = pPathCombineW(wbuf, wstr1, wstr2);
539 ok(wszString == NULL, "Expected a NULL return\n");
540 ok(wbuf[0] == 0 ||
541 broken(wbuf[0] == 0xbfbf), /* Win95 and some W2K */
542 "Buffer contains data\n");
544 /* PathCombineW can be used in place */
545 wstr1[3] = 0;
546 wstr2[2] = 0;
547 ok(PathCombineW(wstr1, wstr1, wstr2) == wstr1, "Expected a wstr1 return\n");
548 ok(StrCmpW(wstr1, expout) == 0, "Unexpected PathCombine output\n");
552 #define LONG_LEN (MAX_PATH * 2)
553 #define HALF_LEN (MAX_PATH / 2 + 1)
555 static void test_PathCombineA(void)
557 LPSTR str;
558 char dest[MAX_PATH];
559 char too_long[LONG_LEN];
560 char one[HALF_LEN], two[HALF_LEN];
562 /* try NULL dest */
563 SetLastError(0xdeadbeef);
564 str = PathCombineA(NULL, "C:\\", "one\\two\\three");
565 ok(str == NULL, "Expected NULL, got %p\n", str);
566 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
568 /* try NULL dest and NULL directory */
569 SetLastError(0xdeadbeef);
570 str = PathCombineA(NULL, NULL, "one\\two\\three");
571 ok(str == NULL, "Expected NULL, got %p\n", str);
572 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
574 /* try all NULL*/
575 SetLastError(0xdeadbeef);
576 str = PathCombineA(NULL, NULL, NULL);
577 ok(str == NULL, "Expected NULL, got %p\n", str);
578 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
580 /* try NULL file part */
581 SetLastError(0xdeadbeef);
582 lstrcpyA(dest, "control");
583 str = PathCombineA(dest, "C:\\", NULL);
584 ok(str == dest, "Expected str == dest, got %p\n", str);
585 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
586 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
588 /* try empty file part */
589 SetLastError(0xdeadbeef);
590 lstrcpyA(dest, "control");
591 str = PathCombineA(dest, "C:\\", "");
592 ok(str == dest, "Expected str == dest, got %p\n", str);
593 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
594 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
596 /* try empty directory and file part */
597 SetLastError(0xdeadbeef);
598 lstrcpyA(dest, "control");
599 str = PathCombineA(dest, "", "");
600 ok(str == dest, "Expected str == dest, got %p\n", str);
601 ok(!lstrcmp(str, "\\") ||
602 broken(!lstrcmp(str, "control")), /* Win95 and some W2K */
603 "Expected \\, got %s\n", str);
604 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
606 /* try NULL directory */
607 SetLastError(0xdeadbeef);
608 lstrcpyA(dest, "control");
609 str = PathCombineA(dest, NULL, "one\\two\\three");
610 ok(str == dest, "Expected str == dest, got %p\n", str);
611 ok(!lstrcmp(str, "one\\two\\three"), "Expected one\\two\\three, got %s\n", str);
612 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
614 /* try NULL directory and empty file part */
615 SetLastError(0xdeadbeef);
616 lstrcpyA(dest, "control");
617 str = PathCombineA(dest, NULL, "");
618 ok(str == dest, "Expected str == dest, got %p\n", str);
619 ok(!lstrcmp(str, "\\") ||
620 broken(!lstrcmp(str, "one\\two\\three")), /* Win95 and some W2K */
621 "Expected \\, got %s\n", str);
622 ok(GetLastError() == 0xdeadbeef ||
623 broken(GetLastError() == ERROR_INVALID_PARAMETER), /* Win95 */
624 "Expected 0xdeadbeef, got %d\n", GetLastError());
626 /* try NULL directory and file part */
627 SetLastError(0xdeadbeef);
628 lstrcpyA(dest, "control");
629 str = PathCombineA(dest, NULL, NULL);
630 ok(str == NULL ||
631 broken(str != NULL), /* Win95 and some W2K */
632 "Expected str == NULL, got %p\n", str);
633 ok(lstrlenA(dest) == 0 ||
634 broken(!lstrcmp(dest, "control")), /* Win95 and some W2K */
635 "Expected 0 length, got %i\n", lstrlenA(dest));
636 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
638 /* try directory without backslash */
639 SetLastError(0xdeadbeef);
640 lstrcpyA(dest, "control");
641 str = PathCombineA(dest, "C:", "one\\two\\three");
642 ok(str == dest, "Expected str == dest, got %p\n", str);
643 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
644 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
646 /* try directory with backslash */
647 SetLastError(0xdeadbeef);
648 lstrcpyA(dest, "control");
649 str = PathCombineA(dest, "C:\\", "one\\two\\three");
650 ok(str == dest, "Expected str == dest, got %p\n", str);
651 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
652 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
654 /* try directory with backslash and file with prepended backslash */
655 SetLastError(0xdeadbeef);
656 lstrcpyA(dest, "control");
657 str = PathCombineA(dest, "C:\\", "\\one\\two\\three");
658 ok(str == dest, "Expected str == dest, got %p\n", str);
659 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
660 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
662 /* try previous test, with backslash appended as well */
663 SetLastError(0xdeadbeef);
664 lstrcpyA(dest, "control");
665 str = PathCombineA(dest, "C:\\", "\\one\\two\\three\\");
666 ok(str == dest, "Expected str == dest, got %p\n", str);
667 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
668 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
670 /* try a relative directory */
671 SetLastError(0xdeadbeef);
672 lstrcpyA(dest, "control");
673 str = PathCombineA(dest, "relative\\dir", "\\one\\two\\three\\");
674 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
675 /* Vista fails which probably makes sense as PathCombineA expects an absolute dir */
676 if (str)
678 ok(str == dest, "Expected str == dest, got %p\n", str);
679 ok(!lstrcmp(str, "one\\two\\three\\"), "Expected one\\two\\three\\, got %s\n", str);
682 /* try forward slashes */
683 SetLastError(0xdeadbeef);
684 lstrcpyA(dest, "control");
685 str = PathCombineA(dest, "C:\\", "one/two/three\\");
686 ok(str == dest, "Expected str == dest, got %p\n", str);
687 ok(!lstrcmp(str, "C:\\one/two/three\\"), "Expected one/two/three\\, got %s\n", str);
688 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
690 /* try a really weird directory */
691 SetLastError(0xdeadbeef);
692 lstrcpyA(dest, "control");
693 str = PathCombineA(dest, "C:\\/\\/", "\\one\\two\\three\\");
694 ok(str == dest, "Expected str == dest, got %p\n", str);
695 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
696 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
698 /* try periods */
699 SetLastError(0xdeadbeef);
700 lstrcpyA(dest, "control");
701 str = PathCombineA(dest, "C:\\", "one\\..\\two\\.\\three");
702 ok(str == dest, "Expected str == dest, got %p\n", str);
703 ok(!lstrcmp(str, "C:\\two\\three"), "Expected C:\\two\\three, got %s\n", str);
704 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
706 /* try .. as file */
707 /* try forward slashes */
708 SetLastError(0xdeadbeef);
709 lstrcpyA(dest, "control");
710 str = PathCombineA(dest, "C:\\", "..");
711 ok(str == dest, "Expected str == dest, got %p\n", str);
712 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
713 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
715 memset(too_long, 'a', LONG_LEN);
716 too_long[LONG_LEN - 1] = '\0';
718 /* try a file longer than MAX_PATH */
719 SetLastError(0xdeadbeef);
720 lstrcpyA(dest, "control");
721 str = PathCombineA(dest, "C:\\", too_long);
722 ok(str == NULL, "Expected str == NULL, got %p\n", str);
723 ok(lstrlenA(dest) == 0 ||
724 broken(!lstrcmp(dest, "control")), /* Win95 and some W2K */
725 "Expected 0 length, got %i\n", lstrlenA(dest));
726 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
728 /* try a directory longer than MAX_PATH */
729 SetLastError(0xdeadbeef);
730 lstrcpyA(dest, "control");
731 str = PathCombineA(dest, too_long, "one\\two\\three");
732 ok(str == NULL, "Expected str == NULL, got %p\n", str);
733 ok(lstrlenA(dest) == 0 ||
734 broken(!lstrcmp(dest, "control")), /* Win95 and some W2K */
735 "Expected 0 length, got %i\n", lstrlenA(dest));
736 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
738 memset(one, 'b', HALF_LEN);
739 memset(two, 'c', HALF_LEN);
740 one[HALF_LEN - 1] = '\0';
741 two[HALF_LEN - 1] = '\0';
743 /* destination string is longer than MAX_PATH, but not the constituent parts */
744 SetLastError(0xdeadbeef);
745 lstrcpyA(dest, "control");
746 str = PathCombineA(dest, one, two);
747 ok(str == NULL, "Expected str == NULL, got %p\n", str);
748 ok(lstrlenA(dest) == 0 ||
749 broken(!lstrcmp(dest, "control")), /* Win95 and some W2K */
750 "Expected 0 length, got %i\n", lstrlenA(dest));
751 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
754 static void test_PathAddBackslash(void)
756 LPSTR str;
757 char path[MAX_PATH];
758 char too_long[LONG_LEN];
760 /* try a NULL path */
761 SetLastError(0xdeadbeef);
762 str = PathAddBackslashA(NULL);
763 ok(str == NULL, "Expected str == NULL, got %p\n", str);
764 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
766 /* try an empty path */
767 path[0] = '\0';
768 SetLastError(0xdeadbeef);
769 str = PathAddBackslashA(path);
770 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
771 ok(lstrlenA(path) == 0, "Expected empty string, got %i\n", lstrlenA(path));
772 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
774 /* try a relative path */
775 lstrcpyA(path, "one\\two");
776 SetLastError(0xdeadbeef);
777 str = PathAddBackslashA(path);
778 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
779 ok(!lstrcmp(path, "one\\two\\"), "Expected one\\two\\, got %s\n", path);
780 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
782 /* try periods */
783 lstrcpyA(path, "one\\..\\two");
784 SetLastError(0xdeadbeef);
785 str = PathAddBackslashA(path);
786 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
787 ok(!lstrcmp(path, "one\\..\\two\\"), "Expected one\\..\\two\\, got %s\n", path);
788 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
790 /* try just a space */
791 lstrcpyA(path, " ");
792 SetLastError(0xdeadbeef);
793 str = PathAddBackslashA(path);
794 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
795 ok(!lstrcmp(path, " \\"), "Expected \\, got %s\n", path);
796 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
798 /* path already has backslash */
799 lstrcpyA(path, "C:\\one\\");
800 SetLastError(0xdeadbeef);
801 str = PathAddBackslashA(path);
802 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
803 ok(!lstrcmp(path, "C:\\one\\"), "Expected C:\\one\\, got %s\n", path);
804 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
806 memset(too_long, 'a', LONG_LEN);
807 too_long[LONG_LEN - 1] = '\0';
809 /* path is longer than MAX_PATH */
810 SetLastError(0xdeadbeef);
811 str = PathAddBackslashA(too_long);
812 ok(str == NULL, "Expected str == NULL, got %p\n", str);
813 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
816 static void test_PathAppendA(void)
818 char path[MAX_PATH];
819 char too_long[LONG_LEN];
820 char half[HALF_LEN];
821 BOOL res;
823 lstrcpy(path, "C:\\one");
825 /* try NULL pszMore */
826 SetLastError(0xdeadbeef);
827 res = PathAppendA(path, NULL);
828 ok(!res, "Expected failure\n");
829 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
830 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
832 /* try empty pszMore */
833 SetLastError(0xdeadbeef);
834 res = PathAppendA(path, "");
835 ok(res, "Expected success\n");
836 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
837 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
839 /* try NULL pszPath */
840 SetLastError(0xdeadbeef);
841 res = PathAppendA(NULL, "two\\three");
842 ok(!res, "Expected failure\n");
843 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
845 /* try empty pszPath */
846 path[0] = '\0';
847 SetLastError(0xdeadbeef);
848 res = PathAppendA(path, "two\\three");
849 ok(res, "Expected success\n");
850 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
851 ok(!lstrcmp(path, "two\\three"), "Expected \\two\\three, got %s\n", path);
853 /* try empty pszPath and empty pszMore */
854 path[0] = '\0';
855 SetLastError(0xdeadbeef);
856 res = PathAppendA(path, "");
857 ok(res, "Expected success\n");
858 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
859 ok(!lstrcmp(path, "\\"), "Expected \\, got %s\n", path);
861 /* try legit params */
862 lstrcpy(path, "C:\\one");
863 SetLastError(0xdeadbeef);
864 res = PathAppendA(path, "two\\three");
865 ok(res, "Expected success\n");
866 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
867 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
869 /* try pszPath with backslash after it */
870 lstrcpy(path, "C:\\one\\");
871 SetLastError(0xdeadbeef);
872 res = PathAppendA(path, "two\\three");
873 ok(res, "Expected success\n");
874 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
875 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
877 /* try pszMore with backslash before it */
878 lstrcpy(path, "C:\\one");
879 SetLastError(0xdeadbeef);
880 res = PathAppendA(path, "\\two\\three");
881 ok(res, "Expected success\n");
882 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
883 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
885 /* try pszMore with backslash after it */
886 lstrcpy(path, "C:\\one");
887 SetLastError(0xdeadbeef);
888 res = PathAppendA(path, "two\\three\\");
889 ok(res, "Expected success\n");
890 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
891 ok(!lstrcmp(path, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", path);
893 /* try spaces in pszPath */
894 lstrcpy(path, "C: \\ one ");
895 SetLastError(0xdeadbeef);
896 res = PathAppendA(path, "two\\three");
897 ok(res, "Expected success\n");
898 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
899 ok(!lstrcmp(path, "C: \\ one \\two\\three"), "Expected C: \\ one \\two\\three, got %s\n", path);
901 /* try spaces in pszMore */
902 lstrcpy(path, "C:\\one");
903 SetLastError(0xdeadbeef);
904 res = PathAppendA(path, " two \\ three ");
905 ok(res, "Expected success\n");
906 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
907 ok(!lstrcmp(path, "C:\\one\\ two \\ three "), "Expected 'C:\\one\\ two \\ three ', got %s\n", path);
909 /* pszPath is too long */
910 memset(too_long, 'a', LONG_LEN);
911 too_long[LONG_LEN - 1] = '\0';
912 SetLastError(0xdeadbeef);
913 res = PathAppendA(too_long, "two\\three");
914 ok(!res, "Expected failure\n");
915 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
916 ok(lstrlen(too_long) == 0 ||
917 broken(lstrlen(too_long) == (LONG_LEN - 1)), /* Win95 and some W2K */
918 "Expected length of too_long to be zero, got %i\n", lstrlen(too_long));
920 /* pszMore is too long */
921 lstrcpy(path, "C:\\one");
922 memset(too_long, 'a', LONG_LEN);
923 too_long[LONG_LEN - 1] = '\0';
924 SetLastError(0xdeadbeef);
925 res = PathAppendA(path, too_long);
926 ok(!res, "Expected failure\n");
927 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
928 ok(lstrlen(path) == 0 ||
929 broken(!lstrcmp(path, "C:\\one")), /* Win95 and some W2K */
930 "Expected length of path to be zero, got %i\n", lstrlen(path));
932 /* both params combined are too long */
933 memset(path, 'a', HALF_LEN);
934 path[HALF_LEN - 1] = '\0';
935 memset(half, 'b', HALF_LEN);
936 half[HALF_LEN - 1] = '\0';
937 SetLastError(0xdeadbeef);
938 res = PathAppendA(path, half);
939 ok(!res, "Expected failure\n");
940 ok(lstrlen(path) == 0 ||
941 broken(lstrlen(path) == (HALF_LEN - 1)), /* Win95 and some W2K */
942 "Expected length of path to be zero, got %i\n", lstrlen(path));
943 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
946 static void test_PathCanonicalizeA(void)
948 char dest[LONG_LEN + MAX_PATH];
949 char too_long[LONG_LEN];
950 BOOL res;
952 /* try a NULL source */
953 lstrcpy(dest, "test");
954 SetLastError(0xdeadbeef);
955 res = PathCanonicalizeA(dest, NULL);
956 ok(!res, "Expected failure\n");
957 ok(GetLastError() == ERROR_INVALID_PARAMETER,
958 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
959 ok(dest[0] == 0 || !lstrcmp(dest, "test"),
960 "Expected either an empty string (Vista) or test, got %s\n", dest);
962 /* try an empty source */
963 lstrcpy(dest, "test");
964 SetLastError(0xdeadbeef);
965 res = PathCanonicalizeA(dest, "");
966 ok(res, "Expected success\n");
967 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
968 ok(!lstrcmp(dest, "\\") ||
969 broken(!lstrcmp(dest, "test")), /* Win95 and some W2K */
970 "Expected \\, got %s\n", dest);
972 /* try a NULL dest */
973 SetLastError(0xdeadbeef);
974 res = PathCanonicalizeA(NULL, "C:\\");
975 ok(!res, "Expected failure\n");
976 ok(GetLastError() == ERROR_INVALID_PARAMETER,
977 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
979 /* try empty dest */
980 dest[0] = '\0';
981 SetLastError(0xdeadbeef);
982 res = PathCanonicalizeA(dest, "C:\\");
983 ok(res, "Expected success\n");
984 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
985 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
987 /* try non-empty dest */
988 lstrcpy(dest, "test");
989 SetLastError(0xdeadbeef);
990 res = PathCanonicalizeA(dest, "C:\\");
991 ok(res, "Expected success\n");
992 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
993 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
995 /* try a space for source */
996 lstrcpy(dest, "test");
997 SetLastError(0xdeadbeef);
998 res = PathCanonicalizeA(dest, " ");
999 ok(res, "Expected success\n");
1000 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1001 ok(!lstrcmp(dest, " "), "Expected ' ', got %s\n", dest);
1003 /* try a relative path */
1004 lstrcpy(dest, "test");
1005 SetLastError(0xdeadbeef);
1006 res = PathCanonicalizeA(dest, "one\\two");
1007 ok(res, "Expected success\n");
1008 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1009 ok(!lstrcmp(dest, "one\\two"), "Expected one\\two, got %s\n", dest);
1011 /* try current dir and previous dir */
1012 lstrcpy(dest, "test");
1013 SetLastError(0xdeadbeef);
1014 res = PathCanonicalizeA(dest, "C:\\one\\.\\..\\two\\three\\..");
1015 ok(res, "Expected success\n");
1016 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1017 ok(!lstrcmp(dest, "C:\\two"), "Expected C:\\two, got %s\n", dest);
1019 /* try simple forward slashes */
1020 lstrcpy(dest, "test");
1021 SetLastError(0xdeadbeef);
1022 res = PathCanonicalizeA(dest, "C:\\one/two/three\\four/five\\six");
1023 ok(res, "Expected success\n");
1024 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1025 ok(!lstrcmp(dest, "C:\\one/two/three\\four/five\\six"),
1026 "Expected C:\\one/two/three\\four/five\\six, got %s\n", dest);
1028 /* try simple forward slashes with same dir */
1029 lstrcpy(dest, "test");
1030 SetLastError(0xdeadbeef);
1031 res = PathCanonicalizeA(dest, "C:\\one/.\\two");
1032 ok(res, "Expected success\n");
1033 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1034 ok(!lstrcmp(dest, "C:\\one/.\\two"), "Expected C:\\one/.\\two, got %s\n", dest);
1036 /* try simple forward slashes with change dir */
1037 lstrcpy(dest, "test");
1038 SetLastError(0xdeadbeef);
1039 res = PathCanonicalizeA(dest, "C:\\one/.\\two\\..");
1040 ok(res, "Expected success\n");
1041 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1042 ok(!lstrcmp(dest, "C:\\one/.") ||
1043 !lstrcmp(dest, "C:\\one/"), /* Vista */
1044 "Expected \"C:\\one/.\" or \"C:\\one/\", got \"%s\"\n", dest);
1046 /* try forward slashes with change dirs
1047 * NOTE: if there is a forward slash in between two backslashes,
1048 * everything in between the two backslashes is considered on dir
1050 lstrcpy(dest, "test");
1051 SetLastError(0xdeadbeef);
1052 res = PathCanonicalizeA(dest, "C:\\one/.\\..\\two/three\\..\\four/.five");
1053 ok(res, "Expected success\n");
1054 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1055 ok(!lstrcmp(dest, "C:\\four/.five"), "Expected C:\\four/.five, got %s\n", dest);
1057 /* try src is too long */
1058 memset(too_long, 'a', LONG_LEN);
1059 too_long[LONG_LEN - 1] = '\0';
1060 lstrcpy(dest, "test");
1061 SetLastError(0xdeadbeef);
1062 res = PathCanonicalizeA(dest, too_long);
1063 ok(!res ||
1064 broken(res), /* Win95, some W2K and XP-SP1 */
1065 "Expected failure\n");
1066 todo_wine
1068 ok(GetLastError() == 0xdeadbeef || GetLastError() == ERROR_FILENAME_EXCED_RANGE /* Vista */,
1069 "Expected 0xdeadbeef or ERROR_FILENAME_EXCED_RANGE, got %d\n", GetLastError());
1071 ok(lstrlen(too_long) == LONG_LEN - 1, "Expected length LONG_LEN - 1, got %i\n", lstrlen(too_long));
1074 static void test_PathFindExtensionA(void)
1076 LPSTR ext;
1077 char path[MAX_PATH];
1078 char too_long[LONG_LEN];
1080 /* try a NULL path */
1081 SetLastError(0xdeadbeef);
1082 ext = PathFindExtensionA(NULL);
1083 ok(ext == NULL, "Expected NULL, got %p\n", ext);
1084 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1086 /* try an empty path */
1087 path[0] = '\0';
1088 SetLastError(0xdeadbeef);
1089 ext = PathFindExtensionA(path);
1090 ok(ext == path, "Expected ext == path, got %p\n", ext);
1091 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1092 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1094 /* try a path without an extension */
1095 lstrcpy(path, "file");
1096 SetLastError(0xdeadbeef);
1097 ext = PathFindExtensionA(path);
1098 ok(ext == path + lstrlen(path), "Expected ext == path, got %p\n", ext);
1099 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1100 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1102 /* try a path with an extension */
1103 lstrcpy(path, "file.txt");
1104 SetLastError(0xdeadbeef);
1105 ext = PathFindExtensionA(path);
1106 ok(ext == path + lstrlen("file"),
1107 "Expected ext == path + lstrlen(\"file\"), got %p\n", ext);
1108 ok(!lstrcmp(ext, ".txt"), "Expected .txt, got %s\n", ext);
1109 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1111 /* try a path with two extensions */
1112 lstrcpy(path, "file.txt.doc");
1113 SetLastError(0xdeadbeef);
1114 ext = PathFindExtensionA(path);
1115 ok(ext == path + lstrlen("file.txt"),
1116 "Expected ext == path + lstrlen(\"file.txt\"), got %p\n", ext);
1117 ok(!lstrcmp(ext, ".doc"), "Expected .txt, got %s\n", ext);
1118 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1120 /* try a path longer than MAX_PATH without an extension*/
1121 memset(too_long, 'a', LONG_LEN);
1122 too_long[LONG_LEN - 1] = '\0';
1123 SetLastError(0xdeadbeef);
1124 ext = PathFindExtensionA(too_long);
1125 ok(ext == too_long + LONG_LEN - 1, "Expected ext == too_long + LONG_LEN - 1, got %p\n", ext);
1126 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1128 /* try a path longer than MAX_PATH with an extension*/
1129 memset(too_long, 'a', LONG_LEN);
1130 too_long[LONG_LEN - 1] = '\0';
1131 lstrcpy(too_long + 300, ".abcde");
1132 too_long[lstrlen(too_long)] = 'a';
1133 SetLastError(0xdeadbeef);
1134 ext = PathFindExtensionA(too_long);
1135 ok(ext == too_long + 300, "Expected ext == too_long + 300, got %p\n", ext);
1136 ok(lstrlen(ext) == LONG_LEN - 301, "Expected LONG_LEN - 301, got %i\n", lstrlen(ext));
1137 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1140 static void test_PathBuildRootA(void)
1142 LPSTR root;
1143 char path[10];
1144 char root_expected[26][4];
1145 char drive;
1146 int j;
1148 /* set up the expected paths */
1149 for (drive = 'A'; drive <= 'Z'; drive++)
1150 sprintf(root_expected[drive - 'A'], "%c:\\", drive);
1152 /* test the expected values */
1153 for (j = 0; j < 26; j++)
1155 SetLastError(0xdeadbeef);
1156 lstrcpy(path, "aaaaaaaaa");
1157 root = PathBuildRootA(path, j);
1158 ok(root == path, "Expected root == path, got %p\n", root);
1159 ok(!lstrcmp(root, root_expected[j]), "Expected %s, got %s\n", root_expected[j], root);
1160 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1163 /* test a negative drive number */
1164 SetLastError(0xdeadbeef);
1165 lstrcpy(path, "aaaaaaaaa");
1166 root = PathBuildRootA(path, -1);
1167 ok(root == path, "Expected root == path, got %p\n", root);
1168 ok(!lstrcmp(path, "aaaaaaaaa") ||
1169 lstrlenA(path) == 0, /* Vista */
1170 "Expected aaaaaaaaa or empty string, got %s\n", path);
1171 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1173 /* test a drive number greater than 25 */
1174 SetLastError(0xdeadbeef);
1175 lstrcpy(path, "aaaaaaaaa");
1176 root = PathBuildRootA(path, 26);
1177 ok(root == path, "Expected root == path, got %p\n", root);
1178 ok(!lstrcmp(path, "aaaaaaaaa") ||
1179 lstrlenA(path) == 0, /* Vista */
1180 "Expected aaaaaaaaa or empty string, got %s\n", path);
1181 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1183 /* length of path is less than 4 */
1184 SetLastError(0xdeadbeef);
1185 lstrcpy(path, "aa");
1186 root = PathBuildRootA(path, 0);
1187 ok(root == path, "Expected root == path, got %p\n", root);
1188 ok(!lstrcmp(path, "A:\\"), "Expected A:\\, got %s\n", path);
1189 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1191 /* path is NULL */
1192 SetLastError(0xdeadbeef);
1193 root = PathBuildRootA(NULL, 0);
1194 ok(root == NULL, "Expected root == NULL, got %p\n", root);
1195 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1198 static void test_PathCommonPrefixA(void)
1200 char path1[MAX_PATH], path2[MAX_PATH];
1201 char out[MAX_PATH];
1202 int count;
1204 /* test NULL path1 */
1205 SetLastError(0xdeadbeef);
1206 lstrcpy(path2, "C:\\");
1207 lstrcpy(out, "aaa");
1208 count = PathCommonPrefixA(NULL, path2, out);
1209 ok(count == 0, "Expected 0, got %i\n", count);
1210 todo_wine
1212 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1214 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1215 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1217 /* test NULL path2 */
1218 SetLastError(0xdeadbeef);
1219 lstrcpy(path1, "C:\\");
1220 lstrcpy(out, "aaa");
1221 count = PathCommonPrefixA(path1, NULL, out);
1222 ok(count == 0, "Expected 0, got %i\n", count);
1223 todo_wine
1225 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1227 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1228 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1230 /* test empty path1 */
1231 SetLastError(0xdeadbeef);
1232 path1[0] = '\0';
1233 lstrcpy(path2, "C:\\");
1234 lstrcpy(out, "aaa");
1235 count = PathCommonPrefixA(path1, path2, out);
1236 ok(count == 0, "Expected 0, got %i\n", count);
1237 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1238 ok(lstrlen(path1) == 0, "Expected 0 length path1, got %i\n", lstrlen(path1));
1239 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1240 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1242 /* test empty path1 */
1243 SetLastError(0xdeadbeef);
1244 path2[0] = '\0';
1245 lstrcpy(path1, "C:\\");
1246 lstrcpy(out, "aaa");
1247 count = PathCommonPrefixA(path1, path2, out);
1248 ok(count == 0, "Expected 0, got %i\n", count);
1249 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1250 ok(lstrlen(path2) == 0, "Expected 0 length path2, got %i\n", lstrlen(path2));
1251 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1252 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1254 /* paths are legit, out is NULL */
1255 SetLastError(0xdeadbeef);
1256 lstrcpy(path1, "C:\\");
1257 lstrcpy(path2, "C:\\");
1258 count = PathCommonPrefixA(path1, path2, NULL);
1259 ok(count == 3, "Expected 3, got %i\n", count);
1260 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1261 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1262 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1264 /* all parameters legit */
1265 SetLastError(0xdeadbeef);
1266 lstrcpy(path1, "C:\\");
1267 lstrcpy(path2, "C:\\");
1268 lstrcpy(out, "aaa");
1269 count = PathCommonPrefixA(path1, path2, out);
1270 ok(count == 3, "Expected 3, got %i\n", count);
1271 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1272 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1273 ok(!lstrcmp(out, "C:\\"), "Expected C:\\, got %s\n", out);
1274 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1276 /* path1 and path2 not the same, but common prefix */
1277 SetLastError(0xdeadbeef);
1278 lstrcpy(path1, "C:\\one\\two");
1279 lstrcpy(path2, "C:\\one\\three");
1280 lstrcpy(out, "aaa");
1281 count = PathCommonPrefixA(path1, path2, out);
1282 ok(count == 6, "Expected 6, got %i\n", count);
1283 ok(!lstrcmp(path1, "C:\\one\\two"), "Expected C:\\one\\two, got %s\n", path1);
1284 ok(!lstrcmp(path2, "C:\\one\\three"), "Expected C:\\one\\three, got %s\n", path2);
1285 ok(!lstrcmp(out, "C:\\one"), "Expected C:\\one, got %s\n", out);
1286 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1288 /* try . prefix */
1289 SetLastError(0xdeadbeef);
1290 lstrcpy(path1, "one\\.two");
1291 lstrcpy(path2, "one\\.three");
1292 lstrcpy(out, "aaa");
1293 count = PathCommonPrefixA(path1, path2, out);
1294 ok(count == 3, "Expected 3, got %i\n", count);
1295 ok(!lstrcmp(path1, "one\\.two"), "Expected one\\.two, got %s\n", path1);
1296 ok(!lstrcmp(path2, "one\\.three"), "Expected one\\.three, got %s\n", path2);
1297 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1298 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1300 /* try .. prefix */
1301 SetLastError(0xdeadbeef);
1302 lstrcpy(path1, "one\\..two");
1303 lstrcpy(path2, "one\\..three");
1304 lstrcpy(out, "aaa");
1305 count = PathCommonPrefixA(path1, path2, out);
1306 ok(count == 3, "Expected 3, got %i\n", count);
1307 ok(!lstrcmp(path1, "one\\..two"), "Expected one\\..two, got %s\n", path1);
1308 ok(!lstrcmp(path2, "one\\..three"), "Expected one\\..three, got %s\n", path2);
1309 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1310 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1312 /* try ... prefix */
1313 SetLastError(0xdeadbeef);
1314 lstrcpy(path1, "one\\...two");
1315 lstrcpy(path2, "one\\...three");
1316 lstrcpy(out, "aaa");
1317 count = PathCommonPrefixA(path1, path2, out);
1318 ok(count == 3, "Expected 3, got %i\n", count);
1319 ok(!lstrcmp(path1, "one\\...two"), "Expected one\\...two, got %s\n", path1);
1320 ok(!lstrcmp(path2, "one\\...three"), "Expected one\\...three, got %s\n", path2);
1321 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1322 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1324 /* try .\ prefix */
1325 SetLastError(0xdeadbeef);
1326 lstrcpy(path1, "one\\.\\two");
1327 lstrcpy(path2, "one\\.\\three");
1328 lstrcpy(out, "aaa");
1329 count = PathCommonPrefixA(path1, path2, out);
1330 ok(count == 5, "Expected 5, got %i\n", count);
1331 ok(!lstrcmp(path1, "one\\.\\two"), "Expected one\\.\\two, got %s\n", path1);
1332 ok(!lstrcmp(path2, "one\\.\\three"), "Expected one\\.\\three, got %s\n", path2);
1333 ok(!lstrcmp(out, "one\\."), "Expected one\\., got %s\n", out);
1334 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1336 /* try ..\ prefix */
1337 SetLastError(0xdeadbeef);
1338 lstrcpy(path1, "one\\..\\two");
1339 lstrcpy(path2, "one\\..\\three");
1340 lstrcpy(out, "aaa");
1341 count = PathCommonPrefixA(path1, path2, out);
1342 ok(count == 6, "Expected 6, got %i\n", count);
1343 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1344 ok(!lstrcmp(path2, "one\\..\\three"), "Expected one\\..\\three, got %s\n", path2);
1345 ok(!lstrcmp(out, "one\\.."), "Expected one\\.., got %s\n", out);
1346 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1348 /* try ...\\ prefix */
1349 SetLastError(0xdeadbeef);
1350 lstrcpy(path1, "one\\...\\two");
1351 lstrcpy(path2, "one\\...\\three");
1352 lstrcpy(out, "aaa");
1353 count = PathCommonPrefixA(path1, path2, out);
1354 ok(count == 7, "Expected 7, got %i\n", count);
1355 ok(!lstrcmp(path1, "one\\...\\two"), "Expected one\\...\\two, got %s\n", path1);
1356 ok(!lstrcmp(path2, "one\\...\\three"), "Expected one\\...\\three, got %s\n", path2);
1357 ok(!lstrcmp(out, "one\\..."), "Expected one\\..., got %s\n", out);
1358 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1360 /* try prefix that is not an msdn labeled prefix type */
1361 SetLastError(0xdeadbeef);
1362 lstrcpy(path1, "same");
1363 lstrcpy(path2, "same");
1364 lstrcpy(out, "aaa");
1365 count = PathCommonPrefixA(path1, path2, out);
1366 ok(count == 4, "Expected 4, got %i\n", count);
1367 ok(!lstrcmp(path1, "same"), "Expected same, got %s\n", path1);
1368 ok(!lstrcmp(path2, "same"), "Expected same, got %s\n", path2);
1369 ok(!lstrcmp(out, "same"), "Expected same, got %s\n", out);
1370 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1372 /* try . after directory */
1373 SetLastError(0xdeadbeef);
1374 lstrcpy(path1, "one\\mid.\\two");
1375 lstrcpy(path2, "one\\mid.\\three");
1376 lstrcpy(out, "aaa");
1377 count = PathCommonPrefixA(path1, path2, out);
1378 ok(count == 8, "Expected 8, got %i\n", count);
1379 ok(!lstrcmp(path1, "one\\mid.\\two"), "Expected one\\mid.\\two, got %s\n", path1);
1380 ok(!lstrcmp(path2, "one\\mid.\\three"), "Expected one\\mid.\\three, got %s\n", path2);
1381 ok(!lstrcmp(out, "one\\mid."), "Expected one\\mid., got %s\n", out);
1382 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1384 /* try . in the middle of a directory */
1385 SetLastError(0xdeadbeef);
1386 lstrcpy(path1, "one\\mid.end\\two");
1387 lstrcpy(path2, "one\\mid.end\\three");
1388 lstrcpy(out, "aaa");
1389 count = PathCommonPrefixA(path1, path2, out);
1390 ok(count == 11, "Expected 11, got %i\n", count);
1391 ok(!lstrcmp(path1, "one\\mid.end\\two"), "Expected one\\mid.end\\two, got %s\n", path1);
1392 ok(!lstrcmp(path2, "one\\mid.end\\three"), "Expected one\\mid.end\\three, got %s\n", path2);
1393 ok(!lstrcmp(out, "one\\mid.end"), "Expected one\\mid.end, got %s\n", out);
1394 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1396 /* try comparing a .. with the expanded path */
1397 SetLastError(0xdeadbeef);
1398 lstrcpy(path1, "one\\..\\two");
1399 lstrcpy(path2, "two");
1400 lstrcpy(out, "aaa");
1401 count = PathCommonPrefixA(path1, path2, out);
1402 ok(count == 0, "Expected 0, got %i\n", count);
1403 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1404 ok(!lstrcmp(path2, "two"), "Expected two, got %s\n", path2);
1405 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1406 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1409 static void test_PathUnquoteSpaces(void)
1411 int i;
1412 for(i = 0; i < sizeof(TEST_PATH_UNQUOTE_SPACES) / sizeof(TEST_PATH_UNQUOTE_SPACES[0]); i++)
1414 char *path = strdupA(TEST_PATH_UNQUOTE_SPACES[i].path);
1415 WCHAR *pathW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].path);
1416 WCHAR *resultW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].result);
1418 PathUnquoteSpacesA(path);
1419 ok(!strcmp(path, TEST_PATH_UNQUOTE_SPACES[i].result), "%s (A): got %s expected %s\n",
1420 TEST_PATH_UNQUOTE_SPACES[i].path, path,
1421 TEST_PATH_UNQUOTE_SPACES[i].result);
1423 PathUnquoteSpacesW(pathW);
1424 ok(!lstrcmpW(pathW, resultW), "%s (W): strings differ\n",
1425 TEST_PATH_UNQUOTE_SPACES[i].path);
1426 FreeWideString(pathW);
1427 FreeWideString(resultW);
1428 HeapFree(GetProcessHeap(), 0, path);
1432 static void test_PathGetDriveNumber(void)
1434 static const CHAR test1A[] = "a:\\test.file";
1435 static const CHAR test2A[] = "file:////b:\\test.file";
1436 static const CHAR test3A[] = "file:///c:\\test.file";
1437 static const CHAR test4A[] = "file:\\\\c:\\test.file";
1438 int ret;
1440 SetLastError(0xdeadbeef);
1441 ret = PathGetDriveNumberA(NULL);
1442 ok(ret == -1, "got %d\n", ret);
1443 ok(GetLastError() == 0xdeadbeef, "got %d\n", GetLastError());
1445 ret = PathGetDriveNumberA(test1A);
1446 ok(ret == 0, "got %d\n", ret);
1447 ret = PathGetDriveNumberA(test2A);
1448 ok(ret == -1, "got %d\n", ret);
1449 ret = PathGetDriveNumberA(test3A);
1450 ok(ret == -1, "got %d\n", ret);
1451 ret = PathGetDriveNumberA(test4A);
1452 ok(ret == -1, "got %d\n", ret);
1455 /* ################ */
1457 START_TEST(path)
1459 HMODULE hShlwapi = GetModuleHandleA("shlwapi.dll");
1461 /* SHCreateStreamOnFileEx was introduced in shlwapi v6.0 */
1462 if(!GetProcAddress(hShlwapi, "SHCreateStreamOnFileEx")){
1463 win_skip("Too old shlwapi version\n");
1464 return;
1467 pPathCreateFromUrlA = (void*)GetProcAddress(hShlwapi, "PathCreateFromUrlA");
1468 pPathCreateFromUrlW = (void*)GetProcAddress(hShlwapi, "PathCreateFromUrlW");
1469 pPathCreateFromUrlAlloc = (void*)GetProcAddress(hShlwapi, "PathCreateFromUrlAlloc");
1470 pPathCombineW = (void*)GetProcAddress(hShlwapi, "PathCombineW");
1471 pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
1472 pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
1473 pPathAppendA = (void*)GetProcAddress(hShlwapi, "PathAppendA");
1475 test_PathSearchAndQualify();
1476 test_PathCreateFromUrl();
1477 test_PathIsUrl();
1479 test_PathAddBackslash();
1480 test_PathMakePretty();
1481 test_PathMatchSpec();
1483 test_PathIsValidCharA();
1484 test_PathIsValidCharW();
1486 test_PathCombineW();
1487 test_PathCombineA();
1488 test_PathAppendA();
1489 test_PathCanonicalizeA();
1490 test_PathFindExtensionA();
1491 test_PathBuildRootA();
1492 test_PathCommonPrefixA();
1493 test_PathUnquoteSpaces();
1494 test_PathGetDriveNumber();