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%08lx 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 %08lX\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 %08lX\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%08lx 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%08lx 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 %08lx\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%08lx\n", dwExpectReturn);
462 ok(strcmp(szReturnUrl,szExpectUrl)==0, "UrlCanonicalizeA dwFlags 0x%08lx 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%08lx\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%08lx\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%08lx 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%08lx, expected 0x%08lx\n", hr, E_INVALIDARG);
531 hr = UrlCombineA(szUrl1, szUrl2, NULL, &dwSize, dwFlags);
532 ok(hr == E_POINTER, "Checking length of string, return was 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
533 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
536 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
537 ok(hr == E_POINTER, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
538 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
540 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
541 ok(hr == dwExpectReturn, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, dwExpectReturn);
542 ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\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%08lx, expected 0x%08lx\n", hr, E_POINTER);
550 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
553 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
554 ok(hr == E_POINTER, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
555 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
557 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
558 ok(hr == dwExpectReturn, "UrlCombineW returned 0x%08lx, expected 0x%08lx\n", hr, dwExpectReturn);
559 ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\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 %08lx 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 %ld 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 %08lx from path L\"%s\", expected %08lx\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 %ld 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%08lx 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%08lx 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];
742 for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
743 len = INTERNET_MAX_URL_LENGTH;
744 ret = PathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
745 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url %s\n", ret, TEST_PATHFROMURL[i].url);
746 if(TEST_PATHFROMURL[i].path) {
747 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);
748 ok(len == strlen(ret_path), "ret len %ld from url %s\n", len, TEST_PATHFROMURL[i].url);
750 len = INTERNET_MAX_URL_LENGTH;
751 pathW = GetWideString(TEST_PATHFROMURL[i].path);
752 urlW = GetWideString(TEST_PATHFROMURL[i].url);
753 ret = PathCreateFromUrlW(urlW, ret_pathW, &len, 0);
754 WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),0,0);
755 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
756 if(TEST_PATHFROMURL[i].path) {
757 ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
758 ok(len == lstrlenW(ret_pathW), "ret len %ld from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url);
760 FreeWideString(urlW);
761 FreeWideString(pathW);
766 static void test_PathIsUrl(void)
771 for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
772 ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
773 ok(ret == TEST_PATH_IS_URL[i].expect,
774 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
775 TEST_PATH_IS_URL[i].expect);
779 static const DWORD SHELL_charclass[] =
781 0x00000000, 0x00000000, 0x00000000, 0x00000000,
782 0x00000000, 0x00000000, 0x00000000, 0x00000000,
783 0x00000000, 0x00000000, 0x00000000, 0x00000000,
784 0x00000000, 0x00000000, 0x00000000, 0x00000000,
785 0x00000000, 0x00000000, 0x00000000, 0x00000000,
786 0x00000000, 0x00000000, 0x00000000, 0x00000000,
787 0x00000000, 0x00000000, 0x00000000, 0x00000000,
788 0x00000000, 0x00000000, 0x00000000, 0x00000000,
789 0x00000080, 0x00000100, 0x00000200, 0x00000100,
790 0x00000100, 0x00000100, 0x00000100, 0x00000100,
791 0x00000100, 0x00000100, 0x00000002, 0x00000100,
792 0x00000040, 0x00000100, 0x00000004, 0x00000000,
793 0x00000100, 0x00000100, 0x00000100, 0x00000100,
794 0x00000100, 0x00000100, 0x00000100, 0x00000100,
795 0x00000100, 0x00000100, 0x00000010, 0x00000020,
796 0x00000000, 0x00000100, 0x00000000, 0x00000001,
797 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
798 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
799 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
800 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
801 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
802 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
803 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
804 0x00000008, 0x00000100, 0x00000100, 0x00000100,
805 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
806 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
807 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
808 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
809 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
810 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
811 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
812 0x00000000, 0x00000100, 0x00000100
815 static void test_PathIsValidCharA(void)
820 ret = pPathIsValidCharA( 0x7f, 0 );
821 ok ( !ret, "PathIsValidCharA succeeded: 0x%08lx\n", (DWORD)ret );
823 ret = pPathIsValidCharA( 0x7f, 1 );
824 ok ( !ret, "PathIsValidCharA succeeded: 0x%08lx\n", (DWORD)ret );
826 for (c = 0; c < 0x7f; c++)
828 ret = pPathIsValidCharA( c, ~0U );
829 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
830 "PathIsValidCharA failed: 0x%02x got 0x%08lx expected 0x%08lx\n",
831 c, (DWORD)ret, SHELL_charclass[c] );
834 for (c = 0x7f; c <= 0xff; c++)
836 ret = pPathIsValidCharA( c, ~0U );
837 ok ( ret == 0x00000100,
838 "PathIsValidCharA failed: 0x%02x got 0x%08lx expected 0x00000100\n",
843 static void test_PathIsValidCharW(void)
846 unsigned int c, err_count = 0;
848 ret = pPathIsValidCharW( 0x7f, 0 );
849 ok ( !ret, "PathIsValidCharW succeeded: 0x%08lx\n", (DWORD)ret );
851 ret = pPathIsValidCharW( 0x7f, 1 );
852 ok ( !ret, "PathIsValidCharW succeeded: 0x%08lx\n", (DWORD)ret );
854 for (c = 0; c < 0x7f; c++)
856 ret = pPathIsValidCharW( c, ~0U );
857 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
858 "PathIsValidCharW failed: 0x%02x got 0x%08lx expected 0x%08lx\n",
859 c, (DWORD)ret, SHELL_charclass[c] );
862 for (c = 0x007f; c <= 0xffff; c++)
864 ret = pPathIsValidCharW( c, ~0U );
865 ok ( ret == 0x00000100,
866 "PathIsValidCharW failed: 0x%02x got 0x%08lx expected 0x00000100\n",
868 if (ret != 0x00000100)
870 if(++err_count > 100 ) {
871 trace("skipping rest of PathIsValidCharW tests "
872 "because of the current number of errors\n");
879 static void test_PathMakePretty(void)
883 ok (PathMakePrettyA(NULL) == FALSE, "PathMakePretty: NULL path succeeded\n");
885 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Empty path failed\n");
887 strcpy(buff, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
888 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Long UC name failed\n");
889 ok (strcmp(buff, "C:\\a long file name with \\spaces.txt") == 0,
890 "PathMakePretty: Long UC name not changed\n");
892 strcpy(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
893 ok (PathMakePrettyA(buff) == FALSE, "PathMakePretty: Long MC name succeeded\n");
894 ok (strcmp(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
895 "PathMakePretty: Failed but modified path\n");
897 strcpy(buff, "TEST");
898 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Short name failed\n");
899 ok (strcmp(buff, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff);
902 static void test_PathMatchSpec(void)
904 static const char file[] = "c:\\foo\\bar\\filename.ext";
905 static const char spec1[] = ".ext";
906 static const char spec2[] = "*.ext";
907 static const char spec3[] = "*.ext ";
908 static const char spec4[] = " *.ext";
909 static const char spec5[] = "* .ext";
910 static const char spec6[] = "*. ext";
911 static const char spec7[] = "* . ext";
912 static const char spec8[] = "*.e?t";
913 static const char spec9[] = "filename.ext";
914 static const char spec10[] = "*bar\\filename.ext";
915 static const char spec11[] = " foo; *.ext";
916 static const char spec12[] = "*.ext;*.bar";
917 static const char spec13[] = "*bar*";
919 ok (PathMatchSpecA(file, spec1) == FALSE, "PathMatchSpec: Spec1 failed\n");
920 ok (PathMatchSpecA(file, spec2) == TRUE, "PathMatchSpec: Spec2 failed\n");
921 ok (PathMatchSpecA(file, spec3) == FALSE, "PathMatchSpec: Spec3 failed\n");
922 ok (PathMatchSpecA(file, spec4) == TRUE, "PathMatchSpec: Spec4 failed\n");
923 todo_wine ok (PathMatchSpecA(file, spec5) == TRUE, "PathMatchSpec: Spec5 failed\n");
924 todo_wine ok (PathMatchSpecA(file, spec6) == TRUE, "PathMatchSpec: Spec6 failed\n");
925 ok (PathMatchSpecA(file, spec7) == FALSE, "PathMatchSpec: Spec7 failed\n");
926 ok (PathMatchSpecA(file, spec8) == TRUE, "PathMatchSpec: Spec8 failed\n");
927 ok (PathMatchSpecA(file, spec9) == FALSE, "PathMatchSpec: Spec9 failed\n");
928 ok (PathMatchSpecA(file, spec10) == TRUE, "PathMatchSpec: Spec10 failed\n");
929 ok (PathMatchSpecA(file, spec11) == TRUE, "PathMatchSpec: Spec11 failed\n");
930 ok (PathMatchSpecA(file, spec12) == TRUE, "PathMatchSpec: Spec12 failed\n");
931 ok (PathMatchSpecA(file, spec13) == TRUE, "PathMatchSpec: Spec13 failed\n");
934 static void test_PathCombineW(void)
936 LPWSTR wszString, wszString2;
938 wszString2 = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
941 wszString = pPathCombineW(NULL, NULL, NULL);
942 ok (wszString == NULL, "Expected a NULL return\n");
945 wszString = pPathCombineW(wszString2, NULL, NULL);
946 ok (wszString == NULL, "Expected a NULL return\n");
948 HeapFree(GetProcessHeap(), 0, wszString2);
951 #define LONG_LEN (MAX_PATH * 2)
952 #define HALF_LEN (MAX_PATH / 2 + 1)
954 static void test_PathCombineA(void)
958 char too_long[LONG_LEN];
959 char one[HALF_LEN], two[HALF_LEN];
962 SetLastError(0xdeadbeef);
963 str = PathCombineA(NULL, "C:\\", "one\\two\\three");
964 ok(str == NULL, "Expected NULL, got %p\n", str);
965 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
967 /* try NULL dest and NULL directory */
968 SetLastError(0xdeadbeef);
969 str = PathCombineA(NULL, NULL, "one\\two\\three");
970 ok(str == NULL, "Expected NULL, got %p\n", str);
971 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
974 SetLastError(0xdeadbeef);
975 str = PathCombineA(NULL, NULL, NULL);
976 ok(str == NULL, "Expected NULL, got %p\n", str);
977 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
979 /* try NULL file part */
980 SetLastError(0xdeadbeef);
981 lstrcpyA(dest, "control");
982 str = PathCombineA(dest, "C:\\", NULL);
983 ok(str == dest, "Expected str == dest, got %p\n", str);
984 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
985 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
987 /* try empty file part */
988 SetLastError(0xdeadbeef);
989 lstrcpyA(dest, "control");
990 str = PathCombineA(dest, "C:\\", "");
991 ok(str == dest, "Expected str == dest, got %p\n", str);
992 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
993 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
995 /* try empty directory and file part */
996 SetLastError(0xdeadbeef);
997 lstrcpyA(dest, "control");
998 str = PathCombineA(dest, "", "");
999 ok(str == dest, "Expected str == dest, got %p\n", str);
1000 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
1001 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1003 /* try NULL directory */
1004 SetLastError(0xdeadbeef);
1005 lstrcpyA(dest, "control");
1006 str = PathCombineA(dest, NULL, "one\\two\\three");
1007 ok(str == dest, "Expected str == dest, got %p\n", str);
1008 ok(!lstrcmp(str, "one\\two\\three"), "Expected one\\two\\three, got %s\n", str);
1009 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1011 /* try NULL directory and empty file part */
1012 SetLastError(0xdeadbeef);
1013 lstrcpyA(dest, "control");
1014 str = PathCombineA(dest, NULL, "");
1015 ok(str == dest, "Expected str == dest, got %p\n", str);
1016 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
1017 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1019 /* try NULL directory and file part */
1020 SetLastError(0xdeadbeef);
1021 lstrcpyA(dest, "control");
1022 str = PathCombineA(dest, NULL, NULL);
1023 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1026 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1028 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1030 /* try directory without backslash */
1031 SetLastError(0xdeadbeef);
1032 lstrcpyA(dest, "control");
1033 str = PathCombineA(dest, "C:", "one\\two\\three");
1034 ok(str == dest, "Expected str == dest, got %p\n", str);
1035 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1036 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1038 /* try directory with backslash */
1039 SetLastError(0xdeadbeef);
1040 lstrcpyA(dest, "control");
1041 str = PathCombineA(dest, "C:\\", "one\\two\\three");
1042 ok(str == dest, "Expected str == dest, got %p\n", str);
1043 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1044 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1046 /* try directory with backslash and file with prepended backslash */
1047 SetLastError(0xdeadbeef);
1048 lstrcpyA(dest, "control");
1049 str = PathCombineA(dest, "C:\\", "\\one\\two\\three");
1050 ok(str == dest, "Expected str == dest, got %p\n", str);
1051 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1052 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1054 /* try previous test, with backslash appended as well */
1055 SetLastError(0xdeadbeef);
1056 lstrcpyA(dest, "control");
1057 str = PathCombineA(dest, "C:\\", "\\one\\two\\three\\");
1058 ok(str == dest, "Expected str == dest, got %p\n", str);
1059 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
1060 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1062 /* try a relative directory */
1063 SetLastError(0xdeadbeef);
1064 lstrcpyA(dest, "control");
1065 str = PathCombineA(dest, "relative\\dir", "\\one\\two\\three\\");
1066 ok(str == dest, "Expected str == dest, got %p\n", str);
1067 ok(!lstrcmp(str, "one\\two\\three\\"), "Expected one\\two\\three\\, got %s\n", str);
1068 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1070 /* try forward slashes */
1071 SetLastError(0xdeadbeef);
1072 lstrcpyA(dest, "control");
1073 str = PathCombineA(dest, "C:\\", "one/two/three\\");
1074 ok(str == dest, "Expected str == dest, got %p\n", str);
1075 ok(!lstrcmp(str, "C:\\one/two/three\\"), "Expected one/two/three\\, got %s\n", str);
1076 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1078 /* try a really weird directory */
1079 SetLastError(0xdeadbeef);
1080 lstrcpyA(dest, "control");
1081 str = PathCombineA(dest, "C:\\/\\/", "\\one\\two\\three\\");
1082 ok(str == dest, "Expected str == dest, got %p\n", str);
1083 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
1084 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1087 SetLastError(0xdeadbeef);
1088 lstrcpyA(dest, "control");
1089 str = PathCombineA(dest, "C:\\", "one\\..\\two\\.\\three");
1090 ok(str == dest, "Expected str == dest, got %p\n", str);
1091 ok(!lstrcmp(str, "C:\\two\\three"), "Expected C:\\two\\three, got %s\n", str);
1092 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1094 /* try .. as file */
1095 /* try forward slashes */
1096 SetLastError(0xdeadbeef);
1097 lstrcpyA(dest, "control");
1098 str = PathCombineA(dest, "C:\\", "..");
1099 ok(str == dest, "Expected str == dest, got %p\n", str);
1100 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
1101 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1103 memset(too_long, 'a', LONG_LEN);
1104 too_long[LONG_LEN - 1] = '\0';
1106 /* try a file longer than MAX_PATH */
1107 SetLastError(0xdeadbeef);
1108 lstrcpyA(dest, "control");
1109 str = PathCombineA(dest, "C:\\", too_long);
1112 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1113 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1114 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1117 /* try a directory longer than MAX_PATH */
1118 SetLastError(0xdeadbeef);
1119 lstrcpyA(dest, "control");
1120 str = PathCombineA(dest, too_long, "one\\two\\three");
1123 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1124 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1125 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1128 memset(one, 'b', HALF_LEN);
1129 memset(two, 'c', HALF_LEN);
1130 one[HALF_LEN - 1] = '\0';
1131 two[HALF_LEN - 1] = '\0';
1133 /* destination string is longer than MAX_PATH, but not the constituent parts */
1134 SetLastError(0xdeadbeef);
1135 lstrcpyA(dest, "control");
1136 str = PathCombineA(dest, one, two);
1139 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1140 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1142 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1145 static void test_PathAddBackslash(void)
1148 char path[MAX_PATH];
1149 char too_long[LONG_LEN];
1151 /* try a NULL path */
1152 SetLastError(0xdeadbeef);
1153 str = PathAddBackslashA(NULL);
1154 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1155 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1157 /* try an empty path */
1159 SetLastError(0xdeadbeef);
1160 str = PathAddBackslashA(path);
1161 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1162 ok(lstrlenA(path) == 0, "Expected empty string, got %i\n", lstrlenA(path));
1163 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1165 /* try a relative path */
1166 lstrcpyA(path, "one\\two");
1167 SetLastError(0xdeadbeef);
1168 str = PathAddBackslashA(path);
1169 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1170 ok(!lstrcmp(path, "one\\two\\"), "Expected one\\two\\, got %s\n", path);
1171 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1174 lstrcpyA(path, "one\\..\\two");
1175 SetLastError(0xdeadbeef);
1176 str = PathAddBackslashA(path);
1177 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1178 ok(!lstrcmp(path, "one\\..\\two\\"), "Expected one\\..\\two\\, got %s\n", path);
1179 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1181 /* try just a space */
1182 lstrcpyA(path, " ");
1183 SetLastError(0xdeadbeef);
1184 str = PathAddBackslashA(path);
1185 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1186 ok(!lstrcmp(path, " \\"), "Expected \\, got %s\n", path);
1187 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1189 /* path already has backslash */
1190 lstrcpyA(path, "C:\\one\\");
1191 SetLastError(0xdeadbeef);
1192 str = PathAddBackslashA(path);
1193 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1194 ok(!lstrcmp(path, "C:\\one\\"), "Expected C:\\one\\, got %s\n", path);
1195 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1197 memset(too_long, 'a', LONG_LEN);
1198 too_long[LONG_LEN - 1] = '\0';
1200 /* path is longer than MAX_PATH */
1201 SetLastError(0xdeadbeef);
1202 str = PathAddBackslashA(too_long);
1203 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1204 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1207 static void test_PathAppendA(void)
1209 char path[MAX_PATH];
1210 char too_long[LONG_LEN];
1211 char one[HALF_LEN], two[HALF_LEN];
1214 lstrcpy(path, "C:\\one");
1216 /* try NULL pszMore */
1217 SetLastError(0xdeadbeef);
1218 res = PathAppendA(path, NULL);
1219 ok(!res, "Expected failure\n");
1220 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1221 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
1223 /* try empty pszMore */
1224 SetLastError(0xdeadbeef);
1225 res = PathAppendA(path, "");
1226 ok(res, "Expected success\n");
1227 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1228 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
1230 /* try NULL pszPath */
1231 SetLastError(0xdeadbeef);
1232 res = PathAppendA(NULL, "two\\three");
1233 ok(!res, "Expected failure\n");
1234 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1236 /* try empty pszPath */
1238 SetLastError(0xdeadbeef);
1239 res = PathAppendA(path, "two\\three");
1240 ok(res, "Expected success\n");
1241 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1242 ok(!lstrcmp(path, "two\\three"), "Expected \\two\\three, got %s\n", path);
1244 /* try empty pszPath and empty pszMore */
1246 SetLastError(0xdeadbeef);
1247 res = PathAppendA(path, "");
1248 ok(res, "Expected success\n");
1249 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1250 ok(!lstrcmp(path, "\\"), "Expected \\, got %s\n", path);
1252 /* try legit params */
1253 lstrcpy(path, "C:\\one");
1254 SetLastError(0xdeadbeef);
1255 res = PathAppendA(path, "two\\three");
1256 ok(res, "Expected success\n");
1257 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1258 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1260 /* try pszPath with backslash after it */
1261 lstrcpy(path, "C:\\one\\");
1262 SetLastError(0xdeadbeef);
1263 res = PathAppendA(path, "two\\three");
1264 ok(res, "Expected success\n");
1265 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1266 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1268 /* try pszMore with backslash before it */
1269 lstrcpy(path, "C:\\one");
1270 SetLastError(0xdeadbeef);
1271 res = PathAppendA(path, "\\two\\three");
1272 ok(res, "Expected success\n");
1273 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1274 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1276 /* try pszMore with backslash after it */
1277 lstrcpy(path, "C:\\one");
1278 SetLastError(0xdeadbeef);
1279 res = PathAppendA(path, "two\\three\\");
1280 ok(res, "Expected success\n");
1281 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1282 ok(!lstrcmp(path, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", path);
1284 /* try spaces in pszPath */
1285 lstrcpy(path, "C: \\ one ");
1286 SetLastError(0xdeadbeef);
1287 res = PathAppendA(path, "two\\three");
1288 ok(res, "Expected success\n");
1289 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1290 ok(!lstrcmp(path, "C: \\ one \\two\\three"), "Expected C: \\ one \\two\\three, got %s\n", path);
1292 /* try spaces in pszMore */
1293 lstrcpy(path, "C:\\one");
1294 SetLastError(0xdeadbeef);
1295 res = PathAppendA(path, " two \\ three ");
1296 ok(res, "Expected success\n");
1297 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1298 ok(!lstrcmp(path, "C:\\one\\ two \\ three "), "Expected 'C:\\one\\ two \\ three ', got %s\n", path);
1300 /* pszPath is too long */
1301 memset(too_long, 'a', LONG_LEN);
1302 too_long[LONG_LEN - 1] = '\0';
1303 SetLastError(0xdeadbeef);
1304 res = PathAppendA(too_long, "two\\three");
1307 ok(!res, "Expected failure\n");
1308 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1309 ok(lstrlen(too_long) == 0, "Expected length of too_long to be zero, got %i\n", lstrlen(too_long));
1312 /* pszMore is too long */
1313 lstrcpy(path, "C:\\one");
1314 memset(too_long, 'a', LONG_LEN);
1315 too_long[LONG_LEN - 1] = '\0';
1316 SetLastError(0xdeadbeef);
1317 res = PathAppendA(path, too_long);
1320 ok(!res, "Expected failure\n");
1321 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1322 ok(lstrlen(path) == 0, "Expected length of path to be zero, got %i\n", lstrlen(path));
1325 /* both params combined are too long */
1326 memset(one, 'a', HALF_LEN);
1327 one[HALF_LEN - 1] = '\0';
1328 memset(two, 'b', HALF_LEN);
1329 two[HALF_LEN - 1] = '\0';
1330 SetLastError(0xdeadbeef);
1331 res = PathAppendA(one, two);
1334 ok(!res, "Expected failure\n");
1335 ok(lstrlen(one) == 0, "Expected length of one to be zero, got %i\n", lstrlen(one));
1337 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1340 static void test_PathCanonicalizeA(void)
1342 char dest[MAX_PATH];
1343 char too_long[LONG_LEN];
1346 /* try a NULL source */
1347 lstrcpy(dest, "test");
1348 SetLastError(0xdeadbeef);
1349 res = PathCanonicalizeA(dest, NULL);
1350 ok(!res, "Expected failure\n");
1351 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1352 "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
1355 ok(!lstrcmp(dest, "test"), "Expected test, got %s\n", dest);
1358 /* try an empty source */
1359 lstrcpy(dest, "test");
1360 SetLastError(0xdeadbeef);
1361 res = PathCanonicalizeA(dest, "");
1362 ok(res, "Expected success\n");
1363 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1364 ok(!lstrcmp(dest, "\\"), "Expected \\, got %s\n", dest);
1366 /* try a NULL dest */
1367 SetLastError(0xdeadbeef);
1368 res = PathCanonicalizeA(NULL, "C:\\");
1369 ok(!res, "Expected failure\n");
1370 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1371 "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
1373 /* try empty dest */
1375 SetLastError(0xdeadbeef);
1376 res = PathCanonicalizeA(dest, "C:\\");
1377 ok(res, "Expected success\n");
1378 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1379 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
1381 /* try non-empty dest */
1382 lstrcpy(dest, "test");
1383 SetLastError(0xdeadbeef);
1384 res = PathCanonicalizeA(dest, "C:\\");
1385 ok(res, "Expected success\n");
1386 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1387 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
1389 /* try a space for source */
1390 lstrcpy(dest, "test");
1391 SetLastError(0xdeadbeef);
1392 res = PathCanonicalizeA(dest, " ");
1393 ok(res, "Expected success\n");
1394 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1395 ok(!lstrcmp(dest, " "), "Expected ' ', got %s\n", dest);
1397 /* try a relative path */
1398 lstrcpy(dest, "test");
1399 SetLastError(0xdeadbeef);
1400 res = PathCanonicalizeA(dest, "one\\two");
1401 ok(res, "Expected success\n");
1402 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1403 ok(!lstrcmp(dest, "one\\two"), "Expected one\\two, got %s\n", dest);
1405 /* try current dir and previous dir */
1406 lstrcpy(dest, "test");
1407 SetLastError(0xdeadbeef);
1408 res = PathCanonicalizeA(dest, "C:\\one\\.\\..\\two\\three\\..");
1409 ok(res, "Expected success\n");
1410 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1411 ok(!lstrcmp(dest, "C:\\two"), "Expected C:\\two, got %s\n", dest);
1413 /* try simple forward slashes */
1414 lstrcpy(dest, "test");
1415 SetLastError(0xdeadbeef);
1416 res = PathCanonicalizeA(dest, "C:\\one/two/three\\four/five\\six");
1417 ok(res, "Expected success\n");
1418 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1419 ok(!lstrcmp(dest, "C:\\one/two/three\\four/five\\six"),
1420 "Expected C:\\one/two/three\\four/five\\six, got %s\n", dest);
1422 /* try simple forward slashes with same dir */
1423 lstrcpy(dest, "test");
1424 SetLastError(0xdeadbeef);
1425 res = PathCanonicalizeA(dest, "C:\\one/.\\two");
1426 ok(res, "Expected success\n");
1427 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1428 ok(!lstrcmp(dest, "C:\\one/.\\two"), "Expected C:\\one/.\\two, got %s\n", dest);
1430 /* try simple forward slashes with change dir */
1431 lstrcpy(dest, "test");
1432 SetLastError(0xdeadbeef);
1433 res = PathCanonicalizeA(dest, "C:\\one/.\\two\\..");
1434 ok(res, "Expected success\n");
1435 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1436 ok(!lstrcmp(dest, "C:\\one/."), "Expected C:\\one/., got %s\n", dest);
1438 /* try forward slashes with change dirs
1439 * NOTE: if there is a forward slash in between two backslashes,
1440 * everything in between the two backslashes is considered on dir
1442 lstrcpy(dest, "test");
1443 SetLastError(0xdeadbeef);
1444 res = PathCanonicalizeA(dest, "C:\\one/.\\..\\two/three\\..\\four/.five");
1445 ok(res, "Expected success\n");
1446 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1447 ok(!lstrcmp(dest, "C:\\four/.five"), "Expected C:\\four/.five, got %s\n", dest);
1449 /* try src is too long */
1450 memset(too_long, 'a', LONG_LEN);
1451 too_long[LONG_LEN - 1] = '\0';
1452 lstrcpy(dest, "test");
1453 SetLastError(0xdeadbeef);
1454 res = PathCanonicalizeA(dest, too_long);
1457 ok(!res, "Expected failure\n");
1458 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1460 ok(lstrlen(too_long) == LONG_LEN - 1, "Expected length LONG_LEN - 1, got %i\n", lstrlen(too_long));
1463 static void test_PathFindExtensionA(void)
1466 char path[MAX_PATH];
1467 char too_long[LONG_LEN];
1469 /* try a NULL path */
1470 SetLastError(0xdeadbeef);
1471 ext = PathFindExtensionA(NULL);
1472 ok(ext == NULL, "Expected NULL, got %p\n", ext);
1473 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1475 /* try an empty path */
1477 SetLastError(0xdeadbeef);
1478 ext = PathFindExtensionA(path);
1479 ok(ext == path, "Expected ext == path, got %p\n", ext);
1480 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1481 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1483 /* try a path without an extension */
1484 lstrcpy(path, "file");
1485 SetLastError(0xdeadbeef);
1486 ext = PathFindExtensionA(path);
1487 ok(ext == path + lstrlen(path), "Expected ext == path, got %p\n", ext);
1488 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1489 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1491 /* try a path with an extension */
1492 lstrcpy(path, "file.txt");
1493 SetLastError(0xdeadbeef);
1494 ext = PathFindExtensionA(path);
1495 ok(ext == path + lstrlen("file"),
1496 "Expected ext == path + lstrlen(\"file\"), got %p\n", ext);
1497 ok(!lstrcmp(ext, ".txt"), "Expected .txt, got %s\n", ext);
1498 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1500 /* try a path with two extensions */
1501 lstrcpy(path, "file.txt.doc");
1502 SetLastError(0xdeadbeef);
1503 ext = PathFindExtensionA(path);
1504 ok(ext == path + lstrlen("file.txt"),
1505 "Expected ext == path + lstrlen(\"file.txt\"), got %p\n", ext);
1506 ok(!lstrcmp(ext, ".doc"), "Expected .txt, got %s\n", ext);
1507 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1509 /* try a path longer than MAX_PATH without an extension*/
1510 memset(too_long, 'a', LONG_LEN);
1511 too_long[LONG_LEN - 1] = '\0';
1512 SetLastError(0xdeadbeef);
1513 ext = PathFindExtensionA(too_long);
1514 ok(ext == too_long + LONG_LEN - 1, "Expected ext == too_long + LONG_LEN - 1, got %p\n", ext);
1515 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1517 /* try a path longer than MAX_PATH with an extension*/
1518 memset(too_long, 'a', LONG_LEN);
1519 too_long[LONG_LEN - 1] = '\0';
1520 lstrcpy(too_long + 300, ".abcde");
1521 too_long[lstrlen(too_long)] = 'a';
1522 SetLastError(0xdeadbeef);
1523 ext = PathFindExtensionA(too_long);
1524 ok(ext == too_long + 300, "Expected ext == too_long + 300, got %p\n", ext);
1525 ok(lstrlen(ext) == LONG_LEN - 301, "Expected LONG_LEN - 301, got %i\n", lstrlen(ext));
1526 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1529 static void test_PathBuildRootA(void)
1533 char root_expected[26][4];
1537 /* set up the expected paths */
1538 for (drive = 'A'; drive <= 'Z'; drive++)
1539 sprintf(root_expected[drive - 'A'], "%c:\\", drive);
1541 /* test the expected values */
1542 for (j = 0; j < 26; j++)
1544 SetLastError(0xdeadbeef);
1545 lstrcpy(path, "aaaaaaaaa");
1546 root = PathBuildRootA(path, j);
1547 ok(root == path, "Expected root == path, got %p\n", root);
1548 ok(!lstrcmp(root, root_expected[j]), "Expected %s, got %s\n", root_expected[j], root);
1549 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1552 /* test a negative drive number */
1553 SetLastError(0xdeadbeef);
1554 lstrcpy(path, "aaaaaaaaa");
1555 root = PathBuildRootA(path, -1);
1556 ok(root == path, "Expected root == path, got %p\n", root);
1557 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1558 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1560 /* test a drive number greater than 25 */
1561 SetLastError(0xdeadbeef);
1562 lstrcpy(path, "aaaaaaaaa");
1563 root = PathBuildRootA(path, 26);
1564 ok(root == path, "Expected root == path, got %p\n", root);
1565 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1566 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1568 /* length of path is less than 4 */
1569 SetLastError(0xdeadbeef);
1570 lstrcpy(path, "aa");
1571 root = PathBuildRootA(path, 0);
1572 ok(root == path, "Expected root == path, got %p\n", root);
1573 ok(!lstrcmp(path, "A:\\"), "Expected A:\\, got %s\n", path);
1574 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1577 SetLastError(0xdeadbeef);
1578 root = PathBuildRootA(NULL, 0);
1579 ok(root == NULL, "Expected root == NULL, got %p\n", root);
1580 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1583 static void test_PathCommonPrefixA(void)
1585 char path1[MAX_PATH], path2[MAX_PATH];
1589 /* test NULL path1 */
1590 SetLastError(0xdeadbeef);
1591 lstrcpy(path2, "C:\\");
1592 lstrcpy(out, "aaa");
1593 count = PathCommonPrefixA(NULL, path2, out);
1594 ok(count == 0, "Expected 0, got %i\n", count);
1597 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1599 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1600 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1602 /* test NULL path2 */
1603 SetLastError(0xdeadbeef);
1604 lstrcpy(path1, "C:\\");
1605 lstrcpy(out, "aaa");
1606 count = PathCommonPrefixA(path1, NULL, out);
1607 ok(count == 0, "Expected 0, got %i\n", count);
1610 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1612 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1613 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1615 /* test empty path1 */
1616 SetLastError(0xdeadbeef);
1618 lstrcpy(path2, "C:\\");
1619 lstrcpy(out, "aaa");
1620 count = PathCommonPrefixA(path1, path2, out);
1621 ok(count == 0, "Expected 0, got %i\n", count);
1622 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1623 ok(lstrlen(path1) == 0, "Expected 0 length path1, got %i\n", lstrlen(path1));
1624 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1625 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1627 /* test empty path1 */
1628 SetLastError(0xdeadbeef);
1630 lstrcpy(path1, "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(path2) == 0, "Expected 0 length path2, got %i\n", lstrlen(path2));
1636 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1637 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1639 /* paths are legit, out is NULL */
1640 SetLastError(0xdeadbeef);
1641 lstrcpy(path1, "C:\\");
1642 lstrcpy(path2, "C:\\");
1643 count = PathCommonPrefixA(path1, path2, NULL);
1644 ok(count == 3, "Expected 3, got %i\n", count);
1645 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1646 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1647 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1649 /* all parameters legit */
1650 SetLastError(0xdeadbeef);
1651 lstrcpy(path1, "C:\\");
1652 lstrcpy(path2, "C:\\");
1653 lstrcpy(out, "aaa");
1654 count = PathCommonPrefixA(path1, path2, out);
1655 ok(count == 3, "Expected 3, got %i\n", count);
1656 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1657 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1658 ok(!lstrcmp(out, "C:\\"), "Expected C:\\, got %s\n", out);
1659 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1661 /* path1 and path2 not the same, but common prefix */
1662 SetLastError(0xdeadbeef);
1663 lstrcpy(path1, "C:\\one\\two");
1664 lstrcpy(path2, "C:\\one\\three");
1665 lstrcpy(out, "aaa");
1666 count = PathCommonPrefixA(path1, path2, out);
1667 ok(count == 6, "Expected 6, got %i\n", count);
1668 ok(!lstrcmp(path1, "C:\\one\\two"), "Expected C:\\one\\two, got %s\n", path1);
1669 ok(!lstrcmp(path2, "C:\\one\\three"), "Expected C:\\one\\three, got %s\n", path2);
1670 ok(!lstrcmp(out, "C:\\one"), "Expected C:\\one, got %s\n", out);
1671 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1674 SetLastError(0xdeadbeef);
1675 lstrcpy(path1, "one\\.two");
1676 lstrcpy(path2, "one\\.three");
1677 lstrcpy(out, "aaa");
1678 count = PathCommonPrefixA(path1, path2, out);
1679 ok(count == 3, "Expected 3, got %i\n", count);
1680 ok(!lstrcmp(path1, "one\\.two"), "Expected one\\.two, got %s\n", path1);
1681 ok(!lstrcmp(path2, "one\\.three"), "Expected one\\.three, got %s\n", path2);
1682 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1683 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\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 %ld\n", GetLastError());
1697 /* try ... prefix */
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 %ld\n", GetLastError());
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 == 5, "Expected 5, 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 %ld\n", GetLastError());
1721 /* try ..\ prefix */
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 == 6, "Expected 6, 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 %ld\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 == 7, "Expected 7, 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 %ld\n", GetLastError());
1745 /* try prefix that is not an msdn labeled prefix type */
1746 SetLastError(0xdeadbeef);
1747 lstrcpy(path1, "same");
1748 lstrcpy(path2, "same");
1749 lstrcpy(out, "aaa");
1750 count = PathCommonPrefixA(path1, path2, out);
1751 ok(count == 4, "Expected 4, got %i\n", count);
1752 ok(!lstrcmp(path1, "same"), "Expected same, got %s\n", path1);
1753 ok(!lstrcmp(path2, "same"), "Expected same, got %s\n", path2);
1754 ok(!lstrcmp(out, "same"), "Expected same, got %s\n", out);
1755 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1757 /* try . after directory */
1758 SetLastError(0xdeadbeef);
1759 lstrcpy(path1, "one\\mid.\\two");
1760 lstrcpy(path2, "one\\mid.\\three");
1761 lstrcpy(out, "aaa");
1762 count = PathCommonPrefixA(path1, path2, out);
1763 ok(count == 8, "Expected 8, got %i\n", count);
1764 ok(!lstrcmp(path1, "one\\mid.\\two"), "Expected one\\mid.\\two, got %s\n", path1);
1765 ok(!lstrcmp(path2, "one\\mid.\\three"), "Expected one\\mid.\\three, got %s\n", path2);
1766 ok(!lstrcmp(out, "one\\mid."), "Expected one\\mid., got %s\n", out);
1767 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1769 /* try . in the middle of a directory */
1770 SetLastError(0xdeadbeef);
1771 lstrcpy(path1, "one\\mid.end\\two");
1772 lstrcpy(path2, "one\\mid.end\\three");
1773 lstrcpy(out, "aaa");
1774 count = PathCommonPrefixA(path1, path2, out);
1775 ok(count == 11, "Expected 11, got %i\n", count);
1776 ok(!lstrcmp(path1, "one\\mid.end\\two"), "Expected one\\mid.end\\two, got %s\n", path1);
1777 ok(!lstrcmp(path2, "one\\mid.end\\three"), "Expected one\\mid.end\\three, got %s\n", path2);
1778 ok(!lstrcmp(out, "one\\mid.end"), "Expected one\\mid.end, got %s\n", out);
1779 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1781 /* try comparing a .. with the expanded path */
1782 SetLastError(0xdeadbeef);
1783 lstrcpy(path1, "one\\..\\two");
1784 lstrcpy(path2, "two");
1785 lstrcpy(out, "aaa");
1786 count = PathCommonPrefixA(path1, path2, out);
1787 ok(count == 0, "Expected 0, got %i\n", count);
1788 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1789 ok(!lstrcmp(path2, "two"), "Expected two, got %s\n", path2);
1790 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1791 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1794 static void test_PathUnquoteSpaces(void)
1797 for(i = 0; i < sizeof(TEST_PATH_UNQUOTE_SPACES) / sizeof(TEST_PATH_UNQUOTE_SPACES[0]); i++)
1799 char *path = strdupA(TEST_PATH_UNQUOTE_SPACES[i].path);
1800 WCHAR *pathW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].path);
1801 WCHAR *resultW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].result);
1803 PathUnquoteSpacesA(path);
1804 ok(!strcmp(path, TEST_PATH_UNQUOTE_SPACES[i].result), "%s (A): got %s expected %s\n",
1805 TEST_PATH_UNQUOTE_SPACES[i].path, path,
1806 TEST_PATH_UNQUOTE_SPACES[i].result);
1808 PathUnquoteSpacesW(pathW);
1809 ok(!lstrcmpW(pathW, resultW), "%s (W): strings differ\n",
1810 TEST_PATH_UNQUOTE_SPACES[i].path);
1811 FreeWideString(pathW);
1812 FreeWideString(resultW);
1813 HeapFree(GetProcessHeap(), 0, path);
1819 hShlwapi = LoadLibraryA("shlwapi.dll");
1820 if (!hShlwapi) return;
1824 test_UrlCanonicalize();
1827 test_UrlCreateFromPath();
1831 test_PathSearchAndQualify();
1832 test_PathCreateFromUrl();
1835 test_PathAddBackslash();
1836 test_PathMakePretty();
1837 test_PathMatchSpec();
1839 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
1840 * ordinal number in some native versions. Check this to prevent a crash.
1842 pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
1843 if (pPathIsValidCharA && pPathIsValidCharA != (void*)GetProcAddress(hShlwapi, "PathAppendA"))
1845 test_PathIsValidCharA();
1847 pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
1848 if (pPathIsValidCharW) test_PathIsValidCharW();
1851 pPathCombineW = (void*)GetProcAddress(hShlwapi, "PathCombineW");
1853 test_PathCombineW();
1855 test_PathCombineA();
1857 test_PathCanonicalizeA();
1858 test_PathFindExtensionA();
1859 test_PathBuildRootA();
1860 test_PathCommonPrefixA();
1861 test_PathUnquoteSpaces();