Tests should not use wine/unicode.h.
[wine/multimedia.git] / dlls / shlwapi / tests / path.c
blob043e8992d3416f5f9cea856a09b270ea4d839cb2
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
20 #include <assert.h>
21 #include <stdarg.h>
22 #include <stdio.h>
24 #include "wine/test.h"
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winreg.h"
28 #include "shlwapi.h"
29 #include "wininet.h"
31 static HMODULE hShlwapi;
32 static HRESULT (WINAPI *pPathIsValidCharA)(char,DWORD);
33 static HRESULT (WINAPI *pPathIsValidCharW)(WCHAR,DWORD);
35 const char* TEST_URL_1 = "http://www.winehq.org/tests?date=10/10/1923";
36 const char* TEST_URL_2 = "http://localhost:8080/tests%2e.html?date=Mon%2010/10/1923";
37 const char* TEST_URL_3 = "http://foo:bar@localhost:21/internal.php?query=x&return=y";
39 typedef struct _TEST_URL_CANONICALIZE {
40 const char *url;
41 DWORD flags;
42 HRESULT expectret;
43 const char *expecturl;
44 } TEST_URL_CANONICALIZE;
46 const TEST_URL_CANONICALIZE TEST_CANONICALIZE[] = {
47 /*FIXME {"http://www.winehq.org/tests/../tests/../..", 0, S_OK, "http://www.winehq.org/"},*/
48 {"http://www.winehq.org/tests/../tests", 0, S_OK, "http://www.winehq.org/tests"},
49 {"http://www.winehq.org/tests\n", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests"},
50 {"http://www.winehq.org/tests\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests"},
51 {"http://www.winehq.org/tests\r", 0, S_OK, "http://www.winehq.org/tests"},
52 {"http://www.winehq.org/tests\r", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests"},
53 {"http://www.winehq.org/tests/../tests/", 0, S_OK, "http://www.winehq.org/tests/"},
54 {"http://www.winehq.org/tests/../tests/..", 0, S_OK, "http://www.winehq.org/"},
55 {"http://www.winehq.org/tests/../tests/../", 0, S_OK, "http://www.winehq.org/"},
56 {"http://www.winehq.org/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/..?query=x&return=y", 0, S_OK, "http://www.winehq.org/?query=x&return=y"},
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/..#example", 0, S_OK, "http://www.winehq.org/#example"},
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", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../#example"},
66 {"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"},
67 {"http://www.winehq.org/tests/foo%20bar", URL_UNESCAPE , S_OK, "http://www.winehq.org/tests/foo bar"},
68 {"file:///c:/tests/foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/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_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar"},
71 {"file://c:/tests/../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/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 bar", 0, S_OK, "file:///c:/tests/foo bar"},
76 {"file:///c:\\tests\\foo bar", URL_DONT_SIMPLIFY, S_OK, "file:///c:/tests/foo bar"},
79 typedef struct _TEST_URL_ESCAPE {
80 const char *url;
81 DWORD flags;
82 DWORD expectescaped;
83 HRESULT expectret;
84 const char *expecturl;
85 } TEST_URL_ESCAPE;
87 const TEST_URL_ESCAPE TEST_ESCAPE[] = {
88 {"http://www.winehq.org/tests0", 0, 0, S_OK, "http://www.winehq.org/tests0"},
89 {"http://www.winehq.org/tests1\n", 0, 0, S_OK, "http://www.winehq.org/tests1%0A"},
90 {"http://www.winehq.org/tests2\r", 0, 0, S_OK, "http://www.winehq.org/tests2%0D"},
91 {"http://www.winehq.org/tests3\r", URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, 0, S_OK, "http://www.winehq.org/tests3\r"},
92 {"http://www.winehq.org/tests4\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests4\r"},
93 {"http://www.winehq.org/tests5\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests5\r"},
94 {"/direct/swhelp/series6/6.2i_latestservicepack.dat\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "/direct/swhelp/series6/6.2i_latestservicepack.dat\r"},
96 {"file://////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
97 {"file://///foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
98 {"file:////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
99 {"file:///localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"},
100 {"file:///foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
101 {"file://loCalHost/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
102 {"file://foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
103 {"file:/localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"},
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:\\\\foo/bar\\baz", 0, 0, S_OK, "file://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:///f oo/b?a r\\baz", 0, 0, S_OK, "file:///f%20oo/b?a r\\baz"},
111 {"file:///foo/b#a r\\baz", 0, 0, S_OK, "file:///foo/b%23a%20r/baz"},
112 {"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"},
113 {"file:///f o%o/b?a r\\b%az", URL_ESCAPE_PERCENT, 0, S_OK, "file:///f%20o%25o/b?a r\\b%az"},
114 {"file:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "file:%2Ffoo%2Fbar%5Cbaz"},
116 {"foo/b%ar\\ba?z\\", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%ar%5Cba%3Fz%5C"},
117 {"foo/b%ar\\ba?z\\", URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%25ar%5Cba%3Fz%5C"},
118 {"foo/bar\\ba?z\\", 0, 0, S_OK, "foo/bar%5Cba?z\\"},
119 {"/foo/bar\\ba?z\\", 0, 0, S_OK, "/foo/bar%5Cba?z\\"},
120 {"/foo/bar\\ba#z\\", 0, 0, S_OK, "/foo/bar%5Cba#z\\"},
121 {"/foo/%5C", 0, 0, S_OK, "/foo/%5C"},
122 {"/foo/%5C", URL_ESCAPE_PERCENT, 0, S_OK, "/foo/%255C"},
124 {"http://////foo/bar\\baz", 0, 0, S_OK, "http://////foo/bar/baz"},
125 {"http://///foo/bar\\baz", 0, 0, S_OK, "http://///foo/bar/baz"},
126 {"http:////foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"},
127 {"http:///foo/bar\\baz", 0, 0, S_OK, "http:///foo/bar/baz"},
128 {"http://localhost/foo/bar\\baz", 0, 0, S_OK, "http://localhost/foo/bar/baz"},
129 {"http://foo/bar\\baz", 0, 0, S_OK, "http://foo/bar/baz"},
130 {"http:/foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"},
131 {"http:foo/bar\\ba?z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba?z\\"},
132 {"http:foo/bar\\ba#z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba#z\\"},
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:\\\\\\\\foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"},
137 {"http:/fo ?o/b ar\\baz", 0, 0, S_OK, "http:/fo%20?o/b ar\\baz"},
138 {"http:fo ?o/b ar\\baz", 0, 0, S_OK, "http:fo%20?o/b ar\\baz"},
139 {"http:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "http:%2Ffoo%2Fbar%5Cbaz"},
141 {"https://foo/bar\\baz", 0, 0, S_OK, "https://foo/bar/baz"},
142 {"https:/foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"},
143 {"https:\\foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"},
145 {"foo:////foo/bar\\baz", 0, 0, S_OK, "foo:////foo/bar%5Cbaz"},
146 {"foo:///foo/bar\\baz", 0, 0, S_OK, "foo:///foo/bar%5Cbaz"},
147 {"foo://localhost/foo/bar\\baz", 0, 0, S_OK, "foo://localhost/foo/bar%5Cbaz"},
148 {"foo://foo/bar\\baz", 0, 0, S_OK, "foo://foo/bar%5Cbaz"},
149 {"foo:/foo/bar\\baz", 0, 0, S_OK, "foo:/foo/bar%5Cbaz"},
150 {"foo:foo/bar\\baz", 0, 0, S_OK, "foo:foo%2Fbar%5Cbaz"},
151 {"foo:\\foo/bar\\baz", 0, 0, S_OK, "foo:%5Cfoo%2Fbar%5Cbaz"},
152 {"foo:/foo/bar\\ba?\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba?\\z"},
153 {"foo:/foo/bar\\ba#\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba#\\z"},
155 {"mailto:/fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:%2Ffo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
156 {"mailto:fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:fo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
157 {"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"},
159 {"ftp:fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:fo%2Fo@bar.baz%2Ffoo%2Fbar"},
160 {"ftp:/fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:/fo/o@bar.baz/foo/bar"},
161 {"ftp://fo/o@bar.baz/fo?o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo?o\\bar"},
162 {"ftp://fo/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo#o\\bar"},
163 {"ftp://localhost/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://localhost/o@bar.baz/fo#o\\bar"},
164 {"ftp:///fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:///fo/o@bar.baz/foo/bar"},
165 {"ftp:////fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:////fo/o@bar.baz/foo/bar"}
168 typedef struct _TEST_URL_COMBINE {
169 const char *url1;
170 const char *url2;
171 DWORD flags;
172 HRESULT expectret;
173 const char *expecturl;
174 } TEST_URL_COMBINE;
176 const TEST_URL_COMBINE TEST_COMBINE[] = {
177 {"http://www.winehq.org/tests", "tests1", 0, S_OK, "http://www.winehq.org/tests1"},
178 {"http://www.%77inehq.org/tests", "tests1", 0, S_OK, "http://www.%77inehq.org/tests1"},
179 /*FIXME {"http://www.winehq.org/tests", "../tests2", 0, S_OK, "http://www.winehq.org/tests2"},*/
180 {"http://www.winehq.org/tests/", "../tests3", 0, S_OK, "http://www.winehq.org/tests3"},
181 {"http://www.winehq.org/tests/test1", "test2", 0, S_OK, "http://www.winehq.org/tests/test2"},
182 {"http://www.winehq.org/tests/../tests", "tests4", 0, S_OK, "http://www.winehq.org/tests4"},
183 {"http://www.winehq.org/tests/../tests/", "tests5", 0, S_OK, "http://www.winehq.org/tests/tests5"},
184 {"http://www.winehq.org/tests/../tests/", "/tests6/..", 0, S_OK, "http://www.winehq.org/"},
185 {"http://www.winehq.org/tests/../tests/..", "tests7/..", 0, S_OK, "http://www.winehq.org/"},
186 {"http://www.winehq.org/tests/?query=x&return=y", "tests8", 0, S_OK, "http://www.winehq.org/tests/tests8"},
187 {"http://www.winehq.org/tests/#example", "tests9", 0, S_OK, "http://www.winehq.org/tests/tests9"},
188 {"http://www.winehq.org/tests/../tests/", "/tests10/..", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests10/.."},
189 {"http://www.winehq.org/tests/../", "tests11", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../tests11"},
190 {"file:///C:\\dir\\file.txt", "test.txt", 0, S_OK, "file:///C:/dir/test.txt"}
193 struct {
194 const char *path;
195 const char *url;
196 DWORD ret;
197 } TEST_URLFROMPATH [] = {
198 {"foo", "file:foo", S_OK},
199 {"foo\\bar", "file:foo/bar", S_OK},
200 {"\\foo\\bar", "file:///foo/bar", S_OK},
201 {"c:\\foo\\bar", "file:///c:/foo/bar", S_OK},
202 {"c:foo\\bar", "file:///c:foo/bar", S_OK},
203 {"c:\\foo/b a%r", "file:///c:/foo/b%20a%25r", S_OK},
204 {"c:\\foo\\foo bar", "file:///c:/foo/foo%20bar", S_OK},
205 #if 0
206 /* The following test fails on native shlwapi as distributed with Win95/98.
207 * Wine matches the behaviour of later versions.
209 {"xx:c:\\foo\\bar", "xx:c:\\foo\\bar", S_FALSE}
210 #endif
213 struct {
214 const char *url;
215 const char *path;
216 DWORD ret;
217 } TEST_PATHFROMURL[] = {
218 {"file:///c:/foo/ba%5Cr", "c:\\foo\\ba\\r", S_OK},
219 {"file:///c:/foo/../ba%5Cr", "c:\\foo\\..\\ba\\r", S_OK},
220 {"file:///host/c:/foo/bar", "\\host\\c:\\foo\\bar", S_OK},
221 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
222 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
223 {"file:\\\\host\\c:\\foo\\bar", "\\\\hostc:\\foo\\bar", S_OK},
224 {"file:\\\\host\\ca\\foo\\bar", "\\\\host\\ca\\foo\\bar", S_OK},
225 {"file:\\\\host\\c|\\foo\\bar", "\\\\hostc|\\foo\\bar", S_OK},
226 {"file:\\%5Chost\\c:\\foo\\bar", "\\\\host\\c:\\foo\\bar", S_OK},
227 {"file:\\\\host\\cx:\\foo\\bar", "\\\\host\\cx:\\foo\\bar", S_OK},
228 {"file://c:/foo/bar", "c:\\foo\\bar", S_OK},
229 {"file://c:/d:/foo/bar", "c:\\d:\\foo\\bar", S_OK},
230 {"file://c|/d|/foo/bar", "c:\\d|\\foo\\bar", S_OK},
231 {"file://host/foo/bar", "\\\\host\\foo\\bar", S_OK},
232 {"file:/foo/bar", "\\foo\\bar", S_OK},
233 {"file:/foo/bar/", "\\foo\\bar\\", S_OK},
234 {"file:foo/bar", "foo\\bar", S_OK},
235 {"file:c:/foo/bar", "c:\\foo\\bar", S_OK},
236 {"file:c|/foo/bar", "c:\\foo\\bar", S_OK},
237 {"file:cx|/foo/bar", "cx|\\foo\\bar", S_OK},
238 {"file:////c:/foo/bar", "c:\\foo\\bar", S_OK},
239 /* {"file:////c:/foo/foo%20bar", "c:\\foo\\foo%20bar", S_OK},*/
241 {"c:\\foo\\bar", NULL, E_INVALIDARG},
242 {"foo/bar", NULL, E_INVALIDARG},
243 {"http://foo/bar", NULL, E_INVALIDARG},
247 struct {
248 char url[30];
249 const char *expect;
250 } TEST_URL_UNESCAPE[] = {
251 {"file://foo/bar", "file://foo/bar"},
252 {"file://fo%20o%5Ca/bar", "file://fo o\\a/bar"}
256 struct {
257 const char *path;
258 BOOL expect;
259 } TEST_PATH_IS_URL[] = {
260 {"http://foo/bar", TRUE},
261 {"c:\\foo\\bar", FALSE},
262 {"foo://foo/bar", TRUE},
263 {"foo\\bar", FALSE},
264 {"foo.bar", FALSE},
265 {"bogusscheme:", TRUE},
266 {"http:partial", TRUE}
269 struct {
270 const char *url;
271 BOOL expectOpaque;
272 BOOL expectFile;
273 } TEST_URLIS_ATTRIBS[] = {
274 { "ftp:", FALSE, FALSE },
275 { "http:", FALSE, FALSE },
276 { "gopher:", FALSE, FALSE },
277 { "mailto:", TRUE, FALSE },
278 { "news:", FALSE, FALSE },
279 { "nntp:", FALSE, FALSE },
280 { "telnet:", FALSE, FALSE },
281 { "wais:", FALSE, FALSE },
282 { "file:", FALSE, TRUE },
283 { "mk:", FALSE, FALSE },
284 { "https:", FALSE, FALSE },
285 { "shell:", TRUE, FALSE },
286 { "https:", FALSE, FALSE },
287 { "snews:", FALSE, FALSE },
288 { "local:", FALSE, FALSE },
289 { "javascript:", TRUE, FALSE },
290 { "vbscript:", TRUE, FALSE },
291 { "about:", TRUE, FALSE },
292 { "res:", FALSE, FALSE },
293 { "bogusscheme:", FALSE, FALSE },
294 { "file:\\\\e:\\b\\c", FALSE, TRUE },
295 { "file://e:/b/c", FALSE, TRUE },
296 { "http:partial", FALSE, FALSE },
297 { "mailto://www.winehq.org/test.html", TRUE, FALSE },
298 { "file:partial", FALSE, TRUE }
302 static LPWSTR GetWideString(const char* szString)
304 LPWSTR wszString = HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
306 MultiByteToWideChar(0, 0, szString, -1, wszString, INTERNET_MAX_URL_LENGTH);
308 return wszString;
311 static void FreeWideString(LPWSTR wszString)
313 HeapFree(GetProcessHeap(), 0, wszString);
316 static void hash_url(const char* szUrl)
318 LPCSTR szTestUrl = szUrl;
319 LPWSTR wszTestUrl = GetWideString(szTestUrl);
321 DWORD cbSize = sizeof(DWORD);
322 DWORD dwHash1, dwHash2;
323 ok(UrlHashA(szTestUrl, (LPBYTE)&dwHash1, cbSize) == S_OK, "UrlHashA didn't return S_OK\n");
324 ok(UrlHashW(wszTestUrl, (LPBYTE)&dwHash2, cbSize) == S_OK, "UrlHashW didn't return S_OK\n");
326 FreeWideString(wszTestUrl);
328 ok(dwHash1 == dwHash2, "Hashes didn't compare\n");
331 static void test_UrlHash(void)
333 hash_url(TEST_URL_1);
334 hash_url(TEST_URL_2);
335 hash_url(TEST_URL_3);
338 static void test_url_part(const char* szUrl, DWORD dwPart, DWORD dwFlags, const char* szExpected)
340 CHAR szPart[INTERNET_MAX_URL_LENGTH];
341 WCHAR wszPart[INTERNET_MAX_URL_LENGTH];
342 LPWSTR wszUrl = GetWideString(szUrl);
343 LPWSTR wszConvertedPart;
345 DWORD dwSize;
347 dwSize = INTERNET_MAX_URL_LENGTH;
348 ok( UrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags) == S_OK, "UrlGetPartA for \"%s\" part 0x%08lx didn't return S_OK but \"%s\"\n", szUrl, dwPart, szPart);
349 dwSize = INTERNET_MAX_URL_LENGTH;
350 ok( UrlGetPartW(wszUrl, wszPart, &dwSize, dwPart, dwFlags) == S_OK, "UrlGetPartW didn't return S_OK\n" );
352 wszConvertedPart = GetWideString(szPart);
354 ok(lstrcmpW(wszPart,wszConvertedPart)==0, "Strings didn't match between ascii and unicode UrlGetPart!\n");
356 FreeWideString(wszUrl);
357 FreeWideString(wszConvertedPart);
359 /* Note that v6.0 and later don't return '?' with the query */
360 ok(strcmp(szPart,szExpected)==0 ||
361 (*szExpected=='?' && !strcmp(szPart,szExpected+1)),
362 "Expected %s, but got %s\n", szExpected, szPart);
365 static void test_UrlGetPart(void)
367 test_url_part(TEST_URL_3, URL_PART_HOSTNAME, 0, "localhost");
368 test_url_part(TEST_URL_3, URL_PART_PORT, 0, "21");
369 test_url_part(TEST_URL_3, URL_PART_USERNAME, 0, "foo");
370 test_url_part(TEST_URL_3, URL_PART_PASSWORD, 0, "bar");
371 test_url_part(TEST_URL_3, URL_PART_SCHEME, 0, "http");
372 test_url_part(TEST_URL_3, URL_PART_QUERY, 0, "?query=x&return=y");
375 static void test_url_escape(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
377 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
378 DWORD dwEscaped;
379 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
380 WCHAR *urlW, *expected_urlW;
381 dwEscaped=INTERNET_MAX_URL_LENGTH;
383 ok(UrlEscapeA(szUrl, szReturnUrl, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeA didn't return 0x%08lx from \"%s\"\n", dwExpectReturn, szUrl);
384 ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected \"%s\", but got \"%s\" from \"%s\"\n", szExpectUrl, szReturnUrl, szUrl);
386 dwEscaped = INTERNET_MAX_URL_LENGTH;
387 urlW = GetWideString(szUrl);
388 expected_urlW = GetWideString(szExpectUrl);
389 ok(UrlEscapeW(urlW, ret_urlW, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeW didn't return 0x%08lx from \"%s\"\n", dwExpectReturn, szUrl);
390 WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
391 ok(lstrcmpW(ret_urlW, expected_urlW)==0, "Expected \"%s\", but got \"%s\" from \"%s\" flags %08lx\n", szExpectUrl, szReturnUrl, szUrl, dwFlags);
392 FreeWideString(urlW);
393 FreeWideString(expected_urlW);
397 static void test_url_canonicalize(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
399 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
400 WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
401 LPWSTR wszUrl = GetWideString(szUrl);
402 LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
403 LPWSTR wszConvertedUrl;
405 DWORD dwSize;
407 dwSize = INTERNET_MAX_URL_LENGTH;
408 ok(UrlCanonicalizeA(szUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
409 ok(UrlCanonicalizeA(szUrl, szReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeA didn't return 0x%08lx\n", dwExpectReturn);
410 ok(strcmp(szReturnUrl,szExpectUrl)==0, "UrlCanonicalizeA dwFlags 0x%08lx Expected %s, but got %s\n", dwFlags, szExpectUrl, szReturnUrl);
412 dwSize = INTERNET_MAX_URL_LENGTH;
413 ok(UrlCanonicalizeW(wszUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
414 ok(UrlCanonicalizeW(wszUrl, wszReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeW didn't return 0x%08lx\n", dwExpectReturn);
415 wszConvertedUrl = GetWideString(szReturnUrl);
416 ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCanonicalize!\n");
417 FreeWideString(wszConvertedUrl);
420 FreeWideString(wszUrl);
421 FreeWideString(wszExpectUrl);
425 static void test_UrlEscape(void)
427 unsigned int i;
428 for(i=0; i<sizeof(TEST_ESCAPE)/sizeof(TEST_ESCAPE[0]); i++) {
429 test_url_escape(TEST_ESCAPE[i].url, TEST_ESCAPE[i].flags,
430 TEST_ESCAPE[i].expectret, TEST_ESCAPE[i].expecturl);
434 static void test_UrlCanonicalize(void)
436 unsigned int i;
437 for(i=0; i<sizeof(TEST_CANONICALIZE)/sizeof(TEST_CANONICALIZE[0]); i++) {
438 test_url_canonicalize(TEST_CANONICALIZE[i].url, TEST_CANONICALIZE[i].flags,
439 TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expecturl);
443 static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
445 HRESULT hr;
446 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
447 WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
448 LPWSTR wszUrl1 = GetWideString(szUrl1);
449 LPWSTR wszUrl2 = GetWideString(szUrl2);
450 LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
451 LPWSTR wszConvertedUrl;
453 DWORD dwSize;
454 DWORD dwExpectLen = lstrlen(szExpectUrl);
456 hr = UrlCombineA(szUrl1, szUrl2, NULL, NULL, dwFlags);
457 ok(hr == E_INVALIDARG, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_INVALIDARG);
459 dwSize = 0;
460 hr = UrlCombineA(szUrl1, szUrl2, NULL, &dwSize, dwFlags);
461 ok(hr == E_POINTER, "Checking length of string, return was 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
462 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
464 dwSize--;
465 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
466 ok(hr == E_POINTER, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
467 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
469 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
470 ok(hr == dwExpectReturn, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, dwExpectReturn);
471 ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\n", dwSize, dwExpectLen);
472 if(SUCCEEDED(hr)) {
473 ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected %s, but got %s\n", szExpectUrl, szReturnUrl);
476 dwSize = 0;
477 hr = UrlCombineW(wszUrl1, wszUrl2, NULL, &dwSize, dwFlags);
478 ok(hr == E_POINTER, "Checking length of string, return was 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
479 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
481 dwSize--;
482 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
483 ok(hr == E_POINTER, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
484 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
486 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
487 ok(hr == dwExpectReturn, "UrlCombineW returned 0x%08lx, expected 0x%08lx\n", hr, dwExpectReturn);
488 ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\n", dwSize, dwExpectLen);
489 if(SUCCEEDED(hr)) {
490 wszConvertedUrl = GetWideString(szReturnUrl);
491 ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCombine!\n");
492 FreeWideString(wszConvertedUrl);
495 FreeWideString(wszUrl1);
496 FreeWideString(wszUrl2);
497 FreeWideString(wszExpectUrl);
500 static void test_UrlCombine(void)
502 unsigned int i;
503 for(i=0; i<sizeof(TEST_COMBINE)/sizeof(TEST_COMBINE[0]); i++) {
504 test_url_combine(TEST_COMBINE[i].url1, TEST_COMBINE[i].url2, TEST_COMBINE[i].flags,
505 TEST_COMBINE[i].expectret, TEST_COMBINE[i].expecturl);
509 static void test_UrlCreateFromPath(void)
511 size_t i;
512 char ret_url[INTERNET_MAX_URL_LENGTH];
513 DWORD len, ret;
514 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
515 WCHAR *pathW, *urlW;
517 for(i = 0; i < sizeof(TEST_URLFROMPATH) / sizeof(TEST_URLFROMPATH[0]); i++) {
518 len = INTERNET_MAX_URL_LENGTH;
519 ret = UrlCreateFromPathA(TEST_URLFROMPATH[i].path, ret_url, &len, 0);
520 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08lx from path %s\n", ret, TEST_URLFROMPATH[i].path);
521 ok(!lstrcmpi(ret_url, TEST_URLFROMPATH[i].url), "url %s from path %s\n", ret_url, TEST_URLFROMPATH[i].path);
522 ok(len == strlen(ret_url), "ret len %ld from path %s\n", len, TEST_URLFROMPATH[i].path);
524 len = INTERNET_MAX_URL_LENGTH;
525 pathW = GetWideString(TEST_URLFROMPATH[i].path);
526 urlW = GetWideString(TEST_URLFROMPATH[i].url);
527 ret = UrlCreateFromPathW(pathW, ret_urlW, &len, 0);
528 WideCharToMultiByte(CP_ACP, 0, ret_urlW, -1, ret_url, sizeof(ret_url),0,0);
529 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08lx from path L\"%s\", expected %08lx\n",
530 ret, TEST_URLFROMPATH[i].path, TEST_URLFROMPATH[i].ret);
531 ok(!lstrcmpiW(ret_urlW, urlW), "got %s expected %s from path L\"%s\"\n", ret_url, TEST_URLFROMPATH[i].url, TEST_URLFROMPATH[i].path);
532 ok(len == lstrlenW(ret_urlW), "ret len %ld from path L\"%s\"\n", len, TEST_URLFROMPATH[i].path);
533 FreeWideString(urlW);
534 FreeWideString(pathW);
538 static void test_UrlIs(void)
540 BOOL ret;
541 size_t i;
542 WCHAR wurl[80];
544 for(i = 0; i < sizeof(TEST_PATH_IS_URL) / sizeof(TEST_PATH_IS_URL[0]); i++) {
545 MultiByteToWideChar(CP_ACP, 0, TEST_PATH_IS_URL[i].path, -1, wurl, 80);
547 ret = UrlIsA( TEST_PATH_IS_URL[i].path, URLIS_URL );
548 ok( ret == TEST_PATH_IS_URL[i].expect,
549 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
550 TEST_PATH_IS_URL[i].expect );
552 ret = UrlIsW( wurl, URLIS_URL );
553 ok( ret == TEST_PATH_IS_URL[i].expect,
554 "returned %d from path (UrlIsW) %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
555 TEST_PATH_IS_URL[i].expect );
557 for(i = 0; i < sizeof(TEST_URLIS_ATTRIBS) / sizeof(TEST_URLIS_ATTRIBS[0]); i++) {
558 MultiByteToWideChar(CP_ACP, 0, TEST_URLIS_ATTRIBS[i].url, -1, wurl, 80);
560 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_OPAQUE);
561 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
562 "returned %d for URLIS_OPAQUE, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
563 TEST_URLIS_ATTRIBS[i].expectOpaque );
564 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_FILEURL);
565 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
566 "returned %d for URLIS_FILEURL, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
567 TEST_URLIS_ATTRIBS[i].expectFile );
569 ret = UrlIsW( wurl, URLIS_OPAQUE);
570 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
571 "returned %d for URLIS_OPAQUE (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
572 TEST_URLIS_ATTRIBS[i].expectOpaque );
573 ret = UrlIsW( wurl, URLIS_FILEURL);
574 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
575 "returned %d for URLIS_FILEURL (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
576 TEST_URLIS_ATTRIBS[i].expectFile );
580 static void test_UrlUnescape(void)
582 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
583 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
584 WCHAR *urlW, *expected_urlW;
585 DWORD dwEscaped;
586 size_t i;
587 static char inplace[] = "file:///C:/Program%20Files";
588 static WCHAR inplaceW[] = {'f','i','l','e',':','/','/','/','C',':','/',
589 'P','r','o','g','r','a','m','%','2','0','F','i','l','e','s',0};
591 for(i=0; i<sizeof(TEST_URL_UNESCAPE)/sizeof(TEST_URL_UNESCAPE[0]); i++) {
592 dwEscaped=INTERNET_MAX_URL_LENGTH;
593 ok(UrlUnescapeA(TEST_URL_UNESCAPE[i].url, szReturnUrl, &dwEscaped, 0) == S_OK, "UrlEscapeA didn't return 0x%08lx from \"%s\"\n", S_OK, TEST_URL_UNESCAPE[i].url);
594 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);
596 dwEscaped = INTERNET_MAX_URL_LENGTH;
597 urlW = GetWideString(TEST_URL_UNESCAPE[i].url);
598 expected_urlW = GetWideString(TEST_URL_UNESCAPE[i].expect);
599 ok(UrlUnescapeW(urlW, ret_urlW, &dwEscaped, 0) == S_OK, "UrlEscapeW didn't return 0x%08lx from \"%s\"\n", S_OK, TEST_URL_UNESCAPE[i].url);
600 WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
601 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);
602 FreeWideString(urlW);
603 FreeWideString(expected_urlW);
606 dwEscaped = sizeof(inplace);
607 ok(UrlUnescapeA(inplace, NULL, &dwEscaped, URL_UNESCAPE_INPLACE) == S_OK, "UrlUnescapeA failed unexpectedly\n");
609 dwEscaped = sizeof(inplaceW);
610 ok(UrlUnescapeW(inplaceW, NULL, &dwEscaped, URL_UNESCAPE_INPLACE) == S_OK, "UrlUnescapeW failed unexpectedly\n");
613 static void test_PathSearchAndQualify(void)
615 WCHAR path1[] = {'c',':','\\','f','o','o',0};
616 WCHAR expect1[] = {'c',':','\\','f','o','o',0};
617 WCHAR path2[] = {'c',':','f','o','o',0};
618 WCHAR c_drive[] = {'c',':',0};
619 WCHAR foo[] = {'f','o','o',0};
620 WCHAR path3[] = {'\\','f','o','o',0};
621 WCHAR winini[] = {'w','i','n','.','i','n','i',0};
622 WCHAR out[MAX_PATH];
623 WCHAR cur_dir[MAX_PATH];
624 WCHAR dot[] = {'.',0};
626 /* c:\foo */
627 ok(PathSearchAndQualifyW(path1, out, MAX_PATH) != 0,
628 "PathSearchAndQualify rets 0\n");
629 ok(!lstrcmpiW(out, expect1), "strings don't match\n");
631 /* c:foo */
632 ok(PathSearchAndQualifyW(path2, out, MAX_PATH) != 0,
633 "PathSearchAndQualify rets 0\n");
634 GetFullPathNameW(c_drive, MAX_PATH, cur_dir, NULL);
635 PathAddBackslashW(cur_dir);
636 lstrcatW(cur_dir, foo);
637 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
639 /* foo */
640 ok(PathSearchAndQualifyW(foo, out, MAX_PATH) != 0,
641 "PathSearchAndQualify rets 0\n");
642 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
643 PathAddBackslashW(cur_dir);
644 lstrcatW(cur_dir, foo);
645 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
647 /* \foo */
648 ok(PathSearchAndQualifyW(path3, out, MAX_PATH) != 0,
649 "PathSearchAndQualify rets 0\n");
650 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
651 lstrcpyW(cur_dir + 2, path3);
652 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
654 /* win.ini */
655 ok(PathSearchAndQualifyW(winini, out, MAX_PATH) != 0,
656 "PathSearchAndQualify rets 0\n");
657 if(!SearchPathW(NULL, winini, NULL, MAX_PATH, cur_dir, NULL))
658 GetFullPathNameW(winini, MAX_PATH, cur_dir, NULL);
659 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
663 static void test_PathCreateFromUrl(void)
665 size_t i;
666 char ret_path[INTERNET_MAX_URL_LENGTH];
667 DWORD len, ret;
668 WCHAR ret_pathW[INTERNET_MAX_URL_LENGTH];
669 WCHAR *pathW, *urlW;
671 for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
672 len = INTERNET_MAX_URL_LENGTH;
673 ret = PathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
674 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url %s\n", ret, TEST_PATHFROMURL[i].url);
675 if(TEST_PATHFROMURL[i].path) {
676 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);
677 ok(len == strlen(ret_path), "ret len %ld from url %s\n", len, TEST_PATHFROMURL[i].url);
679 len = INTERNET_MAX_URL_LENGTH;
680 pathW = GetWideString(TEST_PATHFROMURL[i].path);
681 urlW = GetWideString(TEST_PATHFROMURL[i].url);
682 ret = PathCreateFromUrlW(urlW, ret_pathW, &len, 0);
683 WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),0,0);
684 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
685 if(TEST_PATHFROMURL[i].path) {
686 ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
687 ok(len == lstrlenW(ret_pathW), "ret len %ld from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url);
689 FreeWideString(urlW);
690 FreeWideString(pathW);
695 static void test_PathIsUrl(void)
697 size_t i;
698 BOOL ret;
700 for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
701 ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
702 ok(ret == TEST_PATH_IS_URL[i].expect,
703 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
704 TEST_PATH_IS_URL[i].expect);
708 static const DWORD SHELL_charclass[] =
710 0x00000000, 0x00000000, 0x00000000, 0x00000000,
711 0x00000000, 0x00000000, 0x00000000, 0x00000000,
712 0x00000000, 0x00000000, 0x00000000, 0x00000000,
713 0x00000000, 0x00000000, 0x00000000, 0x00000000,
714 0x00000000, 0x00000000, 0x00000000, 0x00000000,
715 0x00000000, 0x00000000, 0x00000000, 0x00000000,
716 0x00000000, 0x00000000, 0x00000000, 0x00000000,
717 0x00000000, 0x00000000, 0x00000000, 0x00000000,
718 0x00000080, 0x00000100, 0x00000200, 0x00000100,
719 0x00000100, 0x00000100, 0x00000100, 0x00000100,
720 0x00000100, 0x00000100, 0x00000002, 0x00000100,
721 0x00000040, 0x00000100, 0x00000004, 0x00000000,
722 0x00000100, 0x00000100, 0x00000100, 0x00000100,
723 0x00000100, 0x00000100, 0x00000100, 0x00000100,
724 0x00000100, 0x00000100, 0x00000010, 0x00000020,
725 0x00000000, 0x00000100, 0x00000000, 0x00000001,
726 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
727 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
728 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
729 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
730 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
731 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
732 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
733 0x00000008, 0x00000100, 0x00000100, 0x00000100,
734 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
735 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
736 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
737 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
738 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
739 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
740 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
741 0x00000000, 0x00000100, 0x00000100
744 static void test_PathIsValidCharA(void)
746 BOOL ret;
747 unsigned int c;
749 ret = pPathIsValidCharA( 0x7f, 0 );
750 ok ( !ret, "PathIsValidCharA succeeded: 0x%08lx\n", (DWORD)ret );
752 ret = pPathIsValidCharA( 0x7f, 1 );
753 ok ( !ret, "PathIsValidCharA succeeded: 0x%08lx\n", (DWORD)ret );
755 for (c = 0; c < 0x7f; c++)
757 ret = pPathIsValidCharA( c, ~0U );
758 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
759 "PathIsValidCharA failed: 0x%02x got 0x%08lx expected 0x%08lx\n",
760 c, (DWORD)ret, SHELL_charclass[c] );
763 for (c = 0x7f; c <= 0xff; c++)
765 ret = pPathIsValidCharA( c, ~0U );
766 ok ( ret == 0x00000100,
767 "PathIsValidCharA failed: 0x%02x got 0x%08lx expected 0x00000100\n",
768 c, (DWORD)ret );
772 static void test_PathIsValidCharW(void)
774 BOOL ret;
775 unsigned int c, err_count = 0;
777 ret = pPathIsValidCharW( 0x7f, 0 );
778 ok ( !ret, "PathIsValidCharW succeeded: 0x%08lx\n", (DWORD)ret );
780 ret = pPathIsValidCharW( 0x7f, 1 );
781 ok ( !ret, "PathIsValidCharW succeeded: 0x%08lx\n", (DWORD)ret );
783 for (c = 0; c < 0x7f; c++)
785 ret = pPathIsValidCharW( c, ~0U );
786 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
787 "PathIsValidCharW failed: 0x%02x got 0x%08lx expected 0x%08lx\n",
788 c, (DWORD)ret, SHELL_charclass[c] );
791 for (c = 0x007f; c <= 0xffff; c++)
793 ret = pPathIsValidCharW( c, ~0U );
794 ok ( ret == 0x00000100,
795 "PathIsValidCharW failed: 0x%02x got 0x%08lx expected 0x00000100\n",
796 c, (DWORD)ret );
797 if (ret != 0x00000100)
799 if(++err_count > 100 ) {
800 trace("skipping rest of PathIsValidCharW tests "
801 "because of the current number of errors\n");
802 break;
808 static void test_PathMakePretty(void)
810 char buff[MAX_PATH];
812 ok (PathMakePrettyA(NULL) == FALSE, "PathMakePretty: NULL path succeeded\n");
813 buff[0] = '\0';
814 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Empty path failed\n");
816 strcpy(buff, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
817 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Long UC name failed\n");
818 ok (strcmp(buff, "C:\\a long file name with \\spaces.txt") == 0,
819 "PathMakePretty: Long UC name not changed\n");
821 strcpy(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
822 ok (PathMakePrettyA(buff) == FALSE, "PathMakePretty: Long MC name succeeded\n");
823 ok (strcmp(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
824 "PathMakePretty: Failed but modified path\n");
826 strcpy(buff, "TEST");
827 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Short name failed\n");
828 ok (strcmp(buff, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff);
831 static void test_PathMatchSpec(void)
833 static const char file[] = "c:\\foo\\bar\\filename.ext";
834 static const char spec1[] = ".ext";
835 static const char spec2[] = "*.ext";
836 static const char spec3[] = "*.ext ";
837 static const char spec4[] = " *.ext";
838 static const char spec5[] = "* .ext";
839 static const char spec6[] = "*. ext";
840 static const char spec7[] = "* . ext";
841 static const char spec8[] = "*.e?t";
842 static const char spec9[] = "filename.ext";
843 static const char spec10[] = "*bar\\filename.ext";
844 static const char spec11[] = " foo; *.ext";
845 static const char spec12[] = "*.ext;*.bar";
846 static const char spec13[] = "*bar*";
848 ok (PathMatchSpecA(file, spec1) == FALSE, "PathMatchSpec: Spec1 failed\n");
849 ok (PathMatchSpecA(file, spec2) == TRUE, "PathMatchSpec: Spec2 failed\n");
850 ok (PathMatchSpecA(file, spec3) == FALSE, "PathMatchSpec: Spec3 failed\n");
851 ok (PathMatchSpecA(file, spec4) == TRUE, "PathMatchSpec: Spec4 failed\n");
852 todo_wine ok (PathMatchSpecA(file, spec5) == TRUE, "PathMatchSpec: Spec5 failed\n");
853 todo_wine ok (PathMatchSpecA(file, spec6) == TRUE, "PathMatchSpec: Spec6 failed\n");
854 ok (PathMatchSpecA(file, spec7) == FALSE, "PathMatchSpec: Spec7 failed\n");
855 ok (PathMatchSpecA(file, spec8) == TRUE, "PathMatchSpec: Spec8 failed\n");
856 ok (PathMatchSpecA(file, spec9) == FALSE, "PathMatchSpec: Spec9 failed\n");
857 ok (PathMatchSpecA(file, spec10) == TRUE, "PathMatchSpec: Spec10 failed\n");
858 ok (PathMatchSpecA(file, spec11) == TRUE, "PathMatchSpec: Spec11 failed\n");
859 ok (PathMatchSpecA(file, spec12) == TRUE, "PathMatchSpec: Spec12 failed\n");
860 ok (PathMatchSpecA(file, spec13) == TRUE, "PathMatchSpec: Spec13 failed\n");
864 START_TEST(path)
866 hShlwapi = LoadLibraryA("shlwapi.dll");
867 if (!hShlwapi) return;
869 test_UrlHash();
870 test_UrlGetPart();
871 test_UrlCanonicalize();
872 test_UrlEscape();
873 test_UrlCombine();
874 test_UrlCreateFromPath();
875 test_UrlIs();
876 test_UrlUnescape();
878 test_PathSearchAndQualify();
879 test_PathCreateFromUrl();
880 test_PathIsUrl();
882 test_PathMakePretty();
883 test_PathMatchSpec();
885 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
886 * ordinal number in some native versions. Check this to prevent a crash.
888 pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
889 if (pPathIsValidCharA && pPathIsValidCharA != (void*)GetProcAddress(hShlwapi, "PathAppendA"))
891 test_PathIsValidCharA();
893 pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
894 if (pPathIsValidCharW) test_PathIsValidCharW();