also actually rename the files...
[reactos.git] / reactos / regtests / winetests / shlwapi / path.c
1 /* Unit test suite for Path functions
2 *
3 * Copyright 2002 Matthew Mastracci
4 *
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.
9 *
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.
14 *
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
18 */
19
20 #include <assert.h>
21 #include <stdarg.h>
22 #include <stdio.h>
23
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"
31
32 static HMODULE hShlwapi;
33 static HRESULT (WINAPI *pPathIsValidCharA)(char,DWORD);
34 static HRESULT (WINAPI *pPathIsValidCharW)(WCHAR,DWORD);
35
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";
39
40 typedef struct _TEST_URL_CANONICALIZE {
41 const char *url;
42 DWORD flags;
43 HRESULT expectret;
44 const char *expecturl;
45 } TEST_URL_CANONICALIZE;
46
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", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../#example"},
64 {"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"},
65 {"http://www.winehq.org/tests/foo%20bar", URL_UNESCAPE , S_OK, "http://www.winehq.org/tests/foo bar"},
66 {"file:///c:/tests/foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar"},
67 };
68
69 typedef struct _TEST_URL_ESCAPE {
70 const char *url;
71 DWORD flags;
72 DWORD expectescaped;
73 HRESULT expectret;
74 const char *expecturl;
75 } TEST_URL_ESCAPE;
76
77 const TEST_URL_ESCAPE TEST_ESCAPE[] = {
78 {"http://www.winehq.org/tests0", 0, 0, S_OK, "http://www.winehq.org/tests0"},
79 {"http://www.winehq.org/tests1\n", 0, 0, S_OK, "http://www.winehq.org/tests1%0A"},
80 {"http://www.winehq.org/tests2\r", 0, 0, S_OK, "http://www.winehq.org/tests2%0D"},
81 {"http://www.winehq.org/tests3\r", URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, 0, S_OK, "http://www.winehq.org/tests3\r"},
82 {"http://www.winehq.org/tests4\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests4\r"},
83 {"http://www.winehq.org/tests5\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests5\r"},
84 {"/direct/swhelp/series6/6.2i_latestservicepack.dat\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "/direct/swhelp/series6/6.2i_latestservicepack.dat\r"},
85
86 {"file://////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
87 {"file://///foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
88 {"file:////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
89 {"file:///localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"},
90 {"file:///foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
91 {"file://loCalHost/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
92 {"file://foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
93 {"file:/localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"},
94 {"file:/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
95 {"file:foo/bar\\baz", 0, 0, S_OK, "file:foo/bar/baz"},
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:///foo/bar/baz"},
100 {"file:///f oo/b?a r\\baz", 0, 0, S_OK, "file:///f%20oo/b?a r\\baz"},
101 {"file:///foo/b#a r\\baz", 0, 0, S_OK, "file:///foo/b%23a%20r/baz"},
102 {"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"},
103 {"file:///f o%o/b?a r\\b%az", URL_ESCAPE_PERCENT, 0, S_OK, "file:///f%20o%25o/b?a r\\b%az"},
104 {"file:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "file:%2Ffoo%2Fbar%5Cbaz"},
105
106 {"foo/b%ar\\ba?z\\", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%ar%5Cba%3Fz%5C"},
107 {"foo/b%ar\\ba?z\\", URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%25ar%5Cba%3Fz%5C"},
108 {"foo/bar\\ba?z\\", 0, 0, S_OK, "foo/bar%5Cba?z\\"},
109 {"/foo/bar\\ba?z\\", 0, 0, S_OK, "/foo/bar%5Cba?z\\"},
110 {"/foo/bar\\ba#z\\", 0, 0, S_OK, "/foo/bar%5Cba#z\\"},
111 {"/foo/%5C", 0, 0, S_OK, "/foo/%5C"},
112 {"/foo/%5C", URL_ESCAPE_PERCENT, 0, S_OK, "/foo/%255C"},
113
114 {"http://////foo/bar\\baz", 0, 0, S_OK, "http://////foo/bar/baz"},
115 {"http://///foo/bar\\baz", 0, 0, S_OK, "http://///foo/bar/baz"},
116 {"http:////foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"},
117 {"http:///foo/bar\\baz", 0, 0, S_OK, "http:///foo/bar/baz"},
118 {"http://localhost/foo/bar\\baz", 0, 0, S_OK, "http://localhost/foo/bar/baz"},
119 {"http://foo/bar\\baz", 0, 0, S_OK, "http://foo/bar/baz"},
120 {"http:/foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"},
121 {"http:foo/bar\\ba?z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba?z\\"},
122 {"http:foo/bar\\ba#z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba#z\\"},
123 {"http:\\foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"},
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:/fo ?o/b ar\\baz", 0, 0, S_OK, "http:/fo%20?o/b ar\\baz"},
128 {"http:fo ?o/b ar\\baz", 0, 0, S_OK, "http:fo%20?o/b ar\\baz"},
129 {"http:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "http:%2Ffoo%2Fbar%5Cbaz"},
130
131 {"https://foo/bar\\baz", 0, 0, S_OK, "https://foo/bar/baz"},
132 {"https:/foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"},
133 {"https:\\foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"},
134
135 {"foo:////foo/bar\\baz", 0, 0, S_OK, "foo:////foo/bar%5Cbaz"},
136 {"foo:///foo/bar\\baz", 0, 0, S_OK, "foo:///foo/bar%5Cbaz"},
137 {"foo://localhost/foo/bar\\baz", 0, 0, S_OK, "foo://localhost/foo/bar%5Cbaz"},
138 {"foo://foo/bar\\baz", 0, 0, S_OK, "foo://foo/bar%5Cbaz"},
139 {"foo:/foo/bar\\baz", 0, 0, S_OK, "foo:/foo/bar%5Cbaz"},
140 {"foo:foo/bar\\baz", 0, 0, S_OK, "foo:foo%2Fbar%5Cbaz"},
141 {"foo:\\foo/bar\\baz", 0, 0, S_OK, "foo:%5Cfoo%2Fbar%5Cbaz"},
142 {"foo:/foo/bar\\ba?\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba?\\z"},
143 {"foo:/foo/bar\\ba#\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba#\\z"},
144
145 {"mailto:/fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:%2Ffo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
146 {"mailto:fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:fo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
147 {"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"},
148
149 {"ftp:fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:fo%2Fo@bar.baz%2Ffoo%2Fbar"},
150 {"ftp:/fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:/fo/o@bar.baz/foo/bar"},
151 {"ftp://fo/o@bar.baz/fo?o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo?o\\bar"},
152 {"ftp://fo/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo#o\\bar"},
153 {"ftp://localhost/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://localhost/o@bar.baz/fo#o\\bar"},
154 {"ftp:///fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:///fo/o@bar.baz/foo/bar"},
155 {"ftp:////fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:////fo/o@bar.baz/foo/bar"}
156 };
157
158 typedef struct _TEST_URL_COMBINE {
159 const char *url1;
160 const char *url2;
161 DWORD flags;
162 HRESULT expectret;
163 const char *expecturl;
164 } TEST_URL_COMBINE;
165
166 const TEST_URL_COMBINE TEST_COMBINE[] = {
167 {"http://www.winehq.org/tests", "tests1", 0, S_OK, "http://www.winehq.org/tests1"},
168 /*FIXME {"http://www.winehq.org/tests", "../tests2", 0, S_OK, "http://www.winehq.org/tests2"},*/
169 {"http://www.winehq.org/tests/", "../tests3", 0, S_OK, "http://www.winehq.org/tests3"},
170 {"http://www.winehq.org/tests/../tests", "tests4", 0, S_OK, "http://www.winehq.org/tests4"},
171 {"http://www.winehq.org/tests/../tests/", "tests5", 0, S_OK, "http://www.winehq.org/tests/tests5"},
172 {"http://www.winehq.org/tests/../tests/", "/tests6/..", 0, S_OK, "http://www.winehq.org/"},
173 {"http://www.winehq.org/tests/../tests/..", "tests7/..", 0, S_OK, "http://www.winehq.org/"},
174 {"http://www.winehq.org/tests/?query=x&return=y", "tests8", 0, S_OK, "http://www.winehq.org/tests/tests8"},
175 {"http://www.winehq.org/tests/#example", "tests9", 0, S_OK, "http://www.winehq.org/tests/tests9"},
176 {"http://www.winehq.org/tests/../tests/", "/tests10/..", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests10/.."},
177 {"http://www.winehq.org/tests/../", "tests11", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../tests11"},
178 };
179
180 struct {
181 const char *path;
182 const char *url;
183 DWORD ret;
184 } TEST_URLFROMPATH [] = {
185 {"foo", "file:foo", S_OK},
186 {"foo\\bar", "file:foo/bar", S_OK},
187 {"\\foo\\bar", "file:///foo/bar", S_OK},
188 {"c:\\foo\\bar", "file:///c:/foo/bar", S_OK},
189 {"c:foo\\bar", "file:///c:foo/bar", S_OK},
190 {"c:\\foo/b a%r", "file:///c:/foo/b%20a%25r", S_OK},
191 {"c:\\foo\\foo bar", "file:///c:/foo/foo%20bar", S_OK},
192 #if 0
193 /* The following test fails on native shlwapi as distributed with Win95/98.
194 * Wine matches the behaviour of later versions.
195 */
196 {"xx:c:\\foo\\bar", "xx:c:\\foo\\bar", S_FALSE}
197 #endif
198 };
199
200 struct {
201 const char *url;
202 const char *path;
203 DWORD ret;
204 } TEST_PATHFROMURL[] = {
205 {"file:///c:/foo/ba%5Cr", "c:\\foo\\ba\\r", S_OK},
206 {"file:///c:/foo/../ba%5Cr", "c:\\foo\\..\\ba\\r", S_OK},
207 {"file:///host/c:/foo/bar", "\\host\\c:\\foo\\bar", S_OK},
208 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
209 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
210 {"file:\\\\host\\c:\\foo\\bar", "\\\\hostc:\\foo\\bar", S_OK},
211 {"file:\\\\host\\ca\\foo\\bar", "\\\\host\\ca\\foo\\bar", S_OK},
212 {"file:\\\\host\\c|\\foo\\bar", "\\\\hostc|\\foo\\bar", S_OK},
213 {"file:\\%5Chost\\c:\\foo\\bar", "\\\\host\\c:\\foo\\bar", S_OK},
214 {"file:\\\\host\\cx:\\foo\\bar", "\\\\host\\cx:\\foo\\bar", S_OK},
215 {"file://c:/foo/bar", "c:\\foo\\bar", S_OK},
216 {"file://c:/d:/foo/bar", "c:\\d:\\foo\\bar", S_OK},
217 {"file://c|/d|/foo/bar", "c:\\d|\\foo\\bar", S_OK},
218 {"file://host/foo/bar", "\\\\host\\foo\\bar", S_OK},
219 {"file:/foo/bar", "\\foo\\bar", S_OK},
220 {"file:/foo/bar/", "\\foo\\bar\\", S_OK},
221 {"file:foo/bar", "foo\\bar", S_OK},
222 {"file:c:/foo/bar", "c:\\foo\\bar", S_OK},
223 {"file:c|/foo/bar", "c:\\foo\\bar", S_OK},
224 {"file:cx|/foo/bar", "cx|\\foo\\bar", S_OK},
225 {"file:////c:/foo/bar", "c:\\foo\\bar", S_OK},
226 /* {"file:////c:/foo/foo%20bar", "c:\\foo\\foo%20bar", S_OK},*/
227
228 {"c:\\foo\\bar", NULL, E_INVALIDARG},
229 {"foo/bar", NULL, E_INVALIDARG},
230 {"http://foo/bar", NULL, E_INVALIDARG},
231
232 };
233
234 struct {
235 char url[30];
236 const char *expect;
237 } TEST_URL_UNESCAPE[] = {
238 {"file://foo/bar", "file://foo/bar"},
239 {"file://fo%20o%5Ca/bar", "file://fo o\\a/bar"}
240 };
241
242
243 struct {
244 const char *path;
245 BOOL expect;
246 } TEST_PATH_IS_URL[] = {
247 {"http://foo/bar", TRUE},
248 {"c:\\foo\\bar", FALSE},
249 {"foo://foo/bar", TRUE},
250 {"foo\\bar", FALSE},
251 {"foo.bar", FALSE},
252 {"bogusscheme:", TRUE},
253 {"http:partial", TRUE}
254 };
255
256 struct {
257 const char *url;
258 BOOL expectOpaque;
259 BOOL expectFile;
260 } TEST_URLIS_ATTRIBS[] = {
261 { "ftp:", FALSE, FALSE },
262 { "http:", FALSE, FALSE },
263 { "gopher:", FALSE, FALSE },
264 { "mailto:", TRUE, FALSE },
265 { "news:", FALSE, FALSE },
266 { "nntp:", FALSE, FALSE },
267 { "telnet:", FALSE, FALSE },
268 { "wais:", FALSE, FALSE },
269 { "file:", FALSE, TRUE },
270 { "mk:", FALSE, FALSE },
271 { "https:", FALSE, FALSE },
272 { "shell:", TRUE, FALSE },
273 { "https:", FALSE, FALSE },
274 { "snews:", FALSE, FALSE },
275 { "local:", FALSE, FALSE },
276 { "javascript:", TRUE, FALSE },
277 { "vbscript:", TRUE, FALSE },
278 { "about:", TRUE, FALSE },
279 { "res:", FALSE, FALSE },
280 { "bogusscheme:", FALSE, FALSE },
281 { "file:\\\\e:\\b\\c", FALSE, TRUE },
282 { "file://e:/b/c", FALSE, TRUE },
283 { "http:partial", FALSE, FALSE },
284 { "mailto://www.winehq.org/test.html", TRUE, FALSE },
285 { "file:partial", FALSE, TRUE }
286 };
287
288
289 static LPWSTR GetWideString(const char* szString)
290 {
291 LPWSTR wszString = HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
292
293 MultiByteToWideChar(0, 0, szString, -1, wszString, INTERNET_MAX_URL_LENGTH);
294
295 return wszString;
296 }
297
298 static void FreeWideString(LPWSTR wszString)
299 {
300 HeapFree(GetProcessHeap(), 0, wszString);
301 }
302
303 static void hash_url(const char* szUrl)
304 {
305 LPCSTR szTestUrl = szUrl;
306 LPWSTR wszTestUrl = GetWideString(szTestUrl);
307
308 DWORD cbSize = sizeof(DWORD);
309 DWORD dwHash1, dwHash2;
310 ok(UrlHashA(szTestUrl, (LPBYTE)&dwHash1, cbSize) == S_OK, "UrlHashA didn't return S_OK\n");
311 ok(UrlHashW(wszTestUrl, (LPBYTE)&dwHash2, cbSize) == S_OK, "UrlHashW didn't return S_OK\n");
312
313 FreeWideString(wszTestUrl);
314
315 ok(dwHash1 == dwHash2, "Hashes didn't compare\n");
316 }
317
318 static void test_UrlHash(void)
319 {
320 hash_url(TEST_URL_1);
321 hash_url(TEST_URL_2);
322 hash_url(TEST_URL_3);
323 }
324
325 static void test_url_part(const char* szUrl, DWORD dwPart, DWORD dwFlags, const char* szExpected)
326 {
327 CHAR szPart[INTERNET_MAX_URL_LENGTH];
328 WCHAR wszPart[INTERNET_MAX_URL_LENGTH];
329 LPWSTR wszUrl = GetWideString(szUrl);
330 LPWSTR wszConvertedPart;
331
332 DWORD dwSize;
333
334 dwSize = INTERNET_MAX_URL_LENGTH;
335 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);
336 dwSize = INTERNET_MAX_URL_LENGTH;
337 ok( UrlGetPartW(wszUrl, wszPart, &dwSize, dwPart, dwFlags) == S_OK, "UrlGetPartW didn't return S_OK\n" );
338
339 wszConvertedPart = GetWideString(szPart);
340
341 ok(strcmpW(wszPart,wszConvertedPart)==0, "Strings didn't match between ascii and unicode UrlGetPart!\n");
342
343 FreeWideString(wszUrl);
344 FreeWideString(wszConvertedPart);
345
346 /* Note that v6.0 and later don't return '?' with the query */
347 ok(strcmp(szPart,szExpected)==0 ||
348 (*szExpected=='?' && !strcmp(szPart,szExpected+1)),
349 "Expected %s, but got %s\n", szExpected, szPart);
350 }
351
352 static void test_UrlGetPart(void)
353 {
354 test_url_part(TEST_URL_3, URL_PART_HOSTNAME, 0, "localhost");
355 test_url_part(TEST_URL_3, URL_PART_PORT, 0, "21");
356 test_url_part(TEST_URL_3, URL_PART_USERNAME, 0, "foo");
357 test_url_part(TEST_URL_3, URL_PART_PASSWORD, 0, "bar");
358 test_url_part(TEST_URL_3, URL_PART_SCHEME, 0, "http");
359 test_url_part(TEST_URL_3, URL_PART_QUERY, 0, "?query=x&return=y");
360 }
361
362 static void test_url_escape(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
363 {
364 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
365 DWORD dwEscaped;
366 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
367 WCHAR *urlW, *expected_urlW;
368 dwEscaped=INTERNET_MAX_URL_LENGTH;
369
370 ok(UrlEscapeA(szUrl, szReturnUrl, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeA didn't return 0x%08lx from \"%s\"\n", dwExpectReturn, szUrl);
371 ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected \"%s\", but got \"%s\" from \"%s\"\n", szExpectUrl, szReturnUrl, szUrl);
372
373 dwEscaped = INTERNET_MAX_URL_LENGTH;
374 urlW = GetWideString(szUrl);
375 expected_urlW = GetWideString(szExpectUrl);
376 ok(UrlEscapeW(urlW, ret_urlW, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeW didn't return 0x%08lx from \"%s\"\n", dwExpectReturn, szUrl);
377 WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
378 ok(strcmpW(ret_urlW, expected_urlW)==0, "Expected \"%s\", but got \"%s\" from \"%s\" flags %08lx\n", szExpectUrl, szReturnUrl, szUrl, dwFlags);
379 FreeWideString(urlW);
380 FreeWideString(expected_urlW);
381
382 }
383
384 static void test_url_canonicalize(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
385 {
386 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
387 WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
388 LPWSTR wszUrl = GetWideString(szUrl);
389 LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
390 LPWSTR wszConvertedUrl;
391
392 DWORD dwSize;
393
394 dwSize = INTERNET_MAX_URL_LENGTH;
395 ok(UrlCanonicalizeA(szUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
396 ok(UrlCanonicalizeA(szUrl, szReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeA didn't return 0x%08lx\n", dwExpectReturn);
397 ok(strcmp(szReturnUrl,szExpectUrl)==0, "UrlCanonicalizeA dwFlags 0x%08lx Expected %s, but got %s\n", dwFlags, szExpectUrl, szReturnUrl);
398
399 dwSize = INTERNET_MAX_URL_LENGTH;
400 ok(UrlCanonicalizeW(wszUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
401 ok(UrlCanonicalizeW(wszUrl, wszReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeW didn't return 0x%08lx\n", dwExpectReturn);
402 wszConvertedUrl = GetWideString(szReturnUrl);
403 ok(strcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCanonicalize!\n");
404 FreeWideString(wszConvertedUrl);
405
406
407 FreeWideString(wszUrl);
408 FreeWideString(wszExpectUrl);
409 }
410
411
412 static void test_UrlEscape(void)
413 {
414 unsigned int i;
415 for(i=0; i<sizeof(TEST_ESCAPE)/sizeof(TEST_ESCAPE[0]); i++) {
416 test_url_escape(TEST_ESCAPE[i].url, TEST_ESCAPE[i].flags,
417 TEST_ESCAPE[i].expectret, TEST_ESCAPE[i].expecturl);
418 }
419 }
420
421 static void test_UrlCanonicalize(void)
422 {
423 unsigned int i;
424 for(i=0; i<sizeof(TEST_CANONICALIZE)/sizeof(TEST_CANONICALIZE[0]); i++) {
425 test_url_canonicalize(TEST_CANONICALIZE[i].url, TEST_CANONICALIZE[i].flags,
426 TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expecturl);
427 }
428 }
429
430 static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
431 {
432 HRESULT hr;
433 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
434 WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
435 LPWSTR wszUrl1 = GetWideString(szUrl1);
436 LPWSTR wszUrl2 = GetWideString(szUrl2);
437 LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
438 LPWSTR wszConvertedUrl;
439
440 DWORD dwSize;
441 DWORD dwExpectLen = lstrlen(szExpectUrl);
442
443 hr = UrlCombineA(szUrl1, szUrl2, NULL, NULL, dwFlags);
444 ok(hr == E_INVALIDARG, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_INVALIDARG);
445
446 dwSize = 0;
447 hr = UrlCombineA(szUrl1, szUrl2, NULL, &dwSize, dwFlags);
448 ok(hr == E_POINTER, "Checking length of string, return was 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
449 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
450
451 dwSize--;
452 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
453 ok(hr == E_POINTER, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
454 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
455
456 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
457 ok(hr == dwExpectReturn, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, dwExpectReturn);
458 ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\n", dwSize, dwExpectLen);
459 if(SUCCEEDED(hr)) {
460 ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected %s, but got %s\n", szExpectUrl, szReturnUrl);
461 }
462
463 dwSize = 0;
464 hr = UrlCombineW(wszUrl1, wszUrl2, NULL, &dwSize, dwFlags);
465 ok(hr == E_POINTER, "Checking length of string, return was 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
466 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
467
468 dwSize--;
469 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
470 ok(hr == E_POINTER, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
471 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
472
473 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
474 ok(hr == dwExpectReturn, "UrlCombineW returned 0x%08lx, expected 0x%08lx\n", hr, dwExpectReturn);
475 ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\n", dwSize, dwExpectLen);
476 if(SUCCEEDED(hr)) {
477 wszConvertedUrl = GetWideString(szReturnUrl);
478 ok(strcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCombine!\n");
479 FreeWideString(wszConvertedUrl);
480 }
481
482 FreeWideString(wszUrl1);
483 FreeWideString(wszUrl2);
484 FreeWideString(wszExpectUrl);
485 }
486
487 static void test_UrlCombine(void)
488 {
489 unsigned int i;
490 for(i=0; i<sizeof(TEST_COMBINE)/sizeof(TEST_COMBINE[0]); i++) {
491 test_url_combine(TEST_COMBINE[i].url1, TEST_COMBINE[i].url2, TEST_COMBINE[i].flags,
492 TEST_COMBINE[i].expectret, TEST_COMBINE[i].expecturl);
493 }
494 }
495
496 static void test_UrlCreateFromPath(void)
497 {
498 size_t i;
499 char ret_url[INTERNET_MAX_URL_LENGTH];
500 DWORD len, ret;
501 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
502 WCHAR *pathW, *urlW;
503
504 for(i = 0; i < sizeof(TEST_URLFROMPATH) / sizeof(TEST_URLFROMPATH[0]); i++) {
505 len = INTERNET_MAX_URL_LENGTH;
506 ret = UrlCreateFromPathA(TEST_URLFROMPATH[i].path, ret_url, &len, 0);
507 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08lx from path %s\n", ret, TEST_URLFROMPATH[i].path);
508 ok(!lstrcmpi(ret_url, TEST_URLFROMPATH[i].url), "url %s from path %s\n", ret_url, TEST_URLFROMPATH[i].path);
509 ok(len == strlen(ret_url), "ret len %ld from path %s\n", len, TEST_URLFROMPATH[i].path);
510
511 len = INTERNET_MAX_URL_LENGTH;
512 pathW = GetWideString(TEST_URLFROMPATH[i].path);
513 urlW = GetWideString(TEST_URLFROMPATH[i].url);
514 ret = UrlCreateFromPathW(pathW, ret_urlW, &len, 0);
515 WideCharToMultiByte(CP_ACP, 0, ret_urlW, -1, ret_url, sizeof(ret_url),0,0);
516 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08lx from path L\"%s\", expected %08lx\n",
517 ret, TEST_URLFROMPATH[i].path, TEST_URLFROMPATH[i].ret);
518 ok(!lstrcmpiW(ret_urlW, urlW), "got %s expected %s from path L\"%s\"\n", ret_url, TEST_URLFROMPATH[i].url, TEST_URLFROMPATH[i].path);
519 ok(len == strlenW(ret_urlW), "ret len %ld from path L\"%s\"\n", len, TEST_URLFROMPATH[i].path);
520 FreeWideString(urlW);
521 FreeWideString(pathW);
522 }
523 }
524
525 static void test_UrlIs(void)
526 {
527 BOOL ret;
528 size_t i;
529 WCHAR wurl[80];
530
531 for(i = 0; i < sizeof(TEST_PATH_IS_URL) / sizeof(TEST_PATH_IS_URL[0]); i++) {
532 MultiByteToWideChar(CP_ACP, 0, TEST_PATH_IS_URL[i].path, -1, wurl, 80);
533
534 ret = UrlIsA( TEST_PATH_IS_URL[i].path, URLIS_URL );
535 ok( ret == TEST_PATH_IS_URL[i].expect,
536 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
537 TEST_PATH_IS_URL[i].expect );
538
539 ret = UrlIsW( wurl, URLIS_URL );
540 ok( ret == TEST_PATH_IS_URL[i].expect,
541 "returned %d from path (UrlIsW) %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
542 TEST_PATH_IS_URL[i].expect );
543 }
544 for(i = 0; i < sizeof(TEST_URLIS_ATTRIBS) / sizeof(TEST_URLIS_ATTRIBS[0]); i++) {
545 MultiByteToWideChar(CP_ACP, 0, TEST_URLIS_ATTRIBS[i].url, -1, wurl, 80);
546
547 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_OPAQUE);
548 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
549 "returned %d for URLIS_OPAQUE, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
550 TEST_URLIS_ATTRIBS[i].expectOpaque );
551 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_FILEURL);
552 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
553 "returned %d for URLIS_FILEURL, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
554 TEST_URLIS_ATTRIBS[i].expectFile );
555
556 ret = UrlIsW( wurl, URLIS_OPAQUE);
557 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
558 "returned %d for URLIS_OPAQUE (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
559 TEST_URLIS_ATTRIBS[i].expectOpaque );
560 ret = UrlIsW( wurl, URLIS_FILEURL);
561 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
562 "returned %d for URLIS_FILEURL (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
563 TEST_URLIS_ATTRIBS[i].expectFile );
564 }
565 }
566
567 static void test_UrlUnescape(void)
568 {
569 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
570 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
571 WCHAR *urlW, *expected_urlW;
572 DWORD dwEscaped;
573 size_t i;
574
575 for(i=0; i<sizeof(TEST_URL_UNESCAPE)/sizeof(TEST_URL_UNESCAPE[0]); i++) {
576 dwEscaped=INTERNET_MAX_URL_LENGTH;
577 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);
578 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);
579
580 dwEscaped = INTERNET_MAX_URL_LENGTH;
581 urlW = GetWideString(TEST_URL_UNESCAPE[i].url);
582 expected_urlW = GetWideString(TEST_URL_UNESCAPE[i].expect);
583 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);
584 WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
585 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);
586 FreeWideString(urlW);
587 FreeWideString(expected_urlW);
588 }
589
590 }
591
592 static void test_PathSearchAndQualify(void)
593 {
594 WCHAR path1[] = {'c',':','\\','f','o','o',0};
595 WCHAR expect1[] = {'c',':','\\','f','o','o',0};
596 WCHAR path2[] = {'c',':','f','o','o',0};
597 WCHAR c_drive[] = {'c',':',0};
598 WCHAR foo[] = {'f','o','o',0};
599 WCHAR path3[] = {'\\','f','o','o',0};
600 WCHAR winini[] = {'w','i','n','.','i','n','i',0};
601 WCHAR out[MAX_PATH];
602 WCHAR cur_dir[MAX_PATH];
603 WCHAR dot[] = {'.',0};
604
605 /* c:\foo */
606 ok(PathSearchAndQualifyW(path1, out, MAX_PATH) != 0,
607 "PathSearchAndQualify rets 0\n");
608 ok(!lstrcmpiW(out, expect1), "strings don't match\n");
609
610 /* c:foo */
611 ok(PathSearchAndQualifyW(path2, out, MAX_PATH) != 0,
612 "PathSearchAndQualify rets 0\n");
613 GetFullPathNameW(c_drive, MAX_PATH, cur_dir, NULL);
614 PathAddBackslashW(cur_dir);
615 strcatW(cur_dir, foo);
616 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
617
618 /* foo */
619 ok(PathSearchAndQualifyW(foo, out, MAX_PATH) != 0,
620 "PathSearchAndQualify rets 0\n");
621 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
622 PathAddBackslashW(cur_dir);
623 strcatW(cur_dir, foo);
624 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
625
626 /* \foo */
627 ok(PathSearchAndQualifyW(path3, out, MAX_PATH) != 0,
628 "PathSearchAndQualify rets 0\n");
629 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
630 strcpyW(cur_dir + 2, path3);
631 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
632
633 /* win.ini */
634 ok(PathSearchAndQualifyW(winini, out, MAX_PATH) != 0,
635 "PathSearchAndQualify rets 0\n");
636 if(!SearchPathW(NULL, winini, NULL, MAX_PATH, cur_dir, NULL))
637 GetFullPathNameW(winini, MAX_PATH, cur_dir, NULL);
638 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
639
640 }
641
642 static void test_PathCreateFromUrl(void)
643 {
644 size_t i;
645 char ret_path[INTERNET_MAX_URL_LENGTH];
646 DWORD len, ret;
647 WCHAR ret_pathW[INTERNET_MAX_URL_LENGTH];
648 WCHAR *pathW, *urlW;
649
650 for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
651 len = INTERNET_MAX_URL_LENGTH;
652 ret = PathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
653 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url %s\n", ret, TEST_PATHFROMURL[i].url);
654 if(TEST_PATHFROMURL[i].path) {
655 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);
656 ok(len == strlen(ret_path), "ret len %ld from url %s\n", len, TEST_PATHFROMURL[i].url);
657 }
658 len = INTERNET_MAX_URL_LENGTH;
659 pathW = GetWideString(TEST_PATHFROMURL[i].path);
660 urlW = GetWideString(TEST_PATHFROMURL[i].url);
661 ret = PathCreateFromUrlW(urlW, ret_pathW, &len, 0);
662 WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),0,0);
663 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
664 if(TEST_PATHFROMURL[i].path) {
665 ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
666 ok(len == strlenW(ret_pathW), "ret len %ld from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url);
667 }
668 FreeWideString(urlW);
669 FreeWideString(pathW);
670 }
671 }
672
673
674 static void test_PathIsUrl(void)
675 {
676 size_t i;
677 BOOL ret;
678
679 for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
680 ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
681 ok(ret == TEST_PATH_IS_URL[i].expect,
682 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
683 TEST_PATH_IS_URL[i].expect);
684 }
685 }
686
687 static const DWORD SHELL_charclass[] =
688 {
689 0x00000000, 0x00000000, 0x00000000, 0x00000000,
690 0x00000000, 0x00000000, 0x00000000, 0x00000000,
691 0x00000000, 0x00000000, 0x00000000, 0x00000000,
692 0x00000000, 0x00000000, 0x00000000, 0x00000000,
693 0x00000000, 0x00000000, 0x00000000, 0x00000000,
694 0x00000000, 0x00000000, 0x00000000, 0x00000000,
695 0x00000000, 0x00000000, 0x00000000, 0x00000000,
696 0x00000000, 0x00000000, 0x00000000, 0x00000000,
697 0x00000080, 0x00000100, 0x00000200, 0x00000100,
698 0x00000100, 0x00000100, 0x00000100, 0x00000100,
699 0x00000100, 0x00000100, 0x00000002, 0x00000100,
700 0x00000040, 0x00000100, 0x00000004, 0x00000000,
701 0x00000100, 0x00000100, 0x00000100, 0x00000100,
702 0x00000100, 0x00000100, 0x00000100, 0x00000100,
703 0x00000100, 0x00000100, 0x00000010, 0x00000020,
704 0x00000000, 0x00000100, 0x00000000, 0x00000001,
705 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
706 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
707 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
708 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
709 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
710 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
711 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
712 0x00000008, 0x00000100, 0x00000100, 0x00000100,
713 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
714 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
715 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
716 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
717 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
718 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
719 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
720 0x00000000, 0x00000100, 0x00000100
721 };
722
723 static void test_PathIsValidCharA(void)
724 {
725 BOOL ret;
726 unsigned int c;
727
728 ret = pPathIsValidCharA( 0x7f, 0 );
729 ok ( !ret, "PathIsValidCharA succeeded: 0x%08lx\n", (DWORD)ret );
730
731 ret = pPathIsValidCharA( 0x7f, 1 );
732 ok ( !ret, "PathIsValidCharA succeeded: 0x%08lx\n", (DWORD)ret );
733
734 for (c = 0; c < 0x7f; c++)
735 {
736 ret = pPathIsValidCharA( c, ~0U );
737 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
738 "PathIsValidCharA failed: 0x%02x got 0x%08lx expected 0x%08lx\n",
739 c, (DWORD)ret, SHELL_charclass[c] );
740 }
741
742 for (c = 0x7f; c <= 0xff; c++)
743 {
744 ret = pPathIsValidCharA( c, ~0U );
745 ok ( ret == 0x00000100,
746 "PathIsValidCharA failed: 0x%02x got 0x%08lx expected 0x00000100\n",
747 c, (DWORD)ret );
748 }
749 }
750
751 static void test_PathIsValidCharW(void)
752 {
753 BOOL ret;
754 unsigned int c;
755
756 ret = pPathIsValidCharW( 0x7f, 0 );
757 ok ( !ret, "PathIsValidCharW succeeded: 0x%08lx\n", (DWORD)ret );
758
759 ret = pPathIsValidCharW( 0x7f, 1 );
760 ok ( !ret, "PathIsValidCharW succeeded: 0x%08lx\n", (DWORD)ret );
761
762 for (c = 0; c < 0x7f; c++)
763 {
764 ret = pPathIsValidCharW( c, ~0U );
765 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
766 "PathIsValidCharW failed: 0x%02x got 0x%08lx expected 0x%08lx\n",
767 c, (DWORD)ret, SHELL_charclass[c] );
768 }
769
770 for (c = 0x007f; c <= 0xffff; c++)
771 {
772 ret = pPathIsValidCharW( c, ~0U );
773 ok ( ret == 0x00000100,
774 "PathIsValidCharW failed: 0x%02x got 0x%08lx expected 0x00000100\n",
775 c, (DWORD)ret );
776 }
777 }
778
779 static void test_PathMakePretty(void)
780 {
781 char buff[MAX_PATH];
782
783 ok (PathMakePrettyA(NULL) == FALSE, "PathMakePretty: NULL path succeeded\n");
784 buff[0] = '\0';
785 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Empty path failed\n");
786
787 strcpy(buff, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
788 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Long UC name failed\n");
789 ok (strcmp(buff, "C:\\a long file name with \\spaces.txt") == 0,
790 "PathMakePretty: Long UC name not changed\n");
791
792 strcpy(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
793 ok (PathMakePrettyA(buff) == FALSE, "PathMakePretty: Long MC name succeeded\n");
794 ok (strcmp(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
795 "PathMakePretty: Failed but modified path\n");
796
797 strcpy(buff, "TEST");
798 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Short name failed\n");
799 ok (strcmp(buff, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff);
800 }
801
802 START_TEST(path)
803 {
804 hShlwapi = LoadLibraryA("shlwapi.dll");
805 if (!hShlwapi) return;
806
807 test_UrlHash();
808 test_UrlGetPart();
809 test_UrlCanonicalize();
810 test_UrlEscape();
811 test_UrlCombine();
812 test_UrlCreateFromPath();
813 test_UrlIs();
814 test_UrlUnescape();
815
816 test_PathSearchAndQualify();
817 test_PathCreateFromUrl();
818 test_PathIsUrl();
819
820 test_PathMakePretty();
821
822 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
823 * ordinal number in some native versions. Check this to prevent a crash.
824 */
825 pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
826 if (pPathIsValidCharA && pPathIsValidCharA != (void*)GetProcAddress(hShlwapi, "PathAppendA"))
827 {
828 test_PathIsValidCharA();
829
830 pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
831 if (pPathIsValidCharW) test_PathIsValidCharW();
832 }
833 }