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 const char* TEST_URL_1 = "http://www.winehq.org/tests?date=10/10/1923";
37 const char* TEST_URL_2 = "http://localhost:8080/tests%2e.html?date=Mon%2010/10/1923";
38 const char* TEST_URL_3 = "http://foo:bar@localhost:21/internal.php?query=x&return=y";
40 typedef struct _TEST_URL_CANONICALIZE {
44 const char *expecturl;
45 } TEST_URL_CANONICALIZE;
47 const TEST_URL_CANONICALIZE TEST_CANONICALIZE[] = {
48 /*FIXME {"http://www.winehq.org/tests/../tests/../..", 0, S_OK, "http://www.winehq.org/"},*/
49 {"http://www.winehq.org/tests/../tests", 0, S_OK, "http://www.winehq.org/tests"},
50 {"http://www.winehq.org/tests\n", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests"},
51 {"http://www.winehq.org/tests\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests"},
52 {"http://www.winehq.org/tests\r", 0, S_OK, "http://www.winehq.org/tests"},
53 {"http://www.winehq.org/tests\r", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests"},
54 {"http://www.winehq.org/tests/../tests/", 0, S_OK, "http://www.winehq.org/tests/"},
55 {"http://www.winehq.org/tests/../tests/..", 0, S_OK, "http://www.winehq.org/"},
56 {"http://www.winehq.org/tests/../tests/../", 0, S_OK, "http://www.winehq.org/"},
57 {"http://www.winehq.org/tests/..", 0, S_OK, "http://www.winehq.org/"},
58 {"http://www.winehq.org/tests/../", 0, S_OK, "http://www.winehq.org/"},
59 {"http://www.winehq.org/tests/..?query=x&return=y", 0, S_OK, "http://www.winehq.org/?query=x&return=y"},
60 {"http://www.winehq.org/tests/../?query=x&return=y", 0, S_OK, "http://www.winehq.org/?query=x&return=y"},
61 {"http://www.winehq.org/tests/..#example", 0, S_OK, "http://www.winehq.org/#example"},
62 {"http://www.winehq.org/tests/../#example", 0, S_OK, "http://www.winehq.org/#example"},
63 {"http://www.winehq.org/tests\\../#example", 0, S_OK, "http://www.winehq.org/#example"},
64 {"http://www.winehq.org/tests/..\\#example", 0, S_OK, "http://www.winehq.org/#example"},
65 {"http://www.winehq.org\\tests/../#example", 0, S_OK, "http://www.winehq.org/#example"},
66 {"http://www.winehq.org/tests/../#example", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../#example"},
67 {"http://www.winehq.org/tests/foo bar", URL_ESCAPE_SPACES_ONLY| URL_DONT_ESCAPE_EXTRA_INFO , S_OK, "http://www.winehq.org/tests/foo%20bar"},
68 {"http://www.winehq.org/tests/foo%20bar", URL_UNESCAPE , S_OK, "http://www.winehq.org/tests/foo bar"},
69 {"file:///c:/tests/foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar"},
70 {"file:///c:/tests\\foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar"},
71 {"file:///c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar"},
72 {"file://c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar"},
73 {"file://c:/tests\\../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar"},
74 {"file://c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar"},
75 {"file:///c://tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\\\tests\\foo bar"},
76 {"file:///c:\\tests\\foo bar", 0, S_OK, "file:///c:/tests/foo bar"},
77 {"file:///c:\\tests\\foo bar", URL_DONT_SIMPLIFY, S_OK, "file:///c:/tests/foo bar"},
78 {"http://www.winehq.org/site/about", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org/site/about"},
79 {"file_://www.winehq.org/site/about", URL_FILE_USE_PATHURL, S_OK, "file_://www.winehq.org/site/about"},
80 {"c:\\dir\\file", 0, S_OK, "file:///c:/dir/file"},
81 {"file:///c:\\dir\\file", 0, S_OK, "file:///c:/dir/file"},
82 {"c:dir\\file", 0, S_OK, "file:///c:dir/file"},
87 typedef struct _TEST_URL_ESCAPE {
92 const char *expecturl;
95 const TEST_URL_ESCAPE TEST_ESCAPE[] = {
96 {"http://www.winehq.org/tests0", 0, 0, S_OK, "http://www.winehq.org/tests0"},
97 {"http://www.winehq.org/tests1\n", 0, 0, S_OK, "http://www.winehq.org/tests1%0A"},
98 {"http://www.winehq.org/tests2\r", 0, 0, S_OK, "http://www.winehq.org/tests2%0D"},
99 {"http://www.winehq.org/tests3\r", URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, 0, S_OK, "http://www.winehq.org/tests3\r"},
100 {"http://www.winehq.org/tests4\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests4\r"},
101 {"http://www.winehq.org/tests5\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests5\r"},
102 {"/direct/swhelp/series6/6.2i_latestservicepack.dat\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "/direct/swhelp/series6/6.2i_latestservicepack.dat\r"},
104 {"file://////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
105 {"file://///foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
106 {"file:////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
107 {"file:///localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"},
108 {"file:///foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
109 {"file://loCalHost/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
110 {"file://foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
111 {"file:/localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"},
112 {"file:/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
113 {"file:foo/bar\\baz", 0, 0, S_OK, "file:foo/bar/baz"},
114 {"file:\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
115 {"file:\\\\foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
116 {"file:\\\\\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
117 {"file:\\\\localhost\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
118 {"file:///f oo/b?a r\\baz", 0, 0, S_OK, "file:///f%20oo/b?a r\\baz"},
119 {"file:///foo/b#a r\\baz", 0, 0, S_OK, "file:///foo/b%23a%20r/baz"},
120 {"file:///f o^&`{}|][\"<>\\%o/b#a r\\baz", 0, 0, S_OK, "file:///f%20o%5E%26%60%7B%7D%7C%5D%5B%22%3C%3E/%o/b%23a%20r/baz"},
121 {"file:///f o%o/b?a r\\b%az", URL_ESCAPE_PERCENT, 0, S_OK, "file:///f%20o%25o/b?a r\\b%az"},
122 {"file:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "file:%2Ffoo%2Fbar%5Cbaz"},
124 {"foo/b%ar\\ba?z\\", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%ar%5Cba%3Fz%5C"},
125 {"foo/b%ar\\ba?z\\", URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%25ar%5Cba%3Fz%5C"},
126 {"foo/bar\\ba?z\\", 0, 0, S_OK, "foo/bar%5Cba?z\\"},
127 {"/foo/bar\\ba?z\\", 0, 0, S_OK, "/foo/bar%5Cba?z\\"},
128 {"/foo/bar\\ba#z\\", 0, 0, S_OK, "/foo/bar%5Cba#z\\"},
129 {"/foo/%5C", 0, 0, S_OK, "/foo/%5C"},
130 {"/foo/%5C", URL_ESCAPE_PERCENT, 0, S_OK, "/foo/%255C"},
132 {"http://////foo/bar\\baz", 0, 0, S_OK, "http://////foo/bar/baz"},
133 {"http://///foo/bar\\baz", 0, 0, S_OK, "http://///foo/bar/baz"},
134 {"http:////foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"},
135 {"http:///foo/bar\\baz", 0, 0, S_OK, "http:///foo/bar/baz"},
136 {"http://localhost/foo/bar\\baz", 0, 0, S_OK, "http://localhost/foo/bar/baz"},
137 {"http://foo/bar\\baz", 0, 0, S_OK, "http://foo/bar/baz"},
138 {"http:/foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"},
139 {"http:foo/bar\\ba?z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba?z\\"},
140 {"http:foo/bar\\ba#z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba#z\\"},
141 {"http:\\foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"},
142 {"http:\\\\foo/bar\\baz", 0, 0, S_OK, "http://foo/bar/baz"},
143 {"http:\\\\\\foo/bar\\baz", 0, 0, S_OK, "http:///foo/bar/baz"},
144 {"http:\\\\\\\\foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"},
145 {"http:/fo ?o/b ar\\baz", 0, 0, S_OK, "http:/fo%20?o/b ar\\baz"},
146 {"http:fo ?o/b ar\\baz", 0, 0, S_OK, "http:fo%20?o/b ar\\baz"},
147 {"http:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "http:%2Ffoo%2Fbar%5Cbaz"},
149 {"https://foo/bar\\baz", 0, 0, S_OK, "https://foo/bar/baz"},
150 {"https:/foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"},
151 {"https:\\foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"},
153 {"foo:////foo/bar\\baz", 0, 0, S_OK, "foo:////foo/bar%5Cbaz"},
154 {"foo:///foo/bar\\baz", 0, 0, S_OK, "foo:///foo/bar%5Cbaz"},
155 {"foo://localhost/foo/bar\\baz", 0, 0, S_OK, "foo://localhost/foo/bar%5Cbaz"},
156 {"foo://foo/bar\\baz", 0, 0, S_OK, "foo://foo/bar%5Cbaz"},
157 {"foo:/foo/bar\\baz", 0, 0, S_OK, "foo:/foo/bar%5Cbaz"},
158 {"foo:foo/bar\\baz", 0, 0, S_OK, "foo:foo%2Fbar%5Cbaz"},
159 {"foo:\\foo/bar\\baz", 0, 0, S_OK, "foo:%5Cfoo%2Fbar%5Cbaz"},
160 {"foo:/foo/bar\\ba?\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba?\\z"},
161 {"foo:/foo/bar\\ba#\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba#\\z"},
163 {"mailto:/fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:%2Ffo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
164 {"mailto:fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:fo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
165 {"mailto:fo/o@b\\%a?\\r.b#\\az", URL_ESCAPE_PERCENT, 0, S_OK, "mailto:fo%2Fo@b%5C%25a%3F%5Cr.b%23%5Caz"},
167 {"ftp:fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:fo%2Fo@bar.baz%2Ffoo%2Fbar"},
168 {"ftp:/fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:/fo/o@bar.baz/foo/bar"},
169 {"ftp://fo/o@bar.baz/fo?o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo?o\\bar"},
170 {"ftp://fo/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo#o\\bar"},
171 {"ftp://localhost/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://localhost/o@bar.baz/fo#o\\bar"},
172 {"ftp:///fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:///fo/o@bar.baz/foo/bar"},
173 {"ftp:////fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:////fo/o@bar.baz/foo/bar"}
176 typedef struct _TEST_URL_COMBINE {
181 const char *expecturl;
184 const TEST_URL_COMBINE TEST_COMBINE[] = {
185 {"http://www.winehq.org/tests", "tests1", 0, S_OK, "http://www.winehq.org/tests1"},
186 {"http://www.%77inehq.org/tests", "tests1", 0, S_OK, "http://www.%77inehq.org/tests1"},
187 /*FIXME {"http://www.winehq.org/tests", "../tests2", 0, S_OK, "http://www.winehq.org/tests2"},*/
188 {"http://www.winehq.org/tests/", "../tests3", 0, S_OK, "http://www.winehq.org/tests3"},
189 {"http://www.winehq.org/tests/test1", "test2", 0, S_OK, "http://www.winehq.org/tests/test2"},
190 {"http://www.winehq.org/tests/../tests", "tests4", 0, S_OK, "http://www.winehq.org/tests4"},
191 {"http://www.winehq.org/tests/../tests/", "tests5", 0, S_OK, "http://www.winehq.org/tests/tests5"},
192 {"http://www.winehq.org/tests/../tests/", "/tests6/..", 0, S_OK, "http://www.winehq.org/"},
193 {"http://www.winehq.org/tests/../tests/..", "tests7/..", 0, S_OK, "http://www.winehq.org/"},
194 {"http://www.winehq.org/tests/?query=x&return=y", "tests8", 0, S_OK, "http://www.winehq.org/tests/tests8"},
195 {"http://www.winehq.org/tests/#example", "tests9", 0, S_OK, "http://www.winehq.org/tests/tests9"},
196 {"http://www.winehq.org/tests/../tests/", "/tests10/..", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests10/.."},
197 {"http://www.winehq.org/tests/../", "tests11", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../tests11"},
198 {"file:///C:\\dir\\file.txt", "test.txt", 0, S_OK, "file:///C:/dir/test.txt"}
205 } TEST_URLFROMPATH [] = {
206 {"foo", "file:foo", S_OK},
207 {"foo\\bar", "file:foo/bar", S_OK},
208 {"\\foo\\bar", "file:///foo/bar", S_OK},
209 {"c:\\foo\\bar", "file:///c:/foo/bar", S_OK},
210 {"c:foo\\bar", "file:///c:foo/bar", S_OK},
211 {"c:\\foo/b a%r", "file:///c:/foo/b%20a%25r", S_OK},
212 {"c:\\foo\\foo bar", "file:///c:/foo/foo%20bar", S_OK},
214 /* The following test fails on native shlwapi as distributed with Win95/98.
215 * Wine matches the behaviour of later versions.
217 {"xx:c:\\foo\\bar", "xx:c:\\foo\\bar", S_FALSE}
225 } TEST_PATHFROMURL[] = {
226 {"file:///c:/foo/ba%5Cr", "c:\\foo\\ba\\r", S_OK},
227 {"file:///c:/foo/../ba%5Cr", "c:\\foo\\..\\ba\\r", S_OK},
228 {"file:///host/c:/foo/bar", "\\host\\c:\\foo\\bar", S_OK},
229 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
230 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
231 {"file:\\\\host\\c:\\foo\\bar", "\\\\hostc:\\foo\\bar", S_OK},
232 {"file:\\\\host\\ca\\foo\\bar", "\\\\host\\ca\\foo\\bar", S_OK},
233 {"file:\\\\host\\c|\\foo\\bar", "\\\\hostc|\\foo\\bar", S_OK},
234 {"file:\\%5Chost\\c:\\foo\\bar", "\\\\host\\c:\\foo\\bar", S_OK},
235 {"file:\\\\host\\cx:\\foo\\bar", "\\\\host\\cx:\\foo\\bar", S_OK},
236 {"file://c:/foo/bar", "c:\\foo\\bar", S_OK},
237 {"file://c:/d:/foo/bar", "c:\\d:\\foo\\bar", S_OK},
238 {"file://c|/d|/foo/bar", "c:\\d|\\foo\\bar", S_OK},
239 {"file://host/foo/bar", "\\\\host\\foo\\bar", S_OK},
240 {"file:/foo/bar", "\\foo\\bar", S_OK},
241 {"file:/foo/bar/", "\\foo\\bar\\", S_OK},
242 {"file:foo/bar", "foo\\bar", S_OK},
243 {"file:c:/foo/bar", "c:\\foo\\bar", S_OK},
244 {"file:c|/foo/bar", "c:\\foo\\bar", S_OK},
245 {"file:cx|/foo/bar", "cx|\\foo\\bar", S_OK},
246 {"file:////c:/foo/bar", "c:\\foo\\bar", S_OK},
247 /* {"file:////c:/foo/foo%20bar", "c:\\foo\\foo%20bar", S_OK},*/
249 {"c:\\foo\\bar", NULL, E_INVALIDARG},
250 {"foo/bar", NULL, E_INVALIDARG},
251 {"http://foo/bar", NULL, E_INVALIDARG},
258 } TEST_URL_UNESCAPE[] = {
259 {"file://foo/bar", "file://foo/bar"},
260 {"file://fo%20o%5Ca/bar", "file://fo o\\a/bar"}
267 } TEST_PATH_IS_URL[] = {
268 {"http://foo/bar", TRUE},
269 {"c:\\foo\\bar", FALSE},
270 {"foo://foo/bar", TRUE},
273 {"bogusscheme:", TRUE},
274 {"http:partial", TRUE}
281 } TEST_URLIS_ATTRIBS[] = {
282 { "ftp:", FALSE, FALSE },
283 { "http:", FALSE, FALSE },
284 { "gopher:", FALSE, FALSE },
285 { "mailto:", TRUE, FALSE },
286 { "news:", FALSE, FALSE },
287 { "nntp:", FALSE, FALSE },
288 { "telnet:", FALSE, FALSE },
289 { "wais:", FALSE, FALSE },
290 { "file:", FALSE, TRUE },
291 { "mk:", FALSE, FALSE },
292 { "https:", FALSE, FALSE },
293 { "shell:", TRUE, FALSE },
294 { "https:", FALSE, FALSE },
295 { "snews:", FALSE, FALSE },
296 { "local:", FALSE, FALSE },
297 { "javascript:", TRUE, FALSE },
298 { "vbscript:", TRUE, FALSE },
299 { "about:", TRUE, FALSE },
300 { "res:", FALSE, FALSE },
301 { "bogusscheme:", FALSE, FALSE },
302 { "file:\\\\e:\\b\\c", FALSE, TRUE },
303 { "file://e:/b/c", FALSE, TRUE },
304 { "http:partial", FALSE, FALSE },
305 { "mailto://www.winehq.org/test.html", TRUE, FALSE },
306 { "file:partial", FALSE, TRUE }
312 } TEST_PATH_UNQUOTE_SPACES[] = {
313 { "abcdef", "abcdef" },
314 { "\"abcdef\"", "abcdef" },
315 { "\"abcdef", "\"abcdef" },
316 { "abcdef\"", "abcdef\"" },
317 { "\"\"abcdef\"\"", "\"abcdef\"" },
318 { "abc\"def", "abc\"def" },
319 { "\"abc\"def", "\"abc\"def" },
320 { "\"abc\"def\"", "abc\"def" },
321 { "\'abcdef\'", "\'abcdef\'" },
326 static LPWSTR GetWideString(const char* szString)
328 LPWSTR wszString = HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
330 MultiByteToWideChar(0, 0, szString, -1, wszString, INTERNET_MAX_URL_LENGTH);
335 static void FreeWideString(LPWSTR wszString)
337 HeapFree(GetProcessHeap(), 0, wszString);
340 static LPSTR strdupA(LPCSTR p)
343 DWORD len = (strlen(p) + 1);
344 ret = HeapAlloc(GetProcessHeap(), 0, len);
349 static void hash_url(const char* szUrl)
351 LPCSTR szTestUrl = szUrl;
352 LPWSTR wszTestUrl = GetWideString(szTestUrl);
354 DWORD cbSize = sizeof(DWORD);
355 DWORD dwHash1, dwHash2;
356 ok(UrlHashA(szTestUrl, (LPBYTE)&dwHash1, cbSize) == S_OK, "UrlHashA didn't return S_OK\n");
357 ok(UrlHashW(wszTestUrl, (LPBYTE)&dwHash2, cbSize) == S_OK, "UrlHashW didn't return S_OK\n");
359 FreeWideString(wszTestUrl);
361 ok(dwHash1 == dwHash2, "Hashes didn't compare\n");
364 static void test_UrlHash(void)
366 hash_url(TEST_URL_1);
367 hash_url(TEST_URL_2);
368 hash_url(TEST_URL_3);
371 static void test_url_part(const char* szUrl, DWORD dwPart, DWORD dwFlags, const char* szExpected)
373 CHAR szPart[INTERNET_MAX_URL_LENGTH];
374 WCHAR wszPart[INTERNET_MAX_URL_LENGTH];
375 LPWSTR wszUrl = GetWideString(szUrl);
376 LPWSTR wszConvertedPart;
380 dwSize = INTERNET_MAX_URL_LENGTH;
381 ok( UrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags) == S_OK, "UrlGetPartA for \"%s\" part 0x%08x didn't return S_OK but \"%s\"\n", szUrl, dwPart, szPart);
382 dwSize = INTERNET_MAX_URL_LENGTH;
383 ok( UrlGetPartW(wszUrl, wszPart, &dwSize, dwPart, dwFlags) == S_OK, "UrlGetPartW didn't return S_OK\n" );
385 wszConvertedPart = GetWideString(szPart);
387 ok(lstrcmpW(wszPart,wszConvertedPart)==0, "Strings didn't match between ascii and unicode UrlGetPart!\n");
389 FreeWideString(wszUrl);
390 FreeWideString(wszConvertedPart);
392 /* Note that v6.0 and later don't return '?' with the query */
393 ok(strcmp(szPart,szExpected)==0 ||
394 (*szExpected=='?' && !strcmp(szPart,szExpected+1)),
395 "Expected %s, but got %s\n", szExpected, szPart);
398 static void test_UrlGetPart(void)
400 CHAR szPart[INTERNET_MAX_URL_LENGTH];
404 dwSize = sizeof szPart;
405 szPart[0]='x'; szPart[1]=0;
406 res = UrlGetPartA("hi", szPart, &dwSize, URL_PART_SCHEME, 0);
408 ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res);
409 ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart);
411 dwSize = sizeof szPart;
412 szPart[0]='x'; szPart[1]=0;
413 res = UrlGetPartA("hi", szPart, &dwSize, URL_PART_QUERY, 0);
415 ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res);
416 ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart);
419 test_url_part(TEST_URL_3, URL_PART_HOSTNAME, 0, "localhost");
420 test_url_part(TEST_URL_3, URL_PART_PORT, 0, "21");
421 test_url_part(TEST_URL_3, URL_PART_USERNAME, 0, "foo");
422 test_url_part(TEST_URL_3, URL_PART_PASSWORD, 0, "bar");
423 test_url_part(TEST_URL_3, URL_PART_SCHEME, 0, "http");
424 test_url_part(TEST_URL_3, URL_PART_QUERY, 0, "?query=x&return=y");
427 static void test_url_escape(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
429 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
431 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
432 WCHAR *urlW, *expected_urlW;
433 dwEscaped=INTERNET_MAX_URL_LENGTH;
435 ok(UrlEscapeA(szUrl, szReturnUrl, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeA didn't return 0x%08x from \"%s\"\n", dwExpectReturn, szUrl);
436 ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected \"%s\", but got \"%s\" from \"%s\"\n", szExpectUrl, szReturnUrl, szUrl);
438 dwEscaped = INTERNET_MAX_URL_LENGTH;
439 urlW = GetWideString(szUrl);
440 expected_urlW = GetWideString(szExpectUrl);
441 ok(UrlEscapeW(urlW, ret_urlW, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeW didn't return 0x%08x from \"%s\"\n", dwExpectReturn, szUrl);
442 WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
443 ok(lstrcmpW(ret_urlW, expected_urlW)==0, "Expected \"%s\", but got \"%s\" from \"%s\" flags %08x\n", szExpectUrl, szReturnUrl, szUrl, dwFlags);
444 FreeWideString(urlW);
445 FreeWideString(expected_urlW);
449 static void test_url_canonicalize(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
451 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
452 WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
453 LPWSTR wszUrl = GetWideString(szUrl);
454 LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
455 LPWSTR wszConvertedUrl;
459 dwSize = INTERNET_MAX_URL_LENGTH;
460 ok(UrlCanonicalizeA(szUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
461 ok(UrlCanonicalizeA(szUrl, szReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeA didn't return 0x%08x\n", dwExpectReturn);
462 ok(strcmp(szReturnUrl,szExpectUrl)==0, "UrlCanonicalizeA dwFlags 0x%08x Expected \"%s\", but got \"%s\"\n", dwFlags, szExpectUrl, szReturnUrl);
464 dwSize = INTERNET_MAX_URL_LENGTH;
465 ok(UrlCanonicalizeW(wszUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
466 ok(UrlCanonicalizeW(wszUrl, wszReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeW didn't return 0x%08x\n", dwExpectReturn);
467 wszConvertedUrl = GetWideString(szReturnUrl);
468 ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCanonicalize!\n");
469 FreeWideString(wszConvertedUrl);
472 FreeWideString(wszUrl);
473 FreeWideString(wszExpectUrl);
477 static void test_UrlEscape(void)
480 for(i=0; i<sizeof(TEST_ESCAPE)/sizeof(TEST_ESCAPE[0]); i++) {
481 test_url_escape(TEST_ESCAPE[i].url, TEST_ESCAPE[i].flags,
482 TEST_ESCAPE[i].expectret, TEST_ESCAPE[i].expecturl);
486 static void test_UrlCanonicalize(void)
489 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
493 for(i=0; i<sizeof(TEST_CANONICALIZE)/sizeof(TEST_CANONICALIZE[0]); i++) {
494 test_url_canonicalize(TEST_CANONICALIZE[i].url, TEST_CANONICALIZE[i].flags,
495 TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expecturl);
498 /* move to TEST_CANONICALIZE when fixed */
499 dwSize = sizeof szReturnUrl;
500 ok(UrlCanonicalizeA("c:\\tests\\foo bar", szReturnUrl, &dwSize, 0) == S_OK, "UrlCanonicalizeA didn't return 0x%08x\n", S_OK);
502 ok(strcmp(szReturnUrl,"file:///c:/tests/foo%20bar")==0, "UrlCanonicalizeA got %s\n", szReturnUrl);
505 dwSize = sizeof szReturnUrl;
506 /*LimeWire online installer calls this*/
507 hr = UrlCanonicalizeA("/uri-res/N2R?urn:sha1:B3K", szReturnUrl, &dwSize,URL_DONT_ESCAPE_EXTRA_INFO | URL_WININET_COMPATIBILITY /*0x82000000*/);
508 ok(hr==S_OK,"UrlCanonicalizeA returned 0x%08x instead of S_OK\n", hr);
510 ok(strcmp(szReturnUrl,"/uri-res/N2R?urn:sha1:B3K")==0, "UrlCanonicalizeA got \"%s\" instead of \"/uri-res/N2R?urn:sha1:B3K\"\n", szReturnUrl);
514 static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
517 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
518 WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
519 LPWSTR wszUrl1 = GetWideString(szUrl1);
520 LPWSTR wszUrl2 = GetWideString(szUrl2);
521 LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
522 LPWSTR wszConvertedUrl;
525 DWORD dwExpectLen = lstrlen(szExpectUrl);
527 hr = UrlCombineA(szUrl1, szUrl2, NULL, NULL, dwFlags);
528 ok(hr == E_INVALIDARG, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_INVALIDARG);
531 hr = UrlCombineA(szUrl1, szUrl2, NULL, &dwSize, dwFlags);
532 ok(hr == E_POINTER, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr, E_POINTER);
533 ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
536 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
537 ok(hr == E_POINTER, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_POINTER);
538 ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
540 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
541 ok(hr == dwExpectReturn, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, dwExpectReturn);
542 ok(dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen);
544 ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected %s, but got %s\n", szExpectUrl, szReturnUrl);
548 hr = UrlCombineW(wszUrl1, wszUrl2, NULL, &dwSize, dwFlags);
549 ok(hr == E_POINTER, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr, E_POINTER);
550 ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
553 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
554 ok(hr == E_POINTER, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_POINTER);
555 ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
557 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
558 ok(hr == dwExpectReturn, "UrlCombineW returned 0x%08x, expected 0x%08x\n", hr, dwExpectReturn);
559 ok(dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen);
561 wszConvertedUrl = GetWideString(szReturnUrl);
562 ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCombine!\n");
563 FreeWideString(wszConvertedUrl);
566 FreeWideString(wszUrl1);
567 FreeWideString(wszUrl2);
568 FreeWideString(wszExpectUrl);
571 static void test_UrlCombine(void)
574 for(i=0; i<sizeof(TEST_COMBINE)/sizeof(TEST_COMBINE[0]); i++) {
575 test_url_combine(TEST_COMBINE[i].url1, TEST_COMBINE[i].url2, TEST_COMBINE[i].flags,
576 TEST_COMBINE[i].expectret, TEST_COMBINE[i].expecturl);
580 static void test_UrlCreateFromPath(void)
583 char ret_url[INTERNET_MAX_URL_LENGTH];
585 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
588 for(i = 0; i < sizeof(TEST_URLFROMPATH) / sizeof(TEST_URLFROMPATH[0]); i++) {
589 len = INTERNET_MAX_URL_LENGTH;
590 ret = UrlCreateFromPathA(TEST_URLFROMPATH[i].path, ret_url, &len, 0);
591 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08x from path %s\n", ret, TEST_URLFROMPATH[i].path);
592 ok(!lstrcmpi(ret_url, TEST_URLFROMPATH[i].url), "url %s from path %s\n", ret_url, TEST_URLFROMPATH[i].path);
593 ok(len == strlen(ret_url), "ret len %d from path %s\n", len, TEST_URLFROMPATH[i].path);
595 len = INTERNET_MAX_URL_LENGTH;
596 pathW = GetWideString(TEST_URLFROMPATH[i].path);
597 urlW = GetWideString(TEST_URLFROMPATH[i].url);
598 ret = UrlCreateFromPathW(pathW, ret_urlW, &len, 0);
599 WideCharToMultiByte(CP_ACP, 0, ret_urlW, -1, ret_url, sizeof(ret_url),0,0);
600 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08x from path L\"%s\", expected %08x\n",
601 ret, TEST_URLFROMPATH[i].path, TEST_URLFROMPATH[i].ret);
602 ok(!lstrcmpiW(ret_urlW, urlW), "got %s expected %s from path L\"%s\"\n", ret_url, TEST_URLFROMPATH[i].url, TEST_URLFROMPATH[i].path);
603 ok(len == lstrlenW(ret_urlW), "ret len %d from path L\"%s\"\n", len, TEST_URLFROMPATH[i].path);
604 FreeWideString(urlW);
605 FreeWideString(pathW);
609 static void test_UrlIs(void)
615 for(i = 0; i < sizeof(TEST_PATH_IS_URL) / sizeof(TEST_PATH_IS_URL[0]); i++) {
616 MultiByteToWideChar(CP_ACP, 0, TEST_PATH_IS_URL[i].path, -1, wurl, 80);
618 ret = UrlIsA( TEST_PATH_IS_URL[i].path, URLIS_URL );
619 ok( ret == TEST_PATH_IS_URL[i].expect,
620 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
621 TEST_PATH_IS_URL[i].expect );
623 ret = UrlIsW( wurl, URLIS_URL );
624 ok( ret == TEST_PATH_IS_URL[i].expect,
625 "returned %d from path (UrlIsW) %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
626 TEST_PATH_IS_URL[i].expect );
628 for(i = 0; i < sizeof(TEST_URLIS_ATTRIBS) / sizeof(TEST_URLIS_ATTRIBS[0]); i++) {
629 MultiByteToWideChar(CP_ACP, 0, TEST_URLIS_ATTRIBS[i].url, -1, wurl, 80);
631 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_OPAQUE);
632 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
633 "returned %d for URLIS_OPAQUE, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
634 TEST_URLIS_ATTRIBS[i].expectOpaque );
635 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_FILEURL);
636 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
637 "returned %d for URLIS_FILEURL, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
638 TEST_URLIS_ATTRIBS[i].expectFile );
640 ret = UrlIsW( wurl, URLIS_OPAQUE);
641 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
642 "returned %d for URLIS_OPAQUE (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
643 TEST_URLIS_ATTRIBS[i].expectOpaque );
644 ret = UrlIsW( wurl, URLIS_FILEURL);
645 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
646 "returned %d for URLIS_FILEURL (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
647 TEST_URLIS_ATTRIBS[i].expectFile );
651 static void test_UrlUnescape(void)
653 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
654 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
655 WCHAR *urlW, *expected_urlW;
658 static char inplace[] = "file:///C:/Program%20Files";
659 static WCHAR inplaceW[] = {'f','i','l','e',':','/','/','/','C',':','/',
660 'P','r','o','g','r','a','m','%','2','0','F','i','l','e','s',0};
662 for(i=0; i<sizeof(TEST_URL_UNESCAPE)/sizeof(TEST_URL_UNESCAPE[0]); i++) {
663 dwEscaped=INTERNET_MAX_URL_LENGTH;
664 ok(UrlUnescapeA(TEST_URL_UNESCAPE[i].url, szReturnUrl, &dwEscaped, 0) == S_OK, "UrlEscapeA didn't return 0x%08x from \"%s\"\n", S_OK, TEST_URL_UNESCAPE[i].url);
665 ok(strcmp(szReturnUrl,TEST_URL_UNESCAPE[i].expect)==0, "Expected \"%s\", but got \"%s\" from \"%s\"\n", TEST_URL_UNESCAPE[i].expect, szReturnUrl, TEST_URL_UNESCAPE[i].url);
667 dwEscaped = INTERNET_MAX_URL_LENGTH;
668 urlW = GetWideString(TEST_URL_UNESCAPE[i].url);
669 expected_urlW = GetWideString(TEST_URL_UNESCAPE[i].expect);
670 ok(UrlUnescapeW(urlW, ret_urlW, &dwEscaped, 0) == S_OK, "UrlEscapeW didn't return 0x%08x from \"%s\"\n", S_OK, TEST_URL_UNESCAPE[i].url);
671 WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
672 ok(lstrcmpW(ret_urlW, expected_urlW)==0, "Expected \"%s\", but got \"%s\" from \"%s\" flags %08lx\n", TEST_URL_UNESCAPE[i].expect, szReturnUrl, TEST_URL_UNESCAPE[i].url, 0L);
673 FreeWideString(urlW);
674 FreeWideString(expected_urlW);
677 dwEscaped = sizeof(inplace);
678 ok(UrlUnescapeA(inplace, NULL, &dwEscaped, URL_UNESCAPE_INPLACE) == S_OK, "UrlUnescapeA failed unexpectedly\n");
680 dwEscaped = sizeof(inplaceW);
681 ok(UrlUnescapeW(inplaceW, NULL, &dwEscaped, URL_UNESCAPE_INPLACE) == S_OK, "UrlUnescapeW failed unexpectedly\n");
684 static void test_PathSearchAndQualify(void)
686 WCHAR path1[] = {'c',':','\\','f','o','o',0};
687 WCHAR expect1[] = {'c',':','\\','f','o','o',0};
688 WCHAR path2[] = {'c',':','f','o','o',0};
689 WCHAR c_drive[] = {'c',':',0};
690 WCHAR foo[] = {'f','o','o',0};
691 WCHAR path3[] = {'\\','f','o','o',0};
692 WCHAR winini[] = {'w','i','n','.','i','n','i',0};
694 WCHAR cur_dir[MAX_PATH];
695 WCHAR dot[] = {'.',0};
698 ok(PathSearchAndQualifyW(path1, out, MAX_PATH) != 0,
699 "PathSearchAndQualify rets 0\n");
700 ok(!lstrcmpiW(out, expect1), "strings don't match\n");
703 ok(PathSearchAndQualifyW(path2, out, MAX_PATH) != 0,
704 "PathSearchAndQualify rets 0\n");
705 GetFullPathNameW(c_drive, MAX_PATH, cur_dir, NULL);
706 PathAddBackslashW(cur_dir);
707 lstrcatW(cur_dir, foo);
708 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
711 ok(PathSearchAndQualifyW(foo, out, MAX_PATH) != 0,
712 "PathSearchAndQualify rets 0\n");
713 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
714 PathAddBackslashW(cur_dir);
715 lstrcatW(cur_dir, foo);
716 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
719 ok(PathSearchAndQualifyW(path3, out, MAX_PATH) != 0,
720 "PathSearchAndQualify rets 0\n");
721 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
722 lstrcpyW(cur_dir + 2, path3);
723 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
726 ok(PathSearchAndQualifyW(winini, out, MAX_PATH) != 0,
727 "PathSearchAndQualify rets 0\n");
728 if(!SearchPathW(NULL, winini, NULL, MAX_PATH, cur_dir, NULL))
729 GetFullPathNameW(winini, MAX_PATH, cur_dir, NULL);
730 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
734 static void test_PathCreateFromUrl(void)
737 char ret_path[INTERNET_MAX_URL_LENGTH];
739 WCHAR ret_pathW[INTERNET_MAX_URL_LENGTH];
741 static const char url[] = "http://www.winehq.org";
743 /* Check ret_path = NULL */
745 ret = PathCreateFromUrlA(url, NULL, &len, 0);
746 ok ( ret == E_INVALIDARG, "got 0x%08x expected E_INVALIDARG\n", ret);
748 for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
749 len = INTERNET_MAX_URL_LENGTH;
750 ret = PathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
751 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url %s\n", ret, TEST_PATHFROMURL[i].url);
752 if(TEST_PATHFROMURL[i].path) {
753 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);
754 ok(len == strlen(ret_path), "ret len %d from url %s\n", len, TEST_PATHFROMURL[i].url);
756 len = INTERNET_MAX_URL_LENGTH;
757 pathW = GetWideString(TEST_PATHFROMURL[i].path);
758 urlW = GetWideString(TEST_PATHFROMURL[i].url);
759 ret = PathCreateFromUrlW(urlW, ret_pathW, &len, 0);
760 WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),0,0);
761 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
762 if(TEST_PATHFROMURL[i].path) {
763 ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
764 ok(len == lstrlenW(ret_pathW), "ret len %d from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url);
766 FreeWideString(urlW);
767 FreeWideString(pathW);
772 static void test_PathIsUrl(void)
777 for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
778 ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
779 ok(ret == TEST_PATH_IS_URL[i].expect,
780 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
781 TEST_PATH_IS_URL[i].expect);
785 static const DWORD SHELL_charclass[] =
787 0x00000000, 0x00000000, 0x00000000, 0x00000000,
788 0x00000000, 0x00000000, 0x00000000, 0x00000000,
789 0x00000000, 0x00000000, 0x00000000, 0x00000000,
790 0x00000000, 0x00000000, 0x00000000, 0x00000000,
791 0x00000000, 0x00000000, 0x00000000, 0x00000000,
792 0x00000000, 0x00000000, 0x00000000, 0x00000000,
793 0x00000000, 0x00000000, 0x00000000, 0x00000000,
794 0x00000000, 0x00000000, 0x00000000, 0x00000000,
795 0x00000080, 0x00000100, 0x00000200, 0x00000100,
796 0x00000100, 0x00000100, 0x00000100, 0x00000100,
797 0x00000100, 0x00000100, 0x00000002, 0x00000100,
798 0x00000040, 0x00000100, 0x00000004, 0x00000000,
799 0x00000100, 0x00000100, 0x00000100, 0x00000100,
800 0x00000100, 0x00000100, 0x00000100, 0x00000100,
801 0x00000100, 0x00000100, 0x00000010, 0x00000020,
802 0x00000000, 0x00000100, 0x00000000, 0x00000001,
803 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
804 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
805 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
806 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
807 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
808 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
809 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
810 0x00000008, 0x00000100, 0x00000100, 0x00000100,
811 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
812 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
813 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
814 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
815 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
816 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
817 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
818 0x00000000, 0x00000100, 0x00000100
821 static void test_PathIsValidCharA(void)
826 ret = pPathIsValidCharA( 0x7f, 0 );
827 ok ( !ret, "PathIsValidCharA succeeded: 0x%08x\n", (DWORD)ret );
829 ret = pPathIsValidCharA( 0x7f, 1 );
830 ok ( !ret, "PathIsValidCharA succeeded: 0x%08x\n", (DWORD)ret );
832 for (c = 0; c < 0x7f; c++)
834 ret = pPathIsValidCharA( c, ~0U );
835 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
836 "PathIsValidCharA failed: 0x%02x got 0x%08x expected 0x%08x\n",
837 c, (DWORD)ret, SHELL_charclass[c] );
840 for (c = 0x7f; c <= 0xff; c++)
842 ret = pPathIsValidCharA( c, ~0U );
843 ok ( ret == 0x00000100,
844 "PathIsValidCharA failed: 0x%02x got 0x%08x expected 0x00000100\n",
849 static void test_PathIsValidCharW(void)
852 unsigned int c, err_count = 0;
854 ret = pPathIsValidCharW( 0x7f, 0 );
855 ok ( !ret, "PathIsValidCharW succeeded: 0x%08x\n", (DWORD)ret );
857 ret = pPathIsValidCharW( 0x7f, 1 );
858 ok ( !ret, "PathIsValidCharW succeeded: 0x%08x\n", (DWORD)ret );
860 for (c = 0; c < 0x7f; c++)
862 ret = pPathIsValidCharW( c, ~0U );
863 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
864 "PathIsValidCharW failed: 0x%02x got 0x%08x expected 0x%08x\n",
865 c, (DWORD)ret, SHELL_charclass[c] );
868 for (c = 0x007f; c <= 0xffff; c++)
870 ret = pPathIsValidCharW( c, ~0U );
871 ok ( ret == 0x00000100,
872 "PathIsValidCharW failed: 0x%02x got 0x%08x expected 0x00000100\n",
874 if (ret != 0x00000100)
876 if(++err_count > 100 ) {
877 trace("skipping rest of PathIsValidCharW tests "
878 "because of the current number of errors\n");
885 static void test_PathMakePretty(void)
889 ok (PathMakePrettyA(NULL) == FALSE, "PathMakePretty: NULL path succeeded\n");
891 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Empty path failed\n");
893 strcpy(buff, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
894 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Long UC name failed\n");
895 ok (strcmp(buff, "C:\\a long file name with \\spaces.txt") == 0,
896 "PathMakePretty: Long UC name not changed\n");
898 strcpy(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
899 ok (PathMakePrettyA(buff) == FALSE, "PathMakePretty: Long MC name succeeded\n");
900 ok (strcmp(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
901 "PathMakePretty: Failed but modified path\n");
903 strcpy(buff, "TEST");
904 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Short name failed\n");
905 ok (strcmp(buff, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff);
908 static void test_PathMatchSpec(void)
910 static const char file[] = "c:\\foo\\bar\\filename.ext";
911 static const char spec1[] = ".ext";
912 static const char spec2[] = "*.ext";
913 static const char spec3[] = "*.ext ";
914 static const char spec4[] = " *.ext";
915 static const char spec5[] = "* .ext";
916 static const char spec6[] = "*. ext";
917 static const char spec7[] = "* . ext";
918 static const char spec8[] = "*.e?t";
919 static const char spec9[] = "filename.ext";
920 static const char spec10[] = "*bar\\filename.ext";
921 static const char spec11[] = " foo; *.ext";
922 static const char spec12[] = "*.ext;*.bar";
923 static const char spec13[] = "*bar*";
925 ok (PathMatchSpecA(file, spec1) == FALSE, "PathMatchSpec: Spec1 failed\n");
926 ok (PathMatchSpecA(file, spec2) == TRUE, "PathMatchSpec: Spec2 failed\n");
927 ok (PathMatchSpecA(file, spec3) == FALSE, "PathMatchSpec: Spec3 failed\n");
928 ok (PathMatchSpecA(file, spec4) == TRUE, "PathMatchSpec: Spec4 failed\n");
929 todo_wine ok (PathMatchSpecA(file, spec5) == TRUE, "PathMatchSpec: Spec5 failed\n");
930 todo_wine ok (PathMatchSpecA(file, spec6) == TRUE, "PathMatchSpec: Spec6 failed\n");
931 ok (PathMatchSpecA(file, spec7) == FALSE, "PathMatchSpec: Spec7 failed\n");
932 ok (PathMatchSpecA(file, spec8) == TRUE, "PathMatchSpec: Spec8 failed\n");
933 ok (PathMatchSpecA(file, spec9) == FALSE, "PathMatchSpec: Spec9 failed\n");
934 ok (PathMatchSpecA(file, spec10) == TRUE, "PathMatchSpec: Spec10 failed\n");
935 ok (PathMatchSpecA(file, spec11) == TRUE, "PathMatchSpec: Spec11 failed\n");
936 ok (PathMatchSpecA(file, spec12) == TRUE, "PathMatchSpec: Spec12 failed\n");
937 ok (PathMatchSpecA(file, spec13) == TRUE, "PathMatchSpec: Spec13 failed\n");
940 static void test_PathCombineW(void)
942 LPWSTR wszString, wszString2;
944 wszString2 = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
947 wszString = pPathCombineW(NULL, NULL, NULL);
948 ok (wszString == NULL, "Expected a NULL return\n");
951 wszString = pPathCombineW(wszString2, NULL, NULL);
952 ok (wszString == NULL, "Expected a NULL return\n");
954 HeapFree(GetProcessHeap(), 0, wszString2);
957 #define LONG_LEN (MAX_PATH * 2)
958 #define HALF_LEN (MAX_PATH / 2 + 1)
960 static void test_PathCombineA(void)
964 char too_long[LONG_LEN];
965 char one[HALF_LEN], two[HALF_LEN];
968 SetLastError(0xdeadbeef);
969 str = PathCombineA(NULL, "C:\\", "one\\two\\three");
970 ok(str == NULL, "Expected NULL, got %p\n", str);
971 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
973 /* try NULL dest and NULL directory */
974 SetLastError(0xdeadbeef);
975 str = PathCombineA(NULL, NULL, "one\\two\\three");
976 ok(str == NULL, "Expected NULL, got %p\n", str);
977 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
980 SetLastError(0xdeadbeef);
981 str = PathCombineA(NULL, NULL, NULL);
982 ok(str == NULL, "Expected NULL, got %p\n", str);
983 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
985 /* try NULL file part */
986 SetLastError(0xdeadbeef);
987 lstrcpyA(dest, "control");
988 str = PathCombineA(dest, "C:\\", NULL);
989 ok(str == dest, "Expected str == dest, got %p\n", str);
990 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
991 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
993 /* try empty file part */
994 SetLastError(0xdeadbeef);
995 lstrcpyA(dest, "control");
996 str = PathCombineA(dest, "C:\\", "");
997 ok(str == dest, "Expected str == dest, got %p\n", str);
998 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
999 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1001 /* try empty directory and file part */
1002 SetLastError(0xdeadbeef);
1003 lstrcpyA(dest, "control");
1004 str = PathCombineA(dest, "", "");
1005 ok(str == dest, "Expected str == dest, got %p\n", str);
1006 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
1007 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1009 /* try NULL directory */
1010 SetLastError(0xdeadbeef);
1011 lstrcpyA(dest, "control");
1012 str = PathCombineA(dest, NULL, "one\\two\\three");
1013 ok(str == dest, "Expected str == dest, got %p\n", str);
1014 ok(!lstrcmp(str, "one\\two\\three"), "Expected one\\two\\three, got %s\n", str);
1015 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1017 /* try NULL directory and empty file part */
1018 SetLastError(0xdeadbeef);
1019 lstrcpyA(dest, "control");
1020 str = PathCombineA(dest, NULL, "");
1021 ok(str == dest, "Expected str == dest, got %p\n", str);
1022 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
1023 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1025 /* try NULL directory and file part */
1026 SetLastError(0xdeadbeef);
1027 lstrcpyA(dest, "control");
1028 str = PathCombineA(dest, NULL, NULL);
1029 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1032 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1034 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1036 /* try directory without backslash */
1037 SetLastError(0xdeadbeef);
1038 lstrcpyA(dest, "control");
1039 str = PathCombineA(dest, "C:", "one\\two\\three");
1040 ok(str == dest, "Expected str == dest, got %p\n", str);
1041 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1042 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1044 /* try directory with backslash */
1045 SetLastError(0xdeadbeef);
1046 lstrcpyA(dest, "control");
1047 str = PathCombineA(dest, "C:\\", "one\\two\\three");
1048 ok(str == dest, "Expected str == dest, got %p\n", str);
1049 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1050 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1052 /* try directory with backslash and file with prepended backslash */
1053 SetLastError(0xdeadbeef);
1054 lstrcpyA(dest, "control");
1055 str = PathCombineA(dest, "C:\\", "\\one\\two\\three");
1056 ok(str == dest, "Expected str == dest, got %p\n", str);
1057 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1058 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1060 /* try previous test, with backslash appended as well */
1061 SetLastError(0xdeadbeef);
1062 lstrcpyA(dest, "control");
1063 str = PathCombineA(dest, "C:\\", "\\one\\two\\three\\");
1064 ok(str == dest, "Expected str == dest, got %p\n", str);
1065 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
1066 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1068 /* try a relative directory */
1069 SetLastError(0xdeadbeef);
1070 lstrcpyA(dest, "control");
1071 str = PathCombineA(dest, "relative\\dir", "\\one\\two\\three\\");
1072 ok(str == dest, "Expected str == dest, got %p\n", str);
1073 ok(!lstrcmp(str, "one\\two\\three\\"), "Expected one\\two\\three\\, got %s\n", str);
1074 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1076 /* try forward slashes */
1077 SetLastError(0xdeadbeef);
1078 lstrcpyA(dest, "control");
1079 str = PathCombineA(dest, "C:\\", "one/two/three\\");
1080 ok(str == dest, "Expected str == dest, got %p\n", str);
1081 ok(!lstrcmp(str, "C:\\one/two/three\\"), "Expected one/two/three\\, got %s\n", str);
1082 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1084 /* try a really weird directory */
1085 SetLastError(0xdeadbeef);
1086 lstrcpyA(dest, "control");
1087 str = PathCombineA(dest, "C:\\/\\/", "\\one\\two\\three\\");
1088 ok(str == dest, "Expected str == dest, got %p\n", str);
1089 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
1090 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1093 SetLastError(0xdeadbeef);
1094 lstrcpyA(dest, "control");
1095 str = PathCombineA(dest, "C:\\", "one\\..\\two\\.\\three");
1096 ok(str == dest, "Expected str == dest, got %p\n", str);
1097 ok(!lstrcmp(str, "C:\\two\\three"), "Expected C:\\two\\three, got %s\n", str);
1098 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1100 /* try .. as file */
1101 /* try forward slashes */
1102 SetLastError(0xdeadbeef);
1103 lstrcpyA(dest, "control");
1104 str = PathCombineA(dest, "C:\\", "..");
1105 ok(str == dest, "Expected str == dest, got %p\n", str);
1106 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
1107 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1109 memset(too_long, 'a', LONG_LEN);
1110 too_long[LONG_LEN - 1] = '\0';
1112 /* try a file longer than MAX_PATH */
1113 SetLastError(0xdeadbeef);
1114 lstrcpyA(dest, "control");
1115 str = PathCombineA(dest, "C:\\", too_long);
1118 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1119 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1120 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1123 /* try a directory longer than MAX_PATH */
1124 SetLastError(0xdeadbeef);
1125 lstrcpyA(dest, "control");
1126 str = PathCombineA(dest, too_long, "one\\two\\three");
1129 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1130 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1131 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1134 memset(one, 'b', HALF_LEN);
1135 memset(two, 'c', HALF_LEN);
1136 one[HALF_LEN - 1] = '\0';
1137 two[HALF_LEN - 1] = '\0';
1139 /* destination string is longer than MAX_PATH, but not the constituent parts */
1140 SetLastError(0xdeadbeef);
1141 lstrcpyA(dest, "control");
1142 str = PathCombineA(dest, one, two);
1145 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1146 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1148 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1151 static void test_PathAddBackslash(void)
1154 char path[MAX_PATH];
1155 char too_long[LONG_LEN];
1157 /* try a NULL path */
1158 SetLastError(0xdeadbeef);
1159 str = PathAddBackslashA(NULL);
1160 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1161 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1163 /* try an empty path */
1165 SetLastError(0xdeadbeef);
1166 str = PathAddBackslashA(path);
1167 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1168 ok(lstrlenA(path) == 0, "Expected empty string, got %i\n", lstrlenA(path));
1169 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1171 /* try a relative path */
1172 lstrcpyA(path, "one\\two");
1173 SetLastError(0xdeadbeef);
1174 str = PathAddBackslashA(path);
1175 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1176 ok(!lstrcmp(path, "one\\two\\"), "Expected one\\two\\, got %s\n", path);
1177 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1180 lstrcpyA(path, "one\\..\\two");
1181 SetLastError(0xdeadbeef);
1182 str = PathAddBackslashA(path);
1183 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1184 ok(!lstrcmp(path, "one\\..\\two\\"), "Expected one\\..\\two\\, got %s\n", path);
1185 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1187 /* try just a space */
1188 lstrcpyA(path, " ");
1189 SetLastError(0xdeadbeef);
1190 str = PathAddBackslashA(path);
1191 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1192 ok(!lstrcmp(path, " \\"), "Expected \\, got %s\n", path);
1193 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1195 /* path already has backslash */
1196 lstrcpyA(path, "C:\\one\\");
1197 SetLastError(0xdeadbeef);
1198 str = PathAddBackslashA(path);
1199 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1200 ok(!lstrcmp(path, "C:\\one\\"), "Expected C:\\one\\, got %s\n", path);
1201 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1203 memset(too_long, 'a', LONG_LEN);
1204 too_long[LONG_LEN - 1] = '\0';
1206 /* path is longer than MAX_PATH */
1207 SetLastError(0xdeadbeef);
1208 str = PathAddBackslashA(too_long);
1209 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1210 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1213 static void test_PathAppendA(void)
1215 char path[MAX_PATH];
1216 char too_long[LONG_LEN];
1217 char one[HALF_LEN], two[HALF_LEN];
1220 lstrcpy(path, "C:\\one");
1222 /* try NULL pszMore */
1223 SetLastError(0xdeadbeef);
1224 res = PathAppendA(path, NULL);
1225 ok(!res, "Expected failure\n");
1226 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1227 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
1229 /* try empty pszMore */
1230 SetLastError(0xdeadbeef);
1231 res = PathAppendA(path, "");
1232 ok(res, "Expected success\n");
1233 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1234 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
1236 /* try NULL pszPath */
1237 SetLastError(0xdeadbeef);
1238 res = PathAppendA(NULL, "two\\three");
1239 ok(!res, "Expected failure\n");
1240 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1242 /* try empty pszPath */
1244 SetLastError(0xdeadbeef);
1245 res = PathAppendA(path, "two\\three");
1246 ok(res, "Expected success\n");
1247 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1248 ok(!lstrcmp(path, "two\\three"), "Expected \\two\\three, got %s\n", path);
1250 /* try empty pszPath and empty pszMore */
1252 SetLastError(0xdeadbeef);
1253 res = PathAppendA(path, "");
1254 ok(res, "Expected success\n");
1255 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1256 ok(!lstrcmp(path, "\\"), "Expected \\, got %s\n", path);
1258 /* try legit params */
1259 lstrcpy(path, "C:\\one");
1260 SetLastError(0xdeadbeef);
1261 res = PathAppendA(path, "two\\three");
1262 ok(res, "Expected success\n");
1263 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1264 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1266 /* try pszPath with backslash after it */
1267 lstrcpy(path, "C:\\one\\");
1268 SetLastError(0xdeadbeef);
1269 res = PathAppendA(path, "two\\three");
1270 ok(res, "Expected success\n");
1271 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1272 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1274 /* try pszMore with backslash before it */
1275 lstrcpy(path, "C:\\one");
1276 SetLastError(0xdeadbeef);
1277 res = PathAppendA(path, "\\two\\three");
1278 ok(res, "Expected success\n");
1279 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1280 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1282 /* try pszMore with backslash after it */
1283 lstrcpy(path, "C:\\one");
1284 SetLastError(0xdeadbeef);
1285 res = PathAppendA(path, "two\\three\\");
1286 ok(res, "Expected success\n");
1287 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1288 ok(!lstrcmp(path, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", path);
1290 /* try spaces in pszPath */
1291 lstrcpy(path, "C: \\ one ");
1292 SetLastError(0xdeadbeef);
1293 res = PathAppendA(path, "two\\three");
1294 ok(res, "Expected success\n");
1295 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1296 ok(!lstrcmp(path, "C: \\ one \\two\\three"), "Expected C: \\ one \\two\\three, got %s\n", path);
1298 /* try spaces in pszMore */
1299 lstrcpy(path, "C:\\one");
1300 SetLastError(0xdeadbeef);
1301 res = PathAppendA(path, " two \\ three ");
1302 ok(res, "Expected success\n");
1303 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1304 ok(!lstrcmp(path, "C:\\one\\ two \\ three "), "Expected 'C:\\one\\ two \\ three ', got %s\n", path);
1306 /* pszPath is too long */
1307 memset(too_long, 'a', LONG_LEN);
1308 too_long[LONG_LEN - 1] = '\0';
1309 SetLastError(0xdeadbeef);
1310 res = PathAppendA(too_long, "two\\three");
1313 ok(!res, "Expected failure\n");
1314 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1315 ok(lstrlen(too_long) == 0, "Expected length of too_long to be zero, got %i\n", lstrlen(too_long));
1318 /* pszMore is too long */
1319 lstrcpy(path, "C:\\one");
1320 memset(too_long, 'a', LONG_LEN);
1321 too_long[LONG_LEN - 1] = '\0';
1322 SetLastError(0xdeadbeef);
1323 res = PathAppendA(path, too_long);
1326 ok(!res, "Expected failure\n");
1327 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1328 ok(lstrlen(path) == 0, "Expected length of path to be zero, got %i\n", lstrlen(path));
1331 /* both params combined are too long */
1332 memset(one, 'a', HALF_LEN);
1333 one[HALF_LEN - 1] = '\0';
1334 memset(two, 'b', HALF_LEN);
1335 two[HALF_LEN - 1] = '\0';
1336 SetLastError(0xdeadbeef);
1337 res = PathAppendA(one, two);
1340 ok(!res, "Expected failure\n");
1341 ok(lstrlen(one) == 0, "Expected length of one to be zero, got %i\n", lstrlen(one));
1343 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1346 static void test_PathCanonicalizeA(void)
1348 char dest[MAX_PATH];
1349 char too_long[LONG_LEN];
1352 /* try a NULL source */
1353 lstrcpy(dest, "test");
1354 SetLastError(0xdeadbeef);
1355 res = PathCanonicalizeA(dest, NULL);
1356 ok(!res, "Expected failure\n");
1357 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1358 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1361 ok(!lstrcmp(dest, "test"), "Expected test, got %s\n", dest);
1364 /* try an empty source */
1365 lstrcpy(dest, "test");
1366 SetLastError(0xdeadbeef);
1367 res = PathCanonicalizeA(dest, "");
1368 ok(res, "Expected success\n");
1369 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1370 ok(!lstrcmp(dest, "\\"), "Expected \\, got %s\n", dest);
1372 /* try a NULL dest */
1373 SetLastError(0xdeadbeef);
1374 res = PathCanonicalizeA(NULL, "C:\\");
1375 ok(!res, "Expected failure\n");
1376 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1377 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1379 /* try empty dest */
1381 SetLastError(0xdeadbeef);
1382 res = PathCanonicalizeA(dest, "C:\\");
1383 ok(res, "Expected success\n");
1384 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1385 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
1387 /* try non-empty dest */
1388 lstrcpy(dest, "test");
1389 SetLastError(0xdeadbeef);
1390 res = PathCanonicalizeA(dest, "C:\\");
1391 ok(res, "Expected success\n");
1392 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1393 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
1395 /* try a space for source */
1396 lstrcpy(dest, "test");
1397 SetLastError(0xdeadbeef);
1398 res = PathCanonicalizeA(dest, " ");
1399 ok(res, "Expected success\n");
1400 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1401 ok(!lstrcmp(dest, " "), "Expected ' ', got %s\n", dest);
1403 /* try a relative path */
1404 lstrcpy(dest, "test");
1405 SetLastError(0xdeadbeef);
1406 res = PathCanonicalizeA(dest, "one\\two");
1407 ok(res, "Expected success\n");
1408 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1409 ok(!lstrcmp(dest, "one\\two"), "Expected one\\two, got %s\n", dest);
1411 /* try current dir and previous dir */
1412 lstrcpy(dest, "test");
1413 SetLastError(0xdeadbeef);
1414 res = PathCanonicalizeA(dest, "C:\\one\\.\\..\\two\\three\\..");
1415 ok(res, "Expected success\n");
1416 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1417 ok(!lstrcmp(dest, "C:\\two"), "Expected C:\\two, got %s\n", dest);
1419 /* try simple forward slashes */
1420 lstrcpy(dest, "test");
1421 SetLastError(0xdeadbeef);
1422 res = PathCanonicalizeA(dest, "C:\\one/two/three\\four/five\\six");
1423 ok(res, "Expected success\n");
1424 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1425 ok(!lstrcmp(dest, "C:\\one/two/three\\four/five\\six"),
1426 "Expected C:\\one/two/three\\four/five\\six, got %s\n", dest);
1428 /* try simple forward slashes with same dir */
1429 lstrcpy(dest, "test");
1430 SetLastError(0xdeadbeef);
1431 res = PathCanonicalizeA(dest, "C:\\one/.\\two");
1432 ok(res, "Expected success\n");
1433 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1434 ok(!lstrcmp(dest, "C:\\one/.\\two"), "Expected C:\\one/.\\two, got %s\n", dest);
1436 /* try simple forward slashes with change dir */
1437 lstrcpy(dest, "test");
1438 SetLastError(0xdeadbeef);
1439 res = PathCanonicalizeA(dest, "C:\\one/.\\two\\..");
1440 ok(res, "Expected success\n");
1441 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1442 ok(!lstrcmp(dest, "C:\\one/."), "Expected C:\\one/., got %s\n", dest);
1444 /* try forward slashes with change dirs
1445 * NOTE: if there is a forward slash in between two backslashes,
1446 * everything in between the two backslashes is considered on dir
1448 lstrcpy(dest, "test");
1449 SetLastError(0xdeadbeef);
1450 res = PathCanonicalizeA(dest, "C:\\one/.\\..\\two/three\\..\\four/.five");
1451 ok(res, "Expected success\n");
1452 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1453 ok(!lstrcmp(dest, "C:\\four/.five"), "Expected C:\\four/.five, got %s\n", dest);
1455 /* try src is too long */
1456 memset(too_long, 'a', LONG_LEN);
1457 too_long[LONG_LEN - 1] = '\0';
1458 lstrcpy(dest, "test");
1459 SetLastError(0xdeadbeef);
1460 res = PathCanonicalizeA(dest, too_long);
1463 ok(!res, "Expected failure\n");
1464 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1466 ok(lstrlen(too_long) == LONG_LEN - 1, "Expected length LONG_LEN - 1, got %i\n", lstrlen(too_long));
1469 static void test_PathFindExtensionA(void)
1472 char path[MAX_PATH];
1473 char too_long[LONG_LEN];
1475 /* try a NULL path */
1476 SetLastError(0xdeadbeef);
1477 ext = PathFindExtensionA(NULL);
1478 ok(ext == NULL, "Expected NULL, got %p\n", ext);
1479 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1481 /* try an empty path */
1483 SetLastError(0xdeadbeef);
1484 ext = PathFindExtensionA(path);
1485 ok(ext == path, "Expected ext == path, got %p\n", ext);
1486 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1487 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1489 /* try a path without an extension */
1490 lstrcpy(path, "file");
1491 SetLastError(0xdeadbeef);
1492 ext = PathFindExtensionA(path);
1493 ok(ext == path + lstrlen(path), "Expected ext == path, got %p\n", ext);
1494 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1495 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1497 /* try a path with an extension */
1498 lstrcpy(path, "file.txt");
1499 SetLastError(0xdeadbeef);
1500 ext = PathFindExtensionA(path);
1501 ok(ext == path + lstrlen("file"),
1502 "Expected ext == path + lstrlen(\"file\"), got %p\n", ext);
1503 ok(!lstrcmp(ext, ".txt"), "Expected .txt, got %s\n", ext);
1504 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1506 /* try a path with two extensions */
1507 lstrcpy(path, "file.txt.doc");
1508 SetLastError(0xdeadbeef);
1509 ext = PathFindExtensionA(path);
1510 ok(ext == path + lstrlen("file.txt"),
1511 "Expected ext == path + lstrlen(\"file.txt\"), got %p\n", ext);
1512 ok(!lstrcmp(ext, ".doc"), "Expected .txt, got %s\n", ext);
1513 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1515 /* try a path longer than MAX_PATH without an extension*/
1516 memset(too_long, 'a', LONG_LEN);
1517 too_long[LONG_LEN - 1] = '\0';
1518 SetLastError(0xdeadbeef);
1519 ext = PathFindExtensionA(too_long);
1520 ok(ext == too_long + LONG_LEN - 1, "Expected ext == too_long + LONG_LEN - 1, got %p\n", ext);
1521 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1523 /* try a path longer than MAX_PATH with an extension*/
1524 memset(too_long, 'a', LONG_LEN);
1525 too_long[LONG_LEN - 1] = '\0';
1526 lstrcpy(too_long + 300, ".abcde");
1527 too_long[lstrlen(too_long)] = 'a';
1528 SetLastError(0xdeadbeef);
1529 ext = PathFindExtensionA(too_long);
1530 ok(ext == too_long + 300, "Expected ext == too_long + 300, got %p\n", ext);
1531 ok(lstrlen(ext) == LONG_LEN - 301, "Expected LONG_LEN - 301, got %i\n", lstrlen(ext));
1532 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1535 static void test_PathBuildRootA(void)
1539 char root_expected[26][4];
1543 /* set up the expected paths */
1544 for (drive = 'A'; drive <= 'Z'; drive++)
1545 sprintf(root_expected[drive - 'A'], "%c:\\", drive);
1547 /* test the expected values */
1548 for (j = 0; j < 26; j++)
1550 SetLastError(0xdeadbeef);
1551 lstrcpy(path, "aaaaaaaaa");
1552 root = PathBuildRootA(path, j);
1553 ok(root == path, "Expected root == path, got %p\n", root);
1554 ok(!lstrcmp(root, root_expected[j]), "Expected %s, got %s\n", root_expected[j], root);
1555 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1558 /* test a negative drive number */
1559 SetLastError(0xdeadbeef);
1560 lstrcpy(path, "aaaaaaaaa");
1561 root = PathBuildRootA(path, -1);
1562 ok(root == path, "Expected root == path, got %p\n", root);
1563 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1564 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1566 /* test a drive number greater than 25 */
1567 SetLastError(0xdeadbeef);
1568 lstrcpy(path, "aaaaaaaaa");
1569 root = PathBuildRootA(path, 26);
1570 ok(root == path, "Expected root == path, got %p\n", root);
1571 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1572 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1574 /* length of path is less than 4 */
1575 SetLastError(0xdeadbeef);
1576 lstrcpy(path, "aa");
1577 root = PathBuildRootA(path, 0);
1578 ok(root == path, "Expected root == path, got %p\n", root);
1579 ok(!lstrcmp(path, "A:\\"), "Expected A:\\, got %s\n", path);
1580 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1583 SetLastError(0xdeadbeef);
1584 root = PathBuildRootA(NULL, 0);
1585 ok(root == NULL, "Expected root == NULL, got %p\n", root);
1586 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1589 static void test_PathCommonPrefixA(void)
1591 char path1[MAX_PATH], path2[MAX_PATH];
1595 /* test NULL path1 */
1596 SetLastError(0xdeadbeef);
1597 lstrcpy(path2, "C:\\");
1598 lstrcpy(out, "aaa");
1599 count = PathCommonPrefixA(NULL, path2, out);
1600 ok(count == 0, "Expected 0, got %i\n", count);
1603 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1605 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1606 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1608 /* test NULL path2 */
1609 SetLastError(0xdeadbeef);
1610 lstrcpy(path1, "C:\\");
1611 lstrcpy(out, "aaa");
1612 count = PathCommonPrefixA(path1, NULL, out);
1613 ok(count == 0, "Expected 0, got %i\n", count);
1616 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1618 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1619 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1621 /* test empty path1 */
1622 SetLastError(0xdeadbeef);
1624 lstrcpy(path2, "C:\\");
1625 lstrcpy(out, "aaa");
1626 count = PathCommonPrefixA(path1, path2, out);
1627 ok(count == 0, "Expected 0, got %i\n", count);
1628 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1629 ok(lstrlen(path1) == 0, "Expected 0 length path1, got %i\n", lstrlen(path1));
1630 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1631 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1633 /* test empty path1 */
1634 SetLastError(0xdeadbeef);
1636 lstrcpy(path1, "C:\\");
1637 lstrcpy(out, "aaa");
1638 count = PathCommonPrefixA(path1, path2, out);
1639 ok(count == 0, "Expected 0, got %i\n", count);
1640 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1641 ok(lstrlen(path2) == 0, "Expected 0 length path2, got %i\n", lstrlen(path2));
1642 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1643 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1645 /* paths are legit, out is NULL */
1646 SetLastError(0xdeadbeef);
1647 lstrcpy(path1, "C:\\");
1648 lstrcpy(path2, "C:\\");
1649 count = PathCommonPrefixA(path1, path2, NULL);
1650 ok(count == 3, "Expected 3, got %i\n", count);
1651 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1652 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1653 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1655 /* all parameters legit */
1656 SetLastError(0xdeadbeef);
1657 lstrcpy(path1, "C:\\");
1658 lstrcpy(path2, "C:\\");
1659 lstrcpy(out, "aaa");
1660 count = PathCommonPrefixA(path1, path2, out);
1661 ok(count == 3, "Expected 3, got %i\n", count);
1662 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1663 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1664 ok(!lstrcmp(out, "C:\\"), "Expected C:\\, got %s\n", out);
1665 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1667 /* path1 and path2 not the same, but common prefix */
1668 SetLastError(0xdeadbeef);
1669 lstrcpy(path1, "C:\\one\\two");
1670 lstrcpy(path2, "C:\\one\\three");
1671 lstrcpy(out, "aaa");
1672 count = PathCommonPrefixA(path1, path2, out);
1673 ok(count == 6, "Expected 6, got %i\n", count);
1674 ok(!lstrcmp(path1, "C:\\one\\two"), "Expected C:\\one\\two, got %s\n", path1);
1675 ok(!lstrcmp(path2, "C:\\one\\three"), "Expected C:\\one\\three, got %s\n", path2);
1676 ok(!lstrcmp(out, "C:\\one"), "Expected C:\\one, got %s\n", out);
1677 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1680 SetLastError(0xdeadbeef);
1681 lstrcpy(path1, "one\\.two");
1682 lstrcpy(path2, "one\\.three");
1683 lstrcpy(out, "aaa");
1684 count = PathCommonPrefixA(path1, path2, out);
1685 ok(count == 3, "Expected 3, got %i\n", count);
1686 ok(!lstrcmp(path1, "one\\.two"), "Expected one\\.two, got %s\n", path1);
1687 ok(!lstrcmp(path2, "one\\.three"), "Expected one\\.three, got %s\n", path2);
1688 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1689 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1692 SetLastError(0xdeadbeef);
1693 lstrcpy(path1, "one\\..two");
1694 lstrcpy(path2, "one\\..three");
1695 lstrcpy(out, "aaa");
1696 count = PathCommonPrefixA(path1, path2, out);
1697 ok(count == 3, "Expected 3, got %i\n", count);
1698 ok(!lstrcmp(path1, "one\\..two"), "Expected one\\..two, got %s\n", path1);
1699 ok(!lstrcmp(path2, "one\\..three"), "Expected one\\..three, got %s\n", path2);
1700 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1701 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1703 /* try ... prefix */
1704 SetLastError(0xdeadbeef);
1705 lstrcpy(path1, "one\\...two");
1706 lstrcpy(path2, "one\\...three");
1707 lstrcpy(out, "aaa");
1708 count = PathCommonPrefixA(path1, path2, out);
1709 ok(count == 3, "Expected 3, got %i\n", count);
1710 ok(!lstrcmp(path1, "one\\...two"), "Expected one\\...two, got %s\n", path1);
1711 ok(!lstrcmp(path2, "one\\...three"), "Expected one\\...three, got %s\n", path2);
1712 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1713 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1716 SetLastError(0xdeadbeef);
1717 lstrcpy(path1, "one\\.\\two");
1718 lstrcpy(path2, "one\\.\\three");
1719 lstrcpy(out, "aaa");
1720 count = PathCommonPrefixA(path1, path2, out);
1721 ok(count == 5, "Expected 5, got %i\n", count);
1722 ok(!lstrcmp(path1, "one\\.\\two"), "Expected one\\.\\two, got %s\n", path1);
1723 ok(!lstrcmp(path2, "one\\.\\three"), "Expected one\\.\\three, got %s\n", path2);
1724 ok(!lstrcmp(out, "one\\."), "Expected one\\., got %s\n", out);
1725 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1727 /* try ..\ prefix */
1728 SetLastError(0xdeadbeef);
1729 lstrcpy(path1, "one\\..\\two");
1730 lstrcpy(path2, "one\\..\\three");
1731 lstrcpy(out, "aaa");
1732 count = PathCommonPrefixA(path1, path2, out);
1733 ok(count == 6, "Expected 6, got %i\n", count);
1734 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1735 ok(!lstrcmp(path2, "one\\..\\three"), "Expected one\\..\\three, got %s\n", path2);
1736 ok(!lstrcmp(out, "one\\.."), "Expected one\\.., got %s\n", out);
1737 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1739 /* try ...\\ prefix */
1740 SetLastError(0xdeadbeef);
1741 lstrcpy(path1, "one\\...\\two");
1742 lstrcpy(path2, "one\\...\\three");
1743 lstrcpy(out, "aaa");
1744 count = PathCommonPrefixA(path1, path2, out);
1745 ok(count == 7, "Expected 7, got %i\n", count);
1746 ok(!lstrcmp(path1, "one\\...\\two"), "Expected one\\...\\two, got %s\n", path1);
1747 ok(!lstrcmp(path2, "one\\...\\three"), "Expected one\\...\\three, got %s\n", path2);
1748 ok(!lstrcmp(out, "one\\..."), "Expected one\\..., got %s\n", out);
1749 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1751 /* try prefix that is not an msdn labeled prefix type */
1752 SetLastError(0xdeadbeef);
1753 lstrcpy(path1, "same");
1754 lstrcpy(path2, "same");
1755 lstrcpy(out, "aaa");
1756 count = PathCommonPrefixA(path1, path2, out);
1757 ok(count == 4, "Expected 4, got %i\n", count);
1758 ok(!lstrcmp(path1, "same"), "Expected same, got %s\n", path1);
1759 ok(!lstrcmp(path2, "same"), "Expected same, got %s\n", path2);
1760 ok(!lstrcmp(out, "same"), "Expected same, got %s\n", out);
1761 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1763 /* try . after directory */
1764 SetLastError(0xdeadbeef);
1765 lstrcpy(path1, "one\\mid.\\two");
1766 lstrcpy(path2, "one\\mid.\\three");
1767 lstrcpy(out, "aaa");
1768 count = PathCommonPrefixA(path1, path2, out);
1769 ok(count == 8, "Expected 8, got %i\n", count);
1770 ok(!lstrcmp(path1, "one\\mid.\\two"), "Expected one\\mid.\\two, got %s\n", path1);
1771 ok(!lstrcmp(path2, "one\\mid.\\three"), "Expected one\\mid.\\three, got %s\n", path2);
1772 ok(!lstrcmp(out, "one\\mid."), "Expected one\\mid., got %s\n", out);
1773 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1775 /* try . in the middle of a directory */
1776 SetLastError(0xdeadbeef);
1777 lstrcpy(path1, "one\\mid.end\\two");
1778 lstrcpy(path2, "one\\mid.end\\three");
1779 lstrcpy(out, "aaa");
1780 count = PathCommonPrefixA(path1, path2, out);
1781 ok(count == 11, "Expected 11, got %i\n", count);
1782 ok(!lstrcmp(path1, "one\\mid.end\\two"), "Expected one\\mid.end\\two, got %s\n", path1);
1783 ok(!lstrcmp(path2, "one\\mid.end\\three"), "Expected one\\mid.end\\three, got %s\n", path2);
1784 ok(!lstrcmp(out, "one\\mid.end"), "Expected one\\mid.end, got %s\n", out);
1785 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1787 /* try comparing a .. with the expanded path */
1788 SetLastError(0xdeadbeef);
1789 lstrcpy(path1, "one\\..\\two");
1790 lstrcpy(path2, "two");
1791 lstrcpy(out, "aaa");
1792 count = PathCommonPrefixA(path1, path2, out);
1793 ok(count == 0, "Expected 0, got %i\n", count);
1794 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1795 ok(!lstrcmp(path2, "two"), "Expected two, got %s\n", path2);
1796 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1797 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1800 static void test_PathUnquoteSpaces(void)
1803 for(i = 0; i < sizeof(TEST_PATH_UNQUOTE_SPACES) / sizeof(TEST_PATH_UNQUOTE_SPACES[0]); i++)
1805 char *path = strdupA(TEST_PATH_UNQUOTE_SPACES[i].path);
1806 WCHAR *pathW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].path);
1807 WCHAR *resultW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].result);
1809 PathUnquoteSpacesA(path);
1810 ok(!strcmp(path, TEST_PATH_UNQUOTE_SPACES[i].result), "%s (A): got %s expected %s\n",
1811 TEST_PATH_UNQUOTE_SPACES[i].path, path,
1812 TEST_PATH_UNQUOTE_SPACES[i].result);
1814 PathUnquoteSpacesW(pathW);
1815 ok(!lstrcmpW(pathW, resultW), "%s (W): strings differ\n",
1816 TEST_PATH_UNQUOTE_SPACES[i].path);
1817 FreeWideString(pathW);
1818 FreeWideString(resultW);
1819 HeapFree(GetProcessHeap(), 0, path);
1825 hShlwapi = LoadLibraryA("shlwapi.dll");
1826 if (!hShlwapi) return;
1830 test_UrlCanonicalize();
1833 test_UrlCreateFromPath();
1837 test_PathSearchAndQualify();
1838 test_PathCreateFromUrl();
1841 test_PathAddBackslash();
1842 test_PathMakePretty();
1843 test_PathMatchSpec();
1845 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
1846 * ordinal number in some native versions. Check this to prevent a crash.
1848 pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
1849 if (pPathIsValidCharA && pPathIsValidCharA != (void*)GetProcAddress(hShlwapi, "PathAppendA"))
1851 test_PathIsValidCharA();
1853 pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
1854 if (pPathIsValidCharW) test_PathIsValidCharW();
1857 pPathCombineW = (void*)GetProcAddress(hShlwapi, "PathCombineW");
1859 test_PathCombineW();
1861 test_PathCombineA();
1863 test_PathCanonicalizeA();
1864 test_PathFindExtensionA();
1865 test_PathBuildRootA();
1866 test_PathCommonPrefixA();
1867 test_PathUnquoteSpaces();