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"},
199 {"http://www.winehq.org/test/", "test%20file.txt", 0, S_OK, "http://www.winehq.org/test/test%20file.txt"},
200 {"http://www.winehq.org/test/", "test%20file.txt", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org/test/test%20file.txt"},
201 {"http://www.winehq.org%2ftest/", "test%20file.txt", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org%2ftest/test%20file.txt"},
202 {"xxx:@MSITStore:file.chm/file.html", "dir/file", 0, S_OK, "xxx:dir/file"},
203 {"mk:@MSITStore:file.chm::/file.html", "/dir/file", 0, S_OK, "mk:@MSITStore:file.chm::/dir/file"},
204 {"mk:@MSITStore:file.chm::/file.html", "mk:@MSITStore:file.chm::/dir/file", 0, S_OK, "mk:@MSITStore:file.chm::/dir/file"},
211 } TEST_URLFROMPATH [] = {
212 {"foo", "file:foo", S_OK},
213 {"foo\\bar", "file:foo/bar", S_OK},
214 {"\\foo\\bar", "file:///foo/bar", S_OK},
215 {"c:\\foo\\bar", "file:///c:/foo/bar", S_OK},
216 {"c:foo\\bar", "file:///c:foo/bar", S_OK},
217 {"c:\\foo/b a%r", "file:///c:/foo/b%20a%25r", S_OK},
218 {"c:\\foo\\foo bar", "file:///c:/foo/foo%20bar", S_OK},
220 /* The following test fails on native shlwapi as distributed with Win95/98.
221 * Wine matches the behaviour of later versions.
223 {"xx:c:\\foo\\bar", "xx:c:\\foo\\bar", S_FALSE}
231 } TEST_PATHFROMURL[] = {
232 {"file:///c:/foo/ba%5Cr", "c:\\foo\\ba\\r", S_OK},
233 {"file:///c:/foo/../ba%5Cr", "c:\\foo\\..\\ba\\r", S_OK},
234 {"file:///host/c:/foo/bar", "\\host\\c:\\foo\\bar", S_OK},
235 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
236 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
237 {"file:\\\\host\\c:\\foo\\bar", "\\\\hostc:\\foo\\bar", S_OK},
238 {"file:\\\\host\\ca\\foo\\bar", "\\\\host\\ca\\foo\\bar", S_OK},
239 {"file:\\\\host\\c|\\foo\\bar", "\\\\hostc|\\foo\\bar", S_OK},
240 {"file:\\%5Chost\\c:\\foo\\bar", "\\\\host\\c:\\foo\\bar", S_OK},
241 {"file:\\\\host\\cx:\\foo\\bar", "\\\\host\\cx:\\foo\\bar", S_OK},
242 {"file://c:/foo/bar", "c:\\foo\\bar", S_OK},
243 {"file://c:/d:/foo/bar", "c:\\d:\\foo\\bar", S_OK},
244 {"file://c|/d|/foo/bar", "c:\\d|\\foo\\bar", S_OK},
245 {"file://host/foo/bar", "\\\\host\\foo\\bar", S_OK},
246 {"file:/foo/bar", "\\foo\\bar", S_OK},
247 {"file:/foo/bar/", "\\foo\\bar\\", S_OK},
248 {"file:foo/bar", "foo\\bar", S_OK},
249 {"file:c:/foo/bar", "c:\\foo\\bar", S_OK},
250 {"file:c|/foo/bar", "c:\\foo\\bar", S_OK},
251 {"file:cx|/foo/bar", "cx|\\foo\\bar", S_OK},
252 {"file:////c:/foo/bar", "c:\\foo\\bar", S_OK},
253 /* {"file:////c:/foo/foo%20bar", "c:\\foo\\foo%20bar", S_OK},*/
255 {"c:\\foo\\bar", NULL, E_INVALIDARG},
256 {"foo/bar", NULL, E_INVALIDARG},
257 {"http://foo/bar", NULL, E_INVALIDARG},
264 } TEST_URL_UNESCAPE[] = {
265 {"file://foo/bar", "file://foo/bar"},
266 {"file://fo%20o%5Ca/bar", "file://fo o\\a/bar"}
273 } TEST_PATH_IS_URL[] = {
274 {"http://foo/bar", TRUE},
275 {"c:\\foo\\bar", FALSE},
276 {"foo://foo/bar", TRUE},
279 {"bogusscheme:", TRUE},
280 {"http:partial", TRUE}
287 } TEST_URLIS_ATTRIBS[] = {
288 { "ftp:", FALSE, FALSE },
289 { "http:", FALSE, FALSE },
290 { "gopher:", FALSE, FALSE },
291 { "mailto:", TRUE, FALSE },
292 { "news:", FALSE, FALSE },
293 { "nntp:", FALSE, FALSE },
294 { "telnet:", FALSE, FALSE },
295 { "wais:", FALSE, FALSE },
296 { "file:", FALSE, TRUE },
297 { "mk:", FALSE, FALSE },
298 { "https:", FALSE, FALSE },
299 { "shell:", TRUE, FALSE },
300 { "https:", FALSE, FALSE },
301 { "snews:", FALSE, FALSE },
302 { "local:", FALSE, FALSE },
303 { "javascript:", TRUE, FALSE },
304 { "vbscript:", TRUE, FALSE },
305 { "about:", TRUE, FALSE },
306 { "res:", FALSE, FALSE },
307 { "bogusscheme:", FALSE, FALSE },
308 { "file:\\\\e:\\b\\c", FALSE, TRUE },
309 { "file://e:/b/c", FALSE, TRUE },
310 { "http:partial", FALSE, FALSE },
311 { "mailto://www.winehq.org/test.html", TRUE, FALSE },
312 { "file:partial", FALSE, TRUE }
318 } TEST_PATH_UNQUOTE_SPACES[] = {
319 { "abcdef", "abcdef" },
320 { "\"abcdef\"", "abcdef" },
321 { "\"abcdef", "\"abcdef" },
322 { "abcdef\"", "abcdef\"" },
323 { "\"\"abcdef\"\"", "\"abcdef\"" },
324 { "abc\"def", "abc\"def" },
325 { "\"abc\"def", "\"abc\"def" },
326 { "\"abc\"def\"", "abc\"def" },
327 { "\'abcdef\'", "\'abcdef\'" },
332 static LPWSTR GetWideString(const char* szString)
334 LPWSTR wszString = HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
336 MultiByteToWideChar(0, 0, szString, -1, wszString, INTERNET_MAX_URL_LENGTH);
341 static void FreeWideString(LPWSTR wszString)
343 HeapFree(GetProcessHeap(), 0, wszString);
346 static LPSTR strdupA(LPCSTR p)
349 DWORD len = (strlen(p) + 1);
350 ret = HeapAlloc(GetProcessHeap(), 0, len);
355 static void hash_url(const char* szUrl)
357 LPCSTR szTestUrl = szUrl;
358 LPWSTR wszTestUrl = GetWideString(szTestUrl);
360 DWORD cbSize = sizeof(DWORD);
361 DWORD dwHash1, dwHash2;
362 ok(UrlHashA(szTestUrl, (LPBYTE)&dwHash1, cbSize) == S_OK, "UrlHashA didn't return S_OK\n");
363 ok(UrlHashW(wszTestUrl, (LPBYTE)&dwHash2, cbSize) == S_OK, "UrlHashW didn't return S_OK\n");
365 FreeWideString(wszTestUrl);
367 ok(dwHash1 == dwHash2, "Hashes didn't compare\n");
370 static void test_UrlHash(void)
372 hash_url(TEST_URL_1);
373 hash_url(TEST_URL_2);
374 hash_url(TEST_URL_3);
377 static void test_url_part(const char* szUrl, DWORD dwPart, DWORD dwFlags, const char* szExpected)
379 CHAR szPart[INTERNET_MAX_URL_LENGTH];
380 WCHAR wszPart[INTERNET_MAX_URL_LENGTH];
381 LPWSTR wszUrl = GetWideString(szUrl);
382 LPWSTR wszConvertedPart;
386 dwSize = INTERNET_MAX_URL_LENGTH;
387 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);
388 dwSize = INTERNET_MAX_URL_LENGTH;
389 ok( UrlGetPartW(wszUrl, wszPart, &dwSize, dwPart, dwFlags) == S_OK, "UrlGetPartW didn't return S_OK\n" );
391 wszConvertedPart = GetWideString(szPart);
393 ok(lstrcmpW(wszPart,wszConvertedPart)==0, "Strings didn't match between ascii and unicode UrlGetPart!\n");
395 FreeWideString(wszUrl);
396 FreeWideString(wszConvertedPart);
398 /* Note that v6.0 and later don't return '?' with the query */
399 ok(strcmp(szPart,szExpected)==0 ||
400 (*szExpected=='?' && !strcmp(szPart,szExpected+1)),
401 "Expected %s, but got %s\n", szExpected, szPart);
404 static void test_UrlGetPart(void)
406 CHAR szPart[INTERNET_MAX_URL_LENGTH];
410 dwSize = sizeof szPart;
411 szPart[0]='x'; szPart[1]=0;
412 res = UrlGetPartA("hi", szPart, &dwSize, URL_PART_SCHEME, 0);
414 ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res);
415 ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart);
417 dwSize = sizeof szPart;
418 szPart[0]='x'; szPart[1]=0;
419 res = UrlGetPartA("hi", szPart, &dwSize, URL_PART_QUERY, 0);
421 ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res);
422 ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart);
425 test_url_part(TEST_URL_3, URL_PART_HOSTNAME, 0, "localhost");
426 test_url_part(TEST_URL_3, URL_PART_PORT, 0, "21");
427 test_url_part(TEST_URL_3, URL_PART_USERNAME, 0, "foo");
428 test_url_part(TEST_URL_3, URL_PART_PASSWORD, 0, "bar");
429 test_url_part(TEST_URL_3, URL_PART_SCHEME, 0, "http");
430 test_url_part(TEST_URL_3, URL_PART_QUERY, 0, "?query=x&return=y");
433 static void test_url_escape(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
435 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
437 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
438 WCHAR *urlW, *expected_urlW;
439 dwEscaped=INTERNET_MAX_URL_LENGTH;
441 ok(UrlEscapeA(szUrl, szReturnUrl, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeA didn't return 0x%08x from \"%s\"\n", dwExpectReturn, szUrl);
442 ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected \"%s\", but got \"%s\" from \"%s\"\n", szExpectUrl, szReturnUrl, szUrl);
444 dwEscaped = INTERNET_MAX_URL_LENGTH;
445 urlW = GetWideString(szUrl);
446 expected_urlW = GetWideString(szExpectUrl);
447 ok(UrlEscapeW(urlW, ret_urlW, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeW didn't return 0x%08x from \"%s\"\n", dwExpectReturn, szUrl);
448 WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
449 ok(lstrcmpW(ret_urlW, expected_urlW)==0, "Expected \"%s\", but got \"%s\" from \"%s\" flags %08x\n", szExpectUrl, szReturnUrl, szUrl, dwFlags);
450 FreeWideString(urlW);
451 FreeWideString(expected_urlW);
455 static void test_url_canonicalize(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
457 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
458 WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
459 LPWSTR wszUrl = GetWideString(szUrl);
460 LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
461 LPWSTR wszConvertedUrl;
465 dwSize = INTERNET_MAX_URL_LENGTH;
466 ok(UrlCanonicalizeA(szUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
467 ok(UrlCanonicalizeA(szUrl, szReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeA didn't return 0x%08x\n", dwExpectReturn);
468 ok(strcmp(szReturnUrl,szExpectUrl)==0, "UrlCanonicalizeA dwFlags 0x%08x Expected \"%s\", but got \"%s\"\n", dwFlags, szExpectUrl, szReturnUrl);
470 dwSize = INTERNET_MAX_URL_LENGTH;
471 ok(UrlCanonicalizeW(wszUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
472 ok(UrlCanonicalizeW(wszUrl, wszReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeW didn't return 0x%08x\n", dwExpectReturn);
473 wszConvertedUrl = GetWideString(szReturnUrl);
474 ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCanonicalize!\n");
475 FreeWideString(wszConvertedUrl);
478 FreeWideString(wszUrl);
479 FreeWideString(wszExpectUrl);
483 static void test_UrlEscape(void)
489 ret = UrlEscapeA("/woningplan/woonkamer basis.swf", NULL, &size, URL_ESCAPE_SPACES_ONLY);
490 ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG);
492 for(i=0; i<sizeof(TEST_ESCAPE)/sizeof(TEST_ESCAPE[0]); i++) {
493 test_url_escape(TEST_ESCAPE[i].url, TEST_ESCAPE[i].flags,
494 TEST_ESCAPE[i].expectret, TEST_ESCAPE[i].expecturl);
498 static void test_UrlCanonicalize(void)
501 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
505 for(i=0; i<sizeof(TEST_CANONICALIZE)/sizeof(TEST_CANONICALIZE[0]); i++) {
506 test_url_canonicalize(TEST_CANONICALIZE[i].url, TEST_CANONICALIZE[i].flags,
507 TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expecturl);
510 /* move to TEST_CANONICALIZE when fixed */
511 dwSize = sizeof szReturnUrl;
512 ok(UrlCanonicalizeA("c:\\tests\\foo bar", szReturnUrl, &dwSize, 0) == S_OK, "UrlCanonicalizeA didn't return 0x%08x\n", S_OK);
514 ok(strcmp(szReturnUrl,"file:///c:/tests/foo%20bar")==0, "UrlCanonicalizeA got %s\n", szReturnUrl);
517 dwSize = sizeof szReturnUrl;
518 /*LimeWire online installer calls this*/
519 hr = UrlCanonicalizeA("/uri-res/N2R?urn:sha1:B3K", szReturnUrl, &dwSize,URL_DONT_ESCAPE_EXTRA_INFO | URL_WININET_COMPATIBILITY /*0x82000000*/);
520 ok(hr==S_OK,"UrlCanonicalizeA returned 0x%08x instead of S_OK\n", hr);
522 ok(strcmp(szReturnUrl,"/uri-res/N2R?urn:sha1:B3K")==0, "UrlCanonicalizeA got \"%s\" instead of \"/uri-res/N2R?urn:sha1:B3K\"\n", szReturnUrl);
526 static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
529 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
530 WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
531 LPWSTR wszUrl1 = GetWideString(szUrl1);
532 LPWSTR wszUrl2 = GetWideString(szUrl2);
533 LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
534 LPWSTR wszConvertedUrl;
537 DWORD dwExpectLen = lstrlen(szExpectUrl);
539 hr = UrlCombineA(szUrl1, szUrl2, NULL, NULL, dwFlags);
540 ok(hr == E_INVALIDARG, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_INVALIDARG);
543 hr = UrlCombineA(szUrl1, szUrl2, NULL, &dwSize, dwFlags);
544 ok(hr == E_POINTER, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr, E_POINTER);
545 ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
548 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
549 ok(hr == E_POINTER, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_POINTER);
550 ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
552 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
553 ok(hr == dwExpectReturn, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, dwExpectReturn);
554 ok(dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen);
556 ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected %s, but got %s\n", szExpectUrl, szReturnUrl);
560 hr = UrlCombineW(wszUrl1, wszUrl2, NULL, &dwSize, dwFlags);
561 ok(hr == E_POINTER, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr, E_POINTER);
562 ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
565 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
566 ok(hr == E_POINTER, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_POINTER);
567 ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
569 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
570 ok(hr == dwExpectReturn, "UrlCombineW returned 0x%08x, expected 0x%08x\n", hr, dwExpectReturn);
571 ok(dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen);
573 wszConvertedUrl = GetWideString(szReturnUrl);
574 ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCombine!\n");
575 FreeWideString(wszConvertedUrl);
578 FreeWideString(wszUrl1);
579 FreeWideString(wszUrl2);
580 FreeWideString(wszExpectUrl);
583 static void test_UrlCombine(void)
586 for(i=0; i<sizeof(TEST_COMBINE)/sizeof(TEST_COMBINE[0]); i++) {
587 test_url_combine(TEST_COMBINE[i].url1, TEST_COMBINE[i].url2, TEST_COMBINE[i].flags,
588 TEST_COMBINE[i].expectret, TEST_COMBINE[i].expecturl);
592 static void test_UrlCreateFromPath(void)
595 char ret_url[INTERNET_MAX_URL_LENGTH];
597 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
600 for(i = 0; i < sizeof(TEST_URLFROMPATH) / sizeof(TEST_URLFROMPATH[0]); i++) {
601 len = INTERNET_MAX_URL_LENGTH;
602 ret = UrlCreateFromPathA(TEST_URLFROMPATH[i].path, ret_url, &len, 0);
603 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08x from path %s\n", ret, TEST_URLFROMPATH[i].path);
604 ok(!lstrcmpi(ret_url, TEST_URLFROMPATH[i].url), "url %s from path %s\n", ret_url, TEST_URLFROMPATH[i].path);
605 ok(len == strlen(ret_url), "ret len %d from path %s\n", len, TEST_URLFROMPATH[i].path);
607 len = INTERNET_MAX_URL_LENGTH;
608 pathW = GetWideString(TEST_URLFROMPATH[i].path);
609 urlW = GetWideString(TEST_URLFROMPATH[i].url);
610 ret = UrlCreateFromPathW(pathW, ret_urlW, &len, 0);
611 WideCharToMultiByte(CP_ACP, 0, ret_urlW, -1, ret_url, sizeof(ret_url),0,0);
612 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08x from path L\"%s\", expected %08x\n",
613 ret, TEST_URLFROMPATH[i].path, TEST_URLFROMPATH[i].ret);
614 ok(!lstrcmpiW(ret_urlW, urlW), "got %s expected %s from path L\"%s\"\n", ret_url, TEST_URLFROMPATH[i].url, TEST_URLFROMPATH[i].path);
615 ok(len == lstrlenW(ret_urlW), "ret len %d from path L\"%s\"\n", len, TEST_URLFROMPATH[i].path);
616 FreeWideString(urlW);
617 FreeWideString(pathW);
621 static void test_UrlIs(void)
627 for(i = 0; i < sizeof(TEST_PATH_IS_URL) / sizeof(TEST_PATH_IS_URL[0]); i++) {
628 MultiByteToWideChar(CP_ACP, 0, TEST_PATH_IS_URL[i].path, -1, wurl, 80);
630 ret = UrlIsA( TEST_PATH_IS_URL[i].path, URLIS_URL );
631 ok( ret == TEST_PATH_IS_URL[i].expect,
632 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
633 TEST_PATH_IS_URL[i].expect );
635 ret = UrlIsW( wurl, URLIS_URL );
636 ok( ret == TEST_PATH_IS_URL[i].expect,
637 "returned %d from path (UrlIsW) %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
638 TEST_PATH_IS_URL[i].expect );
640 for(i = 0; i < sizeof(TEST_URLIS_ATTRIBS) / sizeof(TEST_URLIS_ATTRIBS[0]); i++) {
641 MultiByteToWideChar(CP_ACP, 0, TEST_URLIS_ATTRIBS[i].url, -1, wurl, 80);
643 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_OPAQUE);
644 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
645 "returned %d for URLIS_OPAQUE, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
646 TEST_URLIS_ATTRIBS[i].expectOpaque );
647 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_FILEURL);
648 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
649 "returned %d for URLIS_FILEURL, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
650 TEST_URLIS_ATTRIBS[i].expectFile );
652 ret = UrlIsW( wurl, URLIS_OPAQUE);
653 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
654 "returned %d for URLIS_OPAQUE (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
655 TEST_URLIS_ATTRIBS[i].expectOpaque );
656 ret = UrlIsW( wurl, URLIS_FILEURL);
657 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
658 "returned %d for URLIS_FILEURL (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
659 TEST_URLIS_ATTRIBS[i].expectFile );
663 static void test_UrlUnescape(void)
665 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
666 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
667 WCHAR *urlW, *expected_urlW;
670 static char inplace[] = "file:///C:/Program%20Files";
671 static WCHAR inplaceW[] = {'f','i','l','e',':','/','/','/','C',':','/',
672 'P','r','o','g','r','a','m','%','2','0','F','i','l','e','s',0};
674 for(i=0; i<sizeof(TEST_URL_UNESCAPE)/sizeof(TEST_URL_UNESCAPE[0]); i++) {
675 dwEscaped=INTERNET_MAX_URL_LENGTH;
676 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);
677 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);
679 dwEscaped = INTERNET_MAX_URL_LENGTH;
680 urlW = GetWideString(TEST_URL_UNESCAPE[i].url);
681 expected_urlW = GetWideString(TEST_URL_UNESCAPE[i].expect);
682 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);
683 WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
684 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);
685 FreeWideString(urlW);
686 FreeWideString(expected_urlW);
689 dwEscaped = sizeof(inplace);
690 ok(UrlUnescapeA(inplace, NULL, &dwEscaped, URL_UNESCAPE_INPLACE) == S_OK, "UrlUnescapeA failed unexpectedly\n");
692 dwEscaped = sizeof(inplaceW);
693 ok(UrlUnescapeW(inplaceW, NULL, &dwEscaped, URL_UNESCAPE_INPLACE) == S_OK, "UrlUnescapeW failed unexpectedly\n");
696 static void test_PathSearchAndQualify(void)
698 WCHAR path1[] = {'c',':','\\','f','o','o',0};
699 WCHAR expect1[] = {'c',':','\\','f','o','o',0};
700 WCHAR path2[] = {'c',':','f','o','o',0};
701 WCHAR c_drive[] = {'c',':',0};
702 WCHAR foo[] = {'f','o','o',0};
703 WCHAR path3[] = {'\\','f','o','o',0};
704 WCHAR winini[] = {'w','i','n','.','i','n','i',0};
706 WCHAR cur_dir[MAX_PATH];
707 WCHAR dot[] = {'.',0};
710 ok(PathSearchAndQualifyW(path1, out, MAX_PATH) != 0,
711 "PathSearchAndQualify rets 0\n");
712 ok(!lstrcmpiW(out, expect1), "strings don't match\n");
715 ok(PathSearchAndQualifyW(path2, out, MAX_PATH) != 0,
716 "PathSearchAndQualify rets 0\n");
717 GetFullPathNameW(c_drive, MAX_PATH, cur_dir, NULL);
718 PathAddBackslashW(cur_dir);
719 lstrcatW(cur_dir, foo);
720 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
723 ok(PathSearchAndQualifyW(foo, out, MAX_PATH) != 0,
724 "PathSearchAndQualify rets 0\n");
725 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
726 PathAddBackslashW(cur_dir);
727 lstrcatW(cur_dir, foo);
728 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
731 ok(PathSearchAndQualifyW(path3, out, MAX_PATH) != 0,
732 "PathSearchAndQualify rets 0\n");
733 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
734 lstrcpyW(cur_dir + 2, path3);
735 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
738 ok(PathSearchAndQualifyW(winini, out, MAX_PATH) != 0,
739 "PathSearchAndQualify rets 0\n");
740 if(!SearchPathW(NULL, winini, NULL, MAX_PATH, cur_dir, NULL))
741 GetFullPathNameW(winini, MAX_PATH, cur_dir, NULL);
742 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
746 static void test_PathCreateFromUrl(void)
749 char ret_path[INTERNET_MAX_URL_LENGTH];
751 WCHAR ret_pathW[INTERNET_MAX_URL_LENGTH];
753 static const char url[] = "http://www.winehq.org";
755 /* Check ret_path = NULL */
757 ret = PathCreateFromUrlA(url, NULL, &len, 0);
758 ok ( ret == E_INVALIDARG, "got 0x%08x expected E_INVALIDARG\n", ret);
760 for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
761 len = INTERNET_MAX_URL_LENGTH;
762 ret = PathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
763 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url %s\n", ret, TEST_PATHFROMURL[i].url);
764 if(TEST_PATHFROMURL[i].path) {
765 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);
766 ok(len == strlen(ret_path), "ret len %d from url %s\n", len, TEST_PATHFROMURL[i].url);
768 len = INTERNET_MAX_URL_LENGTH;
769 pathW = GetWideString(TEST_PATHFROMURL[i].path);
770 urlW = GetWideString(TEST_PATHFROMURL[i].url);
771 ret = PathCreateFromUrlW(urlW, ret_pathW, &len, 0);
772 WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),0,0);
773 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
774 if(TEST_PATHFROMURL[i].path) {
775 ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
776 ok(len == lstrlenW(ret_pathW), "ret len %d from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url);
778 FreeWideString(urlW);
779 FreeWideString(pathW);
784 static void test_PathIsUrl(void)
789 for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
790 ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
791 ok(ret == TEST_PATH_IS_URL[i].expect,
792 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
793 TEST_PATH_IS_URL[i].expect);
797 static const DWORD SHELL_charclass[] =
799 0x00000000, 0x00000000, 0x00000000, 0x00000000,
800 0x00000000, 0x00000000, 0x00000000, 0x00000000,
801 0x00000000, 0x00000000, 0x00000000, 0x00000000,
802 0x00000000, 0x00000000, 0x00000000, 0x00000000,
803 0x00000000, 0x00000000, 0x00000000, 0x00000000,
804 0x00000000, 0x00000000, 0x00000000, 0x00000000,
805 0x00000000, 0x00000000, 0x00000000, 0x00000000,
806 0x00000000, 0x00000000, 0x00000000, 0x00000000,
807 0x00000080, 0x00000100, 0x00000200, 0x00000100,
808 0x00000100, 0x00000100, 0x00000100, 0x00000100,
809 0x00000100, 0x00000100, 0x00000002, 0x00000100,
810 0x00000040, 0x00000100, 0x00000004, 0x00000000,
811 0x00000100, 0x00000100, 0x00000100, 0x00000100,
812 0x00000100, 0x00000100, 0x00000100, 0x00000100,
813 0x00000100, 0x00000100, 0x00000010, 0x00000020,
814 0x00000000, 0x00000100, 0x00000000, 0x00000001,
815 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
816 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
817 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
818 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
819 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
820 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
821 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
822 0x00000008, 0x00000100, 0x00000100, 0x00000100,
823 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
824 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
825 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
826 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
827 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
828 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
829 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
830 0x00000000, 0x00000100, 0x00000100
833 static void test_PathIsValidCharA(void)
838 ret = pPathIsValidCharA( 0x7f, 0 );
839 ok ( !ret, "PathIsValidCharA succeeded: 0x%08x\n", (DWORD)ret );
841 ret = pPathIsValidCharA( 0x7f, 1 );
842 ok ( !ret, "PathIsValidCharA succeeded: 0x%08x\n", (DWORD)ret );
844 for (c = 0; c < 0x7f; c++)
846 ret = pPathIsValidCharA( c, ~0U );
847 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
848 "PathIsValidCharA failed: 0x%02x got 0x%08x expected 0x%08x\n",
849 c, (DWORD)ret, SHELL_charclass[c] );
852 for (c = 0x7f; c <= 0xff; c++)
854 ret = pPathIsValidCharA( c, ~0U );
855 ok ( ret == 0x00000100,
856 "PathIsValidCharA failed: 0x%02x got 0x%08x expected 0x00000100\n",
861 static void test_PathIsValidCharW(void)
864 unsigned int c, err_count = 0;
866 ret = pPathIsValidCharW( 0x7f, 0 );
867 ok ( !ret, "PathIsValidCharW succeeded: 0x%08x\n", (DWORD)ret );
869 ret = pPathIsValidCharW( 0x7f, 1 );
870 ok ( !ret, "PathIsValidCharW succeeded: 0x%08x\n", (DWORD)ret );
872 for (c = 0; c < 0x7f; c++)
874 ret = pPathIsValidCharW( c, ~0U );
875 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
876 "PathIsValidCharW failed: 0x%02x got 0x%08x expected 0x%08x\n",
877 c, (DWORD)ret, SHELL_charclass[c] );
880 for (c = 0x007f; c <= 0xffff; c++)
882 ret = pPathIsValidCharW( c, ~0U );
883 ok ( ret == 0x00000100,
884 "PathIsValidCharW failed: 0x%02x got 0x%08x expected 0x00000100\n",
886 if (ret != 0x00000100)
888 if(++err_count > 100 ) {
889 trace("skipping rest of PathIsValidCharW tests "
890 "because of the current number of errors\n");
897 static void test_PathMakePretty(void)
901 ok (PathMakePrettyA(NULL) == FALSE, "PathMakePretty: NULL path succeeded\n");
903 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Empty path failed\n");
905 strcpy(buff, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
906 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Long UC name failed\n");
907 ok (strcmp(buff, "C:\\a long file name with \\spaces.txt") == 0,
908 "PathMakePretty: Long UC name not changed\n");
910 strcpy(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
911 ok (PathMakePrettyA(buff) == FALSE, "PathMakePretty: Long MC name succeeded\n");
912 ok (strcmp(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
913 "PathMakePretty: Failed but modified path\n");
915 strcpy(buff, "TEST");
916 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Short name failed\n");
917 ok (strcmp(buff, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff);
920 static void test_PathMatchSpec(void)
922 static const char file[] = "c:\\foo\\bar\\filename.ext";
923 static const char spec1[] = ".ext";
924 static const char spec2[] = "*.ext";
925 static const char spec3[] = "*.ext ";
926 static const char spec4[] = " *.ext";
927 static const char spec5[] = "* .ext";
928 static const char spec6[] = "*. ext";
929 static const char spec7[] = "* . ext";
930 static const char spec8[] = "*.e?t";
931 static const char spec9[] = "filename.ext";
932 static const char spec10[] = "*bar\\filename.ext";
933 static const char spec11[] = " foo; *.ext";
934 static const char spec12[] = "*.ext;*.bar";
935 static const char spec13[] = "*bar*";
937 ok (PathMatchSpecA(file, spec1) == FALSE, "PathMatchSpec: Spec1 failed\n");
938 ok (PathMatchSpecA(file, spec2) == TRUE, "PathMatchSpec: Spec2 failed\n");
939 ok (PathMatchSpecA(file, spec3) == FALSE, "PathMatchSpec: Spec3 failed\n");
940 ok (PathMatchSpecA(file, spec4) == TRUE, "PathMatchSpec: Spec4 failed\n");
941 todo_wine ok (PathMatchSpecA(file, spec5) == TRUE, "PathMatchSpec: Spec5 failed\n");
942 todo_wine ok (PathMatchSpecA(file, spec6) == TRUE, "PathMatchSpec: Spec6 failed\n");
943 ok (PathMatchSpecA(file, spec7) == FALSE, "PathMatchSpec: Spec7 failed\n");
944 ok (PathMatchSpecA(file, spec8) == TRUE, "PathMatchSpec: Spec8 failed\n");
945 ok (PathMatchSpecA(file, spec9) == FALSE, "PathMatchSpec: Spec9 failed\n");
946 ok (PathMatchSpecA(file, spec10) == TRUE, "PathMatchSpec: Spec10 failed\n");
947 ok (PathMatchSpecA(file, spec11) == TRUE, "PathMatchSpec: Spec11 failed\n");
948 ok (PathMatchSpecA(file, spec12) == TRUE, "PathMatchSpec: Spec12 failed\n");
949 ok (PathMatchSpecA(file, spec13) == TRUE, "PathMatchSpec: Spec13 failed\n");
952 static void test_PathCombineW(void)
954 LPWSTR wszString, wszString2;
956 wszString2 = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
959 wszString = pPathCombineW(NULL, NULL, NULL);
960 ok (wszString == NULL, "Expected a NULL return\n");
963 wszString = pPathCombineW(wszString2, NULL, NULL);
964 ok (wszString == NULL, "Expected a NULL return\n");
966 HeapFree(GetProcessHeap(), 0, wszString2);
969 #define LONG_LEN (MAX_PATH * 2)
970 #define HALF_LEN (MAX_PATH / 2 + 1)
972 static void test_PathCombineA(void)
976 char too_long[LONG_LEN];
977 char one[HALF_LEN], two[HALF_LEN];
980 SetLastError(0xdeadbeef);
981 str = PathCombineA(NULL, "C:\\", "one\\two\\three");
982 ok(str == NULL, "Expected NULL, got %p\n", str);
983 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
985 /* try NULL dest and NULL directory */
986 SetLastError(0xdeadbeef);
987 str = PathCombineA(NULL, NULL, "one\\two\\three");
988 ok(str == NULL, "Expected NULL, got %p\n", str);
989 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
992 SetLastError(0xdeadbeef);
993 str = PathCombineA(NULL, NULL, NULL);
994 ok(str == NULL, "Expected NULL, got %p\n", str);
995 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
997 /* try NULL file part */
998 SetLastError(0xdeadbeef);
999 lstrcpyA(dest, "control");
1000 str = PathCombineA(dest, "C:\\", NULL);
1001 ok(str == dest, "Expected str == dest, got %p\n", str);
1002 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
1003 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1005 /* try empty file part */
1006 SetLastError(0xdeadbeef);
1007 lstrcpyA(dest, "control");
1008 str = PathCombineA(dest, "C:\\", "");
1009 ok(str == dest, "Expected str == dest, got %p\n", str);
1010 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
1011 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1013 /* try empty directory and file part */
1014 SetLastError(0xdeadbeef);
1015 lstrcpyA(dest, "control");
1016 str = PathCombineA(dest, "", "");
1017 ok(str == dest, "Expected str == dest, got %p\n", str);
1018 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
1019 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1021 /* try NULL directory */
1022 SetLastError(0xdeadbeef);
1023 lstrcpyA(dest, "control");
1024 str = PathCombineA(dest, NULL, "one\\two\\three");
1025 ok(str == dest, "Expected str == dest, got %p\n", str);
1026 ok(!lstrcmp(str, "one\\two\\three"), "Expected one\\two\\three, got %s\n", str);
1027 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1029 /* try NULL directory and empty file part */
1030 SetLastError(0xdeadbeef);
1031 lstrcpyA(dest, "control");
1032 str = PathCombineA(dest, NULL, "");
1033 ok(str == dest, "Expected str == dest, got %p\n", str);
1034 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
1035 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1037 /* try NULL directory and file part */
1038 SetLastError(0xdeadbeef);
1039 lstrcpyA(dest, "control");
1040 str = PathCombineA(dest, NULL, NULL);
1041 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1044 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1046 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1048 /* try directory without backslash */
1049 SetLastError(0xdeadbeef);
1050 lstrcpyA(dest, "control");
1051 str = PathCombineA(dest, "C:", "one\\two\\three");
1052 ok(str == dest, "Expected str == dest, got %p\n", str);
1053 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1054 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1056 /* try directory with backslash */
1057 SetLastError(0xdeadbeef);
1058 lstrcpyA(dest, "control");
1059 str = PathCombineA(dest, "C:\\", "one\\two\\three");
1060 ok(str == dest, "Expected str == dest, got %p\n", str);
1061 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1062 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1064 /* try directory with backslash and file with prepended backslash */
1065 SetLastError(0xdeadbeef);
1066 lstrcpyA(dest, "control");
1067 str = PathCombineA(dest, "C:\\", "\\one\\two\\three");
1068 ok(str == dest, "Expected str == dest, got %p\n", str);
1069 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1070 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1072 /* try previous test, with backslash appended as well */
1073 SetLastError(0xdeadbeef);
1074 lstrcpyA(dest, "control");
1075 str = PathCombineA(dest, "C:\\", "\\one\\two\\three\\");
1076 ok(str == dest, "Expected str == dest, got %p\n", str);
1077 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
1078 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1080 /* try a relative directory */
1081 SetLastError(0xdeadbeef);
1082 lstrcpyA(dest, "control");
1083 str = PathCombineA(dest, "relative\\dir", "\\one\\two\\three\\");
1084 ok(str == dest, "Expected str == dest, got %p\n", str);
1085 ok(!lstrcmp(str, "one\\two\\three\\"), "Expected one\\two\\three\\, got %s\n", str);
1086 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1088 /* try forward slashes */
1089 SetLastError(0xdeadbeef);
1090 lstrcpyA(dest, "control");
1091 str = PathCombineA(dest, "C:\\", "one/two/three\\");
1092 ok(str == dest, "Expected str == dest, got %p\n", str);
1093 ok(!lstrcmp(str, "C:\\one/two/three\\"), "Expected one/two/three\\, got %s\n", str);
1094 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1096 /* try a really weird directory */
1097 SetLastError(0xdeadbeef);
1098 lstrcpyA(dest, "control");
1099 str = PathCombineA(dest, "C:\\/\\/", "\\one\\two\\three\\");
1100 ok(str == dest, "Expected str == dest, got %p\n", str);
1101 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
1102 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1105 SetLastError(0xdeadbeef);
1106 lstrcpyA(dest, "control");
1107 str = PathCombineA(dest, "C:\\", "one\\..\\two\\.\\three");
1108 ok(str == dest, "Expected str == dest, got %p\n", str);
1109 ok(!lstrcmp(str, "C:\\two\\three"), "Expected C:\\two\\three, got %s\n", str);
1110 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1112 /* try .. as file */
1113 /* try forward slashes */
1114 SetLastError(0xdeadbeef);
1115 lstrcpyA(dest, "control");
1116 str = PathCombineA(dest, "C:\\", "..");
1117 ok(str == dest, "Expected str == dest, got %p\n", str);
1118 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
1119 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1121 memset(too_long, 'a', LONG_LEN);
1122 too_long[LONG_LEN - 1] = '\0';
1124 /* try a file longer than MAX_PATH */
1125 SetLastError(0xdeadbeef);
1126 lstrcpyA(dest, "control");
1127 str = PathCombineA(dest, "C:\\", too_long);
1130 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1131 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1132 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1135 /* try a directory longer than MAX_PATH */
1136 SetLastError(0xdeadbeef);
1137 lstrcpyA(dest, "control");
1138 str = PathCombineA(dest, too_long, "one\\two\\three");
1141 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1142 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1143 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1146 memset(one, 'b', HALF_LEN);
1147 memset(two, 'c', HALF_LEN);
1148 one[HALF_LEN - 1] = '\0';
1149 two[HALF_LEN - 1] = '\0';
1151 /* destination string is longer than MAX_PATH, but not the constituent parts */
1152 SetLastError(0xdeadbeef);
1153 lstrcpyA(dest, "control");
1154 str = PathCombineA(dest, one, two);
1157 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1158 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1160 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1163 static void test_PathAddBackslash(void)
1166 char path[MAX_PATH];
1167 char too_long[LONG_LEN];
1169 /* try a NULL path */
1170 SetLastError(0xdeadbeef);
1171 str = PathAddBackslashA(NULL);
1172 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1173 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1175 /* try an empty path */
1177 SetLastError(0xdeadbeef);
1178 str = PathAddBackslashA(path);
1179 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1180 ok(lstrlenA(path) == 0, "Expected empty string, got %i\n", lstrlenA(path));
1181 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1183 /* try a relative path */
1184 lstrcpyA(path, "one\\two");
1185 SetLastError(0xdeadbeef);
1186 str = PathAddBackslashA(path);
1187 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1188 ok(!lstrcmp(path, "one\\two\\"), "Expected one\\two\\, got %s\n", path);
1189 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1192 lstrcpyA(path, "one\\..\\two");
1193 SetLastError(0xdeadbeef);
1194 str = PathAddBackslashA(path);
1195 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1196 ok(!lstrcmp(path, "one\\..\\two\\"), "Expected one\\..\\two\\, got %s\n", path);
1197 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1199 /* try just a space */
1200 lstrcpyA(path, " ");
1201 SetLastError(0xdeadbeef);
1202 str = PathAddBackslashA(path);
1203 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1204 ok(!lstrcmp(path, " \\"), "Expected \\, got %s\n", path);
1205 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1207 /* path already has backslash */
1208 lstrcpyA(path, "C:\\one\\");
1209 SetLastError(0xdeadbeef);
1210 str = PathAddBackslashA(path);
1211 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1212 ok(!lstrcmp(path, "C:\\one\\"), "Expected C:\\one\\, got %s\n", path);
1213 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1215 memset(too_long, 'a', LONG_LEN);
1216 too_long[LONG_LEN - 1] = '\0';
1218 /* path is longer than MAX_PATH */
1219 SetLastError(0xdeadbeef);
1220 str = PathAddBackslashA(too_long);
1221 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1222 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1225 static void test_PathAppendA(void)
1227 char path[MAX_PATH];
1228 char too_long[LONG_LEN];
1229 char one[HALF_LEN], two[HALF_LEN];
1232 lstrcpy(path, "C:\\one");
1234 /* try NULL pszMore */
1235 SetLastError(0xdeadbeef);
1236 res = PathAppendA(path, NULL);
1237 ok(!res, "Expected failure\n");
1238 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1239 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
1241 /* try empty pszMore */
1242 SetLastError(0xdeadbeef);
1243 res = PathAppendA(path, "");
1244 ok(res, "Expected success\n");
1245 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1246 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
1248 /* try NULL pszPath */
1249 SetLastError(0xdeadbeef);
1250 res = PathAppendA(NULL, "two\\three");
1251 ok(!res, "Expected failure\n");
1252 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1254 /* try empty pszPath */
1256 SetLastError(0xdeadbeef);
1257 res = PathAppendA(path, "two\\three");
1258 ok(res, "Expected success\n");
1259 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1260 ok(!lstrcmp(path, "two\\three"), "Expected \\two\\three, got %s\n", path);
1262 /* try empty pszPath and empty pszMore */
1264 SetLastError(0xdeadbeef);
1265 res = PathAppendA(path, "");
1266 ok(res, "Expected success\n");
1267 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1268 ok(!lstrcmp(path, "\\"), "Expected \\, got %s\n", path);
1270 /* try legit params */
1271 lstrcpy(path, "C:\\one");
1272 SetLastError(0xdeadbeef);
1273 res = PathAppendA(path, "two\\three");
1274 ok(res, "Expected success\n");
1275 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1276 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1278 /* try pszPath with backslash after it */
1279 lstrcpy(path, "C:\\one\\");
1280 SetLastError(0xdeadbeef);
1281 res = PathAppendA(path, "two\\three");
1282 ok(res, "Expected success\n");
1283 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1284 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1286 /* try pszMore with backslash before it */
1287 lstrcpy(path, "C:\\one");
1288 SetLastError(0xdeadbeef);
1289 res = PathAppendA(path, "\\two\\three");
1290 ok(res, "Expected success\n");
1291 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1292 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1294 /* try pszMore with backslash after it */
1295 lstrcpy(path, "C:\\one");
1296 SetLastError(0xdeadbeef);
1297 res = PathAppendA(path, "two\\three\\");
1298 ok(res, "Expected success\n");
1299 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1300 ok(!lstrcmp(path, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", path);
1302 /* try spaces in pszPath */
1303 lstrcpy(path, "C: \\ one ");
1304 SetLastError(0xdeadbeef);
1305 res = PathAppendA(path, "two\\three");
1306 ok(res, "Expected success\n");
1307 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1308 ok(!lstrcmp(path, "C: \\ one \\two\\three"), "Expected C: \\ one \\two\\three, got %s\n", path);
1310 /* try spaces in pszMore */
1311 lstrcpy(path, "C:\\one");
1312 SetLastError(0xdeadbeef);
1313 res = PathAppendA(path, " two \\ three ");
1314 ok(res, "Expected success\n");
1315 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1316 ok(!lstrcmp(path, "C:\\one\\ two \\ three "), "Expected 'C:\\one\\ two \\ three ', got %s\n", path);
1318 /* pszPath is too long */
1319 memset(too_long, 'a', LONG_LEN);
1320 too_long[LONG_LEN - 1] = '\0';
1321 SetLastError(0xdeadbeef);
1322 res = PathAppendA(too_long, "two\\three");
1325 ok(!res, "Expected failure\n");
1326 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1327 ok(lstrlen(too_long) == 0, "Expected length of too_long to be zero, got %i\n", lstrlen(too_long));
1330 /* pszMore is too long */
1331 lstrcpy(path, "C:\\one");
1332 memset(too_long, 'a', LONG_LEN);
1333 too_long[LONG_LEN - 1] = '\0';
1334 SetLastError(0xdeadbeef);
1335 res = PathAppendA(path, too_long);
1338 ok(!res, "Expected failure\n");
1339 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1340 ok(lstrlen(path) == 0, "Expected length of path to be zero, got %i\n", lstrlen(path));
1343 /* both params combined are too long */
1344 memset(one, 'a', HALF_LEN);
1345 one[HALF_LEN - 1] = '\0';
1346 memset(two, 'b', HALF_LEN);
1347 two[HALF_LEN - 1] = '\0';
1348 SetLastError(0xdeadbeef);
1349 res = PathAppendA(one, two);
1352 ok(!res, "Expected failure\n");
1353 ok(lstrlen(one) == 0, "Expected length of one to be zero, got %i\n", lstrlen(one));
1355 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1358 static void test_PathCanonicalizeA(void)
1360 char dest[MAX_PATH];
1361 char too_long[LONG_LEN];
1364 /* try a NULL source */
1365 lstrcpy(dest, "test");
1366 SetLastError(0xdeadbeef);
1367 res = PathCanonicalizeA(dest, NULL);
1368 ok(!res, "Expected failure\n");
1369 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1370 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1373 ok(!lstrcmp(dest, "test"), "Expected test, got %s\n", dest);
1376 /* try an empty source */
1377 lstrcpy(dest, "test");
1378 SetLastError(0xdeadbeef);
1379 res = PathCanonicalizeA(dest, "");
1380 ok(res, "Expected success\n");
1381 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1382 ok(!lstrcmp(dest, "\\"), "Expected \\, got %s\n", dest);
1384 /* try a NULL dest */
1385 SetLastError(0xdeadbeef);
1386 res = PathCanonicalizeA(NULL, "C:\\");
1387 ok(!res, "Expected failure\n");
1388 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1389 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1391 /* try empty dest */
1393 SetLastError(0xdeadbeef);
1394 res = PathCanonicalizeA(dest, "C:\\");
1395 ok(res, "Expected success\n");
1396 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1397 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
1399 /* try non-empty dest */
1400 lstrcpy(dest, "test");
1401 SetLastError(0xdeadbeef);
1402 res = PathCanonicalizeA(dest, "C:\\");
1403 ok(res, "Expected success\n");
1404 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1405 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
1407 /* try a space for source */
1408 lstrcpy(dest, "test");
1409 SetLastError(0xdeadbeef);
1410 res = PathCanonicalizeA(dest, " ");
1411 ok(res, "Expected success\n");
1412 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1413 ok(!lstrcmp(dest, " "), "Expected ' ', got %s\n", dest);
1415 /* try a relative path */
1416 lstrcpy(dest, "test");
1417 SetLastError(0xdeadbeef);
1418 res = PathCanonicalizeA(dest, "one\\two");
1419 ok(res, "Expected success\n");
1420 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1421 ok(!lstrcmp(dest, "one\\two"), "Expected one\\two, got %s\n", dest);
1423 /* try current dir and previous dir */
1424 lstrcpy(dest, "test");
1425 SetLastError(0xdeadbeef);
1426 res = PathCanonicalizeA(dest, "C:\\one\\.\\..\\two\\three\\..");
1427 ok(res, "Expected success\n");
1428 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1429 ok(!lstrcmp(dest, "C:\\two"), "Expected C:\\two, got %s\n", dest);
1431 /* try simple forward slashes */
1432 lstrcpy(dest, "test");
1433 SetLastError(0xdeadbeef);
1434 res = PathCanonicalizeA(dest, "C:\\one/two/three\\four/five\\six");
1435 ok(res, "Expected success\n");
1436 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1437 ok(!lstrcmp(dest, "C:\\one/two/three\\four/five\\six"),
1438 "Expected C:\\one/two/three\\four/five\\six, got %s\n", dest);
1440 /* try simple forward slashes with same dir */
1441 lstrcpy(dest, "test");
1442 SetLastError(0xdeadbeef);
1443 res = PathCanonicalizeA(dest, "C:\\one/.\\two");
1444 ok(res, "Expected success\n");
1445 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1446 ok(!lstrcmp(dest, "C:\\one/.\\two"), "Expected C:\\one/.\\two, got %s\n", dest);
1448 /* try simple forward slashes with change dir */
1449 lstrcpy(dest, "test");
1450 SetLastError(0xdeadbeef);
1451 res = PathCanonicalizeA(dest, "C:\\one/.\\two\\..");
1452 ok(res, "Expected success\n");
1453 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1454 ok(!lstrcmp(dest, "C:\\one/."), "Expected C:\\one/., got %s\n", dest);
1456 /* try forward slashes with change dirs
1457 * NOTE: if there is a forward slash in between two backslashes,
1458 * everything in between the two backslashes is considered on dir
1460 lstrcpy(dest, "test");
1461 SetLastError(0xdeadbeef);
1462 res = PathCanonicalizeA(dest, "C:\\one/.\\..\\two/three\\..\\four/.five");
1463 ok(res, "Expected success\n");
1464 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1465 ok(!lstrcmp(dest, "C:\\four/.five"), "Expected C:\\four/.five, got %s\n", dest);
1467 /* try src is too long */
1468 memset(too_long, 'a', LONG_LEN);
1469 too_long[LONG_LEN - 1] = '\0';
1470 lstrcpy(dest, "test");
1471 SetLastError(0xdeadbeef);
1472 res = PathCanonicalizeA(dest, too_long);
1475 ok(!res, "Expected failure\n");
1476 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1478 ok(lstrlen(too_long) == LONG_LEN - 1, "Expected length LONG_LEN - 1, got %i\n", lstrlen(too_long));
1481 static void test_PathFindExtensionA(void)
1484 char path[MAX_PATH];
1485 char too_long[LONG_LEN];
1487 /* try a NULL path */
1488 SetLastError(0xdeadbeef);
1489 ext = PathFindExtensionA(NULL);
1490 ok(ext == NULL, "Expected NULL, got %p\n", ext);
1491 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1493 /* try an empty path */
1495 SetLastError(0xdeadbeef);
1496 ext = PathFindExtensionA(path);
1497 ok(ext == path, "Expected ext == path, got %p\n", ext);
1498 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1499 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1501 /* try a path without an extension */
1502 lstrcpy(path, "file");
1503 SetLastError(0xdeadbeef);
1504 ext = PathFindExtensionA(path);
1505 ok(ext == path + lstrlen(path), "Expected ext == path, got %p\n", ext);
1506 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1507 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1509 /* try a path with an extension */
1510 lstrcpy(path, "file.txt");
1511 SetLastError(0xdeadbeef);
1512 ext = PathFindExtensionA(path);
1513 ok(ext == path + lstrlen("file"),
1514 "Expected ext == path + lstrlen(\"file\"), got %p\n", ext);
1515 ok(!lstrcmp(ext, ".txt"), "Expected .txt, got %s\n", ext);
1516 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1518 /* try a path with two extensions */
1519 lstrcpy(path, "file.txt.doc");
1520 SetLastError(0xdeadbeef);
1521 ext = PathFindExtensionA(path);
1522 ok(ext == path + lstrlen("file.txt"),
1523 "Expected ext == path + lstrlen(\"file.txt\"), got %p\n", ext);
1524 ok(!lstrcmp(ext, ".doc"), "Expected .txt, got %s\n", ext);
1525 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1527 /* try a path longer than MAX_PATH without an extension*/
1528 memset(too_long, 'a', LONG_LEN);
1529 too_long[LONG_LEN - 1] = '\0';
1530 SetLastError(0xdeadbeef);
1531 ext = PathFindExtensionA(too_long);
1532 ok(ext == too_long + LONG_LEN - 1, "Expected ext == too_long + LONG_LEN - 1, got %p\n", ext);
1533 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1535 /* try a path longer than MAX_PATH with an extension*/
1536 memset(too_long, 'a', LONG_LEN);
1537 too_long[LONG_LEN - 1] = '\0';
1538 lstrcpy(too_long + 300, ".abcde");
1539 too_long[lstrlen(too_long)] = 'a';
1540 SetLastError(0xdeadbeef);
1541 ext = PathFindExtensionA(too_long);
1542 ok(ext == too_long + 300, "Expected ext == too_long + 300, got %p\n", ext);
1543 ok(lstrlen(ext) == LONG_LEN - 301, "Expected LONG_LEN - 301, got %i\n", lstrlen(ext));
1544 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1547 static void test_PathBuildRootA(void)
1551 char root_expected[26][4];
1555 /* set up the expected paths */
1556 for (drive = 'A'; drive <= 'Z'; drive++)
1557 sprintf(root_expected[drive - 'A'], "%c:\\", drive);
1559 /* test the expected values */
1560 for (j = 0; j < 26; j++)
1562 SetLastError(0xdeadbeef);
1563 lstrcpy(path, "aaaaaaaaa");
1564 root = PathBuildRootA(path, j);
1565 ok(root == path, "Expected root == path, got %p\n", root);
1566 ok(!lstrcmp(root, root_expected[j]), "Expected %s, got %s\n", root_expected[j], root);
1567 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1570 /* test a negative drive number */
1571 SetLastError(0xdeadbeef);
1572 lstrcpy(path, "aaaaaaaaa");
1573 root = PathBuildRootA(path, -1);
1574 ok(root == path, "Expected root == path, got %p\n", root);
1575 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1576 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1578 /* test a drive number greater than 25 */
1579 SetLastError(0xdeadbeef);
1580 lstrcpy(path, "aaaaaaaaa");
1581 root = PathBuildRootA(path, 26);
1582 ok(root == path, "Expected root == path, got %p\n", root);
1583 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1584 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1586 /* length of path is less than 4 */
1587 SetLastError(0xdeadbeef);
1588 lstrcpy(path, "aa");
1589 root = PathBuildRootA(path, 0);
1590 ok(root == path, "Expected root == path, got %p\n", root);
1591 ok(!lstrcmp(path, "A:\\"), "Expected A:\\, got %s\n", path);
1592 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1595 SetLastError(0xdeadbeef);
1596 root = PathBuildRootA(NULL, 0);
1597 ok(root == NULL, "Expected root == NULL, got %p\n", root);
1598 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1601 static void test_PathCommonPrefixA(void)
1603 char path1[MAX_PATH], path2[MAX_PATH];
1607 /* test NULL path1 */
1608 SetLastError(0xdeadbeef);
1609 lstrcpy(path2, "C:\\");
1610 lstrcpy(out, "aaa");
1611 count = PathCommonPrefixA(NULL, path2, out);
1612 ok(count == 0, "Expected 0, got %i\n", count);
1615 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1617 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1618 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1620 /* test NULL path2 */
1621 SetLastError(0xdeadbeef);
1622 lstrcpy(path1, "C:\\");
1623 lstrcpy(out, "aaa");
1624 count = PathCommonPrefixA(path1, NULL, out);
1625 ok(count == 0, "Expected 0, got %i\n", count);
1628 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1630 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1631 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1633 /* test empty path1 */
1634 SetLastError(0xdeadbeef);
1636 lstrcpy(path2, "C:\\");
1637 lstrcpy(out, "aaa");
1638 count = PathCommonPrefixA(path1, path2, out);
1639 ok(count == 0, "Expected 0, got %i\n", count);
1640 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1641 ok(lstrlen(path1) == 0, "Expected 0 length path1, got %i\n", lstrlen(path1));
1642 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1643 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1645 /* test empty path1 */
1646 SetLastError(0xdeadbeef);
1648 lstrcpy(path1, "C:\\");
1649 lstrcpy(out, "aaa");
1650 count = PathCommonPrefixA(path1, path2, out);
1651 ok(count == 0, "Expected 0, got %i\n", count);
1652 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1653 ok(lstrlen(path2) == 0, "Expected 0 length path2, got %i\n", lstrlen(path2));
1654 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1655 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1657 /* paths are legit, out is NULL */
1658 SetLastError(0xdeadbeef);
1659 lstrcpy(path1, "C:\\");
1660 lstrcpy(path2, "C:\\");
1661 count = PathCommonPrefixA(path1, path2, NULL);
1662 ok(count == 3, "Expected 3, got %i\n", count);
1663 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1664 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1665 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1667 /* all parameters legit */
1668 SetLastError(0xdeadbeef);
1669 lstrcpy(path1, "C:\\");
1670 lstrcpy(path2, "C:\\");
1671 lstrcpy(out, "aaa");
1672 count = PathCommonPrefixA(path1, path2, out);
1673 ok(count == 3, "Expected 3, got %i\n", count);
1674 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1675 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1676 ok(!lstrcmp(out, "C:\\"), "Expected C:\\, got %s\n", out);
1677 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1679 /* path1 and path2 not the same, but common prefix */
1680 SetLastError(0xdeadbeef);
1681 lstrcpy(path1, "C:\\one\\two");
1682 lstrcpy(path2, "C:\\one\\three");
1683 lstrcpy(out, "aaa");
1684 count = PathCommonPrefixA(path1, path2, out);
1685 ok(count == 6, "Expected 6, got %i\n", count);
1686 ok(!lstrcmp(path1, "C:\\one\\two"), "Expected C:\\one\\two, got %s\n", path1);
1687 ok(!lstrcmp(path2, "C:\\one\\three"), "Expected C:\\one\\three, got %s\n", path2);
1688 ok(!lstrcmp(out, "C:\\one"), "Expected C:\\one, got %s\n", out);
1689 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1692 SetLastError(0xdeadbeef);
1693 lstrcpy(path1, "one\\.two");
1694 lstrcpy(path2, "one\\.three");
1695 lstrcpy(out, "aaa");
1696 count = PathCommonPrefixA(path1, path2, out);
1697 ok(count == 3, "Expected 3, got %i\n", count);
1698 ok(!lstrcmp(path1, "one\\.two"), "Expected one\\.two, got %s\n", path1);
1699 ok(!lstrcmp(path2, "one\\.three"), "Expected one\\.three, got %s\n", path2);
1700 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1701 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1704 SetLastError(0xdeadbeef);
1705 lstrcpy(path1, "one\\..two");
1706 lstrcpy(path2, "one\\..three");
1707 lstrcpy(out, "aaa");
1708 count = PathCommonPrefixA(path1, path2, out);
1709 ok(count == 3, "Expected 3, got %i\n", count);
1710 ok(!lstrcmp(path1, "one\\..two"), "Expected one\\..two, got %s\n", path1);
1711 ok(!lstrcmp(path2, "one\\..three"), "Expected one\\..three, got %s\n", path2);
1712 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1713 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1715 /* try ... prefix */
1716 SetLastError(0xdeadbeef);
1717 lstrcpy(path1, "one\\...two");
1718 lstrcpy(path2, "one\\...three");
1719 lstrcpy(out, "aaa");
1720 count = PathCommonPrefixA(path1, path2, out);
1721 ok(count == 3, "Expected 3, got %i\n", count);
1722 ok(!lstrcmp(path1, "one\\...two"), "Expected one\\...two, got %s\n", path1);
1723 ok(!lstrcmp(path2, "one\\...three"), "Expected one\\...three, got %s\n", path2);
1724 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1725 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1728 SetLastError(0xdeadbeef);
1729 lstrcpy(path1, "one\\.\\two");
1730 lstrcpy(path2, "one\\.\\three");
1731 lstrcpy(out, "aaa");
1732 count = PathCommonPrefixA(path1, path2, out);
1733 ok(count == 5, "Expected 5, got %i\n", count);
1734 ok(!lstrcmp(path1, "one\\.\\two"), "Expected one\\.\\two, got %s\n", path1);
1735 ok(!lstrcmp(path2, "one\\.\\three"), "Expected one\\.\\three, got %s\n", path2);
1736 ok(!lstrcmp(out, "one\\."), "Expected one\\., got %s\n", out);
1737 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1739 /* try ..\ prefix */
1740 SetLastError(0xdeadbeef);
1741 lstrcpy(path1, "one\\..\\two");
1742 lstrcpy(path2, "one\\..\\three");
1743 lstrcpy(out, "aaa");
1744 count = PathCommonPrefixA(path1, path2, out);
1745 ok(count == 6, "Expected 6, got %i\n", count);
1746 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1747 ok(!lstrcmp(path2, "one\\..\\three"), "Expected one\\..\\three, got %s\n", path2);
1748 ok(!lstrcmp(out, "one\\.."), "Expected one\\.., got %s\n", out);
1749 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1751 /* try ...\\ prefix */
1752 SetLastError(0xdeadbeef);
1753 lstrcpy(path1, "one\\...\\two");
1754 lstrcpy(path2, "one\\...\\three");
1755 lstrcpy(out, "aaa");
1756 count = PathCommonPrefixA(path1, path2, out);
1757 ok(count == 7, "Expected 7, got %i\n", count);
1758 ok(!lstrcmp(path1, "one\\...\\two"), "Expected one\\...\\two, got %s\n", path1);
1759 ok(!lstrcmp(path2, "one\\...\\three"), "Expected one\\...\\three, got %s\n", path2);
1760 ok(!lstrcmp(out, "one\\..."), "Expected one\\..., got %s\n", out);
1761 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1763 /* try prefix that is not an msdn labeled prefix type */
1764 SetLastError(0xdeadbeef);
1765 lstrcpy(path1, "same");
1766 lstrcpy(path2, "same");
1767 lstrcpy(out, "aaa");
1768 count = PathCommonPrefixA(path1, path2, out);
1769 ok(count == 4, "Expected 4, got %i\n", count);
1770 ok(!lstrcmp(path1, "same"), "Expected same, got %s\n", path1);
1771 ok(!lstrcmp(path2, "same"), "Expected same, got %s\n", path2);
1772 ok(!lstrcmp(out, "same"), "Expected same, got %s\n", out);
1773 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1775 /* try . after directory */
1776 SetLastError(0xdeadbeef);
1777 lstrcpy(path1, "one\\mid.\\two");
1778 lstrcpy(path2, "one\\mid.\\three");
1779 lstrcpy(out, "aaa");
1780 count = PathCommonPrefixA(path1, path2, out);
1781 ok(count == 8, "Expected 8, got %i\n", count);
1782 ok(!lstrcmp(path1, "one\\mid.\\two"), "Expected one\\mid.\\two, got %s\n", path1);
1783 ok(!lstrcmp(path2, "one\\mid.\\three"), "Expected one\\mid.\\three, got %s\n", path2);
1784 ok(!lstrcmp(out, "one\\mid."), "Expected one\\mid., got %s\n", out);
1785 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1787 /* try . in the middle of a directory */
1788 SetLastError(0xdeadbeef);
1789 lstrcpy(path1, "one\\mid.end\\two");
1790 lstrcpy(path2, "one\\mid.end\\three");
1791 lstrcpy(out, "aaa");
1792 count = PathCommonPrefixA(path1, path2, out);
1793 ok(count == 11, "Expected 11, got %i\n", count);
1794 ok(!lstrcmp(path1, "one\\mid.end\\two"), "Expected one\\mid.end\\two, got %s\n", path1);
1795 ok(!lstrcmp(path2, "one\\mid.end\\three"), "Expected one\\mid.end\\three, got %s\n", path2);
1796 ok(!lstrcmp(out, "one\\mid.end"), "Expected one\\mid.end, got %s\n", out);
1797 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1799 /* try comparing a .. with the expanded path */
1800 SetLastError(0xdeadbeef);
1801 lstrcpy(path1, "one\\..\\two");
1802 lstrcpy(path2, "two");
1803 lstrcpy(out, "aaa");
1804 count = PathCommonPrefixA(path1, path2, out);
1805 ok(count == 0, "Expected 0, got %i\n", count);
1806 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1807 ok(!lstrcmp(path2, "two"), "Expected two, got %s\n", path2);
1808 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1809 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1812 static void test_PathUnquoteSpaces(void)
1815 for(i = 0; i < sizeof(TEST_PATH_UNQUOTE_SPACES) / sizeof(TEST_PATH_UNQUOTE_SPACES[0]); i++)
1817 char *path = strdupA(TEST_PATH_UNQUOTE_SPACES[i].path);
1818 WCHAR *pathW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].path);
1819 WCHAR *resultW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].result);
1821 PathUnquoteSpacesA(path);
1822 ok(!strcmp(path, TEST_PATH_UNQUOTE_SPACES[i].result), "%s (A): got %s expected %s\n",
1823 TEST_PATH_UNQUOTE_SPACES[i].path, path,
1824 TEST_PATH_UNQUOTE_SPACES[i].result);
1826 PathUnquoteSpacesW(pathW);
1827 ok(!lstrcmpW(pathW, resultW), "%s (W): strings differ\n",
1828 TEST_PATH_UNQUOTE_SPACES[i].path);
1829 FreeWideString(pathW);
1830 FreeWideString(resultW);
1831 HeapFree(GetProcessHeap(), 0, path);
1837 hShlwapi = LoadLibraryA("shlwapi.dll");
1838 if (!hShlwapi) return;
1842 test_UrlCanonicalize();
1845 test_UrlCreateFromPath();
1849 test_PathSearchAndQualify();
1850 test_PathCreateFromUrl();
1853 test_PathAddBackslash();
1854 test_PathMakePretty();
1855 test_PathMatchSpec();
1857 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
1858 * ordinal number in some native versions. Check this to prevent a crash.
1860 pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
1861 if (pPathIsValidCharA && pPathIsValidCharA != (void*)GetProcAddress(hShlwapi, "PathAppendA"))
1863 test_PathIsValidCharA();
1865 pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
1866 if (pPathIsValidCharW) test_PathIsValidCharW();
1869 pPathCombineW = (void*)GetProcAddress(hShlwapi, "PathCombineW");
1871 test_PathCombineW();
1873 test_PathCombineA();
1875 test_PathCanonicalizeA();
1876 test_PathFindExtensionA();
1877 test_PathBuildRootA();
1878 test_PathCommonPrefixA();
1879 test_PathUnquoteSpaces();