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)
483 ret = UrlEscapeA("/woningplan/woonkamer basis.swf", NULL, &size, URL_ESCAPE_SPACES_ONLY);
484 ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG);
486 for(i=0; i<sizeof(TEST_ESCAPE)/sizeof(TEST_ESCAPE[0]); i++) {
487 test_url_escape(TEST_ESCAPE[i].url, TEST_ESCAPE[i].flags,
488 TEST_ESCAPE[i].expectret, TEST_ESCAPE[i].expecturl);
492 static void test_UrlCanonicalize(void)
495 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
499 for(i=0; i<sizeof(TEST_CANONICALIZE)/sizeof(TEST_CANONICALIZE[0]); i++) {
500 test_url_canonicalize(TEST_CANONICALIZE[i].url, TEST_CANONICALIZE[i].flags,
501 TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expecturl);
504 /* move to TEST_CANONICALIZE when fixed */
505 dwSize = sizeof szReturnUrl;
506 ok(UrlCanonicalizeA("c:\\tests\\foo bar", szReturnUrl, &dwSize, 0) == S_OK, "UrlCanonicalizeA didn't return 0x%08x\n", S_OK);
508 ok(strcmp(szReturnUrl,"file:///c:/tests/foo%20bar")==0, "UrlCanonicalizeA got %s\n", szReturnUrl);
511 dwSize = sizeof szReturnUrl;
512 /*LimeWire online installer calls this*/
513 hr = UrlCanonicalizeA("/uri-res/N2R?urn:sha1:B3K", szReturnUrl, &dwSize,URL_DONT_ESCAPE_EXTRA_INFO | URL_WININET_COMPATIBILITY /*0x82000000*/);
514 ok(hr==S_OK,"UrlCanonicalizeA returned 0x%08x instead of S_OK\n", hr);
516 ok(strcmp(szReturnUrl,"/uri-res/N2R?urn:sha1:B3K")==0, "UrlCanonicalizeA got \"%s\" instead of \"/uri-res/N2R?urn:sha1:B3K\"\n", szReturnUrl);
520 static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
523 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
524 WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
525 LPWSTR wszUrl1 = GetWideString(szUrl1);
526 LPWSTR wszUrl2 = GetWideString(szUrl2);
527 LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
528 LPWSTR wszConvertedUrl;
531 DWORD dwExpectLen = lstrlen(szExpectUrl);
533 hr = UrlCombineA(szUrl1, szUrl2, NULL, NULL, dwFlags);
534 ok(hr == E_INVALIDARG, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_INVALIDARG);
537 hr = UrlCombineA(szUrl1, szUrl2, NULL, &dwSize, dwFlags);
538 ok(hr == E_POINTER, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr, E_POINTER);
539 ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
542 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
543 ok(hr == E_POINTER, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_POINTER);
544 ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
546 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
547 ok(hr == dwExpectReturn, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, dwExpectReturn);
548 ok(dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen);
550 ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected %s, but got %s\n", szExpectUrl, szReturnUrl);
554 hr = UrlCombineW(wszUrl1, wszUrl2, NULL, &dwSize, dwFlags);
555 ok(hr == E_POINTER, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr, E_POINTER);
556 ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
559 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
560 ok(hr == E_POINTER, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_POINTER);
561 ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
563 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
564 ok(hr == dwExpectReturn, "UrlCombineW returned 0x%08x, expected 0x%08x\n", hr, dwExpectReturn);
565 ok(dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen);
567 wszConvertedUrl = GetWideString(szReturnUrl);
568 ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCombine!\n");
569 FreeWideString(wszConvertedUrl);
572 FreeWideString(wszUrl1);
573 FreeWideString(wszUrl2);
574 FreeWideString(wszExpectUrl);
577 static void test_UrlCombine(void)
580 for(i=0; i<sizeof(TEST_COMBINE)/sizeof(TEST_COMBINE[0]); i++) {
581 test_url_combine(TEST_COMBINE[i].url1, TEST_COMBINE[i].url2, TEST_COMBINE[i].flags,
582 TEST_COMBINE[i].expectret, TEST_COMBINE[i].expecturl);
586 static void test_UrlCreateFromPath(void)
589 char ret_url[INTERNET_MAX_URL_LENGTH];
591 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
594 for(i = 0; i < sizeof(TEST_URLFROMPATH) / sizeof(TEST_URLFROMPATH[0]); i++) {
595 len = INTERNET_MAX_URL_LENGTH;
596 ret = UrlCreateFromPathA(TEST_URLFROMPATH[i].path, ret_url, &len, 0);
597 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08x from path %s\n", ret, TEST_URLFROMPATH[i].path);
598 ok(!lstrcmpi(ret_url, TEST_URLFROMPATH[i].url), "url %s from path %s\n", ret_url, TEST_URLFROMPATH[i].path);
599 ok(len == strlen(ret_url), "ret len %d from path %s\n", len, TEST_URLFROMPATH[i].path);
601 len = INTERNET_MAX_URL_LENGTH;
602 pathW = GetWideString(TEST_URLFROMPATH[i].path);
603 urlW = GetWideString(TEST_URLFROMPATH[i].url);
604 ret = UrlCreateFromPathW(pathW, ret_urlW, &len, 0);
605 WideCharToMultiByte(CP_ACP, 0, ret_urlW, -1, ret_url, sizeof(ret_url),0,0);
606 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08x from path L\"%s\", expected %08x\n",
607 ret, TEST_URLFROMPATH[i].path, TEST_URLFROMPATH[i].ret);
608 ok(!lstrcmpiW(ret_urlW, urlW), "got %s expected %s from path L\"%s\"\n", ret_url, TEST_URLFROMPATH[i].url, TEST_URLFROMPATH[i].path);
609 ok(len == lstrlenW(ret_urlW), "ret len %d from path L\"%s\"\n", len, TEST_URLFROMPATH[i].path);
610 FreeWideString(urlW);
611 FreeWideString(pathW);
615 static void test_UrlIs(void)
621 for(i = 0; i < sizeof(TEST_PATH_IS_URL) / sizeof(TEST_PATH_IS_URL[0]); i++) {
622 MultiByteToWideChar(CP_ACP, 0, TEST_PATH_IS_URL[i].path, -1, wurl, 80);
624 ret = UrlIsA( TEST_PATH_IS_URL[i].path, URLIS_URL );
625 ok( ret == TEST_PATH_IS_URL[i].expect,
626 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
627 TEST_PATH_IS_URL[i].expect );
629 ret = UrlIsW( wurl, URLIS_URL );
630 ok( ret == TEST_PATH_IS_URL[i].expect,
631 "returned %d from path (UrlIsW) %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
632 TEST_PATH_IS_URL[i].expect );
634 for(i = 0; i < sizeof(TEST_URLIS_ATTRIBS) / sizeof(TEST_URLIS_ATTRIBS[0]); i++) {
635 MultiByteToWideChar(CP_ACP, 0, TEST_URLIS_ATTRIBS[i].url, -1, wurl, 80);
637 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_OPAQUE);
638 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
639 "returned %d for URLIS_OPAQUE, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
640 TEST_URLIS_ATTRIBS[i].expectOpaque );
641 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_FILEURL);
642 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
643 "returned %d for URLIS_FILEURL, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
644 TEST_URLIS_ATTRIBS[i].expectFile );
646 ret = UrlIsW( wurl, URLIS_OPAQUE);
647 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
648 "returned %d for URLIS_OPAQUE (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
649 TEST_URLIS_ATTRIBS[i].expectOpaque );
650 ret = UrlIsW( wurl, URLIS_FILEURL);
651 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
652 "returned %d for URLIS_FILEURL (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
653 TEST_URLIS_ATTRIBS[i].expectFile );
657 static void test_UrlUnescape(void)
659 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
660 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
661 WCHAR *urlW, *expected_urlW;
664 static char inplace[] = "file:///C:/Program%20Files";
665 static WCHAR inplaceW[] = {'f','i','l','e',':','/','/','/','C',':','/',
666 'P','r','o','g','r','a','m','%','2','0','F','i','l','e','s',0};
668 for(i=0; i<sizeof(TEST_URL_UNESCAPE)/sizeof(TEST_URL_UNESCAPE[0]); i++) {
669 dwEscaped=INTERNET_MAX_URL_LENGTH;
670 ok(UrlUnescapeA(TEST_URL_UNESCAPE[i].url, szReturnUrl, &dwEscaped, 0) == S_OK, "UrlUnescapeA didn't return 0x%08x from \"%s\"\n", S_OK, TEST_URL_UNESCAPE[i].url);
671 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);
673 dwEscaped = INTERNET_MAX_URL_LENGTH;
674 urlW = GetWideString(TEST_URL_UNESCAPE[i].url);
675 expected_urlW = GetWideString(TEST_URL_UNESCAPE[i].expect);
676 ok(UrlUnescapeW(urlW, ret_urlW, &dwEscaped, 0) == S_OK, "UrlUnescapeW didn't return 0x%08x from \"%s\"\n", S_OK, TEST_URL_UNESCAPE[i].url);
677 WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
678 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);
679 FreeWideString(urlW);
680 FreeWideString(expected_urlW);
683 dwEscaped = sizeof(inplace);
684 ok(UrlUnescapeA(inplace, NULL, &dwEscaped, URL_UNESCAPE_INPLACE) == S_OK, "UrlUnescapeA failed unexpectedly\n");
686 dwEscaped = sizeof(inplaceW);
687 ok(UrlUnescapeW(inplaceW, NULL, &dwEscaped, URL_UNESCAPE_INPLACE) == S_OK, "UrlUnescapeW failed unexpectedly\n");
690 static void test_PathSearchAndQualify(void)
692 WCHAR path1[] = {'c',':','\\','f','o','o',0};
693 WCHAR expect1[] = {'c',':','\\','f','o','o',0};
694 WCHAR path2[] = {'c',':','f','o','o',0};
695 WCHAR c_drive[] = {'c',':',0};
696 WCHAR foo[] = {'f','o','o',0};
697 WCHAR path3[] = {'\\','f','o','o',0};
698 WCHAR winini[] = {'w','i','n','.','i','n','i',0};
700 WCHAR cur_dir[MAX_PATH];
701 WCHAR dot[] = {'.',0};
704 ok(PathSearchAndQualifyW(path1, out, MAX_PATH) != 0,
705 "PathSearchAndQualify rets 0\n");
706 ok(!lstrcmpiW(out, expect1), "strings don't match\n");
709 ok(PathSearchAndQualifyW(path2, out, MAX_PATH) != 0,
710 "PathSearchAndQualify rets 0\n");
711 GetFullPathNameW(c_drive, MAX_PATH, cur_dir, NULL);
712 PathAddBackslashW(cur_dir);
713 lstrcatW(cur_dir, foo);
714 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
717 ok(PathSearchAndQualifyW(foo, out, MAX_PATH) != 0,
718 "PathSearchAndQualify rets 0\n");
719 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
720 PathAddBackslashW(cur_dir);
721 lstrcatW(cur_dir, foo);
722 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
725 ok(PathSearchAndQualifyW(path3, out, MAX_PATH) != 0,
726 "PathSearchAndQualify rets 0\n");
727 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
728 lstrcpyW(cur_dir + 2, path3);
729 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
732 ok(PathSearchAndQualifyW(winini, out, MAX_PATH) != 0,
733 "PathSearchAndQualify rets 0\n");
734 if(!SearchPathW(NULL, winini, NULL, MAX_PATH, cur_dir, NULL))
735 GetFullPathNameW(winini, MAX_PATH, cur_dir, NULL);
736 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
740 static void test_PathCreateFromUrl(void)
743 char ret_path[INTERNET_MAX_URL_LENGTH];
745 WCHAR ret_pathW[INTERNET_MAX_URL_LENGTH];
747 static const char url[] = "http://www.winehq.org";
749 /* Check ret_path = NULL */
751 ret = PathCreateFromUrlA(url, NULL, &len, 0);
752 ok ( ret == E_INVALIDARG, "got 0x%08x expected E_INVALIDARG\n", ret);
754 for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
755 len = INTERNET_MAX_URL_LENGTH;
756 ret = PathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
757 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url %s\n", ret, TEST_PATHFROMURL[i].url);
758 if(TEST_PATHFROMURL[i].path) {
759 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);
760 ok(len == strlen(ret_path), "ret len %d from url %s\n", len, TEST_PATHFROMURL[i].url);
762 len = INTERNET_MAX_URL_LENGTH;
763 pathW = GetWideString(TEST_PATHFROMURL[i].path);
764 urlW = GetWideString(TEST_PATHFROMURL[i].url);
765 ret = PathCreateFromUrlW(urlW, ret_pathW, &len, 0);
766 WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),0,0);
767 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
768 if(TEST_PATHFROMURL[i].path) {
769 ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
770 ok(len == lstrlenW(ret_pathW), "ret len %d from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url);
772 FreeWideString(urlW);
773 FreeWideString(pathW);
778 static void test_PathIsUrl(void)
783 for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
784 ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
785 ok(ret == TEST_PATH_IS_URL[i].expect,
786 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
787 TEST_PATH_IS_URL[i].expect);
791 static const DWORD SHELL_charclass[] =
793 0x00000000, 0x00000000, 0x00000000, 0x00000000,
794 0x00000000, 0x00000000, 0x00000000, 0x00000000,
795 0x00000000, 0x00000000, 0x00000000, 0x00000000,
796 0x00000000, 0x00000000, 0x00000000, 0x00000000,
797 0x00000000, 0x00000000, 0x00000000, 0x00000000,
798 0x00000000, 0x00000000, 0x00000000, 0x00000000,
799 0x00000000, 0x00000000, 0x00000000, 0x00000000,
800 0x00000000, 0x00000000, 0x00000000, 0x00000000,
801 0x00000080, 0x00000100, 0x00000200, 0x00000100,
802 0x00000100, 0x00000100, 0x00000100, 0x00000100,
803 0x00000100, 0x00000100, 0x00000002, 0x00000100,
804 0x00000040, 0x00000100, 0x00000004, 0x00000000,
805 0x00000100, 0x00000100, 0x00000100, 0x00000100,
806 0x00000100, 0x00000100, 0x00000100, 0x00000100,
807 0x00000100, 0x00000100, 0x00000010, 0x00000020,
808 0x00000000, 0x00000100, 0x00000000, 0x00000001,
809 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
810 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
811 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
812 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
813 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
814 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
815 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
816 0x00000008, 0x00000100, 0x00000100, 0x00000100,
817 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
818 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
819 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
820 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
821 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
822 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
823 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
824 0x00000000, 0x00000100, 0x00000100
827 static void test_PathIsValidCharA(void)
832 ret = pPathIsValidCharA( 0x7f, 0 );
833 ok ( !ret, "PathIsValidCharA succeeded: 0x%08x\n", (DWORD)ret );
835 ret = pPathIsValidCharA( 0x7f, 1 );
836 ok ( !ret, "PathIsValidCharA succeeded: 0x%08x\n", (DWORD)ret );
838 for (c = 0; c < 0x7f; c++)
840 ret = pPathIsValidCharA( c, ~0U );
841 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
842 "PathIsValidCharA failed: 0x%02x got 0x%08x expected 0x%08x\n",
843 c, (DWORD)ret, SHELL_charclass[c] );
846 for (c = 0x7f; c <= 0xff; c++)
848 ret = pPathIsValidCharA( c, ~0U );
849 ok ( ret == 0x00000100,
850 "PathIsValidCharA failed: 0x%02x got 0x%08x expected 0x00000100\n",
855 static void test_PathIsValidCharW(void)
858 unsigned int c, err_count = 0;
860 ret = pPathIsValidCharW( 0x7f, 0 );
861 ok ( !ret, "PathIsValidCharW succeeded: 0x%08x\n", (DWORD)ret );
863 ret = pPathIsValidCharW( 0x7f, 1 );
864 ok ( !ret, "PathIsValidCharW succeeded: 0x%08x\n", (DWORD)ret );
866 for (c = 0; c < 0x7f; c++)
868 ret = pPathIsValidCharW( c, ~0U );
869 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
870 "PathIsValidCharW failed: 0x%02x got 0x%08x expected 0x%08x\n",
871 c, (DWORD)ret, SHELL_charclass[c] );
874 for (c = 0x007f; c <= 0xffff; c++)
876 ret = pPathIsValidCharW( c, ~0U );
877 ok ( ret == 0x00000100,
878 "PathIsValidCharW failed: 0x%02x got 0x%08x expected 0x00000100\n",
880 if (ret != 0x00000100)
882 if(++err_count > 100 ) {
883 trace("skipping rest of PathIsValidCharW tests "
884 "because of the current number of errors\n");
891 static void test_PathMakePretty(void)
895 ok (PathMakePrettyA(NULL) == FALSE, "PathMakePretty: NULL path succeeded\n");
897 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Empty path failed\n");
899 strcpy(buff, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
900 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Long UC name failed\n");
901 ok (strcmp(buff, "C:\\a long file name with \\spaces.txt") == 0,
902 "PathMakePretty: Long UC name not changed\n");
904 strcpy(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
905 ok (PathMakePrettyA(buff) == FALSE, "PathMakePretty: Long MC name succeeded\n");
906 ok (strcmp(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
907 "PathMakePretty: Failed but modified path\n");
909 strcpy(buff, "TEST");
910 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Short name failed\n");
911 ok (strcmp(buff, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff);
914 static void test_PathMatchSpec(void)
916 static const char file[] = "c:\\foo\\bar\\filename.ext";
917 static const char spec1[] = ".ext";
918 static const char spec2[] = "*.ext";
919 static const char spec3[] = "*.ext ";
920 static const char spec4[] = " *.ext";
921 static const char spec5[] = "* .ext";
922 static const char spec6[] = "*. ext";
923 static const char spec7[] = "* . ext";
924 static const char spec8[] = "*.e?t";
925 static const char spec9[] = "filename.ext";
926 static const char spec10[] = "*bar\\filename.ext";
927 static const char spec11[] = " foo; *.ext";
928 static const char spec12[] = "*.ext;*.bar";
929 static const char spec13[] = "*bar*";
931 ok (PathMatchSpecA(file, spec1) == FALSE, "PathMatchSpec: Spec1 failed\n");
932 ok (PathMatchSpecA(file, spec2) == TRUE, "PathMatchSpec: Spec2 failed\n");
933 ok (PathMatchSpecA(file, spec3) == FALSE, "PathMatchSpec: Spec3 failed\n");
934 ok (PathMatchSpecA(file, spec4) == TRUE, "PathMatchSpec: Spec4 failed\n");
935 todo_wine ok (PathMatchSpecA(file, spec5) == TRUE, "PathMatchSpec: Spec5 failed\n");
936 todo_wine ok (PathMatchSpecA(file, spec6) == TRUE, "PathMatchSpec: Spec6 failed\n");
937 ok (PathMatchSpecA(file, spec7) == FALSE, "PathMatchSpec: Spec7 failed\n");
938 ok (PathMatchSpecA(file, spec8) == TRUE, "PathMatchSpec: Spec8 failed\n");
939 ok (PathMatchSpecA(file, spec9) == FALSE, "PathMatchSpec: Spec9 failed\n");
940 ok (PathMatchSpecA(file, spec10) == TRUE, "PathMatchSpec: Spec10 failed\n");
941 ok (PathMatchSpecA(file, spec11) == TRUE, "PathMatchSpec: Spec11 failed\n");
942 ok (PathMatchSpecA(file, spec12) == TRUE, "PathMatchSpec: Spec12 failed\n");
943 ok (PathMatchSpecA(file, spec13) == TRUE, "PathMatchSpec: Spec13 failed\n");
946 static void test_PathCombineW(void)
948 LPWSTR wszString, wszString2;
950 wszString2 = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
953 wszString = pPathCombineW(NULL, NULL, NULL);
954 ok (wszString == NULL, "Expected a NULL return\n");
957 wszString = pPathCombineW(wszString2, NULL, NULL);
958 ok (wszString == NULL, "Expected a NULL return\n");
960 HeapFree(GetProcessHeap(), 0, wszString2);
963 #define LONG_LEN (MAX_PATH * 2)
964 #define HALF_LEN (MAX_PATH / 2 + 1)
966 static void test_PathCombineA(void)
970 char too_long[LONG_LEN];
971 char one[HALF_LEN], two[HALF_LEN];
974 SetLastError(0xdeadbeef);
975 str = PathCombineA(NULL, "C:\\", "one\\two\\three");
976 ok(str == NULL, "Expected NULL, got %p\n", str);
977 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
979 /* try NULL dest and NULL directory */
980 SetLastError(0xdeadbeef);
981 str = PathCombineA(NULL, NULL, "one\\two\\three");
982 ok(str == NULL, "Expected NULL, got %p\n", str);
983 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
986 SetLastError(0xdeadbeef);
987 str = PathCombineA(NULL, NULL, NULL);
988 ok(str == NULL, "Expected NULL, got %p\n", str);
989 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
991 /* try NULL file part */
992 SetLastError(0xdeadbeef);
993 lstrcpyA(dest, "control");
994 str = PathCombineA(dest, "C:\\", NULL);
995 ok(str == dest, "Expected str == dest, got %p\n", str);
996 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
997 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
999 /* try empty file part */
1000 SetLastError(0xdeadbeef);
1001 lstrcpyA(dest, "control");
1002 str = PathCombineA(dest, "C:\\", "");
1003 ok(str == dest, "Expected str == dest, got %p\n", str);
1004 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
1005 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1007 /* try empty directory and file part */
1008 SetLastError(0xdeadbeef);
1009 lstrcpyA(dest, "control");
1010 str = PathCombineA(dest, "", "");
1011 ok(str == dest, "Expected str == dest, got %p\n", str);
1012 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
1013 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1015 /* try NULL directory */
1016 SetLastError(0xdeadbeef);
1017 lstrcpyA(dest, "control");
1018 str = PathCombineA(dest, NULL, "one\\two\\three");
1019 ok(str == dest, "Expected str == dest, got %p\n", str);
1020 ok(!lstrcmp(str, "one\\two\\three"), "Expected one\\two\\three, got %s\n", str);
1021 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1023 /* try NULL directory and empty file part */
1024 SetLastError(0xdeadbeef);
1025 lstrcpyA(dest, "control");
1026 str = PathCombineA(dest, NULL, "");
1027 ok(str == dest, "Expected str == dest, got %p\n", str);
1028 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
1029 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1031 /* try NULL directory and file part */
1032 SetLastError(0xdeadbeef);
1033 lstrcpyA(dest, "control");
1034 str = PathCombineA(dest, NULL, NULL);
1035 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1038 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1040 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1042 /* try directory without backslash */
1043 SetLastError(0xdeadbeef);
1044 lstrcpyA(dest, "control");
1045 str = PathCombineA(dest, "C:", "one\\two\\three");
1046 ok(str == dest, "Expected str == dest, got %p\n", str);
1047 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1048 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1050 /* try directory with backslash */
1051 SetLastError(0xdeadbeef);
1052 lstrcpyA(dest, "control");
1053 str = PathCombineA(dest, "C:\\", "one\\two\\three");
1054 ok(str == dest, "Expected str == dest, got %p\n", str);
1055 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1056 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1058 /* try directory with backslash and file with prepended backslash */
1059 SetLastError(0xdeadbeef);
1060 lstrcpyA(dest, "control");
1061 str = PathCombineA(dest, "C:\\", "\\one\\two\\three");
1062 ok(str == dest, "Expected str == dest, got %p\n", str);
1063 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1064 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1066 /* try previous test, with backslash appended as well */
1067 SetLastError(0xdeadbeef);
1068 lstrcpyA(dest, "control");
1069 str = PathCombineA(dest, "C:\\", "\\one\\two\\three\\");
1070 ok(str == dest, "Expected str == dest, got %p\n", str);
1071 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
1072 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1074 /* try a relative directory */
1075 SetLastError(0xdeadbeef);
1076 lstrcpyA(dest, "control");
1077 str = PathCombineA(dest, "relative\\dir", "\\one\\two\\three\\");
1078 ok(str == dest, "Expected str == dest, got %p\n", str);
1079 ok(!lstrcmp(str, "one\\two\\three\\"), "Expected one\\two\\three\\, got %s\n", str);
1080 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1082 /* try forward slashes */
1083 SetLastError(0xdeadbeef);
1084 lstrcpyA(dest, "control");
1085 str = PathCombineA(dest, "C:\\", "one/two/three\\");
1086 ok(str == dest, "Expected str == dest, got %p\n", str);
1087 ok(!lstrcmp(str, "C:\\one/two/three\\"), "Expected one/two/three\\, got %s\n", str);
1088 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1090 /* try a really weird directory */
1091 SetLastError(0xdeadbeef);
1092 lstrcpyA(dest, "control");
1093 str = PathCombineA(dest, "C:\\/\\/", "\\one\\two\\three\\");
1094 ok(str == dest, "Expected str == dest, got %p\n", str);
1095 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
1096 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1099 SetLastError(0xdeadbeef);
1100 lstrcpyA(dest, "control");
1101 str = PathCombineA(dest, "C:\\", "one\\..\\two\\.\\three");
1102 ok(str == dest, "Expected str == dest, got %p\n", str);
1103 ok(!lstrcmp(str, "C:\\two\\three"), "Expected C:\\two\\three, got %s\n", str);
1104 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1106 /* try .. as file */
1107 /* try forward slashes */
1108 SetLastError(0xdeadbeef);
1109 lstrcpyA(dest, "control");
1110 str = PathCombineA(dest, "C:\\", "..");
1111 ok(str == dest, "Expected str == dest, got %p\n", str);
1112 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
1113 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1115 memset(too_long, 'a', LONG_LEN);
1116 too_long[LONG_LEN - 1] = '\0';
1118 /* try a file longer than MAX_PATH */
1119 SetLastError(0xdeadbeef);
1120 lstrcpyA(dest, "control");
1121 str = PathCombineA(dest, "C:\\", too_long);
1124 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1125 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1126 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1129 /* try a directory longer than MAX_PATH */
1130 SetLastError(0xdeadbeef);
1131 lstrcpyA(dest, "control");
1132 str = PathCombineA(dest, too_long, "one\\two\\three");
1135 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1136 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1137 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1140 memset(one, 'b', HALF_LEN);
1141 memset(two, 'c', HALF_LEN);
1142 one[HALF_LEN - 1] = '\0';
1143 two[HALF_LEN - 1] = '\0';
1145 /* destination string is longer than MAX_PATH, but not the constituent parts */
1146 SetLastError(0xdeadbeef);
1147 lstrcpyA(dest, "control");
1148 str = PathCombineA(dest, one, two);
1151 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1152 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1154 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1157 static void test_PathAddBackslash(void)
1160 char path[MAX_PATH];
1161 char too_long[LONG_LEN];
1163 /* try a NULL path */
1164 SetLastError(0xdeadbeef);
1165 str = PathAddBackslashA(NULL);
1166 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1167 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1169 /* try an empty path */
1171 SetLastError(0xdeadbeef);
1172 str = PathAddBackslashA(path);
1173 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1174 ok(lstrlenA(path) == 0, "Expected empty string, got %i\n", lstrlenA(path));
1175 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1177 /* try a relative path */
1178 lstrcpyA(path, "one\\two");
1179 SetLastError(0xdeadbeef);
1180 str = PathAddBackslashA(path);
1181 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1182 ok(!lstrcmp(path, "one\\two\\"), "Expected one\\two\\, got %s\n", path);
1183 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1186 lstrcpyA(path, "one\\..\\two");
1187 SetLastError(0xdeadbeef);
1188 str = PathAddBackslashA(path);
1189 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1190 ok(!lstrcmp(path, "one\\..\\two\\"), "Expected one\\..\\two\\, got %s\n", path);
1191 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1193 /* try just a space */
1194 lstrcpyA(path, " ");
1195 SetLastError(0xdeadbeef);
1196 str = PathAddBackslashA(path);
1197 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1198 ok(!lstrcmp(path, " \\"), "Expected \\, got %s\n", path);
1199 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1201 /* path already has backslash */
1202 lstrcpyA(path, "C:\\one\\");
1203 SetLastError(0xdeadbeef);
1204 str = PathAddBackslashA(path);
1205 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1206 ok(!lstrcmp(path, "C:\\one\\"), "Expected C:\\one\\, got %s\n", path);
1207 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1209 memset(too_long, 'a', LONG_LEN);
1210 too_long[LONG_LEN - 1] = '\0';
1212 /* path is longer than MAX_PATH */
1213 SetLastError(0xdeadbeef);
1214 str = PathAddBackslashA(too_long);
1215 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1216 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1219 static void test_PathAppendA(void)
1221 char path[MAX_PATH];
1222 char too_long[LONG_LEN];
1223 char one[HALF_LEN], two[HALF_LEN];
1226 lstrcpy(path, "C:\\one");
1228 /* try NULL pszMore */
1229 SetLastError(0xdeadbeef);
1230 res = PathAppendA(path, NULL);
1231 ok(!res, "Expected failure\n");
1232 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1233 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
1235 /* try empty pszMore */
1236 SetLastError(0xdeadbeef);
1237 res = PathAppendA(path, "");
1238 ok(res, "Expected success\n");
1239 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1240 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
1242 /* try NULL pszPath */
1243 SetLastError(0xdeadbeef);
1244 res = PathAppendA(NULL, "two\\three");
1245 ok(!res, "Expected failure\n");
1246 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1248 /* try empty pszPath */
1250 SetLastError(0xdeadbeef);
1251 res = PathAppendA(path, "two\\three");
1252 ok(res, "Expected success\n");
1253 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1254 ok(!lstrcmp(path, "two\\three"), "Expected \\two\\three, got %s\n", path);
1256 /* try empty pszPath and empty pszMore */
1258 SetLastError(0xdeadbeef);
1259 res = PathAppendA(path, "");
1260 ok(res, "Expected success\n");
1261 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1262 ok(!lstrcmp(path, "\\"), "Expected \\, got %s\n", path);
1264 /* try legit params */
1265 lstrcpy(path, "C:\\one");
1266 SetLastError(0xdeadbeef);
1267 res = PathAppendA(path, "two\\three");
1268 ok(res, "Expected success\n");
1269 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1270 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1272 /* try pszPath with backslash after it */
1273 lstrcpy(path, "C:\\one\\");
1274 SetLastError(0xdeadbeef);
1275 res = PathAppendA(path, "two\\three");
1276 ok(res, "Expected success\n");
1277 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1278 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1280 /* try pszMore with backslash before it */
1281 lstrcpy(path, "C:\\one");
1282 SetLastError(0xdeadbeef);
1283 res = PathAppendA(path, "\\two\\three");
1284 ok(res, "Expected success\n");
1285 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1286 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1288 /* try pszMore with backslash after it */
1289 lstrcpy(path, "C:\\one");
1290 SetLastError(0xdeadbeef);
1291 res = PathAppendA(path, "two\\three\\");
1292 ok(res, "Expected success\n");
1293 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1294 ok(!lstrcmp(path, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", path);
1296 /* try spaces in pszPath */
1297 lstrcpy(path, "C: \\ one ");
1298 SetLastError(0xdeadbeef);
1299 res = PathAppendA(path, "two\\three");
1300 ok(res, "Expected success\n");
1301 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1302 ok(!lstrcmp(path, "C: \\ one \\two\\three"), "Expected C: \\ one \\two\\three, got %s\n", path);
1304 /* try spaces in pszMore */
1305 lstrcpy(path, "C:\\one");
1306 SetLastError(0xdeadbeef);
1307 res = PathAppendA(path, " two \\ three ");
1308 ok(res, "Expected success\n");
1309 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1310 ok(!lstrcmp(path, "C:\\one\\ two \\ three "), "Expected 'C:\\one\\ two \\ three ', got %s\n", path);
1312 /* pszPath is too long */
1313 memset(too_long, 'a', LONG_LEN);
1314 too_long[LONG_LEN - 1] = '\0';
1315 SetLastError(0xdeadbeef);
1316 res = PathAppendA(too_long, "two\\three");
1319 ok(!res, "Expected failure\n");
1320 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1321 ok(lstrlen(too_long) == 0, "Expected length of too_long to be zero, got %i\n", lstrlen(too_long));
1324 /* pszMore is too long */
1325 lstrcpy(path, "C:\\one");
1326 memset(too_long, 'a', LONG_LEN);
1327 too_long[LONG_LEN - 1] = '\0';
1328 SetLastError(0xdeadbeef);
1329 res = PathAppendA(path, too_long);
1332 ok(!res, "Expected failure\n");
1333 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1334 ok(lstrlen(path) == 0, "Expected length of path to be zero, got %i\n", lstrlen(path));
1337 /* both params combined are too long */
1338 memset(one, 'a', HALF_LEN);
1339 one[HALF_LEN - 1] = '\0';
1340 memset(two, 'b', HALF_LEN);
1341 two[HALF_LEN - 1] = '\0';
1342 SetLastError(0xdeadbeef);
1343 res = PathAppendA(one, two);
1346 ok(!res, "Expected failure\n");
1347 ok(lstrlen(one) == 0, "Expected length of one to be zero, got %i\n", lstrlen(one));
1349 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1352 static void test_PathCanonicalizeA(void)
1354 char dest[MAX_PATH];
1355 char too_long[LONG_LEN];
1358 /* try a NULL source */
1359 lstrcpy(dest, "test");
1360 SetLastError(0xdeadbeef);
1361 res = PathCanonicalizeA(dest, NULL);
1362 ok(!res, "Expected failure\n");
1363 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1364 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1367 ok(!lstrcmp(dest, "test"), "Expected test, got %s\n", dest);
1370 /* try an empty source */
1371 lstrcpy(dest, "test");
1372 SetLastError(0xdeadbeef);
1373 res = PathCanonicalizeA(dest, "");
1374 ok(res, "Expected success\n");
1375 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1376 ok(!lstrcmp(dest, "\\"), "Expected \\, got %s\n", dest);
1378 /* try a NULL dest */
1379 SetLastError(0xdeadbeef);
1380 res = PathCanonicalizeA(NULL, "C:\\");
1381 ok(!res, "Expected failure\n");
1382 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1383 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1385 /* try empty dest */
1387 SetLastError(0xdeadbeef);
1388 res = PathCanonicalizeA(dest, "C:\\");
1389 ok(res, "Expected success\n");
1390 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1391 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
1393 /* try non-empty dest */
1394 lstrcpy(dest, "test");
1395 SetLastError(0xdeadbeef);
1396 res = PathCanonicalizeA(dest, "C:\\");
1397 ok(res, "Expected success\n");
1398 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1399 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
1401 /* try a space for source */
1402 lstrcpy(dest, "test");
1403 SetLastError(0xdeadbeef);
1404 res = PathCanonicalizeA(dest, " ");
1405 ok(res, "Expected success\n");
1406 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1407 ok(!lstrcmp(dest, " "), "Expected ' ', got %s\n", dest);
1409 /* try a relative path */
1410 lstrcpy(dest, "test");
1411 SetLastError(0xdeadbeef);
1412 res = PathCanonicalizeA(dest, "one\\two");
1413 ok(res, "Expected success\n");
1414 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1415 ok(!lstrcmp(dest, "one\\two"), "Expected one\\two, got %s\n", dest);
1417 /* try current dir and previous dir */
1418 lstrcpy(dest, "test");
1419 SetLastError(0xdeadbeef);
1420 res = PathCanonicalizeA(dest, "C:\\one\\.\\..\\two\\three\\..");
1421 ok(res, "Expected success\n");
1422 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1423 ok(!lstrcmp(dest, "C:\\two"), "Expected C:\\two, got %s\n", dest);
1425 /* try simple forward slashes */
1426 lstrcpy(dest, "test");
1427 SetLastError(0xdeadbeef);
1428 res = PathCanonicalizeA(dest, "C:\\one/two/three\\four/five\\six");
1429 ok(res, "Expected success\n");
1430 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1431 ok(!lstrcmp(dest, "C:\\one/two/three\\four/five\\six"),
1432 "Expected C:\\one/two/three\\four/five\\six, got %s\n", dest);
1434 /* try simple forward slashes with same dir */
1435 lstrcpy(dest, "test");
1436 SetLastError(0xdeadbeef);
1437 res = PathCanonicalizeA(dest, "C:\\one/.\\two");
1438 ok(res, "Expected success\n");
1439 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1440 ok(!lstrcmp(dest, "C:\\one/.\\two"), "Expected C:\\one/.\\two, got %s\n", dest);
1442 /* try simple forward slashes with change dir */
1443 lstrcpy(dest, "test");
1444 SetLastError(0xdeadbeef);
1445 res = PathCanonicalizeA(dest, "C:\\one/.\\two\\..");
1446 ok(res, "Expected success\n");
1447 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1448 ok(!lstrcmp(dest, "C:\\one/."), "Expected C:\\one/., got %s\n", dest);
1450 /* try forward slashes with change dirs
1451 * NOTE: if there is a forward slash in between two backslashes,
1452 * everything in between the two backslashes is considered on dir
1454 lstrcpy(dest, "test");
1455 SetLastError(0xdeadbeef);
1456 res = PathCanonicalizeA(dest, "C:\\one/.\\..\\two/three\\..\\four/.five");
1457 ok(res, "Expected success\n");
1458 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1459 ok(!lstrcmp(dest, "C:\\four/.five"), "Expected C:\\four/.five, got %s\n", dest);
1461 /* try src is too long */
1462 memset(too_long, 'a', LONG_LEN);
1463 too_long[LONG_LEN - 1] = '\0';
1464 lstrcpy(dest, "test");
1465 SetLastError(0xdeadbeef);
1466 res = PathCanonicalizeA(dest, too_long);
1469 ok(!res, "Expected failure\n");
1470 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1472 ok(lstrlen(too_long) == LONG_LEN - 1, "Expected length LONG_LEN - 1, got %i\n", lstrlen(too_long));
1475 static void test_PathFindExtensionA(void)
1478 char path[MAX_PATH];
1479 char too_long[LONG_LEN];
1481 /* try a NULL path */
1482 SetLastError(0xdeadbeef);
1483 ext = PathFindExtensionA(NULL);
1484 ok(ext == NULL, "Expected NULL, got %p\n", ext);
1485 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1487 /* try an empty path */
1489 SetLastError(0xdeadbeef);
1490 ext = PathFindExtensionA(path);
1491 ok(ext == path, "Expected ext == path, got %p\n", ext);
1492 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1493 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1495 /* try a path without an extension */
1496 lstrcpy(path, "file");
1497 SetLastError(0xdeadbeef);
1498 ext = PathFindExtensionA(path);
1499 ok(ext == path + lstrlen(path), "Expected ext == path, got %p\n", ext);
1500 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1501 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1503 /* try a path with an extension */
1504 lstrcpy(path, "file.txt");
1505 SetLastError(0xdeadbeef);
1506 ext = PathFindExtensionA(path);
1507 ok(ext == path + lstrlen("file"),
1508 "Expected ext == path + lstrlen(\"file\"), got %p\n", ext);
1509 ok(!lstrcmp(ext, ".txt"), "Expected .txt, got %s\n", ext);
1510 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1512 /* try a path with two extensions */
1513 lstrcpy(path, "file.txt.doc");
1514 SetLastError(0xdeadbeef);
1515 ext = PathFindExtensionA(path);
1516 ok(ext == path + lstrlen("file.txt"),
1517 "Expected ext == path + lstrlen(\"file.txt\"), got %p\n", ext);
1518 ok(!lstrcmp(ext, ".doc"), "Expected .txt, got %s\n", ext);
1519 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1521 /* try a path longer than MAX_PATH without an extension*/
1522 memset(too_long, 'a', LONG_LEN);
1523 too_long[LONG_LEN - 1] = '\0';
1524 SetLastError(0xdeadbeef);
1525 ext = PathFindExtensionA(too_long);
1526 ok(ext == too_long + LONG_LEN - 1, "Expected ext == too_long + LONG_LEN - 1, got %p\n", ext);
1527 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1529 /* try a path longer than MAX_PATH with an extension*/
1530 memset(too_long, 'a', LONG_LEN);
1531 too_long[LONG_LEN - 1] = '\0';
1532 lstrcpy(too_long + 300, ".abcde");
1533 too_long[lstrlen(too_long)] = 'a';
1534 SetLastError(0xdeadbeef);
1535 ext = PathFindExtensionA(too_long);
1536 ok(ext == too_long + 300, "Expected ext == too_long + 300, got %p\n", ext);
1537 ok(lstrlen(ext) == LONG_LEN - 301, "Expected LONG_LEN - 301, got %i\n", lstrlen(ext));
1538 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1541 static void test_PathBuildRootA(void)
1545 char root_expected[26][4];
1549 /* set up the expected paths */
1550 for (drive = 'A'; drive <= 'Z'; drive++)
1551 sprintf(root_expected[drive - 'A'], "%c:\\", drive);
1553 /* test the expected values */
1554 for (j = 0; j < 26; j++)
1556 SetLastError(0xdeadbeef);
1557 lstrcpy(path, "aaaaaaaaa");
1558 root = PathBuildRootA(path, j);
1559 ok(root == path, "Expected root == path, got %p\n", root);
1560 ok(!lstrcmp(root, root_expected[j]), "Expected %s, got %s\n", root_expected[j], root);
1561 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1564 /* test a negative drive number */
1565 SetLastError(0xdeadbeef);
1566 lstrcpy(path, "aaaaaaaaa");
1567 root = PathBuildRootA(path, -1);
1568 ok(root == path, "Expected root == path, got %p\n", root);
1569 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1570 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1572 /* test a drive number greater than 25 */
1573 SetLastError(0xdeadbeef);
1574 lstrcpy(path, "aaaaaaaaa");
1575 root = PathBuildRootA(path, 26);
1576 ok(root == path, "Expected root == path, got %p\n", root);
1577 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1578 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1580 /* length of path is less than 4 */
1581 SetLastError(0xdeadbeef);
1582 lstrcpy(path, "aa");
1583 root = PathBuildRootA(path, 0);
1584 ok(root == path, "Expected root == path, got %p\n", root);
1585 ok(!lstrcmp(path, "A:\\"), "Expected A:\\, got %s\n", path);
1586 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1589 SetLastError(0xdeadbeef);
1590 root = PathBuildRootA(NULL, 0);
1591 ok(root == NULL, "Expected root == NULL, got %p\n", root);
1592 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1595 static void test_PathCommonPrefixA(void)
1597 char path1[MAX_PATH], path2[MAX_PATH];
1601 /* test NULL path1 */
1602 SetLastError(0xdeadbeef);
1603 lstrcpy(path2, "C:\\");
1604 lstrcpy(out, "aaa");
1605 count = PathCommonPrefixA(NULL, path2, out);
1606 ok(count == 0, "Expected 0, got %i\n", count);
1609 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1611 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1612 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1614 /* test NULL path2 */
1615 SetLastError(0xdeadbeef);
1616 lstrcpy(path1, "C:\\");
1617 lstrcpy(out, "aaa");
1618 count = PathCommonPrefixA(path1, NULL, out);
1619 ok(count == 0, "Expected 0, got %i\n", count);
1622 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1624 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1625 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1627 /* test empty path1 */
1628 SetLastError(0xdeadbeef);
1630 lstrcpy(path2, "C:\\");
1631 lstrcpy(out, "aaa");
1632 count = PathCommonPrefixA(path1, path2, out);
1633 ok(count == 0, "Expected 0, got %i\n", count);
1634 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1635 ok(lstrlen(path1) == 0, "Expected 0 length path1, got %i\n", lstrlen(path1));
1636 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1637 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1639 /* test empty path1 */
1640 SetLastError(0xdeadbeef);
1642 lstrcpy(path1, "C:\\");
1643 lstrcpy(out, "aaa");
1644 count = PathCommonPrefixA(path1, path2, out);
1645 ok(count == 0, "Expected 0, got %i\n", count);
1646 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1647 ok(lstrlen(path2) == 0, "Expected 0 length path2, got %i\n", lstrlen(path2));
1648 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1649 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1651 /* paths are legit, out is NULL */
1652 SetLastError(0xdeadbeef);
1653 lstrcpy(path1, "C:\\");
1654 lstrcpy(path2, "C:\\");
1655 count = PathCommonPrefixA(path1, path2, NULL);
1656 ok(count == 3, "Expected 3, got %i\n", count);
1657 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1658 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1659 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1661 /* all parameters legit */
1662 SetLastError(0xdeadbeef);
1663 lstrcpy(path1, "C:\\");
1664 lstrcpy(path2, "C:\\");
1665 lstrcpy(out, "aaa");
1666 count = PathCommonPrefixA(path1, path2, out);
1667 ok(count == 3, "Expected 3, got %i\n", count);
1668 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1669 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1670 ok(!lstrcmp(out, "C:\\"), "Expected C:\\, got %s\n", out);
1671 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1673 /* path1 and path2 not the same, but common prefix */
1674 SetLastError(0xdeadbeef);
1675 lstrcpy(path1, "C:\\one\\two");
1676 lstrcpy(path2, "C:\\one\\three");
1677 lstrcpy(out, "aaa");
1678 count = PathCommonPrefixA(path1, path2, out);
1679 ok(count == 6, "Expected 6, got %i\n", count);
1680 ok(!lstrcmp(path1, "C:\\one\\two"), "Expected C:\\one\\two, got %s\n", path1);
1681 ok(!lstrcmp(path2, "C:\\one\\three"), "Expected C:\\one\\three, got %s\n", path2);
1682 ok(!lstrcmp(out, "C:\\one"), "Expected C:\\one, got %s\n", out);
1683 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1686 SetLastError(0xdeadbeef);
1687 lstrcpy(path1, "one\\.two");
1688 lstrcpy(path2, "one\\.three");
1689 lstrcpy(out, "aaa");
1690 count = PathCommonPrefixA(path1, path2, out);
1691 ok(count == 3, "Expected 3, got %i\n", count);
1692 ok(!lstrcmp(path1, "one\\.two"), "Expected one\\.two, got %s\n", path1);
1693 ok(!lstrcmp(path2, "one\\.three"), "Expected one\\.three, got %s\n", path2);
1694 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1695 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1698 SetLastError(0xdeadbeef);
1699 lstrcpy(path1, "one\\..two");
1700 lstrcpy(path2, "one\\..three");
1701 lstrcpy(out, "aaa");
1702 count = PathCommonPrefixA(path1, path2, out);
1703 ok(count == 3, "Expected 3, got %i\n", count);
1704 ok(!lstrcmp(path1, "one\\..two"), "Expected one\\..two, got %s\n", path1);
1705 ok(!lstrcmp(path2, "one\\..three"), "Expected one\\..three, got %s\n", path2);
1706 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1707 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1709 /* try ... prefix */
1710 SetLastError(0xdeadbeef);
1711 lstrcpy(path1, "one\\...two");
1712 lstrcpy(path2, "one\\...three");
1713 lstrcpy(out, "aaa");
1714 count = PathCommonPrefixA(path1, path2, out);
1715 ok(count == 3, "Expected 3, got %i\n", count);
1716 ok(!lstrcmp(path1, "one\\...two"), "Expected one\\...two, got %s\n", path1);
1717 ok(!lstrcmp(path2, "one\\...three"), "Expected one\\...three, got %s\n", path2);
1718 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1719 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1722 SetLastError(0xdeadbeef);
1723 lstrcpy(path1, "one\\.\\two");
1724 lstrcpy(path2, "one\\.\\three");
1725 lstrcpy(out, "aaa");
1726 count = PathCommonPrefixA(path1, path2, out);
1727 ok(count == 5, "Expected 5, got %i\n", count);
1728 ok(!lstrcmp(path1, "one\\.\\two"), "Expected one\\.\\two, got %s\n", path1);
1729 ok(!lstrcmp(path2, "one\\.\\three"), "Expected one\\.\\three, got %s\n", path2);
1730 ok(!lstrcmp(out, "one\\."), "Expected one\\., got %s\n", out);
1731 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1733 /* try ..\ prefix */
1734 SetLastError(0xdeadbeef);
1735 lstrcpy(path1, "one\\..\\two");
1736 lstrcpy(path2, "one\\..\\three");
1737 lstrcpy(out, "aaa");
1738 count = PathCommonPrefixA(path1, path2, out);
1739 ok(count == 6, "Expected 6, got %i\n", count);
1740 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1741 ok(!lstrcmp(path2, "one\\..\\three"), "Expected one\\..\\three, got %s\n", path2);
1742 ok(!lstrcmp(out, "one\\.."), "Expected one\\.., got %s\n", out);
1743 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1745 /* try ...\\ prefix */
1746 SetLastError(0xdeadbeef);
1747 lstrcpy(path1, "one\\...\\two");
1748 lstrcpy(path2, "one\\...\\three");
1749 lstrcpy(out, "aaa");
1750 count = PathCommonPrefixA(path1, path2, out);
1751 ok(count == 7, "Expected 7, got %i\n", count);
1752 ok(!lstrcmp(path1, "one\\...\\two"), "Expected one\\...\\two, got %s\n", path1);
1753 ok(!lstrcmp(path2, "one\\...\\three"), "Expected one\\...\\three, got %s\n", path2);
1754 ok(!lstrcmp(out, "one\\..."), "Expected one\\..., got %s\n", out);
1755 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1757 /* try prefix that is not an msdn labeled prefix type */
1758 SetLastError(0xdeadbeef);
1759 lstrcpy(path1, "same");
1760 lstrcpy(path2, "same");
1761 lstrcpy(out, "aaa");
1762 count = PathCommonPrefixA(path1, path2, out);
1763 ok(count == 4, "Expected 4, got %i\n", count);
1764 ok(!lstrcmp(path1, "same"), "Expected same, got %s\n", path1);
1765 ok(!lstrcmp(path2, "same"), "Expected same, got %s\n", path2);
1766 ok(!lstrcmp(out, "same"), "Expected same, got %s\n", out);
1767 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1769 /* try . after directory */
1770 SetLastError(0xdeadbeef);
1771 lstrcpy(path1, "one\\mid.\\two");
1772 lstrcpy(path2, "one\\mid.\\three");
1773 lstrcpy(out, "aaa");
1774 count = PathCommonPrefixA(path1, path2, out);
1775 ok(count == 8, "Expected 8, got %i\n", count);
1776 ok(!lstrcmp(path1, "one\\mid.\\two"), "Expected one\\mid.\\two, got %s\n", path1);
1777 ok(!lstrcmp(path2, "one\\mid.\\three"), "Expected one\\mid.\\three, got %s\n", path2);
1778 ok(!lstrcmp(out, "one\\mid."), "Expected one\\mid., got %s\n", out);
1779 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1781 /* try . in the middle of a directory */
1782 SetLastError(0xdeadbeef);
1783 lstrcpy(path1, "one\\mid.end\\two");
1784 lstrcpy(path2, "one\\mid.end\\three");
1785 lstrcpy(out, "aaa");
1786 count = PathCommonPrefixA(path1, path2, out);
1787 ok(count == 11, "Expected 11, got %i\n", count);
1788 ok(!lstrcmp(path1, "one\\mid.end\\two"), "Expected one\\mid.end\\two, got %s\n", path1);
1789 ok(!lstrcmp(path2, "one\\mid.end\\three"), "Expected one\\mid.end\\three, got %s\n", path2);
1790 ok(!lstrcmp(out, "one\\mid.end"), "Expected one\\mid.end, got %s\n", out);
1791 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1793 /* try comparing a .. with the expanded path */
1794 SetLastError(0xdeadbeef);
1795 lstrcpy(path1, "one\\..\\two");
1796 lstrcpy(path2, "two");
1797 lstrcpy(out, "aaa");
1798 count = PathCommonPrefixA(path1, path2, out);
1799 ok(count == 0, "Expected 0, got %i\n", count);
1800 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1801 ok(!lstrcmp(path2, "two"), "Expected two, got %s\n", path2);
1802 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1803 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1806 static void test_PathUnquoteSpaces(void)
1809 for(i = 0; i < sizeof(TEST_PATH_UNQUOTE_SPACES) / sizeof(TEST_PATH_UNQUOTE_SPACES[0]); i++)
1811 char *path = strdupA(TEST_PATH_UNQUOTE_SPACES[i].path);
1812 WCHAR *pathW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].path);
1813 WCHAR *resultW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].result);
1815 PathUnquoteSpacesA(path);
1816 ok(!strcmp(path, TEST_PATH_UNQUOTE_SPACES[i].result), "%s (A): got %s expected %s\n",
1817 TEST_PATH_UNQUOTE_SPACES[i].path, path,
1818 TEST_PATH_UNQUOTE_SPACES[i].result);
1820 PathUnquoteSpacesW(pathW);
1821 ok(!lstrcmpW(pathW, resultW), "%s (W): strings differ\n",
1822 TEST_PATH_UNQUOTE_SPACES[i].path);
1823 FreeWideString(pathW);
1824 FreeWideString(resultW);
1825 HeapFree(GetProcessHeap(), 0, path);
1831 hShlwapi = LoadLibraryA("shlwapi.dll");
1832 if (!hShlwapi) return;
1836 test_UrlCanonicalize();
1839 test_UrlCreateFromPath();
1843 test_PathSearchAndQualify();
1844 test_PathCreateFromUrl();
1847 test_PathAddBackslash();
1848 test_PathMakePretty();
1849 test_PathMatchSpec();
1851 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
1852 * ordinal number in some native versions. Check this to prevent a crash.
1854 pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
1855 if (pPathIsValidCharA && pPathIsValidCharA != (void*)GetProcAddress(hShlwapi, "PathAppendA"))
1857 test_PathIsValidCharA();
1859 pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
1860 if (pPathIsValidCharW) test_PathIsValidCharW();
1863 pPathCombineW = (void*)GetProcAddress(hShlwapi, "PathCombineW");
1865 test_PathCombineW();
1867 test_PathCombineA();
1869 test_PathCanonicalizeA();
1870 test_PathFindExtensionA();
1871 test_PathBuildRootA();
1872 test_PathCommonPrefixA();
1873 test_PathUnquoteSpaces();