shlwapi: Add tests for PathMatchSpec.
[wine/gsoc_dplay.git] / dlls / shlwapi / tests / path.c
blobd7c7e00af3b9744b84681babaa2a07cc8fb831cd
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 "wine/unicode.h"
28 #include "winreg.h"
29 #include "shlwapi.h"
30 #include "wininet.h"
32 static HMODULE hShlwapi;
33 static HRESULT (WINAPI *pPathIsValidCharA)(char,DWORD);
34 static HRESULT (WINAPI *pPathIsValidCharW)(WCHAR,DWORD);
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 {
41 const char *url;
42 DWORD flags;
43 HRESULT expectret;
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"},
80 typedef struct _TEST_URL_ESCAPE {
81 const char *url;
82 DWORD flags;
83 DWORD expectescaped;
84 HRESULT expectret;
85 const char *expecturl;
86 } TEST_URL_ESCAPE;
88 const TEST_URL_ESCAPE TEST_ESCAPE[] = {
89 {"http://www.winehq.org/tests0", 0, 0, S_OK, "http://www.winehq.org/tests0"},
90 {"http://www.winehq.org/tests1\n", 0, 0, S_OK, "http://www.winehq.org/tests1%0A"},
91 {"http://www.winehq.org/tests2\r", 0, 0, S_OK, "http://www.winehq.org/tests2%0D"},
92 {"http://www.winehq.org/tests3\r", URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, 0, S_OK, "http://www.winehq.org/tests3\r"},
93 {"http://www.winehq.org/tests4\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests4\r"},
94 {"http://www.winehq.org/tests5\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests5\r"},
95 {"/direct/swhelp/series6/6.2i_latestservicepack.dat\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "/direct/swhelp/series6/6.2i_latestservicepack.dat\r"},
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:////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
100 {"file:///localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"},
101 {"file:///foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
102 {"file://loCalHost/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
103 {"file://foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
104 {"file:/localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/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:\\\\\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
110 {"file:\\\\localhost\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
111 {"file:///f oo/b?a r\\baz", 0, 0, S_OK, "file:///f%20oo/b?a r\\baz"},
112 {"file:///foo/b#a r\\baz", 0, 0, S_OK, "file:///foo/b%23a%20r/baz"},
113 {"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"},
114 {"file:///f o%o/b?a r\\b%az", URL_ESCAPE_PERCENT, 0, S_OK, "file:///f%20o%25o/b?a r\\b%az"},
115 {"file:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "file:%2Ffoo%2Fbar%5Cbaz"},
117 {"foo/b%ar\\ba?z\\", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%ar%5Cba%3Fz%5C"},
118 {"foo/b%ar\\ba?z\\", URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%25ar%5Cba%3Fz%5C"},
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/bar\\ba#z\\", 0, 0, S_OK, "/foo/bar%5Cba#z\\"},
122 {"/foo/%5C", 0, 0, S_OK, "/foo/%5C"},
123 {"/foo/%5C", URL_ESCAPE_PERCENT, 0, S_OK, "/foo/%255C"},
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:///foo/bar\\baz", 0, 0, S_OK, "http:///foo/bar/baz"},
129 {"http://localhost/foo/bar\\baz", 0, 0, S_OK, "http://localhost/foo/bar/baz"},
130 {"http://foo/bar\\baz", 0, 0, S_OK, "http://foo/bar/baz"},
131 {"http:/foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"},
132 {"http:foo/bar\\ba?z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba?z\\"},
133 {"http:foo/bar\\ba#z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba#z\\"},
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:\\\\\\\\foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"},
138 {"http:/fo ?o/b ar\\baz", 0, 0, S_OK, "http:/fo%20?o/b ar\\baz"},
139 {"http:fo ?o/b ar\\baz", 0, 0, S_OK, "http:fo%20?o/b ar\\baz"},
140 {"http:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "http:%2Ffoo%2Fbar%5Cbaz"},
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"},
144 {"https:\\foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"},
146 {"foo:////foo/bar\\baz", 0, 0, S_OK, "foo:////foo/bar%5Cbaz"},
147 {"foo:///foo/bar\\baz", 0, 0, S_OK, "foo:///foo/bar%5Cbaz"},
148 {"foo://localhost/foo/bar\\baz", 0, 0, S_OK, "foo://localhost/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/bar%5Cbaz"},
151 {"foo:foo/bar\\baz", 0, 0, S_OK, "foo:foo%2Fbar%5Cbaz"},
152 {"foo:\\foo/bar\\baz", 0, 0, S_OK, "foo:%5Cfoo%2Fbar%5Cbaz"},
153 {"foo:/foo/bar\\ba?\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba?\\z"},
154 {"foo:/foo/bar\\ba#\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba#\\z"},
156 {"mailto:/fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:%2Ffo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
157 {"mailto:fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:fo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
158 {"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"},
160 {"ftp:fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:fo%2Fo@bar.baz%2Ffoo%2Fbar"},
161 {"ftp:/fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:/fo/o@bar.baz/foo/bar"},
162 {"ftp://fo/o@bar.baz/fo?o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo?o\\bar"},
163 {"ftp://fo/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo#o\\bar"},
164 {"ftp://localhost/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://localhost/o@bar.baz/fo#o\\bar"},
165 {"ftp:///fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:///fo/o@bar.baz/foo/bar"},
166 {"ftp:////fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:////fo/o@bar.baz/foo/bar"}
169 typedef struct _TEST_URL_COMBINE {
170 const char *url1;
171 const char *url2;
172 DWORD flags;
173 HRESULT expectret;
174 const char *expecturl;
175 } TEST_URL_COMBINE;
177 const TEST_URL_COMBINE TEST_COMBINE[] = {
178 {"http://www.winehq.org/tests", "tests1", 0, S_OK, "http://www.winehq.org/tests1"},
179 {"http://www.%77inehq.org/tests", "tests1", 0, S_OK, "http://www.%77inehq.org/tests1"},
180 /*FIXME {"http://www.winehq.org/tests", "../tests2", 0, S_OK, "http://www.winehq.org/tests2"},*/
181 {"http://www.winehq.org/tests/", "../tests3", 0, S_OK, "http://www.winehq.org/tests3"},
182 {"http://www.winehq.org/tests/test1", "test2", 0, S_OK, "http://www.winehq.org/tests/test2"},
183 {"http://www.winehq.org/tests/../tests", "tests4", 0, S_OK, "http://www.winehq.org/tests4"},
184 {"http://www.winehq.org/tests/../tests/", "tests5", 0, S_OK, "http://www.winehq.org/tests/tests5"},
185 {"http://www.winehq.org/tests/../tests/", "/tests6/..", 0, S_OK, "http://www.winehq.org/"},
186 {"http://www.winehq.org/tests/../tests/..", "tests7/..", 0, S_OK, "http://www.winehq.org/"},
187 {"http://www.winehq.org/tests/?query=x&return=y", "tests8", 0, S_OK, "http://www.winehq.org/tests/tests8"},
188 {"http://www.winehq.org/tests/#example", "tests9", 0, S_OK, "http://www.winehq.org/tests/tests9"},
189 {"http://www.winehq.org/tests/../tests/", "/tests10/..", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests10/.."},
190 {"http://www.winehq.org/tests/../", "tests11", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../tests11"},
191 {"file:///C:\\dir\\file.txt", "test.txt", 0, S_OK, "file:///C:/dir/test.txt"}
194 struct {
195 const char *path;
196 const char *url;
197 DWORD ret;
198 } TEST_URLFROMPATH [] = {
199 {"foo", "file:foo", S_OK},
200 {"foo\\bar", "file:foo/bar", S_OK},
201 {"\\foo\\bar", "file:///foo/bar", S_OK},
202 {"c:\\foo\\bar", "file:///c:/foo/bar", S_OK},
203 {"c:foo\\bar", "file:///c:foo/bar", S_OK},
204 {"c:\\foo/b a%r", "file:///c:/foo/b%20a%25r", S_OK},
205 {"c:\\foo\\foo bar", "file:///c:/foo/foo%20bar", S_OK},
206 #if 0
207 /* The following test fails on native shlwapi as distributed with Win95/98.
208 * Wine matches the behaviour of later versions.
210 {"xx:c:\\foo\\bar", "xx:c:\\foo\\bar", S_FALSE}
211 #endif
214 struct {
215 const char *url;
216 const char *path;
217 DWORD ret;
218 } TEST_PATHFROMURL[] = {
219 {"file:///c:/foo/ba%5Cr", "c:\\foo\\ba\\r", S_OK},
220 {"file:///c:/foo/../ba%5Cr", "c:\\foo\\..\\ba\\r", S_OK},
221 {"file:///host/c:/foo/bar", "\\host\\c:\\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\\c:\\foo\\bar", "\\\\hostc:\\foo\\bar", S_OK},
225 {"file:\\\\host\\ca\\foo\\bar", "\\\\host\\ca\\foo\\bar", S_OK},
226 {"file:\\\\host\\c|\\foo\\bar", "\\\\hostc|\\foo\\bar", S_OK},
227 {"file:\\%5Chost\\c:\\foo\\bar", "\\\\host\\c:\\foo\\bar", S_OK},
228 {"file:\\\\host\\cx:\\foo\\bar", "\\\\host\\cx:\\foo\\bar", S_OK},
229 {"file://c:/foo/bar", "c:\\foo\\bar", S_OK},
230 {"file://c:/d:/foo/bar", "c:\\d:\\foo\\bar", S_OK},
231 {"file://c|/d|/foo/bar", "c:\\d|\\foo\\bar", S_OK},
232 {"file://host/foo/bar", "\\\\host\\foo\\bar", S_OK},
233 {"file:/foo/bar", "\\foo\\bar", S_OK},
234 {"file:/foo/bar/", "\\foo\\bar\\", S_OK},
235 {"file:foo/bar", "foo\\bar", S_OK},
236 {"file:c:/foo/bar", "c:\\foo\\bar", S_OK},
237 {"file:c|/foo/bar", "c:\\foo\\bar", S_OK},
238 {"file:cx|/foo/bar", "cx|\\foo\\bar", S_OK},
239 {"file:////c:/foo/bar", "c:\\foo\\bar", S_OK},
240 /* {"file:////c:/foo/foo%20bar", "c:\\foo\\foo%20bar", S_OK},*/
242 {"c:\\foo\\bar", NULL, E_INVALIDARG},
243 {"foo/bar", NULL, E_INVALIDARG},
244 {"http://foo/bar", NULL, E_INVALIDARG},
248 struct {
249 char url[30];
250 const char *expect;
251 } TEST_URL_UNESCAPE[] = {
252 {"file://foo/bar", "file://foo/bar"},
253 {"file://fo%20o%5Ca/bar", "file://fo o\\a/bar"}
257 struct {
258 const char *path;
259 BOOL expect;
260 } TEST_PATH_IS_URL[] = {
261 {"http://foo/bar", TRUE},
262 {"c:\\foo\\bar", FALSE},
263 {"foo://foo/bar", TRUE},
264 {"foo\\bar", FALSE},
265 {"foo.bar", FALSE},
266 {"bogusscheme:", TRUE},
267 {"http:partial", TRUE}
270 struct {
271 const char *url;
272 BOOL expectOpaque;
273 BOOL expectFile;
274 } TEST_URLIS_ATTRIBS[] = {
275 { "ftp:", FALSE, FALSE },
276 { "http:", FALSE, FALSE },
277 { "gopher:", FALSE, FALSE },
278 { "mailto:", TRUE, FALSE },
279 { "news:", FALSE, FALSE },
280 { "nntp:", FALSE, FALSE },
281 { "telnet:", FALSE, FALSE },
282 { "wais:", FALSE, FALSE },
283 { "file:", FALSE, TRUE },
284 { "mk:", FALSE, FALSE },
285 { "https:", FALSE, FALSE },
286 { "shell:", TRUE, FALSE },
287 { "https:", FALSE, FALSE },
288 { "snews:", FALSE, FALSE },
289 { "local:", FALSE, FALSE },
290 { "javascript:", TRUE, FALSE },
291 { "vbscript:", TRUE, FALSE },
292 { "about:", TRUE, FALSE },
293 { "res:", FALSE, FALSE },
294 { "bogusscheme:", FALSE, FALSE },
295 { "file:\\\\e:\\b\\c", FALSE, TRUE },
296 { "file://e:/b/c", FALSE, TRUE },
297 { "http:partial", FALSE, FALSE },
298 { "mailto://www.winehq.org/test.html", TRUE, FALSE },
299 { "file:partial", FALSE, TRUE }
303 static LPWSTR GetWideString(const char* szString)
305 LPWSTR wszString = HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
307 MultiByteToWideChar(0, 0, szString, -1, wszString, INTERNET_MAX_URL_LENGTH);
309 return wszString;
312 static void FreeWideString(LPWSTR wszString)
314 HeapFree(GetProcessHeap(), 0, wszString);
317 static void hash_url(const char* szUrl)
319 LPCSTR szTestUrl = szUrl;
320 LPWSTR wszTestUrl = GetWideString(szTestUrl);
322 DWORD cbSize = sizeof(DWORD);
323 DWORD dwHash1, dwHash2;
324 ok(UrlHashA(szTestUrl, (LPBYTE)&dwHash1, cbSize) == S_OK, "UrlHashA didn't return S_OK\n");
325 ok(UrlHashW(wszTestUrl, (LPBYTE)&dwHash2, cbSize) == S_OK, "UrlHashW didn't return S_OK\n");
327 FreeWideString(wszTestUrl);
329 ok(dwHash1 == dwHash2, "Hashes didn't compare\n");
332 static void test_UrlHash(void)
334 hash_url(TEST_URL_1);
335 hash_url(TEST_URL_2);
336 hash_url(TEST_URL_3);
339 static void test_url_part(const char* szUrl, DWORD dwPart, DWORD dwFlags, const char* szExpected)
341 CHAR szPart[INTERNET_MAX_URL_LENGTH];
342 WCHAR wszPart[INTERNET_MAX_URL_LENGTH];
343 LPWSTR wszUrl = GetWideString(szUrl);
344 LPWSTR wszConvertedPart;
346 DWORD dwSize;
348 dwSize = INTERNET_MAX_URL_LENGTH;
349 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);
350 dwSize = INTERNET_MAX_URL_LENGTH;
351 ok( UrlGetPartW(wszUrl, wszPart, &dwSize, dwPart, dwFlags) == S_OK, "UrlGetPartW didn't return S_OK\n" );
353 wszConvertedPart = GetWideString(szPart);
355 ok(strcmpW(wszPart,wszConvertedPart)==0, "Strings didn't match between ascii and unicode UrlGetPart!\n");
357 FreeWideString(wszUrl);
358 FreeWideString(wszConvertedPart);
360 /* Note that v6.0 and later don't return '?' with the query */
361 ok(strcmp(szPart,szExpected)==0 ||
362 (*szExpected=='?' && !strcmp(szPart,szExpected+1)),
363 "Expected %s, but got %s\n", szExpected, szPart);
366 static void test_UrlGetPart(void)
368 test_url_part(TEST_URL_3, URL_PART_HOSTNAME, 0, "localhost");
369 test_url_part(TEST_URL_3, URL_PART_PORT, 0, "21");
370 test_url_part(TEST_URL_3, URL_PART_USERNAME, 0, "foo");
371 test_url_part(TEST_URL_3, URL_PART_PASSWORD, 0, "bar");
372 test_url_part(TEST_URL_3, URL_PART_SCHEME, 0, "http");
373 test_url_part(TEST_URL_3, URL_PART_QUERY, 0, "?query=x&return=y");
376 static void test_url_escape(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
378 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
379 DWORD dwEscaped;
380 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
381 WCHAR *urlW, *expected_urlW;
382 dwEscaped=INTERNET_MAX_URL_LENGTH;
384 ok(UrlEscapeA(szUrl, szReturnUrl, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeA didn't return 0x%08lx from \"%s\"\n", dwExpectReturn, szUrl);
385 ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected \"%s\", but got \"%s\" from \"%s\"\n", szExpectUrl, szReturnUrl, szUrl);
387 dwEscaped = INTERNET_MAX_URL_LENGTH;
388 urlW = GetWideString(szUrl);
389 expected_urlW = GetWideString(szExpectUrl);
390 ok(UrlEscapeW(urlW, ret_urlW, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeW didn't return 0x%08lx from \"%s\"\n", dwExpectReturn, szUrl);
391 WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
392 ok(strcmpW(ret_urlW, expected_urlW)==0, "Expected \"%s\", but got \"%s\" from \"%s\" flags %08lx\n", szExpectUrl, szReturnUrl, szUrl, dwFlags);
393 FreeWideString(urlW);
394 FreeWideString(expected_urlW);
398 static void test_url_canonicalize(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
400 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
401 WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
402 LPWSTR wszUrl = GetWideString(szUrl);
403 LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
404 LPWSTR wszConvertedUrl;
406 DWORD dwSize;
408 dwSize = INTERNET_MAX_URL_LENGTH;
409 ok(UrlCanonicalizeA(szUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
410 ok(UrlCanonicalizeA(szUrl, szReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeA didn't return 0x%08lx\n", dwExpectReturn);
411 ok(strcmp(szReturnUrl,szExpectUrl)==0, "UrlCanonicalizeA dwFlags 0x%08lx Expected %s, but got %s\n", dwFlags, szExpectUrl, szReturnUrl);
413 dwSize = INTERNET_MAX_URL_LENGTH;
414 ok(UrlCanonicalizeW(wszUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
415 ok(UrlCanonicalizeW(wszUrl, wszReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeW didn't return 0x%08lx\n", dwExpectReturn);
416 wszConvertedUrl = GetWideString(szReturnUrl);
417 ok(strcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCanonicalize!\n");
418 FreeWideString(wszConvertedUrl);
421 FreeWideString(wszUrl);
422 FreeWideString(wszExpectUrl);
426 static void test_UrlEscape(void)
428 unsigned int i;
429 for(i=0; i<sizeof(TEST_ESCAPE)/sizeof(TEST_ESCAPE[0]); i++) {
430 test_url_escape(TEST_ESCAPE[i].url, TEST_ESCAPE[i].flags,
431 TEST_ESCAPE[i].expectret, TEST_ESCAPE[i].expecturl);
435 static void test_UrlCanonicalize(void)
437 unsigned int i;
438 for(i=0; i<sizeof(TEST_CANONICALIZE)/sizeof(TEST_CANONICALIZE[0]); i++) {
439 test_url_canonicalize(TEST_CANONICALIZE[i].url, TEST_CANONICALIZE[i].flags,
440 TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expecturl);
444 static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
446 HRESULT hr;
447 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
448 WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
449 LPWSTR wszUrl1 = GetWideString(szUrl1);
450 LPWSTR wszUrl2 = GetWideString(szUrl2);
451 LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
452 LPWSTR wszConvertedUrl;
454 DWORD dwSize;
455 DWORD dwExpectLen = lstrlen(szExpectUrl);
457 hr = UrlCombineA(szUrl1, szUrl2, NULL, NULL, dwFlags);
458 ok(hr == E_INVALIDARG, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_INVALIDARG);
460 dwSize = 0;
461 hr = UrlCombineA(szUrl1, szUrl2, NULL, &dwSize, dwFlags);
462 ok(hr == E_POINTER, "Checking length of string, return was 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
463 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
465 dwSize--;
466 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
467 ok(hr == E_POINTER, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
468 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
470 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
471 ok(hr == dwExpectReturn, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, dwExpectReturn);
472 ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\n", dwSize, dwExpectLen);
473 if(SUCCEEDED(hr)) {
474 ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected %s, but got %s\n", szExpectUrl, szReturnUrl);
477 dwSize = 0;
478 hr = UrlCombineW(wszUrl1, wszUrl2, NULL, &dwSize, dwFlags);
479 ok(hr == E_POINTER, "Checking length of string, return was 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
480 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
482 dwSize--;
483 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
484 ok(hr == E_POINTER, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
485 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
487 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
488 ok(hr == dwExpectReturn, "UrlCombineW returned 0x%08lx, expected 0x%08lx\n", hr, dwExpectReturn);
489 ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\n", dwSize, dwExpectLen);
490 if(SUCCEEDED(hr)) {
491 wszConvertedUrl = GetWideString(szReturnUrl);
492 ok(strcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCombine!\n");
493 FreeWideString(wszConvertedUrl);
496 FreeWideString(wszUrl1);
497 FreeWideString(wszUrl2);
498 FreeWideString(wszExpectUrl);
501 static void test_UrlCombine(void)
503 unsigned int i;
504 for(i=0; i<sizeof(TEST_COMBINE)/sizeof(TEST_COMBINE[0]); i++) {
505 test_url_combine(TEST_COMBINE[i].url1, TEST_COMBINE[i].url2, TEST_COMBINE[i].flags,
506 TEST_COMBINE[i].expectret, TEST_COMBINE[i].expecturl);
510 static void test_UrlCreateFromPath(void)
512 size_t i;
513 char ret_url[INTERNET_MAX_URL_LENGTH];
514 DWORD len, ret;
515 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
516 WCHAR *pathW, *urlW;
518 for(i = 0; i < sizeof(TEST_URLFROMPATH) / sizeof(TEST_URLFROMPATH[0]); i++) {
519 len = INTERNET_MAX_URL_LENGTH;
520 ret = UrlCreateFromPathA(TEST_URLFROMPATH[i].path, ret_url, &len, 0);
521 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08lx from path %s\n", ret, TEST_URLFROMPATH[i].path);
522 ok(!lstrcmpi(ret_url, TEST_URLFROMPATH[i].url), "url %s from path %s\n", ret_url, TEST_URLFROMPATH[i].path);
523 ok(len == strlen(ret_url), "ret len %ld from path %s\n", len, TEST_URLFROMPATH[i].path);
525 len = INTERNET_MAX_URL_LENGTH;
526 pathW = GetWideString(TEST_URLFROMPATH[i].path);
527 urlW = GetWideString(TEST_URLFROMPATH[i].url);
528 ret = UrlCreateFromPathW(pathW, ret_urlW, &len, 0);
529 WideCharToMultiByte(CP_ACP, 0, ret_urlW, -1, ret_url, sizeof(ret_url),0,0);
530 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08lx from path L\"%s\", expected %08lx\n",
531 ret, TEST_URLFROMPATH[i].path, TEST_URLFROMPATH[i].ret);
532 ok(!lstrcmpiW(ret_urlW, urlW), "got %s expected %s from path L\"%s\"\n", ret_url, TEST_URLFROMPATH[i].url, TEST_URLFROMPATH[i].path);
533 ok(len == strlenW(ret_urlW), "ret len %ld from path L\"%s\"\n", len, TEST_URLFROMPATH[i].path);
534 FreeWideString(urlW);
535 FreeWideString(pathW);
539 static void test_UrlIs(void)
541 BOOL ret;
542 size_t i;
543 WCHAR wurl[80];
545 for(i = 0; i < sizeof(TEST_PATH_IS_URL) / sizeof(TEST_PATH_IS_URL[0]); i++) {
546 MultiByteToWideChar(CP_ACP, 0, TEST_PATH_IS_URL[i].path, -1, wurl, 80);
548 ret = UrlIsA( TEST_PATH_IS_URL[i].path, URLIS_URL );
549 ok( ret == TEST_PATH_IS_URL[i].expect,
550 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
551 TEST_PATH_IS_URL[i].expect );
553 ret = UrlIsW( wurl, URLIS_URL );
554 ok( ret == TEST_PATH_IS_URL[i].expect,
555 "returned %d from path (UrlIsW) %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
556 TEST_PATH_IS_URL[i].expect );
558 for(i = 0; i < sizeof(TEST_URLIS_ATTRIBS) / sizeof(TEST_URLIS_ATTRIBS[0]); i++) {
559 MultiByteToWideChar(CP_ACP, 0, TEST_URLIS_ATTRIBS[i].url, -1, wurl, 80);
561 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_OPAQUE);
562 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
563 "returned %d for URLIS_OPAQUE, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
564 TEST_URLIS_ATTRIBS[i].expectOpaque );
565 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_FILEURL);
566 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
567 "returned %d for URLIS_FILEURL, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
568 TEST_URLIS_ATTRIBS[i].expectFile );
570 ret = UrlIsW( wurl, URLIS_OPAQUE);
571 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
572 "returned %d for URLIS_OPAQUE (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
573 TEST_URLIS_ATTRIBS[i].expectOpaque );
574 ret = UrlIsW( wurl, URLIS_FILEURL);
575 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
576 "returned %d for URLIS_FILEURL (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
577 TEST_URLIS_ATTRIBS[i].expectFile );
581 static void test_UrlUnescape(void)
583 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
584 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
585 WCHAR *urlW, *expected_urlW;
586 DWORD dwEscaped;
587 size_t i;
588 static char inplace[] = "file:///C:/Program%20Files";
589 static WCHAR inplaceW[] = {'f','i','l','e',':','/','/','/','C',':','/',
590 'P','r','o','g','r','a','m','%','2','0','F','i','l','e','s',0};
592 for(i=0; i<sizeof(TEST_URL_UNESCAPE)/sizeof(TEST_URL_UNESCAPE[0]); i++) {
593 dwEscaped=INTERNET_MAX_URL_LENGTH;
594 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);
595 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);
597 dwEscaped = INTERNET_MAX_URL_LENGTH;
598 urlW = GetWideString(TEST_URL_UNESCAPE[i].url);
599 expected_urlW = GetWideString(TEST_URL_UNESCAPE[i].expect);
600 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);
601 WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
602 ok(strcmpW(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);
603 FreeWideString(urlW);
604 FreeWideString(expected_urlW);
607 dwEscaped = sizeof(inplace);
608 ok(UrlUnescapeA(inplace, NULL, &dwEscaped, URL_UNESCAPE_INPLACE) == S_OK, "UrlUnescapeA failed unexpectedly\n");
610 dwEscaped = sizeof(inplaceW);
611 ok(UrlUnescapeW(inplaceW, NULL, &dwEscaped, URL_UNESCAPE_INPLACE) == S_OK, "UrlUnescapeW failed unexpectedly\n");
614 static void test_PathSearchAndQualify(void)
616 WCHAR path1[] = {'c',':','\\','f','o','o',0};
617 WCHAR expect1[] = {'c',':','\\','f','o','o',0};
618 WCHAR path2[] = {'c',':','f','o','o',0};
619 WCHAR c_drive[] = {'c',':',0};
620 WCHAR foo[] = {'f','o','o',0};
621 WCHAR path3[] = {'\\','f','o','o',0};
622 WCHAR winini[] = {'w','i','n','.','i','n','i',0};
623 WCHAR out[MAX_PATH];
624 WCHAR cur_dir[MAX_PATH];
625 WCHAR dot[] = {'.',0};
627 /* c:\foo */
628 ok(PathSearchAndQualifyW(path1, out, MAX_PATH) != 0,
629 "PathSearchAndQualify rets 0\n");
630 ok(!lstrcmpiW(out, expect1), "strings don't match\n");
632 /* c:foo */
633 ok(PathSearchAndQualifyW(path2, out, MAX_PATH) != 0,
634 "PathSearchAndQualify rets 0\n");
635 GetFullPathNameW(c_drive, MAX_PATH, cur_dir, NULL);
636 PathAddBackslashW(cur_dir);
637 strcatW(cur_dir, foo);
638 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
640 /* foo */
641 ok(PathSearchAndQualifyW(foo, out, MAX_PATH) != 0,
642 "PathSearchAndQualify rets 0\n");
643 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
644 PathAddBackslashW(cur_dir);
645 strcatW(cur_dir, foo);
646 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
648 /* \foo */
649 ok(PathSearchAndQualifyW(path3, out, MAX_PATH) != 0,
650 "PathSearchAndQualify rets 0\n");
651 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
652 strcpyW(cur_dir + 2, path3);
653 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
655 /* win.ini */
656 ok(PathSearchAndQualifyW(winini, out, MAX_PATH) != 0,
657 "PathSearchAndQualify rets 0\n");
658 if(!SearchPathW(NULL, winini, NULL, MAX_PATH, cur_dir, NULL))
659 GetFullPathNameW(winini, MAX_PATH, cur_dir, NULL);
660 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
664 static void test_PathCreateFromUrl(void)
666 size_t i;
667 char ret_path[INTERNET_MAX_URL_LENGTH];
668 DWORD len, ret;
669 WCHAR ret_pathW[INTERNET_MAX_URL_LENGTH];
670 WCHAR *pathW, *urlW;
672 for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
673 len = INTERNET_MAX_URL_LENGTH;
674 ret = PathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
675 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url %s\n", ret, TEST_PATHFROMURL[i].url);
676 if(TEST_PATHFROMURL[i].path) {
677 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);
678 ok(len == strlen(ret_path), "ret len %ld from url %s\n", len, TEST_PATHFROMURL[i].url);
680 len = INTERNET_MAX_URL_LENGTH;
681 pathW = GetWideString(TEST_PATHFROMURL[i].path);
682 urlW = GetWideString(TEST_PATHFROMURL[i].url);
683 ret = PathCreateFromUrlW(urlW, ret_pathW, &len, 0);
684 WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),0,0);
685 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
686 if(TEST_PATHFROMURL[i].path) {
687 ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
688 ok(len == strlenW(ret_pathW), "ret len %ld from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url);
690 FreeWideString(urlW);
691 FreeWideString(pathW);
696 static void test_PathIsUrl(void)
698 size_t i;
699 BOOL ret;
701 for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
702 ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
703 ok(ret == TEST_PATH_IS_URL[i].expect,
704 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
705 TEST_PATH_IS_URL[i].expect);
709 static const DWORD SHELL_charclass[] =
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 0x00000000, 0x00000000, 0x00000000, 0x00000000,
719 0x00000080, 0x00000100, 0x00000200, 0x00000100,
720 0x00000100, 0x00000100, 0x00000100, 0x00000100,
721 0x00000100, 0x00000100, 0x00000002, 0x00000100,
722 0x00000040, 0x00000100, 0x00000004, 0x00000000,
723 0x00000100, 0x00000100, 0x00000100, 0x00000100,
724 0x00000100, 0x00000100, 0x00000100, 0x00000100,
725 0x00000100, 0x00000100, 0x00000010, 0x00000020,
726 0x00000000, 0x00000100, 0x00000000, 0x00000001,
727 0x00000100, 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, 0xffffffff,
733 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
734 0x00000008, 0x00000100, 0x00000100, 0x00000100,
735 0x00000100, 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, 0xffffffff,
741 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
742 0x00000000, 0x00000100, 0x00000100
745 static void test_PathIsValidCharA(void)
747 BOOL ret;
748 unsigned int c;
750 ret = pPathIsValidCharA( 0x7f, 0 );
751 ok ( !ret, "PathIsValidCharA succeeded: 0x%08lx\n", (DWORD)ret );
753 ret = pPathIsValidCharA( 0x7f, 1 );
754 ok ( !ret, "PathIsValidCharA succeeded: 0x%08lx\n", (DWORD)ret );
756 for (c = 0; c < 0x7f; c++)
758 ret = pPathIsValidCharA( c, ~0U );
759 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
760 "PathIsValidCharA failed: 0x%02x got 0x%08lx expected 0x%08lx\n",
761 c, (DWORD)ret, SHELL_charclass[c] );
764 for (c = 0x7f; c <= 0xff; c++)
766 ret = pPathIsValidCharA( c, ~0U );
767 ok ( ret == 0x00000100,
768 "PathIsValidCharA failed: 0x%02x got 0x%08lx expected 0x00000100\n",
769 c, (DWORD)ret );
773 static void test_PathIsValidCharW(void)
775 BOOL ret;
776 unsigned int c, err_count = 0;
778 ret = pPathIsValidCharW( 0x7f, 0 );
779 ok ( !ret, "PathIsValidCharW succeeded: 0x%08lx\n", (DWORD)ret );
781 ret = pPathIsValidCharW( 0x7f, 1 );
782 ok ( !ret, "PathIsValidCharW succeeded: 0x%08lx\n", (DWORD)ret );
784 for (c = 0; c < 0x7f; c++)
786 ret = pPathIsValidCharW( c, ~0U );
787 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
788 "PathIsValidCharW failed: 0x%02x got 0x%08lx expected 0x%08lx\n",
789 c, (DWORD)ret, SHELL_charclass[c] );
792 for (c = 0x007f; c <= 0xffff; c++)
794 ret = pPathIsValidCharW( c, ~0U );
795 ok ( ret == 0x00000100,
796 "PathIsValidCharW failed: 0x%02x got 0x%08lx expected 0x00000100\n",
797 c, (DWORD)ret );
798 if (ret != 0x00000100)
800 if(++err_count > 100 ) {
801 trace("skipping rest of PathIsValidCharW tests "
802 "because of the current number of errors\n");
803 break;
809 static void test_PathMakePretty(void)
811 char buff[MAX_PATH];
813 ok (PathMakePrettyA(NULL) == FALSE, "PathMakePretty: NULL path succeeded\n");
814 buff[0] = '\0';
815 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Empty path failed\n");
817 strcpy(buff, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
818 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Long UC name failed\n");
819 ok (strcmp(buff, "C:\\a long file name with \\spaces.txt") == 0,
820 "PathMakePretty: Long UC name not changed\n");
822 strcpy(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
823 ok (PathMakePrettyA(buff) == FALSE, "PathMakePretty: Long MC name succeeded\n");
824 ok (strcmp(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
825 "PathMakePretty: Failed but modified path\n");
827 strcpy(buff, "TEST");
828 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Short name failed\n");
829 ok (strcmp(buff, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff);
832 static void test_PathMatchSpec(void)
834 static const char file[] = "c:\\foo\\bar\\filename.ext";
835 static const char spec1[] = ".ext";
836 static const char spec2[] = "*.ext";
837 static const char spec3[] = "*.ext ";
838 static const char spec4[] = " *.ext";
839 static const char spec5[] = "* .ext";
840 static const char spec6[] = "*. ext";
841 static const char spec7[] = "* . ext";
842 static const char spec8[] = "*.e?t";
843 static const char spec9[] = "filename.ext";
844 static const char spec10[] = "*bar\\filename.ext";
845 static const char spec11[] = " foo; *.ext";
846 static const char spec12[] = "*.ext;*.bar";
847 static const char spec13[] = "*bar*";
849 ok (PathMatchSpecA(file, spec1) == FALSE, "PathMatchSpec: Spec1 failed\n");
850 ok (PathMatchSpecA(file, spec2) == TRUE, "PathMatchSpec: Spec2 failed\n");
851 ok (PathMatchSpecA(file, spec3) == FALSE, "PathMatchSpec: Spec3 failed\n");
852 todo_wine ok (PathMatchSpecA(file, spec4) == TRUE, "PathMatchSpec: Spec4 failed\n");
853 todo_wine ok (PathMatchSpecA(file, spec5) == TRUE, "PathMatchSpec: Spec5 failed\n");
854 todo_wine ok (PathMatchSpecA(file, spec6) == TRUE, "PathMatchSpec: Spec6 failed\n");
855 ok (PathMatchSpecA(file, spec7) == FALSE, "PathMatchSpec: Spec7 failed\n");
856 ok (PathMatchSpecA(file, spec8) == TRUE, "PathMatchSpec: Spec8 failed\n");
857 ok (PathMatchSpecA(file, spec9) == FALSE, "PathMatchSpec: Spec9 failed\n");
858 ok (PathMatchSpecA(file, spec10) == TRUE, "PathMatchSpec: Spec10 failed\n");
859 ok (PathMatchSpecA(file, spec11) == TRUE, "PathMatchSpec: Spec11 failed\n");
860 ok (PathMatchSpecA(file, spec12) == TRUE, "PathMatchSpec: Spec12 failed\n");
861 ok (PathMatchSpecA(file, spec13) == TRUE, "PathMatchSpec: Spec13 failed\n");
865 START_TEST(path)
867 hShlwapi = LoadLibraryA("shlwapi.dll");
868 if (!hShlwapi) return;
870 test_UrlHash();
871 test_UrlGetPart();
872 test_UrlCanonicalize();
873 test_UrlEscape();
874 test_UrlCombine();
875 test_UrlCreateFromPath();
876 test_UrlIs();
877 test_UrlUnescape();
879 test_PathSearchAndQualify();
880 test_PathCreateFromUrl();
881 test_PathIsUrl();
883 test_PathMakePretty();
884 test_PathMatchSpec();
886 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
887 * ordinal number in some native versions. Check this to prevent a crash.
889 pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
890 if (pPathIsValidCharA && pPathIsValidCharA != (void*)GetProcAddress(hShlwapi, "PathAppendA"))
892 test_PathIsValidCharA();
894 pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
895 if (pPathIsValidCharW) test_PathIsValidCharW();