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;
955 WCHAR wbuf[MAX_PATH+1], wstr1[MAX_PATH] = {'C',':','\\',0}, wstr2[MAX_PATH];
956 static const WCHAR expout[] = {'C',':','\\','A','A',0};
959 wszString2 = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
962 wszString = pPathCombineW(NULL, NULL, NULL);
963 ok (wszString == NULL, "Expected a NULL return\n");
967 wszString = pPathCombineW(wszString2, NULL, NULL);
968 ok (wszString == NULL, "Expected a NULL return\n");
969 ok (wszString2[0] == 0, "Destination string not empty\n");
971 HeapFree(GetProcessHeap(), 0, wszString2);
974 wstr2[0] = wstr2[1] = wstr2[2] = 'A';
975 for (i=3; i<MAX_PATH/2; i++)
976 wstr1[i] = wstr2[i] = 'A';
977 wstr1[(MAX_PATH/2) - 1] = wstr2[MAX_PATH/2] = 0;
978 memset(wbuf, 0xbf, sizeof(wbuf));
980 wszString = pPathCombineW(wbuf, wstr1, wstr2);
981 ok(wszString == NULL, "Expected a NULL return\n");
982 ok(wbuf[0] == 0, "Buffer contains data\n");
984 /* PathCombineW can be used in place */
987 ok(PathCombineW(wstr1, wstr1, wstr2) == wstr1, "Expected a wstr1 return\n");
988 ok(StrCmpW(wstr1, expout) == 0, "Unexpected PathCombine output\n");
992 #define LONG_LEN (MAX_PATH * 2)
993 #define HALF_LEN (MAX_PATH / 2 + 1)
995 static void test_PathCombineA(void)
999 char too_long[LONG_LEN];
1000 char one[HALF_LEN], two[HALF_LEN];
1003 SetLastError(0xdeadbeef);
1004 str = PathCombineA(NULL, "C:\\", "one\\two\\three");
1005 ok(str == NULL, "Expected NULL, got %p\n", str);
1006 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1008 /* try NULL dest and NULL directory */
1009 SetLastError(0xdeadbeef);
1010 str = PathCombineA(NULL, NULL, "one\\two\\three");
1011 ok(str == NULL, "Expected NULL, got %p\n", str);
1012 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1015 SetLastError(0xdeadbeef);
1016 str = PathCombineA(NULL, NULL, NULL);
1017 ok(str == NULL, "Expected NULL, got %p\n", str);
1018 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1020 /* try NULL file part */
1021 SetLastError(0xdeadbeef);
1022 lstrcpyA(dest, "control");
1023 str = PathCombineA(dest, "C:\\", NULL);
1024 ok(str == dest, "Expected str == dest, got %p\n", str);
1025 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
1026 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1028 /* try empty file part */
1029 SetLastError(0xdeadbeef);
1030 lstrcpyA(dest, "control");
1031 str = PathCombineA(dest, "C:\\", "");
1032 ok(str == dest, "Expected str == dest, got %p\n", str);
1033 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
1034 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1036 /* try empty directory and file part */
1037 SetLastError(0xdeadbeef);
1038 lstrcpyA(dest, "control");
1039 str = PathCombineA(dest, "", "");
1040 ok(str == dest, "Expected str == dest, got %p\n", str);
1041 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
1042 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1044 /* try NULL directory */
1045 SetLastError(0xdeadbeef);
1046 lstrcpyA(dest, "control");
1047 str = PathCombineA(dest, NULL, "one\\two\\three");
1048 ok(str == dest, "Expected str == dest, got %p\n", str);
1049 ok(!lstrcmp(str, "one\\two\\three"), "Expected one\\two\\three, got %s\n", str);
1050 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1052 /* try NULL directory and empty file part */
1053 SetLastError(0xdeadbeef);
1054 lstrcpyA(dest, "control");
1055 str = PathCombineA(dest, NULL, "");
1056 ok(str == dest, "Expected str == dest, got %p\n", str);
1057 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
1058 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1060 /* try NULL directory and file part */
1061 SetLastError(0xdeadbeef);
1062 lstrcpyA(dest, "control");
1063 str = PathCombineA(dest, NULL, NULL);
1064 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1065 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1066 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1068 /* try directory without backslash */
1069 SetLastError(0xdeadbeef);
1070 lstrcpyA(dest, "control");
1071 str = PathCombineA(dest, "C:", "one\\two\\three");
1072 ok(str == dest, "Expected str == dest, got %p\n", str);
1073 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1074 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1076 /* try directory with backslash */
1077 SetLastError(0xdeadbeef);
1078 lstrcpyA(dest, "control");
1079 str = PathCombineA(dest, "C:\\", "one\\two\\three");
1080 ok(str == dest, "Expected str == dest, got %p\n", str);
1081 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1082 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1084 /* try directory with backslash and file with prepended backslash */
1085 SetLastError(0xdeadbeef);
1086 lstrcpyA(dest, "control");
1087 str = PathCombineA(dest, "C:\\", "\\one\\two\\three");
1088 ok(str == dest, "Expected str == dest, got %p\n", str);
1089 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1090 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1092 /* try previous test, with backslash appended as well */
1093 SetLastError(0xdeadbeef);
1094 lstrcpyA(dest, "control");
1095 str = PathCombineA(dest, "C:\\", "\\one\\two\\three\\");
1096 ok(str == dest, "Expected str == dest, got %p\n", str);
1097 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
1098 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1100 /* try a relative directory */
1101 SetLastError(0xdeadbeef);
1102 lstrcpyA(dest, "control");
1103 str = PathCombineA(dest, "relative\\dir", "\\one\\two\\three\\");
1104 ok(str == dest, "Expected str == dest, got %p\n", str);
1105 ok(!lstrcmp(str, "one\\two\\three\\"), "Expected one\\two\\three\\, got %s\n", str);
1106 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1108 /* try forward slashes */
1109 SetLastError(0xdeadbeef);
1110 lstrcpyA(dest, "control");
1111 str = PathCombineA(dest, "C:\\", "one/two/three\\");
1112 ok(str == dest, "Expected str == dest, got %p\n", str);
1113 ok(!lstrcmp(str, "C:\\one/two/three\\"), "Expected one/two/three\\, got %s\n", str);
1114 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1116 /* try a really weird directory */
1117 SetLastError(0xdeadbeef);
1118 lstrcpyA(dest, "control");
1119 str = PathCombineA(dest, "C:\\/\\/", "\\one\\two\\three\\");
1120 ok(str == dest, "Expected str == dest, got %p\n", str);
1121 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
1122 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1125 SetLastError(0xdeadbeef);
1126 lstrcpyA(dest, "control");
1127 str = PathCombineA(dest, "C:\\", "one\\..\\two\\.\\three");
1128 ok(str == dest, "Expected str == dest, got %p\n", str);
1129 ok(!lstrcmp(str, "C:\\two\\three"), "Expected C:\\two\\three, got %s\n", str);
1130 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1132 /* try .. as file */
1133 /* try forward slashes */
1134 SetLastError(0xdeadbeef);
1135 lstrcpyA(dest, "control");
1136 str = PathCombineA(dest, "C:\\", "..");
1137 ok(str == dest, "Expected str == dest, got %p\n", str);
1138 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
1139 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1141 memset(too_long, 'a', LONG_LEN);
1142 too_long[LONG_LEN - 1] = '\0';
1144 /* try a file longer than MAX_PATH */
1145 SetLastError(0xdeadbeef);
1146 lstrcpyA(dest, "control");
1147 str = PathCombineA(dest, "C:\\", too_long);
1148 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1149 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1150 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1152 /* try a directory longer than MAX_PATH */
1153 SetLastError(0xdeadbeef);
1154 lstrcpyA(dest, "control");
1155 str = PathCombineA(dest, too_long, "one\\two\\three");
1156 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1157 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1158 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1160 memset(one, 'b', HALF_LEN);
1161 memset(two, 'c', HALF_LEN);
1162 one[HALF_LEN - 1] = '\0';
1163 two[HALF_LEN - 1] = '\0';
1165 /* destination string is longer than MAX_PATH, but not the constituent parts */
1166 SetLastError(0xdeadbeef);
1167 lstrcpyA(dest, "control");
1168 str = PathCombineA(dest, one, two);
1169 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1170 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1171 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1174 static void test_PathAddBackslash(void)
1177 char path[MAX_PATH];
1178 char too_long[LONG_LEN];
1180 /* try a NULL path */
1181 SetLastError(0xdeadbeef);
1182 str = PathAddBackslashA(NULL);
1183 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1184 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1186 /* try an empty path */
1188 SetLastError(0xdeadbeef);
1189 str = PathAddBackslashA(path);
1190 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1191 ok(lstrlenA(path) == 0, "Expected empty string, got %i\n", lstrlenA(path));
1192 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1194 /* try a relative path */
1195 lstrcpyA(path, "one\\two");
1196 SetLastError(0xdeadbeef);
1197 str = PathAddBackslashA(path);
1198 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1199 ok(!lstrcmp(path, "one\\two\\"), "Expected one\\two\\, got %s\n", path);
1200 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1203 lstrcpyA(path, "one\\..\\two");
1204 SetLastError(0xdeadbeef);
1205 str = PathAddBackslashA(path);
1206 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1207 ok(!lstrcmp(path, "one\\..\\two\\"), "Expected one\\..\\two\\, got %s\n", path);
1208 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1210 /* try just a space */
1211 lstrcpyA(path, " ");
1212 SetLastError(0xdeadbeef);
1213 str = PathAddBackslashA(path);
1214 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1215 ok(!lstrcmp(path, " \\"), "Expected \\, got %s\n", path);
1216 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1218 /* path already has backslash */
1219 lstrcpyA(path, "C:\\one\\");
1220 SetLastError(0xdeadbeef);
1221 str = PathAddBackslashA(path);
1222 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1223 ok(!lstrcmp(path, "C:\\one\\"), "Expected C:\\one\\, got %s\n", path);
1224 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1226 memset(too_long, 'a', LONG_LEN);
1227 too_long[LONG_LEN - 1] = '\0';
1229 /* path is longer than MAX_PATH */
1230 SetLastError(0xdeadbeef);
1231 str = PathAddBackslashA(too_long);
1232 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1233 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1236 static void test_PathAppendA(void)
1238 char path[MAX_PATH];
1239 char too_long[LONG_LEN];
1240 char one[HALF_LEN], two[HALF_LEN];
1243 lstrcpy(path, "C:\\one");
1245 /* try NULL pszMore */
1246 SetLastError(0xdeadbeef);
1247 res = PathAppendA(path, NULL);
1248 ok(!res, "Expected failure\n");
1249 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1250 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
1252 /* try empty pszMore */
1253 SetLastError(0xdeadbeef);
1254 res = PathAppendA(path, "");
1255 ok(res, "Expected success\n");
1256 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1257 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
1259 /* try NULL pszPath */
1260 SetLastError(0xdeadbeef);
1261 res = PathAppendA(NULL, "two\\three");
1262 ok(!res, "Expected failure\n");
1263 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1265 /* try empty pszPath */
1267 SetLastError(0xdeadbeef);
1268 res = PathAppendA(path, "two\\three");
1269 ok(res, "Expected success\n");
1270 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1271 ok(!lstrcmp(path, "two\\three"), "Expected \\two\\three, got %s\n", path);
1273 /* try empty pszPath and empty pszMore */
1275 SetLastError(0xdeadbeef);
1276 res = PathAppendA(path, "");
1277 ok(res, "Expected success\n");
1278 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1279 ok(!lstrcmp(path, "\\"), "Expected \\, got %s\n", path);
1281 /* try legit params */
1282 lstrcpy(path, "C:\\one");
1283 SetLastError(0xdeadbeef);
1284 res = PathAppendA(path, "two\\three");
1285 ok(res, "Expected success\n");
1286 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1287 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1289 /* try pszPath with backslash after it */
1290 lstrcpy(path, "C:\\one\\");
1291 SetLastError(0xdeadbeef);
1292 res = PathAppendA(path, "two\\three");
1293 ok(res, "Expected success\n");
1294 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1295 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1297 /* try pszMore with backslash before it */
1298 lstrcpy(path, "C:\\one");
1299 SetLastError(0xdeadbeef);
1300 res = PathAppendA(path, "\\two\\three");
1301 ok(res, "Expected success\n");
1302 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1303 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1305 /* try pszMore with backslash after it */
1306 lstrcpy(path, "C:\\one");
1307 SetLastError(0xdeadbeef);
1308 res = PathAppendA(path, "two\\three\\");
1309 ok(res, "Expected success\n");
1310 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1311 ok(!lstrcmp(path, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", path);
1313 /* try spaces in pszPath */
1314 lstrcpy(path, "C: \\ one ");
1315 SetLastError(0xdeadbeef);
1316 res = PathAppendA(path, "two\\three");
1317 ok(res, "Expected success\n");
1318 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1319 ok(!lstrcmp(path, "C: \\ one \\two\\three"), "Expected C: \\ one \\two\\three, got %s\n", path);
1321 /* try spaces in pszMore */
1322 lstrcpy(path, "C:\\one");
1323 SetLastError(0xdeadbeef);
1324 res = PathAppendA(path, " two \\ three ");
1325 ok(res, "Expected success\n");
1326 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1327 ok(!lstrcmp(path, "C:\\one\\ two \\ three "), "Expected 'C:\\one\\ two \\ three ', got %s\n", path);
1329 /* pszPath is too long */
1330 memset(too_long, 'a', LONG_LEN);
1331 too_long[LONG_LEN - 1] = '\0';
1332 SetLastError(0xdeadbeef);
1333 res = PathAppendA(too_long, "two\\three");
1334 ok(!res, "Expected failure\n");
1335 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1336 ok(lstrlen(too_long) == 0, "Expected length of too_long to be zero, got %i\n", lstrlen(too_long));
1338 /* pszMore is too long */
1339 lstrcpy(path, "C:\\one");
1340 memset(too_long, 'a', LONG_LEN);
1341 too_long[LONG_LEN - 1] = '\0';
1342 SetLastError(0xdeadbeef);
1343 res = PathAppendA(path, too_long);
1344 ok(!res, "Expected failure\n");
1345 todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1346 ok(lstrlen(path) == 0, "Expected length of path to be zero, got %i\n", lstrlen(path));
1348 /* both params combined are too long */
1349 memset(one, 'a', HALF_LEN);
1350 one[HALF_LEN - 1] = '\0';
1351 memset(two, 'b', HALF_LEN);
1352 two[HALF_LEN - 1] = '\0';
1353 SetLastError(0xdeadbeef);
1354 res = PathAppendA(one, two);
1355 ok(!res, "Expected failure\n");
1356 ok(lstrlen(one) == 0, "Expected length of one to be zero, got %i\n", lstrlen(one));
1357 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1360 static void test_PathCanonicalizeA(void)
1362 char dest[MAX_PATH];
1363 char too_long[LONG_LEN];
1366 /* try a NULL source */
1367 lstrcpy(dest, "test");
1368 SetLastError(0xdeadbeef);
1369 res = PathCanonicalizeA(dest, NULL);
1370 ok(!res, "Expected failure\n");
1371 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1372 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1375 ok(!lstrcmp(dest, "test"), "Expected test, got %s\n", dest);
1378 /* try an empty source */
1379 lstrcpy(dest, "test");
1380 SetLastError(0xdeadbeef);
1381 res = PathCanonicalizeA(dest, "");
1382 ok(res, "Expected success\n");
1383 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1384 ok(!lstrcmp(dest, "\\"), "Expected \\, got %s\n", dest);
1386 /* try a NULL dest */
1387 SetLastError(0xdeadbeef);
1388 res = PathCanonicalizeA(NULL, "C:\\");
1389 ok(!res, "Expected failure\n");
1390 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1391 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1393 /* try empty dest */
1395 SetLastError(0xdeadbeef);
1396 res = PathCanonicalizeA(dest, "C:\\");
1397 ok(res, "Expected success\n");
1398 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1399 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
1401 /* try non-empty dest */
1402 lstrcpy(dest, "test");
1403 SetLastError(0xdeadbeef);
1404 res = PathCanonicalizeA(dest, "C:\\");
1405 ok(res, "Expected success\n");
1406 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1407 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
1409 /* try a space for source */
1410 lstrcpy(dest, "test");
1411 SetLastError(0xdeadbeef);
1412 res = PathCanonicalizeA(dest, " ");
1413 ok(res, "Expected success\n");
1414 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1415 ok(!lstrcmp(dest, " "), "Expected ' ', got %s\n", dest);
1417 /* try a relative path */
1418 lstrcpy(dest, "test");
1419 SetLastError(0xdeadbeef);
1420 res = PathCanonicalizeA(dest, "one\\two");
1421 ok(res, "Expected success\n");
1422 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1423 ok(!lstrcmp(dest, "one\\two"), "Expected one\\two, got %s\n", dest);
1425 /* try current dir and previous dir */
1426 lstrcpy(dest, "test");
1427 SetLastError(0xdeadbeef);
1428 res = PathCanonicalizeA(dest, "C:\\one\\.\\..\\two\\three\\..");
1429 ok(res, "Expected success\n");
1430 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1431 ok(!lstrcmp(dest, "C:\\two"), "Expected C:\\two, got %s\n", dest);
1433 /* try simple forward slashes */
1434 lstrcpy(dest, "test");
1435 SetLastError(0xdeadbeef);
1436 res = PathCanonicalizeA(dest, "C:\\one/two/three\\four/five\\six");
1437 ok(res, "Expected success\n");
1438 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1439 ok(!lstrcmp(dest, "C:\\one/two/three\\four/five\\six"),
1440 "Expected C:\\one/two/three\\four/five\\six, got %s\n", dest);
1442 /* try simple forward slashes with same dir */
1443 lstrcpy(dest, "test");
1444 SetLastError(0xdeadbeef);
1445 res = PathCanonicalizeA(dest, "C:\\one/.\\two");
1446 ok(res, "Expected success\n");
1447 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1448 ok(!lstrcmp(dest, "C:\\one/.\\two"), "Expected C:\\one/.\\two, got %s\n", dest);
1450 /* try simple forward slashes with change dir */
1451 lstrcpy(dest, "test");
1452 SetLastError(0xdeadbeef);
1453 res = PathCanonicalizeA(dest, "C:\\one/.\\two\\..");
1454 ok(res, "Expected success\n");
1455 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1456 ok(!lstrcmp(dest, "C:\\one/."), "Expected C:\\one/., got %s\n", dest);
1458 /* try forward slashes with change dirs
1459 * NOTE: if there is a forward slash in between two backslashes,
1460 * everything in between the two backslashes is considered on dir
1462 lstrcpy(dest, "test");
1463 SetLastError(0xdeadbeef);
1464 res = PathCanonicalizeA(dest, "C:\\one/.\\..\\two/three\\..\\four/.five");
1465 ok(res, "Expected success\n");
1466 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1467 ok(!lstrcmp(dest, "C:\\four/.five"), "Expected C:\\four/.five, got %s\n", dest);
1469 /* try src is too long */
1470 memset(too_long, 'a', LONG_LEN);
1471 too_long[LONG_LEN - 1] = '\0';
1472 lstrcpy(dest, "test");
1473 SetLastError(0xdeadbeef);
1474 res = PathCanonicalizeA(dest, too_long);
1477 ok(!res, "Expected failure\n");
1478 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1480 ok(lstrlen(too_long) == LONG_LEN - 1, "Expected length LONG_LEN - 1, got %i\n", lstrlen(too_long));
1483 static void test_PathFindExtensionA(void)
1486 char path[MAX_PATH];
1487 char too_long[LONG_LEN];
1489 /* try a NULL path */
1490 SetLastError(0xdeadbeef);
1491 ext = PathFindExtensionA(NULL);
1492 ok(ext == NULL, "Expected NULL, got %p\n", ext);
1493 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1495 /* try an empty path */
1497 SetLastError(0xdeadbeef);
1498 ext = PathFindExtensionA(path);
1499 ok(ext == path, "Expected ext == path, got %p\n", ext);
1500 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1501 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1503 /* try a path without an extension */
1504 lstrcpy(path, "file");
1505 SetLastError(0xdeadbeef);
1506 ext = PathFindExtensionA(path);
1507 ok(ext == path + lstrlen(path), "Expected ext == path, got %p\n", ext);
1508 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1509 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1511 /* try a path with an extension */
1512 lstrcpy(path, "file.txt");
1513 SetLastError(0xdeadbeef);
1514 ext = PathFindExtensionA(path);
1515 ok(ext == path + lstrlen("file"),
1516 "Expected ext == path + lstrlen(\"file\"), got %p\n", ext);
1517 ok(!lstrcmp(ext, ".txt"), "Expected .txt, got %s\n", ext);
1518 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1520 /* try a path with two extensions */
1521 lstrcpy(path, "file.txt.doc");
1522 SetLastError(0xdeadbeef);
1523 ext = PathFindExtensionA(path);
1524 ok(ext == path + lstrlen("file.txt"),
1525 "Expected ext == path + lstrlen(\"file.txt\"), got %p\n", ext);
1526 ok(!lstrcmp(ext, ".doc"), "Expected .txt, got %s\n", ext);
1527 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1529 /* try a path longer than MAX_PATH without an extension*/
1530 memset(too_long, 'a', LONG_LEN);
1531 too_long[LONG_LEN - 1] = '\0';
1532 SetLastError(0xdeadbeef);
1533 ext = PathFindExtensionA(too_long);
1534 ok(ext == too_long + LONG_LEN - 1, "Expected ext == too_long + LONG_LEN - 1, got %p\n", ext);
1535 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1537 /* try a path longer than MAX_PATH with an extension*/
1538 memset(too_long, 'a', LONG_LEN);
1539 too_long[LONG_LEN - 1] = '\0';
1540 lstrcpy(too_long + 300, ".abcde");
1541 too_long[lstrlen(too_long)] = 'a';
1542 SetLastError(0xdeadbeef);
1543 ext = PathFindExtensionA(too_long);
1544 ok(ext == too_long + 300, "Expected ext == too_long + 300, got %p\n", ext);
1545 ok(lstrlen(ext) == LONG_LEN - 301, "Expected LONG_LEN - 301, got %i\n", lstrlen(ext));
1546 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1549 static void test_PathBuildRootA(void)
1553 char root_expected[26][4];
1557 /* set up the expected paths */
1558 for (drive = 'A'; drive <= 'Z'; drive++)
1559 sprintf(root_expected[drive - 'A'], "%c:\\", drive);
1561 /* test the expected values */
1562 for (j = 0; j < 26; j++)
1564 SetLastError(0xdeadbeef);
1565 lstrcpy(path, "aaaaaaaaa");
1566 root = PathBuildRootA(path, j);
1567 ok(root == path, "Expected root == path, got %p\n", root);
1568 ok(!lstrcmp(root, root_expected[j]), "Expected %s, got %s\n", root_expected[j], root);
1569 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1572 /* test a negative drive number */
1573 SetLastError(0xdeadbeef);
1574 lstrcpy(path, "aaaaaaaaa");
1575 root = PathBuildRootA(path, -1);
1576 ok(root == path, "Expected root == path, got %p\n", root);
1577 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1578 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1580 /* test a drive number greater than 25 */
1581 SetLastError(0xdeadbeef);
1582 lstrcpy(path, "aaaaaaaaa");
1583 root = PathBuildRootA(path, 26);
1584 ok(root == path, "Expected root == path, got %p\n", root);
1585 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1586 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1588 /* length of path is less than 4 */
1589 SetLastError(0xdeadbeef);
1590 lstrcpy(path, "aa");
1591 root = PathBuildRootA(path, 0);
1592 ok(root == path, "Expected root == path, got %p\n", root);
1593 ok(!lstrcmp(path, "A:\\"), "Expected A:\\, got %s\n", path);
1594 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1597 SetLastError(0xdeadbeef);
1598 root = PathBuildRootA(NULL, 0);
1599 ok(root == NULL, "Expected root == NULL, got %p\n", root);
1600 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1603 static void test_PathCommonPrefixA(void)
1605 char path1[MAX_PATH], path2[MAX_PATH];
1609 /* test NULL path1 */
1610 SetLastError(0xdeadbeef);
1611 lstrcpy(path2, "C:\\");
1612 lstrcpy(out, "aaa");
1613 count = PathCommonPrefixA(NULL, path2, out);
1614 ok(count == 0, "Expected 0, got %i\n", count);
1617 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1619 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1620 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1622 /* test NULL path2 */
1623 SetLastError(0xdeadbeef);
1624 lstrcpy(path1, "C:\\");
1625 lstrcpy(out, "aaa");
1626 count = PathCommonPrefixA(path1, NULL, out);
1627 ok(count == 0, "Expected 0, got %i\n", count);
1630 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1632 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1633 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1635 /* test empty path1 */
1636 SetLastError(0xdeadbeef);
1638 lstrcpy(path2, "C:\\");
1639 lstrcpy(out, "aaa");
1640 count = PathCommonPrefixA(path1, path2, out);
1641 ok(count == 0, "Expected 0, got %i\n", count);
1642 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1643 ok(lstrlen(path1) == 0, "Expected 0 length path1, got %i\n", lstrlen(path1));
1644 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1645 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1647 /* test empty path1 */
1648 SetLastError(0xdeadbeef);
1650 lstrcpy(path1, "C:\\");
1651 lstrcpy(out, "aaa");
1652 count = PathCommonPrefixA(path1, path2, out);
1653 ok(count == 0, "Expected 0, got %i\n", count);
1654 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1655 ok(lstrlen(path2) == 0, "Expected 0 length path2, got %i\n", lstrlen(path2));
1656 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1657 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1659 /* paths are legit, out is NULL */
1660 SetLastError(0xdeadbeef);
1661 lstrcpy(path1, "C:\\");
1662 lstrcpy(path2, "C:\\");
1663 count = PathCommonPrefixA(path1, path2, NULL);
1664 ok(count == 3, "Expected 3, got %i\n", count);
1665 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1666 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1667 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1669 /* all parameters legit */
1670 SetLastError(0xdeadbeef);
1671 lstrcpy(path1, "C:\\");
1672 lstrcpy(path2, "C:\\");
1673 lstrcpy(out, "aaa");
1674 count = PathCommonPrefixA(path1, path2, out);
1675 ok(count == 3, "Expected 3, got %i\n", count);
1676 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1677 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1678 ok(!lstrcmp(out, "C:\\"), "Expected C:\\, got %s\n", out);
1679 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1681 /* path1 and path2 not the same, but common prefix */
1682 SetLastError(0xdeadbeef);
1683 lstrcpy(path1, "C:\\one\\two");
1684 lstrcpy(path2, "C:\\one\\three");
1685 lstrcpy(out, "aaa");
1686 count = PathCommonPrefixA(path1, path2, out);
1687 ok(count == 6, "Expected 6, got %i\n", count);
1688 ok(!lstrcmp(path1, "C:\\one\\two"), "Expected C:\\one\\two, got %s\n", path1);
1689 ok(!lstrcmp(path2, "C:\\one\\three"), "Expected C:\\one\\three, got %s\n", path2);
1690 ok(!lstrcmp(out, "C:\\one"), "Expected C:\\one, got %s\n", out);
1691 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1694 SetLastError(0xdeadbeef);
1695 lstrcpy(path1, "one\\.two");
1696 lstrcpy(path2, "one\\.three");
1697 lstrcpy(out, "aaa");
1698 count = PathCommonPrefixA(path1, path2, out);
1699 ok(count == 3, "Expected 3, got %i\n", count);
1700 ok(!lstrcmp(path1, "one\\.two"), "Expected one\\.two, got %s\n", path1);
1701 ok(!lstrcmp(path2, "one\\.three"), "Expected one\\.three, got %s\n", path2);
1702 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1703 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1706 SetLastError(0xdeadbeef);
1707 lstrcpy(path1, "one\\..two");
1708 lstrcpy(path2, "one\\..three");
1709 lstrcpy(out, "aaa");
1710 count = PathCommonPrefixA(path1, path2, out);
1711 ok(count == 3, "Expected 3, got %i\n", count);
1712 ok(!lstrcmp(path1, "one\\..two"), "Expected one\\..two, got %s\n", path1);
1713 ok(!lstrcmp(path2, "one\\..three"), "Expected one\\..three, got %s\n", path2);
1714 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1715 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1717 /* try ... prefix */
1718 SetLastError(0xdeadbeef);
1719 lstrcpy(path1, "one\\...two");
1720 lstrcpy(path2, "one\\...three");
1721 lstrcpy(out, "aaa");
1722 count = PathCommonPrefixA(path1, path2, out);
1723 ok(count == 3, "Expected 3, got %i\n", count);
1724 ok(!lstrcmp(path1, "one\\...two"), "Expected one\\...two, got %s\n", path1);
1725 ok(!lstrcmp(path2, "one\\...three"), "Expected one\\...three, got %s\n", path2);
1726 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1727 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1730 SetLastError(0xdeadbeef);
1731 lstrcpy(path1, "one\\.\\two");
1732 lstrcpy(path2, "one\\.\\three");
1733 lstrcpy(out, "aaa");
1734 count = PathCommonPrefixA(path1, path2, out);
1735 ok(count == 5, "Expected 5, got %i\n", count);
1736 ok(!lstrcmp(path1, "one\\.\\two"), "Expected one\\.\\two, got %s\n", path1);
1737 ok(!lstrcmp(path2, "one\\.\\three"), "Expected one\\.\\three, got %s\n", path2);
1738 ok(!lstrcmp(out, "one\\."), "Expected one\\., got %s\n", out);
1739 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1741 /* try ..\ prefix */
1742 SetLastError(0xdeadbeef);
1743 lstrcpy(path1, "one\\..\\two");
1744 lstrcpy(path2, "one\\..\\three");
1745 lstrcpy(out, "aaa");
1746 count = PathCommonPrefixA(path1, path2, out);
1747 ok(count == 6, "Expected 6, got %i\n", count);
1748 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1749 ok(!lstrcmp(path2, "one\\..\\three"), "Expected one\\..\\three, got %s\n", path2);
1750 ok(!lstrcmp(out, "one\\.."), "Expected one\\.., got %s\n", out);
1751 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1753 /* try ...\\ prefix */
1754 SetLastError(0xdeadbeef);
1755 lstrcpy(path1, "one\\...\\two");
1756 lstrcpy(path2, "one\\...\\three");
1757 lstrcpy(out, "aaa");
1758 count = PathCommonPrefixA(path1, path2, out);
1759 ok(count == 7, "Expected 7, got %i\n", count);
1760 ok(!lstrcmp(path1, "one\\...\\two"), "Expected one\\...\\two, got %s\n", path1);
1761 ok(!lstrcmp(path2, "one\\...\\three"), "Expected one\\...\\three, got %s\n", path2);
1762 ok(!lstrcmp(out, "one\\..."), "Expected one\\..., got %s\n", out);
1763 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1765 /* try prefix that is not an msdn labeled prefix type */
1766 SetLastError(0xdeadbeef);
1767 lstrcpy(path1, "same");
1768 lstrcpy(path2, "same");
1769 lstrcpy(out, "aaa");
1770 count = PathCommonPrefixA(path1, path2, out);
1771 ok(count == 4, "Expected 4, got %i\n", count);
1772 ok(!lstrcmp(path1, "same"), "Expected same, got %s\n", path1);
1773 ok(!lstrcmp(path2, "same"), "Expected same, got %s\n", path2);
1774 ok(!lstrcmp(out, "same"), "Expected same, got %s\n", out);
1775 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1777 /* try . after directory */
1778 SetLastError(0xdeadbeef);
1779 lstrcpy(path1, "one\\mid.\\two");
1780 lstrcpy(path2, "one\\mid.\\three");
1781 lstrcpy(out, "aaa");
1782 count = PathCommonPrefixA(path1, path2, out);
1783 ok(count == 8, "Expected 8, got %i\n", count);
1784 ok(!lstrcmp(path1, "one\\mid.\\two"), "Expected one\\mid.\\two, got %s\n", path1);
1785 ok(!lstrcmp(path2, "one\\mid.\\three"), "Expected one\\mid.\\three, got %s\n", path2);
1786 ok(!lstrcmp(out, "one\\mid."), "Expected one\\mid., got %s\n", out);
1787 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1789 /* try . in the middle of a directory */
1790 SetLastError(0xdeadbeef);
1791 lstrcpy(path1, "one\\mid.end\\two");
1792 lstrcpy(path2, "one\\mid.end\\three");
1793 lstrcpy(out, "aaa");
1794 count = PathCommonPrefixA(path1, path2, out);
1795 ok(count == 11, "Expected 11, got %i\n", count);
1796 ok(!lstrcmp(path1, "one\\mid.end\\two"), "Expected one\\mid.end\\two, got %s\n", path1);
1797 ok(!lstrcmp(path2, "one\\mid.end\\three"), "Expected one\\mid.end\\three, got %s\n", path2);
1798 ok(!lstrcmp(out, "one\\mid.end"), "Expected one\\mid.end, got %s\n", out);
1799 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1801 /* try comparing a .. with the expanded path */
1802 SetLastError(0xdeadbeef);
1803 lstrcpy(path1, "one\\..\\two");
1804 lstrcpy(path2, "two");
1805 lstrcpy(out, "aaa");
1806 count = PathCommonPrefixA(path1, path2, out);
1807 ok(count == 0, "Expected 0, got %i\n", count);
1808 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1809 ok(!lstrcmp(path2, "two"), "Expected two, got %s\n", path2);
1810 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1811 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1814 static void test_PathUnquoteSpaces(void)
1817 for(i = 0; i < sizeof(TEST_PATH_UNQUOTE_SPACES) / sizeof(TEST_PATH_UNQUOTE_SPACES[0]); i++)
1819 char *path = strdupA(TEST_PATH_UNQUOTE_SPACES[i].path);
1820 WCHAR *pathW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].path);
1821 WCHAR *resultW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].result);
1823 PathUnquoteSpacesA(path);
1824 ok(!strcmp(path, TEST_PATH_UNQUOTE_SPACES[i].result), "%s (A): got %s expected %s\n",
1825 TEST_PATH_UNQUOTE_SPACES[i].path, path,
1826 TEST_PATH_UNQUOTE_SPACES[i].result);
1828 PathUnquoteSpacesW(pathW);
1829 ok(!lstrcmpW(pathW, resultW), "%s (W): strings differ\n",
1830 TEST_PATH_UNQUOTE_SPACES[i].path);
1831 FreeWideString(pathW);
1832 FreeWideString(resultW);
1833 HeapFree(GetProcessHeap(), 0, path);
1839 hShlwapi = LoadLibraryA("shlwapi.dll");
1840 if (!hShlwapi) return;
1844 test_UrlCanonicalize();
1847 test_UrlCreateFromPath();
1851 test_PathSearchAndQualify();
1852 test_PathCreateFromUrl();
1855 test_PathAddBackslash();
1856 test_PathMakePretty();
1857 test_PathMatchSpec();
1859 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
1860 * ordinal number in some native versions. Check this to prevent a crash.
1862 pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
1863 if (pPathIsValidCharA && pPathIsValidCharA != (void*)GetProcAddress(hShlwapi, "PathAppendA"))
1865 test_PathIsValidCharA();
1867 pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
1868 if (pPathIsValidCharW) test_PathIsValidCharW();
1871 pPathCombineW = (void*)GetProcAddress(hShlwapi, "PathCombineW");
1873 test_PathCombineW();
1875 test_PathCombineA();
1877 test_PathCanonicalizeA();
1878 test_PathFindExtensionA();
1879 test_PathBuildRootA();
1880 test_PathCommonPrefixA();
1881 test_PathUnquoteSpaces();