urlmon: Implemented a fragment parser.
[wine] / dlls / urlmon / tests / uri.c
1 /*
2  * UrlMon IUri tests
3  *
4  * Copyright 2010 Thomas Mullaly
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /*
22  * IUri testing framework goals:
23  *  - Test invalid args
24  *      - invalid flags
25  *      - invalid args (IUri, uri string)
26  *  - Test parsing for components when no canonicalization occurs
27  *  - Test parsing for components when canonicalization occurs.
28  *  - More tests...
29  */
30
31 #include <wine/test.h>
32 #include <stdarg.h>
33 #include <stddef.h>
34
35 #define COBJMACROS
36
37 #include "windef.h"
38 #include "winbase.h"
39 #include "urlmon.h"
40 #include "shlwapi.h"
41
42 #define URI_STR_PROPERTY_COUNT Uri_PROPERTY_STRING_LAST+1
43 #define URI_DWORD_PROPERTY_COUNT (Uri_PROPERTY_DWORD_LAST - Uri_PROPERTY_DWORD_START)+1
44
45 static HRESULT (WINAPI *pCreateUri)(LPCWSTR, DWORD, DWORD_PTR, IUri**);
46
47 static const WCHAR http_urlW[] = { 'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q',
48         '.','o','r','g','/',0};
49
50 typedef struct _uri_create_flag_test {
51     DWORD   flags;
52     HRESULT expected;
53 } uri_create_flag_test;
54
55 static const uri_create_flag_test invalid_flag_tests[] = {
56     /* Set of invalid flag combinations to test for. */
57     {Uri_CREATE_DECODE_EXTRA_INFO | Uri_CREATE_NO_DECODE_EXTRA_INFO, E_INVALIDARG},
58     {Uri_CREATE_CANONICALIZE | Uri_CREATE_NO_CANONICALIZE, E_INVALIDARG},
59     {Uri_CREATE_CRACK_UNKNOWN_SCHEMES | Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES, E_INVALIDARG},
60     {Uri_CREATE_PRE_PROCESS_HTML_URI | Uri_CREATE_NO_PRE_PROCESS_HTML_URI, E_INVALIDARG},
61     {Uri_CREATE_IE_SETTINGS | Uri_CREATE_NO_IE_SETTINGS, E_INVALIDARG}
62 };
63
64 typedef struct _uri_str_property {
65     const char* value;
66     HRESULT     expected;
67     BOOL        todo;
68     const char* broken_value;
69 } uri_str_property;
70
71 typedef struct _uri_dword_property {
72     DWORD   value;
73     HRESULT expected;
74     BOOL    todo;
75 } uri_dword_property;
76
77 typedef struct _uri_properties {
78     const char*         uri;
79     DWORD               create_flags;
80     HRESULT             create_expected;
81     BOOL                create_todo;
82     DWORD               props;
83     BOOL                props_todo;
84
85     uri_str_property    str_props[URI_STR_PROPERTY_COUNT];
86     uri_dword_property  dword_props[URI_DWORD_PROPERTY_COUNT];
87 } uri_properties;
88
89 static const uri_properties uri_tests[] = {
90     {   "http://www.winehq.org/tests/../tests/../..", 0, S_OK, FALSE,
91         /* A flag bitmap containing all the Uri_HAS_* flags that correspond to this uri. */
92         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
93         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|
94         Uri_HAS_PORT|Uri_HAS_SCHEME,
95         TRUE,
96         {
97             {"http://www.winehq.org/",S_OK,TRUE},                       /* ABSOLUTE_URI */
98             {"www.winehq.org",S_OK,FALSE},                              /* AUTHORITY */
99             {"http://www.winehq.org/",S_OK,TRUE},                       /* DISPLAY_URI */
100             {"winehq.org",S_OK,FALSE},                                  /* DOMAIN */
101             {"",S_FALSE,FALSE},                                         /* EXTENSION */
102             {"",S_FALSE,TRUE},                                          /* FRAGMENT */
103             {"www.winehq.org",S_OK,FALSE},                              /* HOST */
104             {"",S_FALSE,FALSE},                                         /* PASSWORD */
105             {"/",S_OK,FALSE},                                           /* PATH */
106             {"/",S_OK,FALSE},                                           /* PATH_AND_QUERY */
107             {"",S_FALSE,FALSE},                                         /* QUERY */
108             {"http://www.winehq.org/tests/../tests/../..",S_OK,FALSE},  /* RAW_URI */
109             {"http",S_OK,FALSE},                                        /* SCHEME_NAME */
110             {"",S_FALSE,FALSE},                                         /* USER_INFO */
111             {"",S_FALSE,FALSE}                                          /* USER_NAME */
112         },
113         {
114             {Uri_HOST_DNS,S_OK,FALSE},                                  /* HOST_TYPE */
115             {80,S_OK,FALSE},                                            /* PORT */
116             {URL_SCHEME_HTTP,S_OK,FALSE},                               /* SCHEME */
117             {URLZONE_INVALID,E_NOTIMPL,FALSE}                           /* ZONE */
118         }
119     },
120     {   "http://winehq.org/tests/.././tests", 0, S_OK, FALSE,
121         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
122         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|
123         Uri_HAS_PORT|Uri_HAS_SCHEME,
124         TRUE,
125         {
126             {"http://winehq.org/tests",S_OK,TRUE},
127             {"winehq.org",S_OK,FALSE},
128             {"http://winehq.org/tests",S_OK,TRUE},
129             {"winehq.org",S_OK,FALSE},
130             {"",S_FALSE,FALSE},
131             {"",S_FALSE,TRUE},
132             {"winehq.org",S_OK,FALSE},
133             {"",S_FALSE,FALSE},
134             {"/tests",S_OK,FALSE},
135             {"/tests",S_OK,FALSE},
136             {"",S_FALSE,FALSE},
137             {"http://winehq.org/tests/.././tests",S_OK,FALSE},
138             {"http",S_OK,FALSE},
139             {"",S_FALSE,FALSE},
140             {"",S_FALSE,FALSE}
141         },
142         {
143             {Uri_HOST_DNS,S_OK,FALSE},
144             {80,S_OK,FALSE},
145             {URL_SCHEME_HTTP,S_OK,FALSE},
146             {URLZONE_INVALID,E_NOTIMPL,FALSE}
147         }
148     },
149     {   "HtTp://www.winehq.org/tests/..?query=x&return=y", 0, S_OK, FALSE,
150         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
151         Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
152         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
153         TRUE,
154         {
155             {"http://www.winehq.org/?query=x&return=y",S_OK,TRUE},
156             {"www.winehq.org",S_OK,FALSE},
157             {"http://www.winehq.org/?query=x&return=y",S_OK,TRUE},
158             {"winehq.org",S_OK,FALSE},
159             {"",S_FALSE,FALSE},
160             {"",S_FALSE,TRUE},
161             {"www.winehq.org",S_OK,FALSE},
162             {"",S_FALSE,FALSE},
163             {"/",S_OK,FALSE},
164             {"/?query=x&return=y",S_OK,FALSE},
165             {"?query=x&return=y",S_OK,FALSE},
166             {"HtTp://www.winehq.org/tests/..?query=x&return=y",S_OK,FALSE},
167             {"http",S_OK,FALSE},
168             {"",S_FALSE,FALSE},
169             {"",S_FALSE,FALSE}
170         },
171         {
172             {Uri_HOST_DNS,S_OK,FALSE},
173             {80,S_OK,FALSE},
174             {URL_SCHEME_HTTP,S_OK,FALSE},
175             {URLZONE_INVALID,E_NOTIMPL,FALSE},
176         }
177     },
178     {   "hTTp://us%45r%3Ainfo@examp%4CE.com:80/path/a/b/./c/../%2E%2E/Forbidden'<|> Characters", 0, S_OK, FALSE,
179         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|Uri_HAS_PATH|
180         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|
181         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
182         TRUE,
183         {
184             {"http://usEr%3Ainfo@example.com/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,TRUE},
185             {"usEr%3Ainfo@example.com",S_OK,FALSE},
186             {"http://example.com/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,TRUE},
187             {"example.com",S_OK,FALSE},
188             {"",S_FALSE,FALSE},
189             {"",S_FALSE,TRUE},
190             {"example.com",S_OK,FALSE},
191             {"",S_FALSE,FALSE},
192             {"/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,FALSE},
193             {"/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,FALSE},
194             {"",S_FALSE,FALSE},
195             {"hTTp://us%45r%3Ainfo@examp%4CE.com:80/path/a/b/./c/../%2E%2E/Forbidden'<|> Characters",S_OK,FALSE},
196             {"http",S_OK,FALSE},
197             {"usEr%3Ainfo",S_OK,FALSE},
198             {"usEr%3Ainfo",S_OK,FALSE}
199         },
200         {
201             {Uri_HOST_DNS,S_OK,FALSE},
202             {80,S_OK,FALSE},
203             {URL_SCHEME_HTTP,S_OK,FALSE},
204             {URLZONE_INVALID,E_NOTIMPL,FALSE},
205         }
206     },
207     {   "ftp://winepass:wine@ftp.winehq.org:9999/dir/foo bar.txt", 0, S_OK, FALSE,
208         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_EXTENSION|
209         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
210         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
211         Uri_HAS_SCHEME,
212         TRUE,
213         {
214             {"ftp://winepass:wine@ftp.winehq.org:9999/dir/foo%20bar.txt",S_OK,TRUE},
215             {"winepass:wine@ftp.winehq.org:9999",S_OK,FALSE},
216             {"ftp://ftp.winehq.org:9999/dir/foo%20bar.txt",S_OK,TRUE},
217             {"winehq.org",S_OK,FALSE},
218             {".txt",S_OK,FALSE},
219             {"",S_FALSE,TRUE},
220             {"ftp.winehq.org",S_OK,FALSE},
221             {"wine",S_OK,FALSE},
222             {"/dir/foo%20bar.txt",S_OK,FALSE},
223             {"/dir/foo%20bar.txt",S_OK,FALSE},
224             {"",S_FALSE,FALSE},
225             {"ftp://winepass:wine@ftp.winehq.org:9999/dir/foo bar.txt",S_OK,FALSE},
226             {"ftp",S_OK,FALSE},
227             {"winepass:wine",S_OK,FALSE},
228             {"winepass",S_OK,FALSE}
229         },
230         {
231             {Uri_HOST_DNS,S_OK,FALSE},
232             {9999,S_OK,FALSE},
233             {URL_SCHEME_FTP,S_OK,FALSE},
234             {URLZONE_INVALID,E_NOTIMPL,FALSE}
235         }
236     },
237     {   "file://c:\\tests\\../tests/foo%20bar.mp3", 0, S_OK, FALSE,
238         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
239         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
240         TRUE,
241         {
242             {"file:///c:/tests/foo%2520bar.mp3",S_OK,TRUE},
243             {"",S_FALSE,FALSE},
244             {"file:///c:/tests/foo%2520bar.mp3",S_OK,TRUE},
245             {"",S_FALSE,FALSE},
246             {".mp3",S_OK,FALSE},
247             {"",S_FALSE,TRUE},
248             {"",S_FALSE,FALSE},
249             {"",S_FALSE,FALSE},
250             {"/c:/tests/foo%2520bar.mp3",S_OK,FALSE},
251             {"/c:/tests/foo%2520bar.mp3",S_OK,FALSE},
252             {"",S_FALSE,FALSE},
253             {"file://c:\\tests\\../tests/foo%20bar.mp3",S_OK,FALSE},
254             {"file",S_OK,FALSE},
255             {"",S_FALSE,FALSE},
256             {"",S_FALSE,FALSE}
257         },
258         {
259             {Uri_HOST_UNKNOWN,S_OK,FALSE},
260             {0,S_FALSE,FALSE},
261             {URL_SCHEME_FILE,S_OK,FALSE},
262             {URLZONE_INVALID,E_NOTIMPL,FALSE}
263         }
264     },
265     {   "FILE://localhost/test dir\\../tests/test%20file.README.txt", 0, S_OK, FALSE,
266         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
267         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
268         TRUE,
269         {
270             {"file:///tests/test%20file.README.txt",S_OK,TRUE},
271             {"",S_FALSE,FALSE},
272             {"file:///tests/test%20file.README.txt",S_OK,TRUE},
273             {"",S_FALSE,FALSE},
274             {".txt",S_OK,FALSE},
275             {"",S_FALSE,TRUE},
276             {"",S_FALSE,FALSE},
277             {"",S_FALSE,FALSE},
278             {"/tests/test%20file.README.txt",S_OK,FALSE},
279             {"/tests/test%20file.README.txt",S_OK,FALSE},
280             {"",S_FALSE,FALSE},
281             {"FILE://localhost/test dir\\../tests/test%20file.README.txt",S_OK,FALSE},
282             {"file",S_OK,FALSE},
283             {"",S_FALSE,FALSE},
284             {"",S_FALSE,FALSE}
285         },
286         {
287             {Uri_HOST_UNKNOWN,S_OK,FALSE},
288             {0,S_FALSE,FALSE},
289             {URL_SCHEME_FILE,S_OK,FALSE},
290             {URLZONE_INVALID,E_NOTIMPL,FALSE}
291         }
292     },
293     {   "urn:nothing:should:happen here", 0, S_OK, FALSE,
294         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|
295         Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
296         TRUE,
297         {
298             {"urn:nothing:should:happen here",S_OK,TRUE},
299             {"",S_FALSE,FALSE},
300             {"urn:nothing:should:happen here",S_OK,TRUE},
301             {"",S_FALSE,FALSE},
302             {"",S_FALSE,FALSE},
303             {"",S_FALSE,TRUE},
304             {"",S_FALSE,FALSE},
305             {"",S_FALSE,FALSE},
306             {"nothing:should:happen here",S_OK,FALSE},
307             {"nothing:should:happen here",S_OK,FALSE},
308             {"",S_FALSE,FALSE},
309             {"urn:nothing:should:happen here",S_OK,FALSE},
310             {"urn",S_OK,FALSE},
311             {"",S_FALSE,FALSE},
312             {"",S_FALSE,FALSE}
313         },
314         {
315             {Uri_HOST_UNKNOWN,S_OK,FALSE},
316             {0,S_FALSE,FALSE},
317             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
318             {URLZONE_INVALID,E_NOTIMPL,FALSE}
319         }
320     },
321     {   "http://127.0.0.1/tests/../test dir/./test.txt", 0, S_OK, FALSE,
322         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|
323         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
324         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
325         TRUE,
326         {
327             {"http://127.0.0.1/test%20dir/test.txt",S_OK,TRUE},
328             {"127.0.0.1",S_OK,FALSE},
329             {"http://127.0.0.1/test%20dir/test.txt",S_OK,TRUE},
330             {"",S_FALSE,FALSE},
331             {".txt",S_OK,FALSE},
332             {"",S_FALSE,TRUE},
333             {"127.0.0.1",S_OK,FALSE},
334             {"",S_FALSE,FALSE},
335             {"/test%20dir/test.txt",S_OK,FALSE},
336             {"/test%20dir/test.txt",S_OK,FALSE},
337             {"",S_FALSE,FALSE},
338             {"http://127.0.0.1/tests/../test dir/./test.txt",S_OK,FALSE},
339             {"http",S_OK,FALSE},
340             {"",S_FALSE,FALSE},
341             {"",S_FALSE,FALSE}
342         },
343         {
344             {Uri_HOST_IPV4,S_OK,FALSE},
345             {80,S_OK,FALSE},
346             {URL_SCHEME_HTTP,S_OK,FALSE},
347             {URLZONE_INVALID,E_NOTIMPL,FALSE}
348         }
349     },
350     {   "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]", 0, S_OK, FALSE,
351         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
352         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
353         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
354         TRUE,
355         {
356             {"http://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]/",S_OK,TRUE},
357             {"[fedc:ba98:7654:3210:fedc:ba98:7654:3210]",S_OK,FALSE},
358             {"http://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]/",S_OK,TRUE},
359             {"",S_FALSE,FALSE},
360             {"",S_FALSE,FALSE},
361             {"",S_FALSE,TRUE},
362             {"fedc:ba98:7654:3210:fedc:ba98:7654:3210",S_OK,FALSE},
363             {"",S_FALSE,FALSE},
364             {"/",S_OK,FALSE},
365             {"/",S_OK,FALSE},
366             {"",S_FALSE,FALSE},
367             {"http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]",S_OK,FALSE},
368             {"http",S_OK,FALSE},
369             {"",S_FALSE,FALSE},
370             {"",S_FALSE,FALSE}
371         },
372         {
373             {Uri_HOST_IPV6,S_OK,FALSE},
374             {80,S_OK,FALSE},
375             {URL_SCHEME_HTTP,S_OK,FALSE},
376             {URLZONE_INVALID,E_NOTIMPL,FALSE}
377         }
378     },
379     {   "ftp://[::13.1.68.3]", 0, S_OK, FALSE,
380         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
381         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
382         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
383         TRUE,
384         {
385             {"ftp://[::13.1.68.3]/",S_OK,TRUE},
386             {"[::13.1.68.3]",S_OK,FALSE},
387             {"ftp://[::13.1.68.3]/",S_OK,TRUE},
388             {"",S_FALSE,FALSE},
389             {"",S_FALSE,FALSE},
390             {"",S_FALSE,TRUE},
391             {"::13.1.68.3",S_OK,FALSE},
392             {"",S_FALSE,FALSE},
393             {"/",S_OK,FALSE},
394             {"/",S_OK,FALSE},
395             {"",S_FALSE,FALSE},
396             {"ftp://[::13.1.68.3]",S_OK,FALSE},
397             {"ftp",S_OK,FALSE},
398             {"",S_FALSE,FALSE},
399             {"",S_FALSE,FALSE}
400         },
401         {
402             {Uri_HOST_IPV6,S_OK,FALSE},
403             {21,S_OK,FALSE},
404             {URL_SCHEME_FTP,S_OK,FALSE},
405             {URLZONE_INVALID,E_NOTIMPL,FALSE}
406         }
407     },
408     {   "http://[FEDC:BA98:0:0:0:0:0:3210]", 0, S_OK, FALSE,
409         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
410         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
411         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
412         TRUE,
413         {
414             {"http://[fedc:ba98::3210]/",S_OK,TRUE},
415             {"[fedc:ba98::3210]",S_OK,FALSE},
416             {"http://[fedc:ba98::3210]/",S_OK,TRUE},
417             {"",S_FALSE,FALSE},
418             {"",S_FALSE,FALSE},
419             {"",S_FALSE,TRUE},
420             {"fedc:ba98::3210",S_OK,FALSE},
421             {"",S_FALSE,FALSE},
422             {"/",S_OK,FALSE},
423             {"/",S_OK,FALSE},
424             {"",S_FALSE,FALSE},
425             {"http://[FEDC:BA98:0:0:0:0:0:3210]",S_OK,FALSE},
426             {"http",S_OK,FALSE},
427             {"",S_FALSE,FALSE},
428             {"",S_FALSE,FALSE},
429         },
430         {
431             {Uri_HOST_IPV6,S_OK,FALSE},
432             {80,S_OK,FALSE},
433             {URL_SCHEME_HTTP,S_OK,FALSE},
434             {URLZONE_INVALID,E_NOTIMPL,FALSE}
435         }
436     },
437     {   "1234://www.winehq.org", 0, S_OK, FALSE,
438         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
439         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
440         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
441         TRUE,
442         {
443             {"1234://www.winehq.org/",S_OK,TRUE},
444             {"www.winehq.org",S_OK,FALSE},
445             {"1234://www.winehq.org/",S_OK,TRUE},
446             {"winehq.org",S_OK,FALSE},
447             {"",S_FALSE,FALSE},
448             {"",S_FALSE,TRUE},
449             {"www.winehq.org",S_OK,FALSE},
450             {"",S_FALSE,FALSE},
451             {"/",S_OK,FALSE},
452             {"/",S_OK,FALSE},
453             {"",S_FALSE,FALSE},
454             {"1234://www.winehq.org",S_OK,FALSE},
455             {"1234",S_OK,FALSE},
456             {"",S_FALSE,FALSE},
457             {"",S_FALSE,FALSE}
458         },
459         {
460             {Uri_HOST_DNS,S_OK,FALSE},
461             {0,S_FALSE,FALSE},
462             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
463             {URLZONE_INVALID,E_NOTIMPL,FALSE}
464         }
465     },
466     /* Test's to make sure the parser/canonicalizer handles implicit file schemes correctly. */
467     {   "C:/test/test.mp3", Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, S_OK, FALSE,
468         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
469         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
470         TRUE,
471         {
472             {"file:///C:/test/test.mp3",S_OK,TRUE},
473             {"",S_FALSE,FALSE},
474             {"file:///C:/test/test.mp3",S_OK,TRUE},
475             {"",S_FALSE,FALSE},
476             {".mp3",S_OK,FALSE},
477             {"",S_FALSE,TRUE},
478             {"",S_FALSE,FALSE},
479             {"",S_FALSE,FALSE},
480             {"/C:/test/test.mp3",S_OK,FALSE},
481             {"/C:/test/test.mp3",S_OK,FALSE},
482             {"",S_FALSE,FALSE},
483             {"C:/test/test.mp3",S_OK,FALSE},
484             {"file",S_OK,FALSE},
485             {"",S_FALSE,FALSE},
486             {"",S_FALSE,FALSE}
487         },
488         {
489             {Uri_HOST_UNKNOWN,S_OK,FALSE},
490             {0,S_FALSE,FALSE},
491             {URL_SCHEME_FILE,S_OK,FALSE},
492             {URLZONE_INVALID,E_NOTIMPL,FALSE}
493         }
494     },
495     /* Test's to make sure the parser/canonicalizer handles implicit file schemes correctly. */
496     {   "\\\\Server/test.mp3", Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, S_OK, FALSE,
497         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|
498         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_HOST|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
499         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
500         TRUE,
501         {
502             {"file://server/test.mp3",S_OK,TRUE},
503             {"server",S_OK,FALSE},
504             {"file://server/test.mp3",S_OK,TRUE},
505             {"",S_FALSE,FALSE},
506             {".mp3",S_OK,FALSE},
507             {"",S_FALSE,TRUE},
508             {"server",S_OK,FALSE},
509             {"",S_FALSE,FALSE},
510             {"/test.mp3",S_OK,FALSE},
511             {"/test.mp3",S_OK,FALSE},
512             {"",S_FALSE,FALSE},
513             {"\\\\Server/test.mp3",S_OK,FALSE},
514             {"file",S_OK,FALSE},
515             {"",S_FALSE,FALSE},
516             {"",S_FALSE,FALSE}
517         },
518         {
519             {Uri_HOST_DNS,S_OK,FALSE},
520             {0,S_FALSE,FALSE},
521             {URL_SCHEME_FILE,S_OK,FALSE},
522             {URLZONE_INVALID,E_NOTIMPL,FALSE}
523         }
524     },
525     {   "www.winehq.org/test", Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME, S_OK, FALSE,
526         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
527         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|
528         Uri_HAS_SCHEME,
529         TRUE,
530         {
531             {"*:www.winehq.org/test",S_OK,TRUE},
532             {"www.winehq.org",S_OK,FALSE},
533             {"*:www.winehq.org/test",S_OK,TRUE},
534             {"winehq.org",S_OK,FALSE},
535             {"",S_FALSE,FALSE},
536             {"",S_FALSE,TRUE},
537             {"www.winehq.org",S_OK,FALSE},
538             {"",S_FALSE,FALSE},
539             {"/test",S_OK,FALSE},
540             {"/test",S_OK,FALSE},
541             {"",S_FALSE,FALSE},
542             {"www.winehq.org/test",S_OK,FALSE},
543             {"*",S_OK,FALSE},
544             {"",S_FALSE,FALSE},
545             {"",S_FALSE,FALSE}
546         },
547         {
548             {Uri_HOST_DNS,S_OK,FALSE},
549             {0,S_FALSE,FALSE},
550             {URL_SCHEME_WILDCARD,S_OK,FALSE},
551             {URLZONE_INVALID,E_NOTIMPL,FALSE}
552         }
553     },
554     /* Valid since the '*' is the only character in the scheme name. */
555     {   "*:www.winehq.org/test", 0, S_OK, FALSE,
556         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
557         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|
558         Uri_HAS_SCHEME,
559         TRUE,
560         {
561             {"*:www.winehq.org/test",S_OK,TRUE},
562             {"www.winehq.org",S_OK,FALSE},
563             {"*:www.winehq.org/test",S_OK,TRUE},
564             {"winehq.org",S_OK,FALSE},
565             {"",S_FALSE,FALSE},
566             {"",S_FALSE,TRUE},
567             {"www.winehq.org",S_OK,FALSE},
568             {"",S_FALSE,FALSE},
569             {"/test",S_OK,FALSE},
570             {"/test",S_OK,FALSE},
571             {"",S_FALSE,FALSE},
572             {"*:www.winehq.org/test",S_OK,FALSE},
573             {"*",S_OK,FALSE},
574             {"",S_FALSE,FALSE},
575             {"",S_FALSE,FALSE}
576         },
577         {
578             {Uri_HOST_DNS,S_OK,FALSE},
579             {0,S_FALSE,FALSE},
580             {URL_SCHEME_WILDCARD,S_OK,FALSE},
581             {URLZONE_INVALID,E_NOTIMPL,FALSE}
582         }
583     },
584     {   "/../some dir/test.ext", Uri_CREATE_ALLOW_RELATIVE, S_OK, FALSE,
585         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
586         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
587         TRUE,
588         {
589             {"/../some dir/test.ext",S_OK,TRUE},
590             {"",S_FALSE,FALSE},
591             {"/../some dir/test.ext",S_OK,TRUE},
592             {"",S_FALSE,FALSE},
593             {".ext",S_OK,FALSE},
594             {"",S_FALSE,TRUE},
595             {"",S_FALSE,FALSE},
596             {"",S_FALSE,FALSE},
597             {"/../some dir/test.ext",S_OK,FALSE},
598             {"/../some dir/test.ext",S_OK,FALSE},
599             {"",S_FALSE,FALSE},
600             {"/../some dir/test.ext",S_OK,FALSE},
601             {"",S_FALSE,FALSE},
602             {"",S_FALSE,FALSE},
603             {"",S_FALSE,FALSE}
604         },
605         {
606             {Uri_HOST_UNKNOWN,S_OK,FALSE},
607             {0,S_FALSE,FALSE},
608             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
609             {URLZONE_INVALID,E_NOTIMPL,FALSE}
610         }
611     },
612     {   "//implicit/wildcard/uri scheme", Uri_CREATE_ALLOW_RELATIVE|Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME, S_OK, FALSE,
613         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|Uri_HAS_PATH|
614         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
615         TRUE,
616         {
617             {"*://implicit/wildcard/uri%20scheme",S_OK,TRUE},
618             {"",S_OK,FALSE},
619             {"*://implicit/wildcard/uri%20scheme",S_OK,TRUE},
620             {"",S_FALSE,FALSE},
621             {"",S_FALSE,FALSE},
622             {"",S_FALSE,TRUE},
623             {"",S_OK,FALSE},
624             {"",S_FALSE,FALSE},
625             {"//implicit/wildcard/uri%20scheme",S_OK,FALSE},
626             {"//implicit/wildcard/uri%20scheme",S_OK,FALSE},
627             {"",S_FALSE,FALSE},
628             {"//implicit/wildcard/uri scheme",S_OK,FALSE},
629             {"*",S_OK,FALSE},
630             {"",S_FALSE,FALSE},
631             {"",S_FALSE,FALSE},
632         },
633         {
634             {Uri_HOST_UNKNOWN,S_OK,FALSE},
635             {0,S_FALSE,FALSE},
636             {URL_SCHEME_WILDCARD,S_OK,FALSE},
637             {URLZONE_INVALID,E_NOTIMPL,FALSE}
638         }
639     },
640     /* URI is considered opaque since CREATE_NO_CRACK_UNKNOWN_SCHEMES is set and its an unknown scheme. */
641     {   "zip://google.com", Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES, S_OK, FALSE,
642         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
643         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME_NAME|
644         Uri_HAS_SCHEME,
645         TRUE,
646         {
647             {"zip:/.//google.com",S_OK,TRUE},
648             {"",S_FALSE,FALSE},
649             {"zip:/.//google.com",S_OK,TRUE},
650             {"",S_FALSE,FALSE},
651             {".com",S_OK,FALSE},
652             {"",S_FALSE,TRUE},
653             {"",S_FALSE,FALSE},
654             {"",S_FALSE,FALSE},
655             {"/.//google.com",S_OK,FALSE},
656             {"/.//google.com",S_OK,FALSE},
657             {"",S_FALSE,FALSE},
658             {"zip://google.com",S_OK,FALSE},
659             {"zip",S_OK,FALSE},
660             {"",S_FALSE,FALSE},
661             {"",S_FALSE,FALSE}
662         },
663         {
664             {Uri_HOST_UNKNOWN,S_OK,FALSE},
665             {0,S_FALSE,FALSE},
666             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
667             {URLZONE_INVALID,E_NOTIMPL,FALSE}
668         }
669     },
670     /* Windows uses the first occurence of ':' to delimit the userinfo. */
671     {   "ftp://user:pass:word@winehq.org/", 0, S_OK, FALSE,
672         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
673         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
674         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
675         Uri_HAS_SCHEME,
676         TRUE,
677         {
678             {"ftp://user:pass:word@winehq.org/",S_OK,TRUE},
679             {"user:pass:word@winehq.org",S_OK,FALSE},
680             {"ftp://winehq.org/",S_OK,TRUE},
681             {"winehq.org",S_OK,FALSE},
682             {"",S_FALSE,FALSE},
683             {"",S_FALSE,TRUE},
684             {"winehq.org",S_OK,FALSE},
685             {"pass:word",S_OK,FALSE},
686             {"/",S_OK,FALSE},
687             {"/",S_OK,FALSE},
688             {"",S_FALSE,FALSE},
689             {"ftp://user:pass:word@winehq.org/",S_OK,FALSE},
690             {"ftp",S_OK,FALSE},
691             {"user:pass:word",S_OK,FALSE},
692             {"user",S_OK,FALSE}
693         },
694         {
695             {Uri_HOST_DNS,S_OK,FALSE},
696             {21,S_OK,FALSE},
697             {URL_SCHEME_FTP,S_OK,FALSE},
698             {URLZONE_INVALID,E_NOTIMPL,FALSE}
699         }
700     },
701     /* Make sure % encoded unreserved characters are decoded. */
702     {   "ftp://w%49%4Ee:PA%53%53@ftp.google.com/", 0, S_OK, FALSE,
703         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
704         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
705         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
706         Uri_HAS_SCHEME,
707         TRUE,
708         {
709             {"ftp://wINe:PASS@ftp.google.com/",S_OK,TRUE},
710             {"wINe:PASS@ftp.google.com",S_OK,FALSE},
711             {"ftp://ftp.google.com/",S_OK,TRUE},
712             {"google.com",S_OK,FALSE},
713             {"",S_FALSE,FALSE},
714             {"",S_FALSE,TRUE},
715             {"ftp.google.com",S_OK,FALSE},
716             {"PASS",S_OK,FALSE},
717             {"/",S_OK,FALSE},
718             {"/",S_OK,FALSE},
719             {"",S_FALSE,FALSE},
720             {"ftp://w%49%4Ee:PA%53%53@ftp.google.com/",S_OK,FALSE},
721             {"ftp",S_OK,FALSE},
722             {"wINe:PASS",S_OK,FALSE},
723             {"wINe",S_OK,FALSE}
724         },
725         {
726             {Uri_HOST_DNS,S_OK,FALSE},
727             {21,S_OK,FALSE},
728             {URL_SCHEME_FTP,S_OK,FALSE},
729             {URLZONE_INVALID,E_NOTIMPL,FALSE}
730         }
731     },
732     /* Make sure % encoded characters which are NOT unreserved are NOT decoded. */
733     {   "ftp://w%5D%5Be:PA%7B%7D@ftp.google.com/", 0, S_OK, FALSE,
734         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
735         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
736         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
737         Uri_HAS_SCHEME,
738         TRUE,
739         {
740             {"ftp://w%5D%5Be:PA%7B%7D@ftp.google.com/",S_OK,TRUE},
741             {"w%5D%5Be:PA%7B%7D@ftp.google.com",S_OK,FALSE},
742             {"ftp://ftp.google.com/",S_OK,TRUE},
743             {"google.com",S_OK,FALSE},
744             {"",S_FALSE,FALSE},
745             {"",S_FALSE,TRUE},
746             {"ftp.google.com",S_OK,FALSE},
747             {"PA%7B%7D",S_OK,FALSE},
748             {"/",S_OK,FALSE},
749             {"/",S_OK,FALSE},
750             {"",S_FALSE,FALSE},
751             {"ftp://w%5D%5Be:PA%7B%7D@ftp.google.com/",S_OK,FALSE},
752             {"ftp",S_OK,FALSE},
753             {"w%5D%5Be:PA%7B%7D",S_OK,FALSE},
754             {"w%5D%5Be",S_OK,FALSE}
755         },
756         {
757             {Uri_HOST_DNS,S_OK,FALSE},
758             {21,S_OK,FALSE},
759             {URL_SCHEME_FTP,S_OK,FALSE},
760             {URLZONE_INVALID,E_NOTIMPL,FALSE}
761         }
762     },
763     /* You're allowed to have an empty password portion in the userinfo section. */
764     {   "ftp://empty:@ftp.google.com/", 0, S_OK, FALSE,
765         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
766         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
767         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
768         Uri_HAS_SCHEME,
769         TRUE,
770         {
771             {"ftp://empty:@ftp.google.com/",S_OK,TRUE},
772             {"empty:@ftp.google.com",S_OK,FALSE},
773             {"ftp://ftp.google.com/",S_OK,TRUE},
774             {"google.com",S_OK,FALSE},
775             {"",S_FALSE,FALSE},
776             {"",S_FALSE,TRUE},
777             {"ftp.google.com",S_OK,FALSE},
778             {"",S_OK,FALSE},
779             {"/",S_OK,FALSE},
780             {"/",S_OK,FALSE},
781             {"",S_FALSE,FALSE},
782             {"ftp://empty:@ftp.google.com/",S_OK,FALSE},
783             {"ftp",S_OK,FALSE},
784             {"empty:",S_OK,FALSE},
785             {"empty",S_OK,FALSE}
786         },
787         {
788             {Uri_HOST_DNS,S_OK,FALSE},
789             {21,S_OK,FALSE},
790             {URL_SCHEME_FTP,S_OK,FALSE},
791             {URLZONE_INVALID,E_NOTIMPL,FALSE}
792         }
793     },
794     /* Make sure forbidden characters in "userinfo" get encoded. */
795     {   "ftp://\" \"weird@ftp.google.com/", 0, S_OK, FALSE,
796         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
797         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
798         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
799         Uri_HAS_SCHEME,
800         TRUE,
801         {
802             {"ftp://%22%20%22weird@ftp.google.com/",S_OK,TRUE},
803             {"%22%20%22weird@ftp.google.com",S_OK,FALSE},
804             {"ftp://ftp.google.com/",S_OK,TRUE},
805             {"google.com",S_OK,FALSE},
806             {"",S_FALSE,FALSE},
807             {"",S_FALSE,TRUE},
808             {"ftp.google.com",S_OK,FALSE},
809             {"",S_FALSE,FALSE},
810             {"/",S_OK,FALSE},
811             {"/",S_OK,FALSE},
812             {"",S_FALSE,FALSE},
813             {"ftp://\" \"weird@ftp.google.com/",S_OK,FALSE},
814             {"ftp",S_OK,FALSE},
815             {"%22%20%22weird",S_OK,FALSE},
816             {"%22%20%22weird",S_OK,FALSE}
817         },
818         {
819             {Uri_HOST_DNS,S_OK,FALSE},
820             {21,S_OK,FALSE},
821             {URL_SCHEME_FTP,S_OK,FALSE},
822             {URLZONE_INVALID,E_NOTIMPL,FALSE}
823         }
824     },
825     /* Make sure the forbidden characters don't get percent encoded. */
826     {   "ftp://\" \"weird@ftp.google.com/", Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS, S_OK, FALSE,
827         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
828         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
829         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
830         Uri_HAS_SCHEME,
831         TRUE,
832         {
833             {"ftp://\" \"weird@ftp.google.com/",S_OK,TRUE},
834             {"\" \"weird@ftp.google.com",S_OK,FALSE},
835             {"ftp://ftp.google.com/",S_OK,TRUE},
836             {"google.com",S_OK,FALSE},
837             {"",S_FALSE,FALSE},
838             {"",S_FALSE,TRUE},
839             {"ftp.google.com",S_OK,FALSE},
840             {"",S_FALSE,FALSE},
841             {"/",S_OK,FALSE},
842             {"/",S_OK,FALSE},
843             {"",S_FALSE,FALSE},
844             {"ftp://\" \"weird@ftp.google.com/",S_OK,FALSE},
845             {"ftp",S_OK,FALSE},
846             {"\" \"weird",S_OK,FALSE},
847             {"\" \"weird",S_OK,FALSE}
848         },
849         {
850             {Uri_HOST_DNS,S_OK,FALSE},
851             {21,S_OK,FALSE},
852             {URL_SCHEME_FTP,S_OK,FALSE},
853             {URLZONE_INVALID,E_NOTIMPL,FALSE}
854         }
855     },
856     /* Allowed to have invalid % encoded because its an unknown scheme type. */
857     {   "zip://%xy:word@winehq.org/", 0, S_OK, FALSE,
858         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
859         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
860         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
861         TRUE,
862         {
863             {"zip://%xy:word@winehq.org/",S_OK,TRUE},
864             {"%xy:word@winehq.org",S_OK,FALSE},
865             {"zip://%xy:word@winehq.org/",S_OK,TRUE},
866             {"winehq.org",S_OK,FALSE},
867             {"",S_FALSE,FALSE},
868             {"",S_FALSE,TRUE},
869             {"winehq.org",S_OK,FALSE},
870             {"word",S_OK,FALSE},
871             {"/",S_OK,FALSE},
872             {"/",S_OK,FALSE},
873             {"",S_FALSE,FALSE},
874             {"zip://%xy:word@winehq.org/",S_OK,FALSE},
875             {"zip",S_OK,FALSE},
876             {"%xy:word",S_OK,FALSE},
877             {"%xy",S_OK,FALSE}
878         },
879         {
880             {Uri_HOST_DNS,S_OK,FALSE},
881             {0,S_FALSE,FALSE},
882             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
883             {URLZONE_INVALID,E_NOTIMPL,FALSE}
884         }
885     },
886     /* Unreserved, percent encoded characters aren't decoded in the userinfo becuase the scheme
887      * isn't known.
888      */
889     {   "zip://%2E:%52%53ord@winehq.org/", 0, S_OK, FALSE,
890         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
891         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
892         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
893         TRUE,
894         {
895             {"zip://%2E:%52%53ord@winehq.org/",S_OK,TRUE},
896             {"%2E:%52%53ord@winehq.org",S_OK,FALSE},
897             {"zip://%2E:%52%53ord@winehq.org/",S_OK,TRUE},
898             {"winehq.org",S_OK,FALSE},
899             {"",S_FALSE,FALSE},
900             {"",S_FALSE,TRUE},
901             {"winehq.org",S_OK,FALSE},
902             {"%52%53ord",S_OK,FALSE},
903             {"/",S_OK,FALSE},
904             {"/",S_OK,FALSE},
905             {"",S_FALSE,FALSE},
906             {"zip://%2E:%52%53ord@winehq.org/",S_OK,FALSE},
907             {"zip",S_OK,FALSE},
908             {"%2E:%52%53ord",S_OK,FALSE},
909             {"%2E",S_OK,FALSE}
910         },
911         {
912             {Uri_HOST_DNS,S_OK,FALSE},
913             {0,S_FALSE,FALSE},
914             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
915             {URLZONE_INVALID,E_NOTIMPL,FALSE}
916         }
917     },
918     {   "ftp://[](),'test':word@winehq.org/", 0, S_OK, FALSE,
919         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
920         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
921         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
922         Uri_HAS_SCHEME,
923         TRUE,
924         {
925             {"ftp://[](),'test':word@winehq.org/",S_OK,TRUE},
926             {"[](),'test':word@winehq.org",S_OK,FALSE},
927             {"ftp://winehq.org/",S_OK,TRUE},
928             {"winehq.org",S_OK,FALSE},
929             {"",S_FALSE,FALSE},
930             {"",S_FALSE,TRUE},
931             {"winehq.org",S_OK,FALSE},
932             {"word",S_OK,FALSE},
933             {"/",S_OK,FALSE},
934             {"/",S_OK,FALSE},
935             {"",S_FALSE,FALSE},
936             {"ftp://[](),'test':word@winehq.org/",S_OK,FALSE},
937             {"ftp",S_OK,FALSE},
938             {"[](),'test':word",S_OK,FALSE},
939             {"[](),'test'",S_OK,FALSE}
940         },
941         {
942             {Uri_HOST_DNS,S_OK,FALSE},
943             {21,S_OK,FALSE},
944             {URL_SCHEME_FTP,S_OK,FALSE},
945             {URLZONE_INVALID,E_NOTIMPL,FALSE}
946         }
947     },
948     {   "ftp://test?:word@winehq.org/", 0, S_OK, FALSE,
949         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
950         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
951         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
952         TRUE,
953         {
954             {"ftp://test/?:word@winehq.org/",S_OK,TRUE},
955             {"test",S_OK,FALSE},
956             {"ftp://test/?:word@winehq.org/",S_OK,TRUE},
957             {"",S_FALSE,FALSE},
958             {"",S_FALSE,FALSE},
959             {"",S_FALSE,TRUE},
960             {"test",S_OK,FALSE},
961             {"",S_FALSE,FALSE},
962             {"/",S_OK,FALSE},
963             {"/?:word@winehq.org/",S_OK,FALSE},
964             {"?:word@winehq.org/",S_OK,FALSE},
965             {"ftp://test?:word@winehq.org/",S_OK,FALSE},
966             {"ftp",S_OK,FALSE},
967             {"",S_FALSE,FALSE},
968             {"",S_FALSE,FALSE}
969         },
970         {
971             {Uri_HOST_DNS,S_OK,FALSE},
972             {21,S_OK,FALSE},
973             {URL_SCHEME_FTP,S_OK,FALSE},
974             {URLZONE_INVALID,E_NOTIMPL,FALSE}
975         }
976     },
977     {   "ftp://test#:word@winehq.org/", 0, S_OK, FALSE,
978         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_FRAGMENT|Uri_HAS_HOST|
979         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
980         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
981         TRUE,
982         {
983             {"ftp://test/#:word@winehq.org/",S_OK,TRUE},
984             {"test",S_OK,FALSE},
985             {"ftp://test/#:word@winehq.org/",S_OK,TRUE},
986             {"",S_FALSE,FALSE},
987             {"",S_FALSE,FALSE},
988             {"#:word@winehq.org/",S_OK,TRUE},
989             {"test",S_OK,FALSE},
990             {"",S_FALSE,FALSE},
991             {"/",S_OK,FALSE},
992             {"/",S_OK,FALSE},
993             {"",S_FALSE,FALSE},
994             {"ftp://test#:word@winehq.org/",S_OK,FALSE},
995             {"ftp",S_OK,FALSE},
996             {"",S_FALSE,FALSE},
997             {"",S_FALSE,FALSE}
998         },
999         {
1000             {Uri_HOST_DNS,S_OK,FALSE},
1001             {21,S_OK,FALSE},
1002             {URL_SCHEME_FTP,S_OK,FALSE},
1003             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1004         }
1005     },
1006     /* Allowed to have a backslash in the userinfo since it's an unknown scheme. */
1007     {   "zip://test\\:word@winehq.org/", 0, S_OK, FALSE,
1008         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
1009         Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1010         Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1011         TRUE,
1012         {
1013             {"zip://test\\:word@winehq.org/",S_OK,TRUE},
1014             {"test\\:word@winehq.org",S_OK,FALSE},
1015             {"zip://test\\:word@winehq.org/",S_OK,TRUE},
1016             {"winehq.org",S_OK,FALSE},
1017             {"",S_FALSE,FALSE},
1018             {"",S_FALSE,TRUE},
1019             {"winehq.org",S_OK,FALSE},
1020             {"word",S_OK,FALSE},
1021             {"/",S_OK,FALSE},
1022             {"/",S_OK,FALSE},
1023             {"",S_FALSE,FALSE},
1024             {"zip://test\\:word@winehq.org/",S_OK,FALSE},
1025             {"zip",S_OK,FALSE},
1026             {"test\\:word",S_OK,FALSE},
1027             {"test\\",S_OK,FALSE}
1028         },
1029         {
1030             {Uri_HOST_DNS,S_OK,FALSE},
1031             {0,S_FALSE,FALSE},
1032             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1033             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1034         }
1035     },
1036     /* It normalizes IPv4 addresses correctly. */
1037     {   "http://127.000.000.100/", 0, S_OK, FALSE,
1038         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1039         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1040         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1041         TRUE,
1042         {
1043             {"http://127.0.0.100/",S_OK,TRUE},
1044             {"127.0.0.100",S_OK,FALSE},
1045             {"http://127.0.0.100/",S_OK,TRUE},
1046             {"",S_FALSE,FALSE},
1047             {"",S_FALSE,FALSE},
1048             {"",S_FALSE,TRUE},
1049             {"127.0.0.100",S_OK,FALSE},
1050             {"",S_FALSE,FALSE},
1051             {"/",S_OK,FALSE},
1052             {"/",S_OK,FALSE},
1053             {"",S_FALSE,FALSE},
1054             {"http://127.000.000.100/",S_OK,FALSE},
1055             {"http",S_OK,FALSE},
1056             {"",S_FALSE,FALSE},
1057             {"",S_FALSE,FALSE}
1058         },
1059         {
1060             {Uri_HOST_IPV4,S_OK,FALSE},
1061             {80,S_OK,FALSE},
1062             {URL_SCHEME_HTTP,S_OK,FALSE},
1063             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1064         }
1065     },
1066     /* Make sure it normalizes partial IPv4 addresses correctly. */
1067     {   "http://127.0/", 0, S_OK, FALSE,
1068         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1069         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1070         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1071         TRUE,
1072         {
1073             {"http://127.0.0.0/",S_OK,TRUE},
1074             {"127.0.0.0",S_OK,FALSE},
1075             {"http://127.0.0.0/",S_OK,TRUE},
1076             {"",S_FALSE,FALSE},
1077             {"",S_FALSE,FALSE},
1078             {"",S_FALSE,TRUE},
1079             {"127.0.0.0",S_OK,FALSE},
1080             {"",S_FALSE,FALSE},
1081             {"/",S_OK,FALSE},
1082             {"/",S_OK,FALSE},
1083             {"",S_FALSE,FALSE},
1084             {"http://127.0/",S_OK,FALSE},
1085             {"http",S_OK,FALSE},
1086             {"",S_FALSE,FALSE},
1087             {"",S_FALSE,FALSE}
1088         },
1089         {
1090             {Uri_HOST_IPV4,S_OK,FALSE},
1091             {80,S_OK,FALSE},
1092             {URL_SCHEME_HTTP,S_OK,FALSE},
1093             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1094         }
1095     },
1096     /* Make sure it converts implicit IPv4's correctly. */
1097     {   "http://123456/", 0, S_OK, FALSE,
1098         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1099         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1100         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1101         TRUE,
1102         {
1103             {"http://0.1.226.64/",S_OK,TRUE},
1104             {"0.1.226.64",S_OK,FALSE},
1105             {"http://0.1.226.64/",S_OK,TRUE},
1106             {"",S_FALSE,FALSE},
1107             {"",S_FALSE,FALSE},
1108             {"",S_FALSE,TRUE},
1109             {"0.1.226.64",S_OK,FALSE},
1110             {"",S_FALSE,FALSE},
1111             {"/",S_OK,FALSE},
1112             {"/",S_OK,FALSE},
1113             {"",S_FALSE,FALSE},
1114             {"http://123456/",S_OK,FALSE},
1115             {"http",S_OK,FALSE},
1116             {"",S_FALSE,FALSE},
1117             {"",S_FALSE,FALSE}
1118         },
1119         {
1120             {Uri_HOST_IPV4,S_OK,FALSE},
1121             {80,S_OK,FALSE},
1122             {URL_SCHEME_HTTP,S_OK,FALSE},
1123             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1124         }
1125     },
1126     /* UINT_MAX */
1127     {   "http://4294967295/", 0, S_OK, FALSE,
1128         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1129         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1130         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1131         TRUE,
1132         {
1133             {"http://255.255.255.255/",S_OK,TRUE},
1134             {"255.255.255.255",S_OK,FALSE},
1135             {"http://255.255.255.255/",S_OK,TRUE},
1136             {"",S_FALSE,FALSE},
1137             {"",S_FALSE,FALSE},
1138             {"",S_FALSE,TRUE},
1139             {"255.255.255.255",S_OK,FALSE},
1140             {"",S_FALSE,FALSE},
1141             {"/",S_OK,FALSE},
1142             {"/",S_OK,FALSE},
1143             {"",S_FALSE,FALSE},
1144             {"http://4294967295/",S_OK,FALSE},
1145             {"http",S_OK,FALSE},
1146             {"",S_FALSE,FALSE},
1147             {"",S_FALSE,FALSE}
1148         },
1149         {
1150             {Uri_HOST_IPV4,S_OK,FALSE},
1151             {80,S_OK,FALSE},
1152             {URL_SCHEME_HTTP,S_OK,FALSE},
1153             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1154         }
1155     },
1156     /* UINT_MAX+1 */
1157     {   "http://4294967296/", 0, S_OK, FALSE,
1158         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1159         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1160         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1161         TRUE,
1162         {
1163             {"http://4294967296/",S_OK,TRUE},
1164             {"4294967296",S_OK,FALSE},
1165             {"http://4294967296/",S_OK,TRUE},
1166             {"",S_FALSE,FALSE},
1167             {"",S_FALSE,FALSE},
1168             {"",S_FALSE,TRUE},
1169             {"4294967296",S_OK,FALSE},
1170             {"",S_FALSE,FALSE},
1171             {"/",S_OK,FALSE},
1172             {"/",S_OK,FALSE},
1173             {"",S_FALSE,FALSE},
1174             {"http://4294967296/",S_OK,FALSE},
1175             {"http",S_OK,FALSE},
1176             {"",S_FALSE,FALSE},
1177             {"",S_FALSE,FALSE}
1178         },
1179         {
1180             {Uri_HOST_DNS,S_OK,FALSE},
1181             {80,S_OK,FALSE},
1182             {URL_SCHEME_HTTP,S_OK,FALSE},
1183             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1184         }
1185     },
1186     /* Window's doesn't normalize IP address for unknown schemes. */
1187     {   "1234://4294967295/", 0, S_OK, FALSE,
1188         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1189         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1190         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1191         TRUE,
1192         {
1193             {"1234://4294967295/",S_OK,TRUE},
1194             {"4294967295",S_OK,FALSE},
1195             {"1234://4294967295/",S_OK,TRUE},
1196             {"",S_FALSE,FALSE},
1197             {"",S_FALSE,FALSE},
1198             {"",S_FALSE,TRUE},
1199             {"4294967295",S_OK,FALSE},
1200             {"",S_FALSE,FALSE},
1201             {"/",S_OK,FALSE},
1202             {"/",S_OK,FALSE},
1203             {"",S_FALSE,FALSE},
1204             {"1234://4294967295/",S_OK,FALSE},
1205             {"1234",S_OK,FALSE},
1206             {"",S_FALSE,FALSE},
1207             {"",S_FALSE,FALSE}
1208         },
1209         {
1210             {Uri_HOST_IPV4,S_OK,FALSE},
1211             {0,S_FALSE,FALSE},
1212             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1213             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1214         }
1215     },
1216     /* Window's doesn't normalize IP address for unknown schemes. */
1217     {   "1234://127.001/", 0, S_OK, FALSE,
1218         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1219         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1220         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1221         TRUE,
1222         {
1223             {"1234://127.001/",S_OK,TRUE},
1224             {"127.001",S_OK,FALSE},
1225             {"1234://127.001/",S_OK,TRUE},
1226             {"",S_FALSE,FALSE},
1227             {"",S_FALSE,FALSE},
1228             {"",S_FALSE,TRUE},
1229             {"127.001",S_OK,FALSE},
1230             {"",S_FALSE,FALSE},
1231             {"/",S_OK,FALSE},
1232             {"/",S_OK,FALSE},
1233             {"",S_FALSE,FALSE},
1234             {"1234://127.001/",S_OK,FALSE},
1235             {"1234",S_OK,FALSE},
1236             {"",S_FALSE,FALSE},
1237             {"",S_FALSE,FALSE}
1238         },
1239         {
1240             {Uri_HOST_IPV4,S_OK,FALSE},
1241             {0,S_FALSE,FALSE},
1242             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1243             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1244         }
1245     },
1246     {   "http://[FEDC:BA98::3210]", 0, S_OK, FALSE,
1247         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1248         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1249         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1250         TRUE,
1251         {
1252             {"http://[fedc:ba98::3210]/",S_OK,TRUE},
1253             {"[fedc:ba98::3210]",S_OK,FALSE},
1254             {"http://[fedc:ba98::3210]/",S_OK,TRUE},
1255             {"",S_FALSE,FALSE},
1256             {"",S_FALSE,FALSE},
1257             {"",S_FALSE,TRUE},
1258             {"fedc:ba98::3210",S_OK,FALSE},
1259             {"",S_FALSE,FALSE},
1260             {"/",S_OK,FALSE},
1261             {"/",S_OK,FALSE},
1262             {"",S_FALSE,FALSE},
1263             {"http://[FEDC:BA98::3210]",S_OK,FALSE},
1264             {"http",S_OK,FALSE},
1265             {"",S_FALSE,FALSE},
1266             {"",S_FALSE,FALSE},
1267         },
1268         {
1269             {Uri_HOST_IPV6,S_OK,FALSE},
1270             {80,S_OK,FALSE},
1271             {URL_SCHEME_HTTP,S_OK,FALSE},
1272             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1273         }
1274     },
1275     {   "http://[::]", 0, S_OK, FALSE,
1276         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1277         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1278         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1279         TRUE,
1280         {
1281             {"http://[::]/",S_OK,TRUE},
1282             {"[::]",S_OK,FALSE},
1283             {"http://[::]/",S_OK,TRUE},
1284             {"",S_FALSE,FALSE},
1285             {"",S_FALSE,FALSE},
1286             {"",S_FALSE,TRUE},
1287             {"::",S_OK,FALSE},
1288             {"",S_FALSE,FALSE},
1289             {"/",S_OK,FALSE},
1290             {"/",S_OK,FALSE},
1291             {"",S_FALSE,FALSE},
1292             {"http://[::]",S_OK,FALSE},
1293             {"http",S_OK,FALSE},
1294             {"",S_FALSE,FALSE},
1295             {"",S_FALSE,FALSE},
1296         },
1297         {
1298             {Uri_HOST_IPV6,S_OK,FALSE},
1299             {80,S_OK,FALSE},
1300             {URL_SCHEME_HTTP,S_OK,FALSE},
1301             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1302         }
1303     },
1304     {   "http://[FEDC:BA98::]", 0, S_OK, FALSE,
1305         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1306         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1307         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1308         TRUE,
1309         {
1310             {"http://[fedc:ba98::]/",S_OK,TRUE},
1311             {"[fedc:ba98::]",S_OK,FALSE},
1312             {"http://[fedc:ba98::]/",S_OK,TRUE},
1313             {"",S_FALSE,FALSE},
1314             {"",S_FALSE,FALSE},
1315             {"",S_FALSE,TRUE},
1316             {"fedc:ba98::",S_OK,FALSE},
1317             {"",S_FALSE,FALSE},
1318             {"/",S_OK,FALSE},
1319             {"/",S_OK,FALSE},
1320             {"",S_FALSE,FALSE},
1321             {"http://[FEDC:BA98::]",S_OK,FALSE},
1322             {"http",S_OK,FALSE},
1323             {"",S_FALSE,FALSE},
1324             {"",S_FALSE,FALSE},
1325         },
1326         {
1327             {Uri_HOST_IPV6,S_OK,FALSE},
1328             {80,S_OK,FALSE},
1329             {URL_SCHEME_HTTP,S_OK,FALSE},
1330             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1331         }
1332     },
1333     /* Valid even with 2 byte elision because it doesn't appear the beginning or end. */
1334     {   "http://[1::3:4:5:6:7:8]", 0, S_OK, FALSE,
1335         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1336         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1337         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1338         TRUE,
1339         {
1340             {"http://[1:0:3:4:5:6:7:8]/",S_OK,TRUE},
1341             {"[1:0:3:4:5:6:7:8]",S_OK,FALSE},
1342             {"http://[1:0:3:4:5:6:7:8]/",S_OK,TRUE},
1343             {"",S_FALSE,FALSE},
1344             {"",S_FALSE,FALSE},
1345             {"",S_FALSE,TRUE},
1346             {"1:0:3:4:5:6:7:8",S_OK,FALSE},
1347             {"",S_FALSE,FALSE},
1348             {"/",S_OK,FALSE},
1349             {"/",S_OK,FALSE},
1350             {"",S_FALSE,FALSE},
1351             {"http://[1::3:4:5:6:7:8]",S_OK,FALSE},
1352             {"http",S_OK,FALSE},
1353             {"",S_FALSE,FALSE},
1354             {"",S_FALSE,FALSE},
1355         },
1356         {
1357             {Uri_HOST_IPV6,S_OK,FALSE},
1358             {80,S_OK,FALSE},
1359             {URL_SCHEME_HTTP,S_OK,FALSE},
1360             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1361         }
1362     },
1363     {   "http://[v2.34]/", 0, S_OK, FALSE,
1364         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1365         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1366         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1367         TRUE,
1368         {
1369             {"http://[v2.34]/",S_OK,TRUE},
1370             {"[v2.34]",S_OK,FALSE},
1371             {"http://[v2.34]/",S_OK,TRUE},
1372             {"",S_FALSE,FALSE},
1373             {"",S_FALSE,FALSE},
1374             {"",S_FALSE,TRUE},
1375             {"[v2.34]",S_OK,FALSE},
1376             {"",S_FALSE,FALSE},
1377             {"/",S_OK,FALSE},
1378             {"/",S_OK,FALSE},
1379             {"",S_FALSE,FALSE},
1380             {"http://[v2.34]/",S_OK,FALSE},
1381             {"http",S_OK,FALSE},
1382             {"",S_FALSE,FALSE},
1383             {"",S_FALSE,FALSE}
1384         },
1385         {
1386             {Uri_HOST_UNKNOWN,S_OK,FALSE},
1387             {80,S_OK,FALSE},
1388             {URL_SCHEME_HTTP,S_OK,FALSE},
1389             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1390         }
1391     },
1392     /* Windows ignores ':' if they appear after a '[' on a non-IPLiteral host. */
1393     {   "http://[xyz:12345.com/test", 0, S_OK, FALSE,
1394         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1395         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1396         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1397         TRUE,
1398         {
1399             {"http://[xyz:12345.com/test",S_OK,TRUE},
1400             {"[xyz:12345.com",S_OK,FALSE},
1401             {"http://[xyz:12345.com/test",S_OK,TRUE},
1402             {"[xyz:12345.com",S_OK,FALSE},
1403             {"",S_FALSE,FALSE},
1404             {"",S_FALSE,TRUE},
1405             {"[xyz:12345.com",S_OK,FALSE},
1406             {"",S_FALSE,FALSE},
1407             {"/test",S_OK,FALSE},
1408             {"/test",S_OK,FALSE},
1409             {"",S_FALSE,FALSE},
1410             {"http://[xyz:12345.com/test",S_OK,FALSE},
1411             {"http",S_OK,FALSE},
1412             {"",S_FALSE,FALSE},
1413             {"",S_FALSE,FALSE}
1414         },
1415         {
1416             {Uri_HOST_DNS,S_OK,FALSE},
1417             {80,S_OK,FALSE},
1418             {URL_SCHEME_HTTP,S_OK,FALSE},
1419             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1420         }
1421     },
1422     /* Valid URI since the '[' and ']' don't appear at the begining and end
1423      * of the host name (respectively).
1424      */
1425     {   "ftp://www.[works].com/", 0, S_OK, FALSE,
1426         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1427         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1428         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1429         TRUE,
1430         {
1431             {"ftp://www.[works].com/",S_OK,TRUE},
1432             {"www.[works].com",S_OK,FALSE},
1433             {"ftp://www.[works].com/",S_OK,TRUE},
1434             {"[works].com",S_OK,FALSE},
1435             {"",S_FALSE,FALSE},
1436             {"",S_FALSE,TRUE},
1437             {"www.[works].com",S_OK,FALSE},
1438             {"",S_FALSE,FALSE},
1439             {"/",S_OK,FALSE},
1440             {"/",S_OK,FALSE},
1441             {"",S_FALSE,FALSE},
1442             {"ftp://www.[works].com/",S_OK,FALSE},
1443             {"ftp",S_OK,FALSE},
1444             {"",S_FALSE,FALSE},
1445             {"",S_FALSE,FALSE}
1446         },
1447         {
1448             {Uri_HOST_DNS,S_OK,FALSE},
1449             {21,S_OK,FALSE},
1450             {URL_SCHEME_FTP,S_OK,FALSE},
1451             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1452         }
1453     },
1454     /* Considers ':' a delimiter since it appears after the ']'. */
1455     {   "http://www.google.com]:12345/", 0, S_OK, FALSE,
1456         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1457         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1458         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1459         TRUE,
1460         {
1461             {"http://www.google.com]:12345/",S_OK,TRUE},
1462             {"www.google.com]:12345",S_OK,FALSE},
1463             {"http://www.google.com]:12345/",S_OK,TRUE},
1464             {"google.com]",S_OK,FALSE},
1465             {"",S_FALSE,FALSE},
1466             {"",S_FALSE,TRUE},
1467             {"www.google.com]",S_OK,FALSE},
1468             {"",S_FALSE,FALSE},
1469             {"/",S_OK,FALSE},
1470             {"/",S_OK,FALSE},
1471             {"",S_FALSE,FALSE},
1472             {"http://www.google.com]:12345/",S_OK,FALSE},
1473             {"http",S_OK,FALSE},
1474             {"",S_FALSE,FALSE},
1475             {"",S_FALSE,FALSE}
1476         },
1477         {
1478             {Uri_HOST_DNS,S_OK,FALSE},
1479             {12345,S_OK,FALSE},
1480             {URL_SCHEME_HTTP,S_OK,FALSE},
1481             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1482         }
1483     },
1484     /* Unknown scheme types can have invalid % encoded data in the hostname. */
1485     {   "zip://w%XXw%GEw.google.com/", 0, S_OK, FALSE,
1486         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1487         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1488         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1489         TRUE,
1490         {
1491             {"zip://w%XXw%GEw.google.com/",S_OK,TRUE},
1492             {"w%XXw%GEw.google.com",S_OK,FALSE},
1493             {"zip://w%XXw%GEw.google.com/",S_OK,TRUE},
1494             {"google.com",S_OK,FALSE},
1495             {"",S_FALSE,FALSE},
1496             {"",S_FALSE,TRUE},
1497             {"w%XXw%GEw.google.com",S_OK,FALSE},
1498             {"",S_FALSE,FALSE},
1499             {"/",S_OK,FALSE},
1500             {"/",S_OK,FALSE},
1501             {"",S_FALSE,FALSE},
1502             {"zip://w%XXw%GEw.google.com/",S_OK,FALSE},
1503             {"zip",S_OK,FALSE},
1504             {"",S_FALSE,FALSE},
1505             {"",S_FALSE,FALSE}
1506         },
1507         {
1508             {Uri_HOST_DNS,S_OK,FALSE},
1509             {0,S_FALSE,FALSE},
1510             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1511             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1512         }
1513     },
1514     /* Unknown scheme types hostname doesn't get lower cased. */
1515     {   "zip://GOOGLE.com/", 0, S_OK, FALSE,
1516         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1517         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1518         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1519         TRUE,
1520         {
1521             {"zip://GOOGLE.com/",S_OK,TRUE},
1522             {"GOOGLE.com",S_OK,FALSE},
1523             {"zip://GOOGLE.com/",S_OK,TRUE},
1524             {"GOOGLE.com",S_OK,FALSE},
1525             {"",S_FALSE,FALSE},
1526             {"",S_FALSE,TRUE},
1527             {"GOOGLE.com",S_OK,FALSE},
1528             {"",S_FALSE,FALSE},
1529             {"/",S_OK,FALSE},
1530             {"/",S_OK,FALSE},
1531             {"",S_FALSE,FALSE},
1532             {"zip://GOOGLE.com/",S_OK,FALSE},
1533             {"zip",S_OK,FALSE},
1534             {"",S_FALSE,FALSE},
1535             {"",S_FALSE,FALSE}
1536         },
1537         {
1538             {Uri_HOST_DNS,S_OK,FALSE},
1539             {0,S_FALSE,FALSE},
1540             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1541             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1542         }
1543     },
1544     /* Hostname get's lower cased for known scheme types. */
1545     {   "http://WWW.GOOGLE.com/", 0, S_OK, FALSE,
1546         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1547         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1548         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1549         TRUE,
1550         {
1551             {"http://www.google.com/",S_OK,TRUE},
1552             {"www.google.com",S_OK,FALSE},
1553             {"http://www.google.com/",S_OK,TRUE},
1554             {"google.com",S_OK,FALSE},
1555             {"",S_FALSE,FALSE},
1556             {"",S_FALSE,TRUE},
1557             {"www.google.com",S_OK,FALSE},
1558             {"",S_FALSE,FALSE},
1559             {"/",S_OK,FALSE},
1560             {"/",S_OK,FALSE},
1561             {"",S_FALSE,FALSE},
1562             {"http://WWW.GOOGLE.com/",S_OK,FALSE},
1563             {"http",S_OK,FALSE},
1564             {"",S_FALSE,FALSE},
1565             {"",S_FALSE,FALSE}
1566         },
1567         {
1568             {Uri_HOST_DNS,S_OK,FALSE},
1569             {80,S_OK,FALSE},
1570             {URL_SCHEME_HTTP,S_OK,FALSE},
1571             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1572         }
1573     },
1574     /* Characters that get % encoded in the hostname also have their percent
1575      * encoded forms lower cased.
1576      */
1577     {   "http://www.%7Cgoogle|.com/", 0, S_OK, FALSE,
1578         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1579         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1580         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1581         TRUE,
1582         {
1583             {"http://www.%7cgoogle%7c.com/",S_OK,TRUE},
1584             {"www.%7cgoogle%7c.com",S_OK,FALSE},
1585             {"http://www.%7cgoogle%7c.com/",S_OK,TRUE},
1586             {"%7cgoogle%7c.com",S_OK,FALSE},
1587             {"",S_FALSE,FALSE},
1588             {"",S_FALSE,TRUE},
1589             {"www.%7cgoogle%7c.com",S_OK,FALSE},
1590             {"",S_FALSE,FALSE},
1591             {"/",S_OK,FALSE},
1592             {"/",S_OK,FALSE},
1593             {"",S_FALSE,FALSE},
1594             {"http://www.%7Cgoogle|.com/",S_OK,FALSE},
1595             {"http",S_OK,FALSE},
1596             {"",S_FALSE,FALSE},
1597             {"",S_FALSE,FALSE}
1598         },
1599         {
1600             {Uri_HOST_DNS,S_OK,FALSE},
1601             {80,S_OK,FALSE},
1602             {URL_SCHEME_HTTP,S_OK,FALSE},
1603             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1604         }
1605     },
1606     /* IPv4 addresses attached to IPv6 can be included in elisions. */
1607     {   "http://[1:2:3:4:5:6:0.0.0.0]", 0, S_OK, FALSE,
1608         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1609         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1610         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1611         TRUE,
1612         {
1613             {"http://[1:2:3:4:5:6::]/",S_OK,TRUE},
1614             {"[1:2:3:4:5:6::]",S_OK,FALSE},
1615             {"http://[1:2:3:4:5:6::]/",S_OK,TRUE},
1616             {"",S_FALSE,FALSE},
1617             {"",S_FALSE,FALSE},
1618             {"",S_FALSE,TRUE},
1619             {"1:2:3:4:5:6::",S_OK,FALSE},
1620             {"",S_FALSE,FALSE},
1621             {"/",S_OK,FALSE},
1622             {"/",S_OK,FALSE},
1623             {"",S_FALSE,FALSE},
1624             {"http://[1:2:3:4:5:6:0.0.0.0]",S_OK,FALSE},
1625             {"http",S_OK,FALSE},
1626             {"",S_FALSE,FALSE},
1627             {"",S_FALSE,FALSE},
1628         },
1629         {
1630             {Uri_HOST_IPV6,S_OK,FALSE},
1631             {80,S_OK,FALSE},
1632             {URL_SCHEME_HTTP,S_OK,FALSE},
1633             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1634         }
1635     },
1636     /* IPv4 addresses get normalized. */
1637     {   "http://[::001.002.003.000]", 0, S_OK, FALSE,
1638         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1639         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1640         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1641         TRUE,
1642         {
1643             {"http://[::1.2.3.0]/",S_OK,TRUE},
1644             {"[::1.2.3.0]",S_OK,FALSE},
1645             {"http://[::1.2.3.0]/",S_OK,TRUE},
1646             {"",S_FALSE,FALSE},
1647             {"",S_FALSE,FALSE},
1648             {"",S_FALSE,TRUE},
1649             {"::1.2.3.0",S_OK,FALSE},
1650             {"",S_FALSE,FALSE},
1651             {"/",S_OK,FALSE},
1652             {"/",S_OK,FALSE},
1653             {"",S_FALSE,FALSE},
1654             {"http://[::001.002.003.000]",S_OK,FALSE},
1655             {"http",S_OK,FALSE},
1656             {"",S_FALSE,FALSE},
1657             {"",S_FALSE,FALSE},
1658         },
1659         {
1660             {Uri_HOST_IPV6,S_OK,FALSE},
1661             {80,S_OK,FALSE},
1662             {URL_SCHEME_HTTP,S_OK,FALSE},
1663             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1664         }
1665     },
1666     /* Windows doesn't do anything to IPv6's in unknown schemes. */
1667     {   "zip://[0001:0:000:0004:0005:0006:001.002.003.000]", 0, S_OK, FALSE,
1668         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1669         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1670         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1671         TRUE,
1672         {
1673             {"zip://[0001:0:000:0004:0005:0006:001.002.003.000]/",S_OK,TRUE},
1674             {"[0001:0:000:0004:0005:0006:001.002.003.000]",S_OK,FALSE},
1675             {"zip://[0001:0:000:0004:0005:0006:001.002.003.000]/",S_OK,TRUE},
1676             {"",S_FALSE,FALSE},
1677             {"",S_FALSE,FALSE},
1678             {"",S_FALSE,TRUE},
1679             {"0001:0:000:0004:0005:0006:001.002.003.000",S_OK,FALSE},
1680             {"",S_FALSE,FALSE},
1681             {"/",S_OK,FALSE},
1682             {"/",S_OK,FALSE},
1683             {"",S_FALSE,FALSE},
1684             {"zip://[0001:0:000:0004:0005:0006:001.002.003.000]",S_OK,FALSE},
1685             {"zip",S_OK,FALSE},
1686             {"",S_FALSE,FALSE},
1687             {"",S_FALSE,FALSE},
1688         },
1689         {
1690             {Uri_HOST_IPV6,S_OK,FALSE},
1691             {0,S_FALSE,FALSE},
1692             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1693             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1694         }
1695     },
1696     /* IPv4 address is converted into 2 h16 components. */
1697     {   "http://[ffff::192.222.111.32]", 0, S_OK, FALSE,
1698         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1699         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1700         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1701         TRUE,
1702         {
1703             {"http://[ffff::c0de:6f20]/",S_OK,TRUE},
1704             {"[ffff::c0de:6f20]",S_OK,FALSE},
1705             {"http://[ffff::c0de:6f20]/",S_OK,TRUE},
1706             {"",S_FALSE,FALSE},
1707             {"",S_FALSE,FALSE},
1708             {"",S_FALSE,TRUE},
1709             {"ffff::c0de:6f20",S_OK,FALSE},
1710             {"",S_FALSE,FALSE},
1711             {"/",S_OK,FALSE},
1712             {"/",S_OK,FALSE},
1713             {"",S_FALSE,FALSE},
1714             {"http://[ffff::192.222.111.32]",S_OK,FALSE},
1715             {"http",S_OK,FALSE},
1716             {"",S_FALSE,FALSE},
1717             {"",S_FALSE,FALSE},
1718         },
1719         {
1720             {Uri_HOST_IPV6,S_OK,FALSE},
1721             {80,S_OK,FALSE},
1722             {URL_SCHEME_HTTP,S_OK,FALSE},
1723             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1724         }
1725     },
1726     /* Max value for a port. */
1727     {   "http://google.com:65535", 0, S_OK, FALSE,
1728         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1729         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1730         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1731         TRUE,
1732         {
1733             {"http://google.com:65535/",S_OK,TRUE},
1734             {"google.com:65535",S_OK,FALSE},
1735             {"http://google.com:65535/",S_OK,TRUE},
1736             {"google.com",S_OK,FALSE},
1737             {"",S_FALSE,FALSE},
1738             {"",S_FALSE,TRUE},
1739             {"google.com",S_OK,FALSE},
1740             {"",S_FALSE,FALSE},
1741             {"/",S_OK,FALSE},
1742             {"/",S_OK,FALSE},
1743             {"",S_FALSE,FALSE},
1744             {"http://google.com:65535",S_OK,FALSE},
1745             {"http",S_OK,FALSE},
1746             {"",S_FALSE,FALSE},
1747             {"",S_FALSE,FALSE}
1748         },
1749         {
1750             {Uri_HOST_DNS,S_OK,FALSE},
1751             {65535,S_OK,FALSE},
1752             {URL_SCHEME_HTTP,S_OK,FALSE},
1753             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1754         }
1755     },
1756     {   "zip://google.com:65536", 0, S_OK, FALSE,
1757         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1758         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1759         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1760         TRUE,
1761         {
1762             {"zip://google.com:65536/",S_OK,TRUE},
1763             {"google.com:65536",S_OK,FALSE},
1764             {"zip://google.com:65536/",S_OK,TRUE},
1765             {"google.com:65536",S_OK,FALSE},
1766             {"",S_FALSE,FALSE},
1767             {"",S_FALSE,TRUE},
1768             {"google.com:65536",S_OK,FALSE},
1769             {"",S_FALSE,FALSE},
1770             {"/",S_OK,FALSE},
1771             {"/",S_OK,FALSE},
1772             {"",S_FALSE,FALSE},
1773             {"zip://google.com:65536",S_OK,FALSE},
1774             {"zip",S_OK,FALSE},
1775             {"",S_FALSE,FALSE},
1776             {"",S_FALSE,FALSE}
1777         },
1778         {
1779             {Uri_HOST_DNS,S_OK,FALSE},
1780             {0,S_FALSE,FALSE},
1781             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1782             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1783         }
1784     },
1785     {   "zip://google.com:65536:25", 0, S_OK, FALSE,
1786         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1787         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1788         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1789         TRUE,
1790         {
1791             {"zip://google.com:65536:25/",S_OK,TRUE},
1792             {"google.com:65536:25",S_OK,FALSE},
1793             {"zip://google.com:65536:25/",S_OK,TRUE},
1794             {"google.com:65536:25",S_OK,FALSE},
1795             {"",S_FALSE,FALSE},
1796             {"",S_FALSE,TRUE},
1797             {"google.com:65536:25",S_OK,FALSE},
1798             {"",S_FALSE,FALSE},
1799             {"/",S_OK,FALSE},
1800             {"/",S_OK,FALSE},
1801             {"",S_FALSE,FALSE},
1802             {"zip://google.com:65536:25",S_OK,FALSE},
1803             {"zip",S_OK,FALSE},
1804             {"",S_FALSE,FALSE},
1805             {"",S_FALSE,FALSE}
1806         },
1807         {
1808             {Uri_HOST_DNS,S_OK,FALSE},
1809             {0,S_FALSE,FALSE},
1810             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1811             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1812         }
1813     },
1814     {   "zip://[::ffff]:abcd", 0, S_OK, FALSE,
1815         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|
1816         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1817         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1818         TRUE,
1819         {
1820             {"zip://[::ffff]:abcd/",S_OK,TRUE},
1821             {"[::ffff]:abcd",S_OK,FALSE},
1822             {"zip://[::ffff]:abcd/",S_OK,TRUE},
1823             {"",S_FALSE,FALSE},
1824             {"",S_FALSE,FALSE},
1825             {"",S_FALSE,TRUE},
1826             {"[::ffff]:abcd",S_OK,FALSE},
1827             {"",S_FALSE,FALSE},
1828             {"/",S_OK,FALSE},
1829             {"/",S_OK,FALSE},
1830             {"",S_FALSE,FALSE},
1831             {"zip://[::ffff]:abcd",S_OK,FALSE},
1832             {"zip",S_OK,FALSE},
1833             {"",S_FALSE,FALSE},
1834             {"",S_FALSE,FALSE}
1835         },
1836         {
1837             {Uri_HOST_DNS,S_OK,FALSE},
1838             {0,S_FALSE,FALSE},
1839             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1840             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1841         }
1842     },
1843     {   "zip://127.0.0.1:abcd", 0, S_OK, FALSE,
1844         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1845         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1846         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1847         TRUE,
1848         {
1849             {"zip://127.0.0.1:abcd/",S_OK,TRUE},
1850             {"127.0.0.1:abcd",S_OK,FALSE},
1851             {"zip://127.0.0.1:abcd/",S_OK,TRUE},
1852             {"0.1:abcd",S_OK,FALSE},
1853             {"",S_FALSE,FALSE},
1854             {"",S_FALSE,TRUE},
1855             {"127.0.0.1:abcd",S_OK,FALSE},
1856             {"",S_FALSE,FALSE},
1857             {"/",S_OK,FALSE},
1858             {"/",S_OK,FALSE},
1859             {"",S_FALSE,FALSE},
1860             {"zip://127.0.0.1:abcd",S_OK,FALSE},
1861             {"zip",S_OK,FALSE},
1862             {"",S_FALSE,FALSE},
1863             {"",S_FALSE,FALSE}
1864         },
1865         {
1866             {Uri_HOST_DNS,S_OK,FALSE},
1867             {0,S_FALSE,FALSE},
1868             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1869             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1870         }
1871     },
1872     /* Port is just copied over. */
1873     {   "http://google.com:00035", Uri_CREATE_NO_CANONICALIZE, S_OK, FALSE,
1874         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1875         Uri_HAS_HOST|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1876         TRUE,
1877         {
1878             {"http://google.com:00035",S_OK,TRUE},
1879             {"google.com:00035",S_OK,FALSE},
1880             {"http://google.com:00035",S_OK,TRUE,"http://google.com:35"},
1881             {"google.com",S_OK,FALSE},
1882             {"",S_FALSE,FALSE},
1883             {"",S_FALSE,TRUE},
1884             {"google.com",S_OK,FALSE},
1885             {"",S_FALSE,FALSE},
1886             {"",S_FALSE,FALSE},
1887             {"",S_FALSE,FALSE},
1888             {"",S_FALSE,FALSE},
1889             {"http://google.com:00035",S_OK,FALSE},
1890             {"http",S_OK,FALSE},
1891             {"",S_FALSE,FALSE},
1892             {"",S_FALSE,FALSE}
1893         },
1894         {
1895             {Uri_HOST_DNS,S_OK,FALSE},
1896             {35,S_OK,FALSE},
1897             {URL_SCHEME_HTTP,S_OK,FALSE},
1898             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1899         }
1900     },
1901     /* Default port is copied over. */
1902     {   "http://google.com:80", Uri_CREATE_NO_CANONICALIZE, S_OK, FALSE,
1903         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1904         Uri_HAS_HOST|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1905         TRUE,
1906         {
1907             {"http://google.com:80",S_OK,TRUE},
1908             {"google.com:80",S_OK,FALSE},
1909             {"http://google.com:80",S_OK,TRUE},
1910             {"google.com",S_OK,FALSE},
1911             {"",S_FALSE,FALSE},
1912             {"",S_FALSE,TRUE},
1913             {"google.com",S_OK,FALSE},
1914             {"",S_FALSE,FALSE},
1915             {"",S_FALSE,FALSE},
1916             {"",S_FALSE,FALSE},
1917             {"",S_FALSE,FALSE},
1918             {"http://google.com:80",S_OK,FALSE},
1919             {"http",S_OK,FALSE},
1920             {"",S_FALSE,FALSE},
1921             {"",S_FALSE,FALSE}
1922         },
1923         {
1924             {Uri_HOST_DNS,S_OK,FALSE},
1925             {80,S_OK,FALSE},
1926             {URL_SCHEME_HTTP,S_OK,FALSE},
1927             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1928         }
1929     },
1930     {   "http://google.com.uk", 0, S_OK, FALSE,
1931         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1932         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1933         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1934         TRUE,
1935         {
1936             {"http://google.com.uk/",S_OK,TRUE},
1937             {"google.com.uk",S_OK,FALSE},
1938             {"http://google.com.uk/",S_OK,TRUE},
1939             {"google.com.uk",S_OK,FALSE},
1940             {"",S_FALSE,FALSE},
1941             {"",S_FALSE,TRUE},
1942             {"google.com.uk",S_OK,FALSE},
1943             {"",S_FALSE,FALSE},
1944             {"/",S_OK,FALSE},
1945             {"/",S_OK,FALSE},
1946             {"",S_FALSE,FALSE},
1947             {"http://google.com.uk",S_OK,FALSE},
1948             {"http",S_OK,FALSE},
1949             {"",S_FALSE,FALSE},
1950             {"",S_FALSE,FALSE}
1951         },
1952         {
1953             {Uri_HOST_DNS,S_OK,FALSE},
1954             {80,S_OK,FALSE},
1955             {URL_SCHEME_HTTP,S_OK,FALSE},
1956             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1957         }
1958     },
1959     {   "http://google.com.com", 0, S_OK, FALSE,
1960         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1961         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1962         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1963         TRUE,
1964         {
1965             {"http://google.com.com/",S_OK,TRUE},
1966             {"google.com.com",S_OK,FALSE},
1967             {"http://google.com.com/",S_OK,TRUE},
1968             {"com.com",S_OK,FALSE},
1969             {"",S_FALSE,FALSE},
1970             {"",S_FALSE,TRUE},
1971             {"google.com.com",S_OK,FALSE},
1972             {"",S_FALSE,FALSE},
1973             {"/",S_OK,FALSE},
1974             {"/",S_OK,FALSE},
1975             {"",S_FALSE,FALSE},
1976             {"http://google.com.com",S_OK,FALSE},
1977             {"http",S_OK,FALSE},
1978             {"",S_FALSE,FALSE},
1979             {"",S_FALSE,FALSE}
1980         },
1981         {
1982             {Uri_HOST_DNS,S_OK,FALSE},
1983             {80,S_OK,FALSE},
1984             {URL_SCHEME_HTTP,S_OK,FALSE},
1985             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1986         }
1987     },
1988     {   "http://google.uk.1", 0, S_OK, FALSE,
1989         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1990         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1991         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1992         TRUE,
1993         {
1994             {"http://google.uk.1/",S_OK,TRUE},
1995             {"google.uk.1",S_OK,FALSE},
1996             {"http://google.uk.1/",S_OK,TRUE},
1997             {"google.uk.1",S_OK,FALSE},
1998             {"",S_FALSE,FALSE},
1999             {"",S_FALSE,TRUE},
2000             {"google.uk.1",S_OK,FALSE},
2001             {"",S_FALSE,FALSE},
2002             {"/",S_OK,FALSE},
2003             {"/",S_OK,FALSE},
2004             {"",S_FALSE,FALSE},
2005             {"http://google.uk.1",S_OK,FALSE},
2006             {"http",S_OK,FALSE},
2007             {"",S_FALSE,FALSE},
2008             {"",S_FALSE,FALSE}
2009         },
2010         {
2011             {Uri_HOST_DNS,S_OK,FALSE},
2012             {80,S_OK,FALSE},
2013             {URL_SCHEME_HTTP,S_OK,FALSE},
2014             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2015         }
2016     },
2017     /* Since foo isn't a recognized 3 character TLD its considered the domain name. */
2018     {   "http://google.foo.uk", 0, S_OK, FALSE,
2019         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
2020         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2021         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
2022         TRUE,
2023         {
2024             {"http://google.foo.uk/",S_OK,TRUE},
2025             {"google.foo.uk",S_OK,FALSE},
2026             {"http://google.foo.uk/",S_OK,TRUE},
2027             {"foo.uk",S_OK,FALSE},
2028             {"",S_FALSE,FALSE},
2029             {"",S_FALSE,TRUE},
2030             {"google.foo.uk",S_OK,FALSE},
2031             {"",S_FALSE,FALSE},
2032             {"/",S_OK,FALSE},
2033             {"/",S_OK,FALSE},
2034             {"",S_FALSE,FALSE},
2035             {"http://google.foo.uk",S_OK,FALSE},
2036             {"http",S_OK,FALSE},
2037             {"",S_FALSE,FALSE},
2038             {"",S_FALSE,FALSE}
2039         },
2040         {
2041             {Uri_HOST_DNS,S_OK,FALSE},
2042             {80,S_OK,FALSE},
2043             {URL_SCHEME_HTTP,S_OK,FALSE},
2044             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2045         }
2046     },
2047     {   "http://.com", 0, S_OK, FALSE,
2048         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
2049         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2050         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
2051         TRUE,
2052         {
2053             {"http://.com/",S_OK,TRUE},
2054             {".com",S_OK,FALSE},
2055             {"http://.com/",S_OK,TRUE},
2056             {".com",S_OK,FALSE},
2057             {"",S_FALSE,FALSE},
2058             {"",S_FALSE,TRUE},
2059             {".com",S_OK,FALSE},
2060             {"",S_FALSE,FALSE},
2061             {"/",S_OK,FALSE},
2062             {"/",S_OK,FALSE},
2063             {"",S_FALSE,FALSE},
2064             {"http://.com",S_OK,FALSE},
2065             {"http",S_OK,FALSE},
2066             {"",S_FALSE,FALSE},
2067             {"",S_FALSE,FALSE}
2068         },
2069         {
2070             {Uri_HOST_DNS,S_OK,FALSE},
2071             {80,S_OK,FALSE},
2072             {URL_SCHEME_HTTP,S_OK,FALSE},
2073             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2074         }
2075     },
2076     {   "http://.uk", 0, S_OK, FALSE,
2077         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
2078         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2079         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
2080         TRUE,
2081         {
2082             {"http://.uk/",S_OK,TRUE},
2083             {".uk",S_OK,FALSE},
2084             {"http://.uk/",S_OK,TRUE},
2085             {"",S_FALSE,FALSE},
2086             {"",S_FALSE,FALSE},
2087             {"",S_FALSE,TRUE},
2088             {".uk",S_OK,FALSE},
2089             {"",S_FALSE,FALSE},
2090             {"/",S_OK,FALSE},
2091             {"/",S_OK,FALSE},
2092             {"",S_FALSE,FALSE},
2093             {"http://.uk",S_OK,FALSE},
2094             {"http",S_OK,FALSE},
2095             {"",S_FALSE,FALSE},
2096             {"",S_FALSE,FALSE}
2097         },
2098         {
2099             {Uri_HOST_DNS,S_OK,FALSE},
2100             {80,S_OK,FALSE},
2101             {URL_SCHEME_HTTP,S_OK,FALSE},
2102             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2103         }
2104     },
2105     {   "http://www.co.google.com.[]", 0, S_OK, FALSE,
2106         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
2107         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2108         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
2109         TRUE,
2110         {
2111             {"http://www.co.google.com.[]/",S_OK,TRUE},
2112             {"www.co.google.com.[]",S_OK,FALSE},
2113             {"http://www.co.google.com.[]/",S_OK,TRUE},
2114             {"google.com.[]",S_OK,FALSE},
2115             {"",S_FALSE,FALSE},
2116             {"",S_FALSE,TRUE},
2117             {"www.co.google.com.[]",S_OK,FALSE},
2118             {"",S_FALSE,FALSE},
2119             {"/",S_OK,FALSE},
2120             {"/",S_OK,FALSE},
2121             {"",S_FALSE,FALSE},
2122             {"http://www.co.google.com.[]",S_OK,FALSE},
2123             {"http",S_OK,FALSE},
2124             {"",S_FALSE,FALSE},
2125             {"",S_FALSE,FALSE}
2126         },
2127         {
2128             {Uri_HOST_DNS,S_OK,FALSE},
2129             {80,S_OK,FALSE},
2130             {URL_SCHEME_HTTP,S_OK,FALSE},
2131             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2132         }
2133     },
2134     {   "http://co.uk", 0, S_OK, FALSE,
2135         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
2136         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2137         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
2138         TRUE,
2139         {
2140             {"http://co.uk/",S_OK,TRUE},
2141             {"co.uk",S_OK,FALSE},
2142             {"http://co.uk/",S_OK,TRUE},
2143             {"",S_FALSE,FALSE},
2144             {"",S_FALSE,FALSE},
2145             {"",S_FALSE,TRUE},
2146             {"co.uk",S_OK,FALSE},
2147             {"",S_FALSE,FALSE},
2148             {"/",S_OK,FALSE},
2149             {"/",S_OK,FALSE},
2150             {"",S_FALSE,FALSE},
2151             {"http://co.uk",S_OK,FALSE},
2152             {"http",S_OK,FALSE},
2153             {"",S_FALSE,FALSE},
2154             {"",S_FALSE,FALSE}
2155         },
2156         {
2157             {Uri_HOST_DNS,S_OK,FALSE},
2158             {80,S_OK,FALSE},
2159             {URL_SCHEME_HTTP,S_OK,FALSE},
2160             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2161         }
2162     },
2163     {   "http://www.co.google.us.test", 0, S_OK, FALSE,
2164         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
2165         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2166         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
2167         TRUE,
2168         {
2169             {"http://www.co.google.us.test/",S_OK,TRUE},
2170             {"www.co.google.us.test",S_OK,FALSE},
2171             {"http://www.co.google.us.test/",S_OK,TRUE},
2172             {"us.test",S_OK,FALSE},
2173             {"",S_FALSE,FALSE},
2174             {"",S_FALSE,TRUE},
2175             {"www.co.google.us.test",S_OK,FALSE},
2176             {"",S_FALSE,FALSE},
2177             {"/",S_OK,FALSE},
2178             {"/",S_OK,FALSE},
2179             {"",S_FALSE,FALSE},
2180             {"http://www.co.google.us.test",S_OK,FALSE},
2181             {"http",S_OK,FALSE},
2182             {"",S_FALSE,FALSE},
2183             {"",S_FALSE,FALSE}
2184         },
2185         {
2186             {Uri_HOST_DNS,S_OK,FALSE},
2187             {80,S_OK,FALSE},
2188             {URL_SCHEME_HTTP,S_OK,FALSE},
2189             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2190         }
2191     },
2192     {   "http://gov.uk", 0, S_OK, FALSE,
2193         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
2194         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2195         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
2196         TRUE,
2197         {
2198             {"http://gov.uk/",S_OK,TRUE},
2199             {"gov.uk",S_OK,FALSE},
2200             {"http://gov.uk/",S_OK,TRUE},
2201             {"",S_FALSE,FALSE},
2202             {"",S_FALSE,FALSE},
2203             {"",S_FALSE,TRUE},
2204             {"gov.uk",S_OK,FALSE},
2205             {"",S_FALSE,FALSE},
2206             {"/",S_OK,FALSE},
2207             {"/",S_OK,FALSE},
2208             {"",S_FALSE,FALSE},
2209             {"http://gov.uk",S_OK,FALSE},
2210             {"http",S_OK,FALSE},
2211             {"",S_FALSE,FALSE},
2212             {"",S_FALSE,FALSE}
2213         },
2214         {
2215             {Uri_HOST_DNS,S_OK,FALSE},
2216             {80,S_OK,FALSE},
2217             {URL_SCHEME_HTTP,S_OK,FALSE},
2218             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2219         }
2220     },
2221     {   "zip://www.google.com\\test", Uri_CREATE_NO_CANONICALIZE, S_OK, FALSE,
2222         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
2223         Uri_HAS_HOST|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2224         TRUE,
2225         {
2226             {"zip://www.google.com\\test",S_OK,TRUE},
2227             {"www.google.com\\test",S_OK,FALSE},
2228             {"zip://www.google.com\\test",S_OK,TRUE},
2229             {"google.com\\test",S_OK,FALSE},
2230             {"",S_FALSE,FALSE},
2231             {"",S_FALSE,TRUE},
2232             {"www.google.com\\test",S_OK,FALSE},
2233             {"",S_FALSE,FALSE},
2234             {"",S_FALSE,FALSE},
2235             {"",S_FALSE,FALSE},
2236             {"",S_FALSE,FALSE},
2237             {"zip://www.google.com\\test",S_OK,FALSE},
2238             {"zip",S_OK,FALSE},
2239             {"",S_FALSE,FALSE},
2240             {"",S_FALSE,FALSE}
2241         },
2242         {
2243             {Uri_HOST_DNS,S_OK,FALSE},
2244             {0,S_FALSE,FALSE},
2245             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
2246             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2247         }
2248     },
2249     {   "urn:excepts:bad:%XY:encoded", 0, S_OK, FALSE,
2250         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|
2251         Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2252         TRUE,
2253         {
2254             {"urn:excepts:bad:%XY:encoded",S_OK,TRUE},
2255             {"",S_FALSE,FALSE},
2256             {"urn:excepts:bad:%XY:encoded",S_OK,TRUE},
2257             {"",S_FALSE,FALSE},
2258             {"",S_FALSE,FALSE},
2259             {"",S_FALSE,TRUE},
2260             {"",S_FALSE,FALSE},
2261             {"",S_FALSE,FALSE},
2262             {"excepts:bad:%XY:encoded",S_OK,FALSE},
2263             {"excepts:bad:%XY:encoded",S_OK,FALSE},
2264             {"",S_FALSE,FALSE},
2265             {"urn:excepts:bad:%XY:encoded",S_OK,FALSE},
2266             {"urn",S_OK,FALSE},
2267             {"",S_FALSE,FALSE},
2268             {"",S_FALSE,FALSE}
2269         },
2270         {
2271             {Uri_HOST_UNKNOWN,S_OK,FALSE},
2272             {0,S_FALSE,FALSE},
2273             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
2274             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2275         }
2276     },
2277     /* Since the original URI doesn't contain an extra '/' before the path no % encoded values
2278      * are decoded and all '%' are encoded.
2279      */
2280     {   "file://C:/te%3Es%2Et/tes%t.mp3", 0, S_OK, FALSE,
2281         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
2282         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2283         TRUE,
2284         {
2285             {"file:///C:/te%253Es%252Et/tes%25t.mp3",S_OK,TRUE},
2286             {"",S_FALSE,FALSE},
2287             {"file:///C:/te%253Es%252Et/tes%25t.mp3",S_OK,TRUE},
2288             {"",S_FALSE,FALSE},
2289             {".mp3",S_OK,FALSE},
2290             {"",S_FALSE,TRUE},
2291             {"",S_FALSE,FALSE},
2292             {"",S_FALSE,FALSE},
2293             {"/C:/te%253Es%252Et/tes%25t.mp3",S_OK,FALSE},
2294             {"/C:/te%253Es%252Et/tes%25t.mp3",S_OK,FALSE},
2295             {"",S_FALSE,FALSE},
2296             {"file://C:/te%3Es%2Et/tes%t.mp3",S_OK,FALSE},
2297             {"file",S_OK,FALSE},
2298             {"",S_FALSE,FALSE},
2299             {"",S_FALSE,FALSE}
2300         },
2301         {
2302             {Uri_HOST_UNKNOWN,S_OK,FALSE},
2303             {0,S_FALSE,FALSE},
2304             {URL_SCHEME_FILE,S_OK,FALSE},
2305             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2306         }
2307     },
2308     /* Since there's a '/' in front of the drive letter, any percent encoded, non-forbidden character
2309      * is decoded and only %'s in front of invalid hex digits are encoded.
2310      */
2311     {   "file:///C:/te%3Es%2Et/t%23es%t.mp3", 0, S_OK, FALSE,
2312         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
2313         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2314         TRUE,
2315         {
2316             {"file:///C:/te%3Es.t/t#es%25t.mp3",S_OK,TRUE},
2317             {"",S_FALSE,FALSE},
2318             {"file:///C:/te%3Es.t/t#es%25t.mp3",S_OK,TRUE},
2319             {"",S_FALSE,FALSE},
2320             {".mp3",S_OK,FALSE},
2321             {"",S_FALSE,TRUE},
2322             {"",S_FALSE,FALSE},
2323             {"",S_FALSE,FALSE},
2324             {"/C:/te%3Es.t/t#es%25t.mp3",S_OK,FALSE},
2325             {"/C:/te%3Es.t/t#es%25t.mp3",S_OK,FALSE},
2326             {"",S_FALSE,FALSE},
2327             {"file:///C:/te%3Es%2Et/t%23es%t.mp3",S_OK,FALSE},
2328             {"file",S_OK,FALSE},
2329             {"",S_FALSE,FALSE},
2330             {"",S_FALSE,FALSE}
2331         },
2332         {
2333             {Uri_HOST_UNKNOWN,S_OK,FALSE},
2334             {0,S_FALSE,FALSE},
2335             {URL_SCHEME_FILE,S_OK,FALSE},
2336             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2337         }
2338     },
2339     /* Only unreserved percent encoded characters are decoded for known schemes that aren't file. */
2340     {   "http://[::001.002.003.000]/%3F%23%2E%54/test", 0, S_OK, FALSE,
2341         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
2342         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2343         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
2344         TRUE,
2345         {
2346             {"http://[::1.2.3.0]/%3F%23.T/test",S_OK,TRUE},
2347             {"[::1.2.3.0]",S_OK,FALSE},
2348             {"http://[::1.2.3.0]/%3F%23.T/test",S_OK,TRUE},
2349             {"",S_FALSE,FALSE},
2350             {"",S_FALSE,FALSE},
2351             {"",S_FALSE,TRUE},
2352             {"::1.2.3.0",S_OK,FALSE},
2353             {"",S_FALSE,FALSE},
2354             {"/%3F%23.T/test",S_OK,FALSE},
2355             {"/%3F%23.T/test",S_OK,FALSE},
2356             {"",S_FALSE,FALSE},
2357             {"http://[::001.002.003.000]/%3F%23%2E%54/test",S_OK,FALSE},
2358             {"http",S_OK,FALSE},
2359             {"",S_FALSE,FALSE},
2360             {"",S_FALSE,FALSE},
2361         },
2362         {
2363             {Uri_HOST_IPV6,S_OK,FALSE},
2364             {80,S_OK,FALSE},
2365             {URL_SCHEME_HTTP,S_OK,FALSE},
2366             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2367         }
2368     },
2369     /* Forbidden characters are always encoded for file URIs. */
2370     {   "file:///C:/\"test\"/test.mp3", Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS, S_OK, FALSE,
2371         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
2372         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2373         TRUE,
2374         {
2375             {"file:///C:/%22test%22/test.mp3",S_OK,TRUE},
2376             {"",S_FALSE,FALSE},
2377             {"file:///C:/%22test%22/test.mp3",S_OK,TRUE},
2378             {"",S_FALSE,FALSE},
2379             {".mp3",S_OK,FALSE},
2380             {"",S_FALSE,TRUE},
2381             {"",S_FALSE,FALSE},
2382             {"",S_FALSE,FALSE},
2383             {"/C:/%22test%22/test.mp3",S_OK,FALSE},
2384             {"/C:/%22test%22/test.mp3",S_OK,FALSE},
2385             {"",S_FALSE,FALSE},
2386             {"file:///C:/\"test\"/test.mp3",S_OK,FALSE},
2387             {"file",S_OK,FALSE},
2388             {"",S_FALSE,FALSE},
2389             {"",S_FALSE,FALSE}
2390         },
2391         {
2392             {Uri_HOST_UNKNOWN,S_OK,FALSE},
2393             {0,S_FALSE,FALSE},
2394             {URL_SCHEME_FILE,S_OK,FALSE},
2395             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2396         }
2397     },
2398     /* Forbidden characters are never encoded for unknown scheme types. */
2399     {   "1234://4294967295/<|>\" test<|>", 0, S_OK, FALSE,
2400         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
2401         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2402         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2403         TRUE,
2404         {
2405             {"1234://4294967295/<|>\" test<|>",S_OK,TRUE},
2406             {"4294967295",S_OK,FALSE},
2407             {"1234://4294967295/<|>\" test<|>",S_OK,TRUE},
2408             {"",S_FALSE,FALSE},
2409             {"",S_FALSE,FALSE},
2410             {"",S_FALSE,TRUE},
2411             {"4294967295",S_OK,FALSE},
2412             {"",S_FALSE,FALSE},
2413             {"/<|>\" test<|>",S_OK,FALSE},
2414             {"/<|>\" test<|>",S_OK,FALSE},
2415             {"",S_FALSE,FALSE},
2416             {"1234://4294967295/<|>\" test<|>",S_OK,FALSE},
2417             {"1234",S_OK,FALSE},
2418             {"",S_FALSE,FALSE},
2419             {"",S_FALSE,FALSE}
2420         },
2421         {
2422             {Uri_HOST_IPV4,S_OK,FALSE},
2423             {0,S_FALSE,FALSE},
2424             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
2425             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2426         }
2427     },
2428     /* Make sure forbidden characters are percent encoded. */
2429     {   "http://gov.uk/<|> test<|>", 0, S_OK, FALSE,
2430         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
2431         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2432         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
2433         TRUE,
2434         {
2435             {"http://gov.uk/%3C%7C%3E%20test%3C%7C%3E",S_OK,TRUE},
2436             {"gov.uk",S_OK,FALSE},
2437             {"http://gov.uk/%3C%7C%3E%20test%3C%7C%3E",S_OK,TRUE},
2438             {"",S_FALSE,FALSE},
2439             {"",S_FALSE,FALSE},
2440             {"",S_FALSE,TRUE},
2441             {"gov.uk",S_OK,FALSE},
2442             {"",S_FALSE,FALSE},
2443             {"/%3C%7C%3E%20test%3C%7C%3E",S_OK,FALSE},
2444             {"/%3C%7C%3E%20test%3C%7C%3E",S_OK,FALSE},
2445             {"",S_FALSE,FALSE},
2446             {"http://gov.uk/<|> test<|>",S_OK,FALSE},
2447             {"http",S_OK,FALSE},
2448             {"",S_FALSE,FALSE},
2449             {"",S_FALSE,FALSE}
2450         },
2451         {
2452             {Uri_HOST_DNS,S_OK,FALSE},
2453             {80,S_OK,FALSE},
2454             {URL_SCHEME_HTTP,S_OK,FALSE},
2455             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2456         }
2457     },
2458     {   "http://gov.uk/test/../test2/././../test3/.././././", 0, S_OK, FALSE,
2459         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
2460         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2461         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
2462         TRUE,
2463         {
2464             {"http://gov.uk/",S_OK,TRUE},
2465             {"gov.uk",S_OK,FALSE},
2466             {"http://gov.uk/",S_OK,TRUE},
2467             {"",S_FALSE,FALSE},
2468             {"",S_FALSE,FALSE},
2469             {"",S_FALSE,TRUE},
2470             {"gov.uk",S_OK,FALSE},
2471             {"",S_FALSE,FALSE},
2472             {"/",S_OK,FALSE},
2473             {"/",S_OK,FALSE},
2474             {"",S_FALSE,FALSE},
2475             {"http://gov.uk/test/../test2/././../test3/.././././",S_OK,FALSE},
2476             {"http",S_OK,FALSE},
2477             {"",S_FALSE,FALSE},
2478             {"",S_FALSE,FALSE}
2479         },
2480         {
2481             {Uri_HOST_DNS,S_OK,FALSE},
2482             {80,S_OK,FALSE},
2483             {URL_SCHEME_HTTP,S_OK,FALSE},
2484             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2485         }
2486     },
2487     {   "http://gov.uk/test/test2/../../..", 0, S_OK, FALSE,
2488         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
2489         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2490         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
2491         TRUE,
2492         {
2493             {"http://gov.uk/",S_OK,TRUE},
2494             {"gov.uk",S_OK,FALSE},
2495             {"http://gov.uk/",S_OK,TRUE},
2496             {"",S_FALSE,FALSE},
2497             {"",S_FALSE,FALSE},
2498             {"",S_FALSE,TRUE},
2499             {"gov.uk",S_OK,FALSE},
2500             {"",S_FALSE,FALSE},
2501             {"/",S_OK,FALSE},
2502             {"/",S_OK,FALSE},
2503             {"",S_FALSE,FALSE},
2504             {"http://gov.uk/test/test2/../../..",S_OK,FALSE},
2505             {"http",S_OK,FALSE},
2506             {"",S_FALSE,FALSE},
2507             {"",S_FALSE,FALSE}
2508         },
2509         {
2510             {Uri_HOST_DNS,S_OK,FALSE},
2511             {80,S_OK,FALSE},
2512             {URL_SCHEME_HTTP,S_OK,FALSE},
2513             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2514         }
2515     },
2516     {   "http://gov.uk/test/test2/../../.", 0, S_OK, FALSE,
2517         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
2518         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2519         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
2520         TRUE,
2521         {
2522             {"http://gov.uk/",S_OK,TRUE},
2523             {"gov.uk",S_OK,FALSE},
2524             {"http://gov.uk/",S_OK,TRUE},
2525             {"",S_FALSE,FALSE},
2526             {"",S_FALSE,FALSE},
2527             {"",S_FALSE,TRUE},
2528             {"gov.uk",S_OK,FALSE},
2529             {"",S_FALSE,FALSE},
2530             {"/",S_OK,FALSE},
2531             {"/",S_OK,FALSE},
2532             {"",S_FALSE,FALSE},
2533             {"http://gov.uk/test/test2/../../.",S_OK,FALSE},
2534             {"http",S_OK,FALSE},
2535             {"",S_FALSE,FALSE},
2536             {"",S_FALSE,FALSE}
2537         },
2538         {
2539             {Uri_HOST_DNS,S_OK,FALSE},
2540             {80,S_OK,FALSE},
2541             {URL_SCHEME_HTTP,S_OK,FALSE},
2542             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2543         }
2544     },
2545     {   "file://c:\\tests\\../tests\\./.\\..\\foo%20bar.mp3", 0, S_OK, FALSE,
2546         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
2547         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2548         TRUE,
2549         {
2550             {"file:///c:/foo%2520bar.mp3",S_OK,TRUE},
2551             {"",S_FALSE,FALSE},
2552             {"file:///c:/foo%2520bar.mp3",S_OK,TRUE},
2553             {"",S_FALSE,FALSE},
2554             {".mp3",S_OK,FALSE},
2555             {"",S_FALSE,TRUE},
2556             {"",S_FALSE,FALSE},
2557             {"",S_FALSE,FALSE},
2558             {"/c:/foo%2520bar.mp3",S_OK,FALSE},
2559             {"/c:/foo%2520bar.mp3",S_OK,FALSE},
2560             {"",S_FALSE,FALSE},
2561             {"file://c:\\tests\\../tests\\./.\\..\\foo%20bar.mp3",S_OK,FALSE},
2562             {"file",S_OK,FALSE},
2563             {"",S_FALSE,FALSE},
2564             {"",S_FALSE,FALSE}
2565         },
2566         {
2567             {Uri_HOST_UNKNOWN,S_OK,FALSE},
2568             {0,S_FALSE,FALSE},
2569             {URL_SCHEME_FILE,S_OK,FALSE},
2570             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2571         }
2572     },
2573     /* Dot removal happens for unknown scheme types. */
2574     {   "zip://gov.uk/test/test2/../../.", 0, S_OK, FALSE,
2575         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
2576         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2577         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2578         TRUE,
2579         {
2580             {"zip://gov.uk/",S_OK,TRUE},
2581             {"gov.uk",S_OK,FALSE},
2582             {"zip://gov.uk/",S_OK,TRUE},
2583             {"",S_FALSE,FALSE},
2584             {"",S_FALSE,FALSE},
2585             {"",S_FALSE,TRUE},
2586             {"gov.uk",S_OK,FALSE},
2587             {"",S_FALSE,FALSE},
2588             {"/",S_OK,FALSE},
2589             {"/",S_OK,FALSE},
2590             {"",S_FALSE,FALSE},
2591             {"zip://gov.uk/test/test2/../../.",S_OK,FALSE},
2592             {"zip",S_OK,FALSE},
2593             {"",S_FALSE,FALSE},
2594             {"",S_FALSE,FALSE}
2595         },
2596         {
2597             {Uri_HOST_DNS,S_OK,FALSE},
2598             {0,S_FALSE,FALSE},
2599             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
2600             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2601         }
2602     },
2603     /* Dot removal doesn't happen if NO_CANONICALIZE is set. */
2604     {   "http://gov.uk/test/test2/../../.", Uri_CREATE_NO_CANONICALIZE, S_OK, FALSE,
2605         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|
2606         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2607         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
2608         TRUE,
2609         {
2610             {"http://gov.uk/test/test2/../../.",S_OK,TRUE},
2611             {"gov.uk",S_OK,FALSE},
2612             {"http://gov.uk/test/test2/../../.",S_OK,TRUE},
2613             {"",S_FALSE,FALSE},
2614             {".",S_OK,FALSE},
2615             {"",S_FALSE,TRUE},
2616             {"gov.uk",S_OK,FALSE},
2617             {"",S_FALSE,FALSE},
2618             {"/test/test2/../../.",S_OK,FALSE},
2619             {"/test/test2/../../.",S_OK,FALSE},
2620             {"",S_FALSE,FALSE},
2621             {"http://gov.uk/test/test2/../../.",S_OK,FALSE},
2622             {"http",S_OK,FALSE},
2623             {"",S_FALSE,FALSE},
2624             {"",S_FALSE,FALSE}
2625         },
2626         {
2627             {Uri_HOST_DNS,S_OK,FALSE},
2628             {80,S_OK,FALSE},
2629             {URL_SCHEME_HTTP,S_OK,FALSE},
2630             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2631         }
2632     },
2633     /* Dot removal doesn't happen for wildcard scheme types. */
2634     {   "*:gov.uk/test/test2/../../.", 0, S_OK, FALSE,
2635         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|
2636         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
2637         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2638         TRUE,
2639         {
2640             {"*:gov.uk/test/test2/../../.",S_OK,TRUE},
2641             {"gov.uk",S_OK,FALSE},
2642             {"*:gov.uk/test/test2/../../.",S_OK,TRUE},
2643             {"",S_FALSE,FALSE},
2644             {".",S_OK,FALSE},
2645             {"",S_FALSE,TRUE},
2646             {"gov.uk",S_OK,FALSE},
2647             {"",S_FALSE,FALSE},
2648             {"/test/test2/../../.",S_OK,FALSE},
2649             {"/test/test2/../../.",S_OK,FALSE},
2650             {"",S_FALSE,FALSE},
2651             {"*:gov.uk/test/test2/../../.",S_OK,FALSE},
2652             {"*",S_OK,FALSE},
2653             {"",S_FALSE,FALSE},
2654             {"",S_FALSE,FALSE}
2655         },
2656         {
2657             {Uri_HOST_DNS,S_OK,FALSE},
2658             {0,S_FALSE,FALSE},
2659             {URL_SCHEME_WILDCARD,S_OK,FALSE},
2660             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2661         }
2662     },
2663     /* Forbidden characters are encoded for opaque known scheme types. */
2664     {   "mailto:\"acco<|>unt@example.com\"", 0, S_OK, FALSE,
2665         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|
2666         Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2667         TRUE,
2668         {
2669             {"mailto:%22acco%3C%7C%3Eunt@example.com%22",S_OK,TRUE},
2670             {"",S_FALSE,FALSE},
2671             {"mailto:%22acco%3C%7C%3Eunt@example.com%22",S_OK,TRUE},
2672             {"",S_FALSE,FALSE},
2673             {".com%22",S_OK,FALSE},
2674             {"",S_FALSE,TRUE},
2675             {"",S_FALSE,FALSE},
2676             {"",S_FALSE,FALSE},
2677             {"%22acco%3C%7C%3Eunt@example.com%22",S_OK,FALSE},
2678             {"%22acco%3C%7C%3Eunt@example.com%22",S_OK,FALSE},
2679             {"",S_FALSE,FALSE},
2680             {"mailto:\"acco<|>unt@example.com\"",S_OK,FALSE},
2681             {"mailto",S_OK,FALSE},
2682             {"",S_FALSE,FALSE},
2683             {"",S_FALSE,FALSE}
2684         },
2685         {
2686             {Uri_HOST_UNKNOWN,S_OK,FALSE},
2687             {0,S_FALSE,FALSE},
2688             {URL_SCHEME_MAILTO,S_OK,FALSE},
2689             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2690         }
2691     },
2692     {   "news:test.tes<|>t.com", 0, S_OK, FALSE,
2693         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|
2694         Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2695         TRUE,
2696         {
2697             {"news:test.tes%3C%7C%3Et.com",S_OK,TRUE},
2698             {"",S_FALSE,FALSE},
2699             {"news:test.tes%3C%7C%3Et.com",S_OK,TRUE},
2700             {"",S_FALSE,FALSE},
2701             {".com",S_OK,FALSE},
2702             {"",S_FALSE,TRUE},
2703             {"",S_FALSE,FALSE},
2704             {"",S_FALSE,FALSE},
2705             {"test.tes%3C%7C%3Et.com",S_OK,FALSE},
2706             {"test.tes%3C%7C%3Et.com",S_OK,FALSE},
2707             {"",S_FALSE,FALSE},
2708             {"news:test.tes<|>t.com",S_OK,FALSE},
2709             {"news",S_OK,FALSE},
2710             {"",S_FALSE,FALSE},
2711             {"",S_FALSE,FALSE}
2712         },
2713         {
2714             {Uri_HOST_UNKNOWN,S_OK,FALSE},
2715             {0,S_FALSE,FALSE},
2716             {URL_SCHEME_NEWS,S_OK,FALSE},
2717             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2718         }
2719     },
2720     /* Don't encode forbidden characters. */
2721     {   "news:test.tes<|>t.com", Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS, S_OK, FALSE,
2722         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|
2723         Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2724         TRUE,
2725         {
2726             {"news:test.tes<|>t.com",S_OK,TRUE},
2727             {"",S_FALSE,FALSE},
2728             {"news:test.tes<|>t.com",S_OK,TRUE},
2729             {"",S_FALSE,FALSE},
2730             {".com",S_OK,FALSE},
2731             {"",S_FALSE,TRUE},
2732             {"",S_FALSE,FALSE},
2733             {"",S_FALSE,FALSE},
2734             {"test.tes<|>t.com",S_OK,FALSE},
2735             {"test.tes<|>t.com",S_OK,FALSE},
2736             {"",S_FALSE,FALSE},
2737             {"news:test.tes<|>t.com",S_OK,FALSE},
2738             {"news",S_OK,FALSE},
2739             {"",S_FALSE,FALSE},
2740             {"",S_FALSE,FALSE}
2741         },
2742         {
2743             {Uri_HOST_UNKNOWN,S_OK,FALSE},
2744             {0,S_FALSE,FALSE},
2745             {URL_SCHEME_NEWS,S_OK,FALSE},
2746             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2747         }
2748     },
2749     /* Forbidden characters aren't encoded for unknown, opaque URIs. */
2750     {   "urn:test.tes<|>t.com", 0, S_OK, FALSE,
2751         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|
2752         Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2753         TRUE,
2754         {
2755             {"urn:test.tes<|>t.com",S_OK,TRUE},
2756             {"",S_FALSE,FALSE},
2757             {"urn:test.tes<|>t.com",S_OK,TRUE},
2758             {"",S_FALSE,FALSE},
2759             {".com",S_OK,FALSE},
2760             {"",S_FALSE,TRUE},
2761             {"",S_FALSE,FALSE},
2762             {"",S_FALSE,FALSE},
2763             {"test.tes<|>t.com",S_OK,FALSE},
2764             {"test.tes<|>t.com",S_OK,FALSE},
2765             {"",S_FALSE,FALSE},
2766             {"urn:test.tes<|>t.com",S_OK,FALSE},
2767             {"urn",S_OK,FALSE},
2768             {"",S_FALSE,FALSE},
2769             {"",S_FALSE,FALSE}
2770         },
2771         {
2772             {Uri_HOST_UNKNOWN,S_OK,FALSE},
2773             {0,S_FALSE,FALSE},
2774             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
2775             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2776         }
2777     },
2778     /* Percent encoded unreserved characters are decoded for known opaque URIs. */
2779     {   "news:test.%74%65%73%74.com", 0, S_OK, FALSE,
2780         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|
2781         Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2782         TRUE,
2783         {
2784             {"news:test.test.com",S_OK,TRUE},
2785             {"",S_FALSE,FALSE},
2786             {"news:test.test.com",S_OK,TRUE},
2787             {"",S_FALSE,FALSE},
2788             {".com",S_OK,FALSE},
2789             {"",S_FALSE,TRUE},
2790             {"",S_FALSE,FALSE},
2791             {"",S_FALSE,FALSE},
2792             {"test.test.com",S_OK,FALSE},
2793             {"test.test.com",S_OK,FALSE},
2794             {"",S_FALSE,FALSE},
2795             {"news:test.%74%65%73%74.com",S_OK,FALSE},
2796             {"news",S_OK,FALSE},
2797             {"",S_FALSE,FALSE},
2798             {"",S_FALSE,FALSE}
2799         },
2800         {
2801             {Uri_HOST_UNKNOWN,S_OK,FALSE},
2802             {0,S_FALSE,FALSE},
2803             {URL_SCHEME_NEWS,S_OK,FALSE},
2804             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2805         }
2806     },
2807     /* Percent encoded characters are still decoded for known scheme types. */
2808     {   "news:test.%74%65%73%74.com", Uri_CREATE_NO_CANONICALIZE, S_OK, FALSE,
2809         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|
2810         Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2811         TRUE,
2812         {
2813             {"news:test.test.com",S_OK,TRUE},
2814             {"",S_FALSE,FALSE},
2815             {"news:test.test.com",S_OK,TRUE},
2816             {"",S_FALSE,FALSE},
2817             {".com",S_OK,FALSE},
2818             {"",S_FALSE,TRUE},
2819             {"",S_FALSE,FALSE},
2820             {"",S_FALSE,FALSE},
2821             {"test.test.com",S_OK,FALSE},
2822             {"test.test.com",S_OK,FALSE},
2823             {"",S_FALSE,FALSE},
2824             {"news:test.%74%65%73%74.com",S_OK,FALSE},
2825             {"news",S_OK,FALSE},
2826             {"",S_FALSE,FALSE},
2827             {"",S_FALSE,FALSE}
2828         },
2829         {
2830             {Uri_HOST_UNKNOWN,S_OK,FALSE},
2831             {0,S_FALSE,FALSE},
2832             {URL_SCHEME_NEWS,S_OK,FALSE},
2833             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2834         }
2835     },
2836     /* Percent encoded characters aren't decoded for unknown scheme types. */
2837     {   "urn:test.%74%65%73%74.com", 0, S_OK, FALSE,
2838         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|
2839         Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2840         TRUE,
2841         {
2842             {"urn:test.%74%65%73%74.com",S_OK,TRUE},
2843             {"",S_FALSE,FALSE},
2844             {"urn:test.%74%65%73%74.com",S_OK,TRUE},
2845             {"",S_FALSE,FALSE},
2846             {".com",S_OK,FALSE},
2847             {"",S_FALSE,TRUE},
2848             {"",S_FALSE,FALSE},
2849             {"",S_FALSE,FALSE},
2850             {"test.%74%65%73%74.com",S_OK,FALSE},
2851             {"test.%74%65%73%74.com",S_OK,FALSE},
2852             {"",S_FALSE,FALSE},
2853             {"urn:test.%74%65%73%74.com",S_OK,FALSE},
2854             {"urn",S_OK,FALSE},
2855             {"",S_FALSE,FALSE},
2856             {"",S_FALSE,FALSE}
2857         },
2858         {
2859             {Uri_HOST_UNKNOWN,S_OK,FALSE},
2860             {0,S_FALSE,FALSE},
2861             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
2862             {URLZONE_INVALID,E_NOTIMPL,FALSE}
2863         }
2864     },
2865     /* Unknown scheme types can have invalid % encoded data in query string. */
2866     {   "zip://www.winehq.org/tests/..?query=%xx&return=y", 0, S_OK, FALSE,
2867         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
2868         Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
2869         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2870         TRUE,
2871         {
2872             {"zip://www.winehq.org/?query=%xx&return=y",S_OK,TRUE},
2873             {"www.winehq.org",S_OK,FALSE},
2874             {"zip://www.winehq.org/?query=%xx&return=y",S_OK,TRUE},
2875             {"winehq.org",S_OK,FALSE},
2876             {"",S_FALSE,FALSE},
2877             {"",S_FALSE,TRUE},
2878             {"www.winehq.org",S_OK,FALSE},
2879             {"",S_FALSE,FALSE},
2880             {"/",S_OK,FALSE},
2881             {"/?query=%xx&return=y",S_OK,FALSE},
2882             {"?query=%xx&return=y",S_OK,FALSE},
2883             {"zip://www.winehq.org/tests/..?query=%xx&return=y",S_OK,FALSE},
2884             {"zip",S_OK,FALSE},
2885             {"",S_FALSE,FALSE},
2886             {"",S_FALSE,FALSE}
2887         },
2888         {
2889             {Uri_HOST_DNS,S_OK,FALSE},
2890             {0,S_FALSE,FALSE},
2891             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
2892             {URLZONE_INVALID,E_NOTIMPL,FALSE},
2893         }
2894     },
2895     /* Known scheme types can have invalid % encoded data with the right flags. */
2896     {   "http://www.winehq.org/tests/..?query=%xx&return=y", Uri_CREATE_NO_DECODE_EXTRA_INFO, S_OK, FALSE,
2897         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
2898         Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_PORT|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
2899         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2900         TRUE,
2901         {
2902             {"http://www.winehq.org/?query=%xx&return=y",S_OK,TRUE},
2903             {"www.winehq.org",S_OK,FALSE},
2904             {"http://www.winehq.org/?query=%xx&return=y",S_OK,TRUE},
2905             {"winehq.org",S_OK,FALSE},
2906             {"",S_FALSE,FALSE},
2907             {"",S_FALSE,TRUE},
2908             {"www.winehq.org",S_OK,FALSE},
2909             {"",S_FALSE,FALSE},
2910             {"/",S_OK,FALSE},
2911             {"/?query=%xx&return=y",S_OK,FALSE},
2912             {"?query=%xx&return=y",S_OK,FALSE},
2913             {"http://www.winehq.org/tests/..?query=%xx&return=y",S_OK,FALSE},
2914             {"http",S_OK,FALSE},
2915             {"",S_FALSE,FALSE},
2916             {"",S_FALSE,FALSE}
2917         },
2918         {
2919             {Uri_HOST_DNS,S_OK,FALSE},
2920             {80,S_OK,FALSE},
2921             {URL_SCHEME_HTTP,S_OK,FALSE},
2922             {URLZONE_INVALID,E_NOTIMPL,FALSE},
2923         }
2924     },
2925     /* Forbidden characters in query aren't percent encoded for known scheme types with this flag. */
2926     {   "http://www.winehq.org/tests/..?query=<|>&return=y", Uri_CREATE_NO_DECODE_EXTRA_INFO, S_OK, FALSE,
2927         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
2928         Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_PORT|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
2929         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2930         TRUE,
2931         {
2932             {"http://www.winehq.org/?query=<|>&return=y",S_OK,TRUE},
2933             {"www.winehq.org",S_OK,FALSE},
2934             {"http://www.winehq.org/?query=<|>&return=y",S_OK,TRUE},
2935             {"winehq.org",S_OK,FALSE},
2936             {"",S_FALSE,FALSE},
2937             {"",S_FALSE,TRUE},
2938             {"www.winehq.org",S_OK,FALSE},
2939             {"",S_FALSE,FALSE},
2940             {"/",S_OK,FALSE},
2941             {"/?query=<|>&return=y",S_OK,FALSE},
2942             {"?query=<|>&return=y",S_OK,FALSE},
2943             {"http://www.winehq.org/tests/..?query=<|>&return=y",S_OK,FALSE},
2944             {"http",S_OK,FALSE},
2945             {"",S_FALSE,FALSE},
2946             {"",S_FALSE,FALSE}
2947         },
2948         {
2949             {Uri_HOST_DNS,S_OK,FALSE},
2950             {80,S_OK,FALSE},
2951             {URL_SCHEME_HTTP,S_OK,FALSE},
2952             {URLZONE_INVALID,E_NOTIMPL,FALSE},
2953         }
2954     },
2955     /* Forbidden characters in query aren't percent encoded for known scheme types with this flag. */
2956     {   "http://www.winehq.org/tests/..?query=<|>&return=y", Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS, S_OK, FALSE,
2957         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
2958         Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_PORT|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
2959         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2960         TRUE,
2961         {
2962             {"http://www.winehq.org/?query=<|>&return=y",S_OK,TRUE},
2963             {"www.winehq.org",S_OK,FALSE},
2964             {"http://www.winehq.org/?query=<|>&return=y",S_OK,TRUE},
2965             {"winehq.org",S_OK,FALSE},
2966             {"",S_FALSE,FALSE},
2967             {"",S_FALSE,TRUE},
2968             {"www.winehq.org",S_OK,FALSE},
2969             {"",S_FALSE,FALSE},
2970             {"/",S_OK,FALSE},
2971             {"/?query=<|>&return=y",S_OK,FALSE},
2972             {"?query=<|>&return=y",S_OK,FALSE},
2973             {"http://www.winehq.org/tests/..?query=<|>&return=y",S_OK,FALSE},
2974             {"http",S_OK,FALSE},
2975             {"",S_FALSE,FALSE},
2976             {"",S_FALSE,FALSE}
2977         },
2978         {
2979             {Uri_HOST_DNS,S_OK,FALSE},
2980             {80,S_OK,FALSE},
2981             {URL_SCHEME_HTTP,S_OK,FALSE},
2982             {URLZONE_INVALID,E_NOTIMPL,FALSE},
2983         }
2984     },
2985     /* Forbidden characters are encoded for known scheme types. */
2986     {   "http://www.winehq.org/tests/..?query=<|>&return=y", 0, S_OK, FALSE,
2987         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
2988         Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_PORT|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
2989         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
2990         TRUE,
2991         {
2992             {"http://www.winehq.org/?query=%3C%7C%3E&return=y",S_OK,TRUE},
2993             {"www.winehq.org",S_OK,FALSE},
2994             {"http://www.winehq.org/?query=%3C%7C%3E&return=y",S_OK,TRUE},
2995             {"winehq.org",S_OK,FALSE},
2996             {"",S_FALSE,FALSE},
2997             {"",S_FALSE,TRUE},
2998             {"www.winehq.org",S_OK,FALSE},
2999             {"",S_FALSE,FALSE},
3000             {"/",S_OK,FALSE},
3001             {"/?query=%3C%7C%3E&return=y",S_OK,FALSE},
3002             {"?query=%3C%7C%3E&return=y",S_OK,FALSE},
3003             {"http://www.winehq.org/tests/..?query=<|>&return=y",S_OK,FALSE},
3004             {"http",S_OK,FALSE},
3005             {"",S_FALSE,FALSE},
3006             {"",S_FALSE,FALSE}
3007         },
3008         {
3009             {Uri_HOST_DNS,S_OK,FALSE},
3010             {80,S_OK,FALSE},
3011             {URL_SCHEME_HTTP,S_OK,FALSE},
3012             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3013         }
3014     },
3015     /* Forbidden characters are not encoded for unknown scheme types. */
3016     {   "zip://www.winehq.org/tests/..?query=<|>&return=y", 0, S_OK, FALSE,
3017         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
3018         Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
3019         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
3020         TRUE,
3021         {
3022             {"zip://www.winehq.org/?query=<|>&return=y",S_OK,TRUE},
3023             {"www.winehq.org",S_OK,FALSE},
3024             {"zip://www.winehq.org/?query=<|>&return=y",S_OK,TRUE},
3025             {"winehq.org",S_OK,FALSE},
3026             {"",S_FALSE,FALSE},
3027             {"",S_FALSE,TRUE},
3028             {"www.winehq.org",S_OK,FALSE},
3029             {"",S_FALSE,FALSE},
3030             {"/",S_OK,FALSE},
3031             {"/?query=<|>&return=y",S_OK,FALSE},
3032             {"?query=<|>&return=y",S_OK,FALSE},
3033             {"zip://www.winehq.org/tests/..?query=<|>&return=y",S_OK,FALSE},
3034             {"zip",S_OK,FALSE},
3035             {"",S_FALSE,FALSE},
3036             {"",S_FALSE,FALSE}
3037         },
3038         {
3039             {Uri_HOST_DNS,S_OK,FALSE},
3040             {0,S_FALSE,FALSE},
3041             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
3042             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3043         }
3044     },
3045     /* Percent encoded, unreserved characters are decoded for known scheme types. */
3046     {   "http://www.winehq.org/tests/..?query=%30%31&return=y", 0, S_OK, FALSE,
3047         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
3048         Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_PORT|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
3049         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
3050         TRUE,
3051         {
3052             {"http://www.winehq.org/?query=01&return=y",S_OK,TRUE},
3053             {"www.winehq.org",S_OK,FALSE},
3054             {"http://www.winehq.org/?query=01&return=y",S_OK,TRUE},
3055             {"winehq.org",S_OK,FALSE},
3056             {"",S_FALSE,FALSE},
3057             {"",S_FALSE,TRUE},
3058             {"www.winehq.org",S_OK,FALSE},
3059             {"",S_FALSE,FALSE},
3060             {"/",S_OK,FALSE},
3061             {"/?query=01&return=y",S_OK,FALSE},
3062             {"?query=01&return=y",S_OK,FALSE},
3063             {"http://www.winehq.org/tests/..?query=%30%31&return=y",S_OK,FALSE},
3064             {"http",S_OK,FALSE},
3065             {"",S_FALSE,FALSE},
3066             {"",S_FALSE,FALSE}
3067         },
3068         {
3069             {Uri_HOST_DNS,S_OK,FALSE},
3070             {80,S_OK,FALSE},
3071             {URL_SCHEME_HTTP,S_OK,FALSE},
3072             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3073         }
3074     },
3075     /* Percent encoded, unreserved characters aren't decoded for unknown scheme types. */
3076     {   "zip://www.winehq.org/tests/..?query=%30%31&return=y", 0, S_OK, FALSE,
3077         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
3078         Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
3079         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
3080         TRUE,
3081         {
3082             {"zip://www.winehq.org/?query=%30%31&return=y",S_OK,TRUE},
3083             {"www.winehq.org",S_OK,FALSE},
3084             {"zip://www.winehq.org/?query=%30%31&return=y",S_OK,TRUE},
3085             {"winehq.org",S_OK,FALSE},
3086             {"",S_FALSE,FALSE},
3087             {"",S_FALSE,TRUE},
3088             {"www.winehq.org",S_OK,FALSE},
3089             {"",S_FALSE,FALSE},
3090             {"/",S_OK,FALSE},
3091             {"/?query=%30%31&return=y",S_OK,FALSE},
3092             {"?query=%30%31&return=y",S_OK,FALSE},
3093             {"zip://www.winehq.org/tests/..?query=%30%31&return=y",S_OK,FALSE},
3094             {"zip",S_OK,FALSE},
3095             {"",S_FALSE,FALSE},
3096             {"",S_FALSE,FALSE}
3097         },
3098         {
3099             {Uri_HOST_DNS,S_OK,FALSE},
3100             {0,S_FALSE,FALSE},
3101             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
3102             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3103         }
3104     },
3105     /* Percent encoded characters aren't decoded when NO_DECODE_EXTRA_INFO is set. */
3106     {   "http://www.winehq.org/tests/..?query=%30%31&return=y", Uri_CREATE_NO_DECODE_EXTRA_INFO, S_OK, FALSE,
3107         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
3108         Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_PORT|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
3109         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
3110         TRUE,
3111         {
3112             {"http://www.winehq.org/?query=%30%31&return=y",S_OK,TRUE},
3113             {"www.winehq.org",S_OK,FALSE},
3114             {"http://www.winehq.org/?query=%30%31&return=y",S_OK,TRUE},
3115             {"winehq.org",S_OK,FALSE},
3116             {"",S_FALSE,FALSE},
3117             {"",S_FALSE,TRUE},
3118             {"www.winehq.org",S_OK,FALSE},
3119             {"",S_FALSE,FALSE},
3120             {"/",S_OK,FALSE},
3121             {"/?query=%30%31&return=y",S_OK,FALSE},
3122             {"?query=%30%31&return=y",S_OK,FALSE},
3123             {"http://www.winehq.org/tests/..?query=%30%31&return=y",S_OK,FALSE},
3124             {"http",S_OK,FALSE},
3125             {"",S_FALSE,FALSE},
3126             {"",S_FALSE,FALSE}
3127         },
3128         {
3129             {Uri_HOST_DNS,S_OK,FALSE},
3130             {80,S_OK,FALSE},
3131             {URL_SCHEME_HTTP,S_OK,FALSE},
3132             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3133         }
3134     },
3135     {   "http://www.winehq.org?query=12&return=y", Uri_CREATE_NO_CANONICALIZE, S_OK, FALSE,
3136         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
3137         Uri_HAS_DOMAIN|Uri_HAS_PATH_AND_QUERY|Uri_HAS_PORT|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
3138         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
3139         TRUE,
3140         {
3141             {"http://www.winehq.org?query=12&return=y",S_OK,TRUE},
3142             {"www.winehq.org",S_OK,FALSE},
3143             {"http://www.winehq.org?query=12&return=y",S_OK,TRUE},
3144             {"winehq.org",S_OK,FALSE},
3145             {"",S_FALSE,FALSE},
3146             {"",S_FALSE,TRUE},
3147             {"www.winehq.org",S_OK,FALSE},
3148             {"",S_FALSE,FALSE},
3149             {"",S_FALSE,FALSE},
3150             {"?query=12&return=y",S_OK,FALSE},
3151             {"?query=12&return=y",S_OK,FALSE},
3152             {"http://www.winehq.org?query=12&return=y",S_OK,FALSE},
3153             {"http",S_OK,FALSE},
3154             {"",S_FALSE,FALSE},
3155             {"",S_FALSE,FALSE}
3156         },
3157         {
3158             {Uri_HOST_DNS,S_OK,FALSE},
3159             {80,S_OK,FALSE},
3160             {URL_SCHEME_HTTP,S_OK,FALSE},
3161             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3162         }
3163     },
3164     /* Unknown scheme types can have invalid % encoded data in fragments. */
3165     {   "zip://www.winehq.org/tests/#Te%xx", 0, S_OK, FALSE,
3166         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
3167         Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
3168         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
3169         TRUE,
3170         {
3171             {"zip://www.winehq.org/tests/#Te%xx",S_OK,TRUE},
3172             {"www.winehq.org",S_OK,FALSE},
3173             {"zip://www.winehq.org/tests/#Te%xx",S_OK,TRUE},
3174             {"winehq.org",S_OK,FALSE},
3175             {"",S_FALSE,FALSE},
3176             {"#Te%xx",S_OK,TRUE},
3177             {"www.winehq.org",S_OK,FALSE},
3178             {"",S_FALSE,FALSE},
3179             {"/tests/",S_OK,FALSE},
3180             {"/tests/",S_OK,FALSE},
3181             {"",S_FALSE,FALSE},
3182             {"zip://www.winehq.org/tests/#Te%xx",S_OK,FALSE},
3183             {"zip",S_OK,FALSE},
3184             {"",S_FALSE,FALSE},
3185             {"",S_FALSE,FALSE}
3186         },
3187         {
3188             {Uri_HOST_DNS,S_OK,FALSE},
3189             {0,S_FALSE,FALSE},
3190             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
3191             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3192         }
3193     }
3194 };
3195
3196 typedef struct _invalid_uri {
3197     const char* uri;
3198     DWORD       flags;
3199     BOOL        todo;
3200 } invalid_uri;
3201
3202 static const invalid_uri invalid_uri_tests[] = {
3203     /* Has to have a scheme name. */
3204     {"://www.winehq.org",0,FALSE},
3205     /* Window's doesn't like URI's which are implicitly file paths without the
3206      * ALLOW_IMPLICIT_FILE_SCHEME flag set.
3207      */
3208     {"C:/test/test.mp3",0,FALSE},
3209     {"\\\\Server/test/test.mp3",0,FALSE},
3210     {"C:/test/test.mp3",Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME,FALSE},
3211     {"\\\\Server/test/test.mp3",Uri_CREATE_ALLOW_RELATIVE,FALSE},
3212     /* Invalid schemes. */
3213     {"*abcd://not.valid.com",0,FALSE},
3214     {"*a*b*c*d://not.valid.com",0,FALSE},
3215     /* Not allowed to have invalid % encoded data. */
3216     {"ftp://google.co%XX/",0,FALSE},
3217     /* To many h16 components. */
3218     {"http://[1:2:3:4:5:6:7:8:9]",0,FALSE},
3219     /* Not enough room for IPv4 address. */
3220     {"http://[1:2:3:4:5:6:7:192.0.1.0]",0,FALSE},
3221     /* Not enough h16 components. */
3222     {"http://[1:2:3:4]",0,FALSE},
3223     /* Not enough components including IPv4. */
3224     {"http://[1:192.0.1.0]",0,FALSE},
3225     /* Not allowed to have partial IPv4 in IPv6. */
3226     {"http://[::192.0]",0,FALSE},
3227     /* Can't have elision of 1 h16 at beginning of address. */
3228     {"http://[::2:3:4:5:6:7:8]",0,FALSE},
3229     /* Can't have elision of 1 h16 at end of address. */
3230     {"http://[1:2:3:4:5:6:7::]",0,FALSE},
3231     /* Expects a valid IP Literal. */
3232     {"ftp://[not.valid.uri]/",0,FALSE},
3233     /* Expects valid port for a known scheme type. */
3234     {"ftp://www.winehq.org:123fgh",0,FALSE},
3235     /* Port exceeds USHORT_MAX for known scheme type. */
3236     {"ftp://www.winehq.org:65536",0,FALSE},
3237     /* Invalid port with IPv4 address. */
3238     {"http://www.winehq.org:1abcd",0,FALSE},
3239     /* Invalid port with IPv6 address. */
3240     {"http://[::ffff]:32xy",0,FALSE},
3241     /* Not allowed to have backslashes with NO_CANONICALIZE. */
3242     {"gopher://www.google.com\\test",Uri_CREATE_NO_CANONICALIZE,FALSE},
3243     /* Not allowed to have invalid % encoded data in opaque URI path. */
3244     {"news:test%XX",0,FALSE},
3245     {"mailto:wine@winehq%G8.com",0,FALSE},
3246     /* Known scheme types can't have invalid % encoded data in query string. */
3247     {"http://google.com/?query=te%xx",0,FALSE},
3248     /* Invalid % encoded data in fragment of know scheme type. */
3249     {"ftp://google.com/#Test%xx",0,FALSE}
3250 };
3251
3252 typedef struct _uri_equality {
3253     const char* a;
3254     DWORD       create_flags_a;
3255     BOOL        create_todo_a;
3256     const char* b;
3257     DWORD       create_flags_b;
3258     BOOL        create_todo_b;
3259     BOOL        equal;
3260     BOOL        todo;
3261 } uri_equality;
3262
3263 static const uri_equality equality_tests[] = {
3264     {
3265         "HTTP://www.winehq.org/test dir/./",0,FALSE,
3266         "http://www.winehq.org/test dir/../test dir/",0,FALSE,
3267         TRUE, TRUE
3268     },
3269     {
3270         /* http://www.winehq.org/test%20dir */
3271         "http://%77%77%77%2E%77%69%6E%65%68%71%2E%6F%72%67/%74%65%73%74%20%64%69%72",0,FALSE,
3272         "http://www.winehq.org/test dir",0,FALSE,
3273         TRUE, TRUE,
3274     },
3275     {
3276         "c:\\test.mp3",Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME,FALSE,
3277         "file:///c:/test.mp3",0,FALSE,
3278         TRUE,TRUE
3279     },
3280     {
3281         "ftp://ftp.winehq.org/",0,FALSE,
3282         "ftp://ftp.winehq.org",0,FALSE,
3283         TRUE, TRUE
3284     },
3285     {
3286         "ftp://ftp.winehq.org/test/test2/../../testB/",0,FALSE,
3287         "ftp://ftp.winehq.org/t%45stB/",0,FALSE,
3288         FALSE, TRUE
3289     }
3290 };
3291
3292 static inline LPWSTR a2w(LPCSTR str) {
3293     LPWSTR ret = NULL;
3294
3295     if(str) {
3296         DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
3297         ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
3298         MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
3299     }
3300
3301     return ret;
3302 }
3303
3304 static inline BOOL heap_free(void* mem) {
3305     return HeapFree(GetProcessHeap(), 0, mem);
3306 }
3307
3308 static inline DWORD strcmp_aw(LPCSTR strA, LPCWSTR strB) {
3309     LPWSTR strAW = a2w(strA);
3310     DWORD ret = lstrcmpW(strAW, strB);
3311     heap_free(strAW);
3312     return ret;
3313 }
3314
3315 /*
3316  * Simple tests to make sure the CreateUri function handles invalid flag combinations
3317  * correctly.
3318  */
3319 static void test_CreateUri_InvalidFlags(void) {
3320     DWORD i;
3321
3322     for(i = 0; i < sizeof(invalid_flag_tests)/sizeof(invalid_flag_tests[0]); ++i) {
3323         HRESULT hr;
3324         IUri *uri = (void*) 0xdeadbeef;
3325
3326         hr = pCreateUri(http_urlW, invalid_flag_tests[i].flags, 0, &uri);
3327         todo_wine {
3328             ok(hr == invalid_flag_tests[i].expected, "Error: CreateUri returned 0x%08x, expected 0x%08x, flags=0x%08x\n",
3329                     hr, invalid_flag_tests[i].expected, invalid_flag_tests[i].flags);
3330         }
3331         todo_wine { ok(uri == NULL, "Error: expected the IUri to be NULL, but it was %p instead\n", uri); }
3332     }
3333 }
3334
3335 static void test_CreateUri_InvalidArgs(void) {
3336     HRESULT hr;
3337     IUri *uri = (void*) 0xdeadbeef;
3338
3339     const WCHAR invalidW[] = {'i','n','v','a','l','i','d',0};
3340
3341     hr = pCreateUri(http_urlW, 0, 0, NULL);
3342     ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x\n", hr, E_INVALIDARG);
3343
3344     hr = pCreateUri(NULL, 0, 0, &uri);
3345     ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x\n", hr, E_INVALIDARG);
3346     ok(uri == NULL, "Error: Expected the IUri to be NULL, but it was %p instead\n", uri);
3347
3348     uri = (void*) 0xdeadbeef;
3349     hr = pCreateUri(invalidW, 0, 0, &uri);
3350     ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
3351     ok(uri == NULL, "Error: Expected the IUri to be NULL, but it was %p instead\n", uri);
3352 }
3353
3354 static void test_CreateUri_InvalidUri(void) {
3355     DWORD i;
3356
3357     for(i = 0; i < sizeof(invalid_uri_tests)/sizeof(invalid_uri_tests[0]); ++i) {
3358         invalid_uri test = invalid_uri_tests[i];
3359         IUri *uri = NULL;
3360         LPWSTR uriW;
3361         HRESULT hr;
3362
3363         uriW = a2w(test.uri);
3364         hr = pCreateUri(uriW, test.flags, 0, &uri);
3365         if(test.todo) {
3366             todo_wine {
3367                 ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x on invalid_uri_tests[%d].\n",
3368                     hr, E_INVALIDARG, i);
3369             }
3370         } else {
3371             ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x on invalid_uri_tests[%d].\n",
3372                 hr, E_INVALIDARG, i);
3373         }
3374         if(uri) IUri_Release(uri);
3375
3376         heap_free(uriW);
3377     }
3378 }
3379
3380 static void test_IUri_GetPropertyBSTR(void) {
3381     IUri *uri = NULL;
3382     HRESULT hr;
3383     DWORD i;
3384
3385     /* Make sure GetPropertyBSTR handles invalid args correctly. */
3386     hr = pCreateUri(http_urlW, 0, 0, &uri);
3387     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
3388     if(SUCCEEDED(hr)) {
3389         BSTR received = NULL;
3390
3391         hr = IUri_GetPropertyBSTR(uri, Uri_PROPERTY_RAW_URI, NULL, 0);
3392         ok(hr == E_POINTER, "Error: GetPropertyBSTR returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3393
3394         /* Make sure it handles a invalid Uri_PROPERTY's correctly. */
3395         hr = IUri_GetPropertyBSTR(uri, Uri_PROPERTY_PORT, &received, 0);
3396         ok(hr == S_OK, "Error: GetPropertyBSTR returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
3397         ok(received != NULL, "Error: Expected the string not to be NULL.\n");
3398         ok(!SysStringLen(received), "Error: Expected the string to be of len=0 but it was %d instead.\n", SysStringLen(received));
3399         SysFreeString(received);
3400
3401         /* Make sure it handles the ZONE property correctly. */
3402         received = NULL;
3403         hr = IUri_GetPropertyBSTR(uri, Uri_PROPERTY_ZONE, &received, 0);
3404         ok(hr == S_FALSE, "Error: GetPropertyBSTR returned 0x%08x, expected 0x%08x.\n", hr, S_FALSE);
3405         ok(received != NULL, "Error: Expected the string not to be NULL.\n");
3406         ok(!SysStringLen(received), "Error: Expected the string to be of len=0 but it was %d instead.\n", SysStringLen(received));
3407         SysFreeString(received);
3408     }
3409     if(uri) IUri_Release(uri);
3410
3411     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
3412         uri_properties test = uri_tests[i];
3413         LPWSTR uriW;
3414         uri = NULL;
3415
3416         uriW = a2w(test.uri);
3417         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
3418         if(test.create_todo) {
3419             todo_wine {
3420                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
3421                         hr, test.create_expected, i);
3422             }
3423         } else {
3424             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
3425                     hr, test.create_expected, i);
3426         }
3427
3428         if(SUCCEEDED(hr)) {
3429             DWORD j;
3430
3431             /* Checks all the string properties of the uri. */
3432             for(j = Uri_PROPERTY_STRING_START; j <= Uri_PROPERTY_STRING_LAST; ++j) {
3433                 BSTR received = NULL;
3434                 uri_str_property prop = test.str_props[j];
3435
3436                 hr = IUri_GetPropertyBSTR(uri, j, &received, 0);
3437                 if(prop.todo) {
3438                     todo_wine {
3439                         ok(hr == prop.expected, "GetPropertyBSTR returned 0x%08x, expected 0x%08x. On uri_tests[%d].str_props[%d].\n",
3440                                 hr, prop.expected, i, j);
3441                     }
3442                     todo_wine {
3443                         ok(!strcmp_aw(prop.value, received) || broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
3444                                 "Expected %s but got %s on uri_tests[%d].str_props[%d].\n",
3445                                 prop.value, wine_dbgstr_w(received), i, j);
3446                     }
3447                     if (hr == E_NOTIMPL)  /* no point in continuing */
3448                     {
3449                         if(uri) IUri_Release(uri);
3450                         heap_free(uriW);
3451                         return;
3452                     }
3453                 } else {
3454                     ok(hr == prop.expected, "GetPropertyBSTR returned 0x%08x, expected 0x%08x. On uri_tests[%d].str_props[%d].\n",
3455                             hr, prop.expected, i, j);
3456                     ok(!strcmp_aw(prop.value, received) || broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
3457                             "Expected %s but got %s on uri_tests[%d].str_props[%d].\n",
3458                             prop.value, wine_dbgstr_w(received), i, j);
3459                 }
3460
3461                 SysFreeString(received);
3462             }
3463         }
3464
3465         if(uri) IUri_Release(uri);
3466
3467         heap_free(uriW);
3468     }
3469 }
3470
3471 static void test_IUri_GetPropertyDWORD(void) {
3472     IUri *uri = NULL;
3473     HRESULT hr;
3474     DWORD i;
3475
3476     hr = pCreateUri(http_urlW, 0, 0, &uri);
3477     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
3478     if(SUCCEEDED(hr)) {
3479         DWORD received = 0xdeadbeef;
3480
3481         hr = IUri_GetPropertyDWORD(uri, Uri_PROPERTY_DWORD_START, NULL, 0);
3482         ok(hr == E_INVALIDARG, "Error: GetPropertyDWORD returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
3483
3484         hr = IUri_GetPropertyDWORD(uri, Uri_PROPERTY_ABSOLUTE_URI, &received, 0);
3485         ok(hr == E_INVALIDARG, "Error: GetPropertyDWORD returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
3486         ok(received == 0, "Error: Expected received=%d but instead received=%d.\n", 0, received);
3487     }
3488     if(uri) IUri_Release(uri);
3489
3490     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
3491         uri_properties test = uri_tests[i];
3492         LPWSTR uriW;
3493         uri = NULL;
3494
3495         uriW = a2w(test.uri);
3496         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
3497         if(test.create_todo) {
3498             todo_wine {
3499                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
3500                         hr, test.create_expected, i);
3501             }
3502         } else {
3503             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
3504                     hr, test.create_expected, i);
3505         }
3506
3507         if(SUCCEEDED(hr)) {
3508             DWORD j;
3509
3510             /* Checks all the DWORD properties of the uri. */
3511             for(j = 0; j < sizeof(test.dword_props)/sizeof(test.dword_props[0]); ++j) {
3512                 DWORD received;
3513                 uri_dword_property prop = test.dword_props[j];
3514
3515                 hr = IUri_GetPropertyDWORD(uri, j+Uri_PROPERTY_DWORD_START, &received, 0);
3516                 if(prop.todo) {
3517                     todo_wine {
3518                         ok(hr == prop.expected, "GetPropertyDWORD returned 0x%08x, expected 0x%08x. On uri_tests[%d].dword_props[%d].\n",
3519                                 hr, prop.expected, i, j);
3520                     }
3521                     todo_wine {
3522                         ok(prop.value == received, "Expected %d but got %d on uri_tests[%d].dword_props[%d].\n",
3523                                 prop.value, received, i, j);
3524                     }
3525                 } else {
3526                     ok(hr == prop.expected, "GetPropertyDWORD returned 0x%08x, expected 0x%08x. On uri_tests[%d].dword_props[%d].\n",
3527                             hr, prop.expected, i, j);
3528                     ok(prop.value == received, "Expected %d but got %d on uri_tests[%d].dword_props[%d].\n",
3529                             prop.value, received, i, j);
3530                 }
3531             }
3532         }
3533
3534         if(uri) IUri_Release(uri);
3535
3536         heap_free(uriW);
3537     }
3538 }
3539
3540 /* Tests all the 'Get*' property functions which deal with strings. */
3541 static void test_IUri_GetStrProperties(void) {
3542     IUri *uri = NULL;
3543     HRESULT hr;
3544     DWORD i;
3545
3546     /* Make sure all the 'Get*' string property functions handle invalid args correctly. */
3547     hr = pCreateUri(http_urlW, 0, 0, &uri);
3548     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
3549     if(SUCCEEDED(hr)) {
3550         hr = IUri_GetAbsoluteUri(uri, NULL);
3551         ok(hr == E_POINTER, "Error: GetAbsoluteUri returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3552
3553         hr = IUri_GetAuthority(uri, NULL);
3554         ok(hr == E_POINTER, "Error: GetAuthority returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3555
3556         hr = IUri_GetDisplayUri(uri, NULL);
3557         ok(hr == E_POINTER, "Error: GetDisplayUri returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3558
3559         hr = IUri_GetDomain(uri, NULL);
3560         ok(hr == E_POINTER, "Error: GetDomain returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3561
3562         hr = IUri_GetExtension(uri, NULL);
3563         ok(hr == E_POINTER, "Error: GetExtension returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3564
3565         hr = IUri_GetFragment(uri, NULL);
3566         ok(hr == E_POINTER, "Error: GetFragment returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3567
3568         hr = IUri_GetHost(uri, NULL);
3569         ok(hr == E_POINTER, "Error: GetHost returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3570
3571         hr = IUri_GetPassword(uri, NULL);
3572         ok(hr == E_POINTER, "Error: GetPassword returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3573
3574         hr = IUri_GetPath(uri, NULL);
3575         ok(hr == E_POINTER, "Error: GetPath returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3576
3577         hr = IUri_GetPathAndQuery(uri, NULL);
3578         ok(hr == E_POINTER, "Error: GetPathAndQuery returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3579
3580         hr = IUri_GetQuery(uri, NULL);
3581         ok(hr == E_POINTER, "Error: GetQuery returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3582
3583         hr = IUri_GetRawUri(uri, NULL);
3584         ok(hr == E_POINTER, "Error: GetRawUri returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3585
3586         hr = IUri_GetSchemeName(uri, NULL);
3587         ok(hr == E_POINTER, "Error: GetSchemeName returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3588
3589         hr = IUri_GetUserInfo(uri, NULL);
3590         ok(hr == E_POINTER, "Error: GetUserInfo returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3591
3592         hr = IUri_GetUserName(uri, NULL);
3593         ok(hr == E_POINTER, "Error: GetUserName returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3594     }
3595     if(uri) IUri_Release(uri);
3596
3597     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
3598         uri_properties test = uri_tests[i];
3599         LPWSTR uriW;
3600         uri = NULL;
3601
3602         uriW = a2w(test.uri);
3603         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
3604         if(test.create_todo) {
3605             todo_wine {
3606                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3607                         hr, test.create_expected, i);
3608             }
3609         } else {
3610             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3611                     hr, test.create_expected, i);
3612         }
3613
3614         if(SUCCEEDED(hr)) {
3615             uri_str_property prop;
3616             BSTR received = NULL;
3617
3618             /* GetAbsoluteUri() tests. */
3619             prop = test.str_props[Uri_PROPERTY_ABSOLUTE_URI];
3620             hr = IUri_GetAbsoluteUri(uri, &received);
3621             if (hr == E_NOTIMPL) goto skip_unimplemented;
3622             if(prop.todo) {
3623                 todo_wine {
3624                     ok(hr == prop.expected, "Error: GetAbsoluteUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3625                             hr, prop.expected, i);
3626                 }
3627                 todo_wine {
3628                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3629                             prop.value, wine_dbgstr_w(received), i);
3630                 }
3631             } else {
3632                 ok(hr == prop.expected, "Error: GetAbsoluteUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3633                         hr, prop.expected, i);
3634                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3635                         prop.value, wine_dbgstr_w(received), i);
3636             }
3637             SysFreeString(received);
3638             received = NULL;
3639
3640             /* GetDisplayUri() tests. */
3641             prop = test.str_props[Uri_PROPERTY_DISPLAY_URI];
3642             hr = IUri_GetDisplayUri(uri, &received);
3643             if(prop.todo) {
3644                 todo_wine {
3645                     ok(hr == prop.expected, "Error: GetDisplayUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3646                             hr, prop.expected, i);
3647                 }
3648                 todo_wine {
3649                     ok(!strcmp_aw(prop.value, received) || broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
3650                             "Error: Expected %s but got %s on uri_test[%d].\n",
3651                             prop.value, wine_dbgstr_w(received), i);
3652                 }
3653             } else {
3654                 ok(hr == prop.expected, "Error: GetDisplayUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3655                         hr, prop.expected, i);
3656                 ok(!strcmp_aw(prop.value, received) || broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
3657                         "Error: Expected %s but got %s on uri_tests[%d].\n",
3658                         prop.value, wine_dbgstr_w(received), i);
3659             }
3660             SysFreeString(received);
3661             received = NULL;
3662
3663             /* GetFragment() tests. */
3664             prop = test.str_props[Uri_PROPERTY_FRAGMENT];
3665             hr = IUri_GetFragment(uri, &received);
3666             if(prop.todo) {
3667                 todo_wine {
3668                     ok(hr == prop.expected, "Error: GetFragment returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3669                             hr, prop.expected, i);
3670                 }
3671                 todo_wine {
3672                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3673                             prop.value, wine_dbgstr_w(received), i);
3674                 }
3675             } else {
3676                 ok(hr == prop.expected, "Error: GetFragment returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3677                         hr, prop.expected, i);
3678                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3679                         prop.value, wine_dbgstr_w(received), i);
3680             }
3681             SysFreeString(received);
3682             received = NULL;
3683
3684             /* GetPassword() tests. */
3685             prop = test.str_props[Uri_PROPERTY_PASSWORD];
3686             hr = IUri_GetPassword(uri, &received);
3687             if(prop.todo) {
3688                 todo_wine {
3689                     ok(hr == prop.expected, "Error: GetPassword returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3690                             hr, prop.expected, i);
3691                 }
3692                 todo_wine {
3693                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3694                             prop.value, wine_dbgstr_w(received), i);
3695                 }
3696             } else {
3697                 ok(hr == prop.expected, "Error: GetPassword returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3698                         hr, prop.expected, i);
3699                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3700                         prop.value, wine_dbgstr_w(received), i);
3701             }
3702             SysFreeString(received);
3703             received = NULL;
3704
3705         skip_unimplemented:
3706             /* GetAuthority() tests. */
3707             prop = test.str_props[Uri_PROPERTY_AUTHORITY];
3708             hr = IUri_GetAuthority(uri, &received);
3709             if(prop.todo) {
3710                 todo_wine {
3711                     ok(hr == prop.expected, "Error: GetAuthority returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3712                             hr, prop.expected, i);
3713                 }
3714                 todo_wine {
3715                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3716                             prop.value, wine_dbgstr_w(received), i);
3717                 }
3718             } else {
3719                 ok(hr == prop.expected, "Error: GetAuthority returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3720                         hr, prop.expected, i);
3721                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3722                         prop.value, wine_dbgstr_w(received), i);
3723             }
3724             SysFreeString(received);
3725             received = NULL;
3726
3727             /* GetDomain() tests. */
3728             prop = test.str_props[Uri_PROPERTY_DOMAIN];
3729             hr = IUri_GetDomain(uri, &received);
3730             if(prop.todo) {
3731                 todo_wine {
3732                     ok(hr == prop.expected, "Error: GetDomain returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3733                             hr, prop.expected, i);
3734                 }
3735                 todo_wine {
3736                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3737                             prop.value, wine_dbgstr_w(received), i);
3738                 }
3739             } else {
3740                 ok(hr == prop.expected, "Error: GetDomain returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3741                         hr, prop.expected, i);
3742                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3743                         prop.value, wine_dbgstr_w(received), i);
3744             }
3745             SysFreeString(received);
3746             received = NULL;
3747
3748             /* GetExtension() tests. */
3749             prop = test.str_props[Uri_PROPERTY_EXTENSION];
3750             hr = IUri_GetExtension(uri, &received);
3751             if(prop.todo) {
3752                 todo_wine {
3753                     ok(hr == prop.expected, "Error: GetExtension returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3754                             hr, prop.expected, i);
3755                 }
3756                 todo_wine {
3757                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3758                             prop.value, wine_dbgstr_w(received), i);
3759                 }
3760             } else {
3761                 ok(hr == prop.expected, "Error: GetExtension returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3762                         hr, prop.expected, i);
3763                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3764                         prop.value, wine_dbgstr_w(received), i);
3765             }
3766             SysFreeString(received);
3767             received = NULL;
3768
3769             /* GetHost() tests. */
3770             prop = test.str_props[Uri_PROPERTY_HOST];
3771             hr = IUri_GetHost(uri, &received);
3772             if(prop.todo) {
3773                 todo_wine {
3774                     ok(hr == prop.expected, "Error: GetHost returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3775                             hr, prop.expected, i);
3776                 }
3777                 todo_wine {
3778                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3779                             prop.value, wine_dbgstr_w(received), i);
3780                 }
3781             } else {
3782                 ok(hr == prop.expected, "Error: GetHost returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3783                         hr, prop.expected, i);
3784                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3785                         prop.value, wine_dbgstr_w(received), i);
3786             }
3787             SysFreeString(received);
3788             received = NULL;
3789
3790             /* GetPath() tests. */
3791             prop = test.str_props[Uri_PROPERTY_PATH];
3792             hr = IUri_GetPath(uri, &received);
3793             if(prop.todo) {
3794                 todo_wine {
3795                     ok(hr == prop.expected, "Error: GetPath returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3796                             hr, prop.expected, i);
3797                 }
3798                 todo_wine {
3799                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3800                             prop.value, wine_dbgstr_w(received), i);
3801                 }
3802             } else {
3803                 ok(hr == prop.expected, "Error: GetPath returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3804                         hr, prop.expected, i);
3805                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3806                         prop.value, wine_dbgstr_w(received), i);
3807             }
3808             SysFreeString(received);
3809             received = NULL;
3810
3811             /* GetPathAndQuery() tests. */
3812             prop = test.str_props[Uri_PROPERTY_PATH_AND_QUERY];
3813             hr = IUri_GetPathAndQuery(uri, &received);
3814             if(prop.todo) {
3815                 todo_wine {
3816                     ok(hr == prop.expected, "Error: GetPathAndQuery returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3817                             hr, prop.expected, i);
3818                 }
3819                 todo_wine {
3820                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3821                             prop.value, wine_dbgstr_w(received), i);
3822                 }
3823             } else {
3824                 ok(hr == prop.expected, "Error: GetPathAndQuery returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3825                         hr, prop.expected, i);
3826                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3827                         prop.value, wine_dbgstr_w(received), i);
3828             }
3829             SysFreeString(received);
3830             received = NULL;
3831
3832             /* GetQuery() tests. */
3833             prop = test.str_props[Uri_PROPERTY_QUERY];
3834             hr = IUri_GetQuery(uri, &received);
3835             if(prop.todo) {
3836                 todo_wine {
3837                     ok(hr == prop.expected, "Error: GetQuery returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3838                             hr, prop.expected, i);
3839                 }
3840                 todo_wine {
3841                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3842                             prop.value, wine_dbgstr_w(received), i);
3843                 }
3844             } else {
3845                 ok(hr == prop.expected, "Error: GetQuery returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3846                         hr, prop.expected, i);
3847                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3848                         prop.value, wine_dbgstr_w(received), i);
3849             }
3850             SysFreeString(received);
3851             received = NULL;
3852
3853             /* GetRawUri() tests. */
3854             prop = test.str_props[Uri_PROPERTY_RAW_URI];
3855             hr = IUri_GetRawUri(uri, &received);
3856             if(prop.todo) {
3857                 todo_wine {
3858                     ok(hr == prop.expected, "Error: GetRawUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3859                             hr, prop.expected, i);
3860                 }
3861                 todo_wine {
3862                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3863                             prop.value, wine_dbgstr_w(received), i);
3864                 }
3865             } else {
3866                 ok(hr == prop.expected, "Error: GetRawUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3867                         hr, prop.expected, i);
3868                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3869                         prop.value, wine_dbgstr_w(received), i);
3870             }
3871             SysFreeString(received);
3872             received = NULL;
3873
3874             /* GetSchemeName() tests. */
3875             prop = test.str_props[Uri_PROPERTY_SCHEME_NAME];
3876             hr = IUri_GetSchemeName(uri, &received);
3877             if(prop.todo) {
3878                 todo_wine {
3879                     ok(hr == prop.expected, "Error: GetSchemeName returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3880                             hr, prop.expected, i);
3881                 }
3882                 todo_wine {
3883                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3884                             prop.value, wine_dbgstr_w(received), i);
3885                 }
3886             } else {
3887                 ok(hr == prop.expected, "Error: GetSchemeName returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3888                         hr, prop.expected, i);
3889                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3890                         prop.value, wine_dbgstr_w(received), i);
3891             }
3892             SysFreeString(received);
3893             received = NULL;
3894
3895             /* GetUserInfo() tests. */
3896             prop = test.str_props[Uri_PROPERTY_USER_INFO];
3897             hr = IUri_GetUserInfo(uri, &received);
3898             if(prop.todo) {
3899                 todo_wine {
3900                     ok(hr == prop.expected, "Error: GetUserInfo returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3901                             hr, prop.expected, i);
3902                 }
3903                 todo_wine {
3904                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3905                             prop.value, wine_dbgstr_w(received), i);
3906                 }
3907             } else {
3908                 ok(hr == prop.expected, "Error: GetUserInfo returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3909                         hr, prop.expected, i);
3910                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3911                         prop.value, wine_dbgstr_w(received), i);
3912             }
3913             SysFreeString(received);
3914             received = NULL;
3915
3916             /* GetUserName() tests. */
3917             prop = test.str_props[Uri_PROPERTY_USER_NAME];
3918             hr = IUri_GetUserName(uri, &received);
3919             if(prop.todo) {
3920                 todo_wine {
3921                     ok(hr == prop.expected, "Error: GetUserName returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3922                             hr, prop.expected, i);
3923                 }
3924                 todo_wine {
3925                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3926                             prop.value, wine_dbgstr_w(received), i);
3927                 }
3928             } else {
3929                 ok(hr == prop.expected, "Error: GetUserName returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3930                         hr, prop.expected, i);
3931                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3932                         prop.value, wine_dbgstr_w(received), i);
3933             }
3934             SysFreeString(received);
3935         }
3936
3937         if(uri) IUri_Release(uri);
3938
3939         heap_free(uriW);
3940     }
3941 }
3942
3943 static void test_IUri_GetDwordProperties(void) {
3944     IUri *uri = NULL;
3945     HRESULT hr;
3946     DWORD i;
3947
3948     /* Make sure all the 'Get*' dword property functions handle invalid args correctly. */
3949     hr = pCreateUri(http_urlW, 0, 0, &uri);
3950     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
3951     if(SUCCEEDED(hr)) {
3952         hr = IUri_GetHostType(uri, NULL);
3953         ok(hr == E_INVALIDARG, "Error: GetHostType returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
3954
3955         hr = IUri_GetPort(uri, NULL);
3956         ok(hr == E_INVALIDARG, "Error: GetPort returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
3957
3958         hr = IUri_GetScheme(uri, NULL);
3959         ok(hr == E_INVALIDARG, "Error: GetScheme returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
3960
3961         hr = IUri_GetZone(uri, NULL);
3962         ok(hr == E_INVALIDARG, "Error: GetZone returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
3963     }
3964     if(uri) IUri_Release(uri);
3965
3966     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
3967         uri_properties test = uri_tests[i];
3968         LPWSTR uriW;
3969         uri = NULL;
3970
3971         uriW = a2w(test.uri);
3972         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
3973         if(test.create_todo) {
3974             todo_wine {
3975                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3976                         hr, test.create_expected, i);
3977             }
3978         } else {
3979             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3980                     hr, test.create_expected, i);
3981         }
3982
3983         if(SUCCEEDED(hr)) {
3984             uri_dword_property prop;
3985             DWORD received;
3986
3987             /* Assign an insane value so tests don't accidentally pass when
3988              * they shouldn't!
3989              */
3990             received = -9999999;
3991
3992             /* GetHostType() tests. */
3993             prop = test.dword_props[Uri_PROPERTY_HOST_TYPE-Uri_PROPERTY_DWORD_START];
3994             hr = IUri_GetHostType(uri, &received);
3995             if(prop.todo) {
3996                 todo_wine {
3997                     ok(hr == prop.expected, "Error: GetHostType returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3998                             hr, prop.expected, i);
3999                 }
4000                 todo_wine {
4001                     ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4002                 }
4003             } else {
4004                 ok(hr == prop.expected, "Error: GetHostType returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4005                         hr, prop.expected, i);
4006                 ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4007             }
4008             received = -9999999;
4009
4010             /* GetPort() tests. */
4011             prop = test.dword_props[Uri_PROPERTY_PORT-Uri_PROPERTY_DWORD_START];
4012             hr = IUri_GetPort(uri, &received);
4013             if(prop.todo) {
4014                 todo_wine {
4015                     ok(hr == prop.expected, "Error: GetPort returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4016                             hr, prop.expected, i);
4017                 }
4018                 todo_wine {
4019                     ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4020                 }
4021             } else {
4022                 ok(hr == prop.expected, "Error: GetPort returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4023                         hr, prop.expected, i);
4024                 ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4025             }
4026             received = -9999999;
4027
4028             /* GetScheme() tests. */
4029             prop = test.dword_props[Uri_PROPERTY_SCHEME-Uri_PROPERTY_DWORD_START];
4030             hr = IUri_GetScheme(uri, &received);
4031             if(prop.todo) {
4032                 todo_wine {
4033                     ok(hr == prop.expected, "Error: GetScheme returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4034                             hr, prop.expected, i);
4035                 }
4036                 todo_wine {
4037                     ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4038                 }
4039             } else {
4040                 ok(hr == prop.expected, "Error: GetScheme returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4041                         hr, prop.expected, i);
4042                 ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4043             }
4044             received = -9999999;
4045
4046             /* GetZone() tests. */
4047             prop = test.dword_props[Uri_PROPERTY_ZONE-Uri_PROPERTY_DWORD_START];
4048             hr = IUri_GetZone(uri, &received);
4049             if(prop.todo) {
4050                 todo_wine {
4051                     ok(hr == prop.expected, "Error: GetZone returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4052                             hr, prop.expected, i);
4053                 }
4054                 todo_wine {
4055                     ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4056                 }
4057             } else {
4058                 ok(hr == prop.expected, "Error: GetZone returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4059                         hr, prop.expected, i);
4060                 ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4061             }
4062         }
4063
4064         if(uri) IUri_Release(uri);
4065
4066         heap_free(uriW);
4067     }
4068 }
4069
4070 static void test_IUri_GetPropertyLength(void) {
4071     IUri *uri = NULL;
4072     HRESULT hr;
4073     DWORD i;
4074
4075     /* Make sure it handles invalid args correctly. */
4076     hr = pCreateUri(http_urlW, 0, 0, &uri);
4077     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
4078     if(SUCCEEDED(hr)) {
4079         DWORD received = 0xdeadbeef;
4080
4081         hr = IUri_GetPropertyLength(uri, Uri_PROPERTY_STRING_START, NULL, 0);
4082         ok(hr == E_INVALIDARG, "Error: GetPropertyLength returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
4083
4084         hr = IUri_GetPropertyLength(uri, Uri_PROPERTY_DWORD_START, &received, 0);
4085         ok(hr == E_INVALIDARG, "Error: GetPropertyLength return 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
4086         ok(received == 0xdeadbeef, "Error: Expected 0xdeadbeef but got 0x%08x.\n", received);
4087     }
4088     if(uri) IUri_Release(uri);
4089
4090     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
4091         uri_properties test = uri_tests[i];
4092         LPWSTR uriW;
4093         uri = NULL;
4094
4095         uriW = a2w(test.uri);
4096         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
4097         if(test.create_todo) {
4098             todo_wine {
4099                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4100                         hr, test.create_expected, i);
4101             }
4102         } else {
4103             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_test[%d].\n",
4104                     hr, test.create_expected, i);
4105         }
4106
4107         if(SUCCEEDED(hr)) {
4108             DWORD j;
4109
4110             for(j = Uri_PROPERTY_STRING_START; j <= Uri_PROPERTY_STRING_LAST; ++j) {
4111                 DWORD expectedLen, brokenLen, receivedLen;
4112                 uri_str_property prop = test.str_props[j];
4113
4114                 expectedLen = lstrlen(prop.value);
4115                 brokenLen = lstrlen(prop.broken_value);
4116
4117                 /* This won't be necessary once GetPropertyLength is implemented. */
4118                 receivedLen = -1;
4119
4120                 hr = IUri_GetPropertyLength(uri, j, &receivedLen, 0);
4121                 if(prop.todo) {
4122                     todo_wine {
4123                         ok(hr == prop.expected, "Error: GetPropertyLength returned 0x%08x, expected 0x%08x on uri_tests[%d].str_props[%d].\n",
4124                                 hr, prop.expected, i, j);
4125                     }
4126                     todo_wine {
4127                         ok(receivedLen == expectedLen || broken(receivedLen == brokenLen),
4128                                 "Error: Expected a length of %d but got %d on uri_tests[%d].str_props[%d].\n",
4129                                 expectedLen, receivedLen, i, j);
4130                     }
4131                     if (hr == E_NOTIMPL)  /* no point in continuing */
4132                     {
4133                         if(uri) IUri_Release(uri);
4134                         heap_free(uriW);
4135                         return;
4136                     }
4137                 } else {
4138                     ok(hr == prop.expected, "Error: GetPropertyLength returned 0x%08x, expected 0x%08x on uri_tests[%d].str_props[%d].\n",
4139                             hr, prop.expected, i, j);
4140                     ok(receivedLen == expectedLen || broken(receivedLen == brokenLen),
4141                             "Error: Expected a length of %d but got %d on uri_tests[%d].str_props[%d].\n",
4142                             expectedLen, receivedLen, i, j);
4143                 }
4144             }
4145         }
4146
4147         if(uri) IUri_Release(uri);
4148
4149         heap_free(uriW);
4150     }
4151 }
4152
4153 static void test_IUri_GetProperties(void) {
4154     IUri *uri = NULL;
4155     HRESULT hr;
4156     DWORD i;
4157
4158     hr = pCreateUri(http_urlW, 0, 0, &uri);
4159     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
4160     if(SUCCEEDED(hr)) {
4161         hr = IUri_GetProperties(uri, NULL);
4162         ok(hr == E_INVALIDARG, "Error: GetProperties returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
4163     }
4164     if(uri) IUri_Release(uri);
4165
4166     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
4167         uri_properties test = uri_tests[i];
4168         LPWSTR uriW;
4169         uri = NULL;
4170
4171         uriW = a2w(test.uri);
4172         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
4173         if(test.create_todo) {
4174             todo_wine {
4175                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
4176             }
4177         } else {
4178             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
4179         }
4180
4181         if(SUCCEEDED(hr)) {
4182             DWORD received = 0;
4183             DWORD j;
4184
4185             hr = IUri_GetProperties(uri, &received);
4186             if(test.props_todo) {
4187                 todo_wine {
4188                     ok(hr == S_OK, "Error: GetProperties returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
4189                 }
4190                 if (hr == E_NOTIMPL)  /* no point in continuing */
4191                 {
4192                     if(uri) IUri_Release(uri);
4193                     heap_free(uriW);
4194                     return;
4195                 }
4196             } else {
4197                 ok(hr == S_OK, "Error: GetProperties returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
4198             }
4199
4200             for(j = 0; j <= Uri_PROPERTY_DWORD_LAST; ++j) {
4201                 /* (1 << j) converts a Uri_PROPERTY to its corresponding Uri_HAS_* flag mask. */
4202                 if(test.props & (1 << j)) {
4203                     if(test.props_todo) {
4204                         todo_wine {
4205                             ok(received & (1 << j), "Error: Expected flag for property %d on uri_tests[%d].\n", j, i);
4206                         }
4207                     } else {
4208                         ok(received & (1 << j), "Error: Expected flag for property %d on uri_tests[%d].\n", j, i);
4209                     }
4210                 } else {
4211                     /* NOTE: Since received is initialized to 0, this test will always pass while
4212                      * GetProperties is unimplemented.
4213                      */
4214                     ok(!(received & (1 << j)), "Error: Received flag for property %d when not expected on uri_tests[%d].\n", j, i);
4215                 }
4216             }
4217         }
4218
4219         if(uri) IUri_Release(uri);
4220
4221         heap_free(uriW);
4222     }
4223 }
4224
4225 static void test_IUri_HasProperty(void) {
4226     IUri *uri = NULL;
4227     HRESULT hr;
4228     DWORD i;
4229
4230     hr = pCreateUri(http_urlW, 0, 0, &uri);
4231     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
4232     if(SUCCEEDED(hr)) {
4233         hr = IUri_HasProperty(uri, Uri_PROPERTY_RAW_URI, NULL);
4234         ok(hr == E_INVALIDARG, "Error: HasProperty returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
4235     }
4236     if(uri) IUri_Release(uri);
4237
4238     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
4239         uri_properties test = uri_tests[i];
4240         LPWSTR uriW;
4241         uri = NULL;
4242
4243         uriW = a2w(test.uri);
4244
4245         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
4246         if(test.create_todo) {
4247             todo_wine {
4248                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
4249             }
4250         } else {
4251             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
4252         }
4253
4254         if(SUCCEEDED(hr)) {
4255             DWORD j;
4256
4257             for(j = 0; j <= Uri_PROPERTY_DWORD_LAST; ++j) {
4258                 /* Assign -1, then explicitly test for TRUE or FALSE later. */
4259                 BOOL received = -1;
4260
4261                 hr = IUri_HasProperty(uri, j, &received);
4262                 if(test.props_todo) {
4263                     todo_wine {
4264                         ok(hr == S_OK, "Error: HasProperty returned 0x%08x, expected 0x%08x for property %d on uri_tests[%d].\n",
4265                                 hr, S_OK, j, i);
4266                     }
4267                     if (hr == E_NOTIMPL)  /* no point in continuing */
4268                     {
4269                         if(uri) IUri_Release(uri);
4270                         heap_free(uriW);
4271                         return;
4272                     }
4273
4274                     /* Check if the property should be true. */
4275                     if(test.props & (1 << j)) {
4276                         todo_wine {
4277                             ok(received == TRUE, "Error: Expected to have property %d on uri_tests[%d].\n", j, i);
4278                         }
4279                     } else {
4280                         todo_wine {
4281                             ok(received == FALSE, "Error: Wasn't expecting to have property %d on uri_tests[%d].\n", j, i);
4282                         }
4283                     }
4284                 } else {
4285                     ok(hr == S_OK, "Error: HasProperty returned 0x%08x, expected 0x%08x for property %d on uri_tests[%d].\n",
4286                             hr, S_OK, j, i);
4287
4288                     if(test.props & (1 << j)) {
4289                         ok(received == TRUE, "Error: Expected to have property %d on uri_tests[%d].\n", j, i);
4290                     } else {
4291                         ok(received == FALSE, "Error: Wasn't expecting to have property %d on uri_tests[%d].\n", j, i);
4292                     }
4293                 }
4294             }
4295         }
4296
4297         if(uri) IUri_Release(uri);
4298
4299         heap_free(uriW);
4300     }
4301 }
4302
4303 static void test_IUri_IsEqual(void) {
4304     IUri *uriA, *uriB;
4305     HRESULT hrA, hrB;
4306     DWORD i;
4307
4308     uriA = uriB = NULL;
4309
4310     /* Make sure IsEqual handles invalid args correctly. */
4311     hrA = pCreateUri(http_urlW, 0, 0, &uriA);
4312     hrB = pCreateUri(http_urlW, 0, 0, &uriB);
4313     ok(hrA == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hrA, S_OK);
4314     ok(hrB == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hrB, S_OK);
4315     if(SUCCEEDED(hrA) && SUCCEEDED(hrB)) {
4316         BOOL equal = -1;
4317         hrA = IUri_IsEqual(uriA, NULL, &equal);
4318         ok(hrA == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x.\n", hrA, S_OK);
4319         ok(equal == FALSE, "Error: Expected equal to be FALSE, but was %d instead.\n", equal);
4320
4321         hrA = IUri_IsEqual(uriA, uriB, NULL);
4322         ok(hrA == E_POINTER, "Error: IsEqual returned 0x%08x, expected 0x%08x.\n", hrA, E_POINTER);
4323     }
4324     if(uriA) IUri_Release(uriA);
4325     if(uriB) IUri_Release(uriB);
4326
4327     for(i = 0; i < sizeof(equality_tests)/sizeof(equality_tests[0]); ++i) {
4328         uri_equality test = equality_tests[i];
4329         LPWSTR uriA_W, uriB_W;
4330
4331         uriA = uriB = NULL;
4332
4333         uriA_W = a2w(test.a);
4334         uriB_W = a2w(test.b);
4335
4336         hrA = pCreateUri(uriA_W, test.create_flags_a, 0, &uriA);
4337         if(test.create_todo_a) {
4338             todo_wine {
4339                 ok(hrA == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].a\n",
4340                         hrA, S_OK, i);
4341             }
4342         } else {
4343             ok(hrA == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].a\n",
4344                     hrA, S_OK, i);
4345         }
4346
4347         hrB = pCreateUri(uriB_W, test.create_flags_b, 0, &uriB);
4348         if(test.create_todo_b) {
4349             todo_wine {
4350                 ok(hrB == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].b\n",
4351                         hrB, S_OK, i);
4352             }
4353         } else {
4354             ok(hrB == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].b\n",
4355                     hrB, S_OK, i);
4356         }
4357
4358         if(SUCCEEDED(hrA) && SUCCEEDED(hrB)) {
4359             BOOL equal = -1;
4360
4361             hrA = IUri_IsEqual(uriA, uriB, &equal);
4362             if(test.todo) {
4363                 todo_wine {
4364                     ok(hrA == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x on equality_tests[%d].\n",
4365                             hrA, S_OK, i);
4366                 }
4367                 todo_wine {
4368                     ok(equal == test.equal, "Error: Expected the comparison to be %d on equality_tests[%d].\n", test.equal, i);
4369                 }
4370             } else {
4371                 ok(hrA == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x on equality_tests[%d].\n", hrA, S_OK, i);
4372                 ok(equal == test.equal, "Error: Expected the comparison to be %d on equality_tests[%d].\n", test.equal, i);
4373             }
4374         }
4375         if(uriA) IUri_Release(uriA);
4376         if(uriB) IUri_Release(uriB);
4377
4378         heap_free(uriA_W);
4379         heap_free(uriB_W);
4380     }
4381 }
4382
4383 START_TEST(uri) {
4384     HMODULE hurlmon;
4385
4386     hurlmon = GetModuleHandle("urlmon.dll");
4387     pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
4388
4389     if(!pCreateUri) {
4390         win_skip("CreateUri is not present, skipping tests.\n");
4391         return;
4392     }
4393
4394     trace("test CreateUri invalid flags...\n");
4395     test_CreateUri_InvalidFlags();
4396
4397     trace("test CreateUri invalid args...\n");
4398     test_CreateUri_InvalidArgs();
4399
4400     trace("test CreateUri invalid URIs...\n");
4401     test_CreateUri_InvalidUri();
4402
4403     trace("test IUri_GetPropertyBSTR...\n");
4404     test_IUri_GetPropertyBSTR();
4405
4406     trace("test IUri_GetPropertyDWORD...\n");
4407     test_IUri_GetPropertyDWORD();
4408
4409     trace("test IUri_GetStrProperties...\n");
4410     test_IUri_GetStrProperties();
4411
4412     trace("test IUri_GetDwordProperties...\n");
4413     test_IUri_GetDwordProperties();
4414
4415     trace("test IUri_GetPropertyLength...\n");
4416     test_IUri_GetPropertyLength();
4417
4418     trace("test IUri_GetProperties...\n");
4419     test_IUri_GetProperties();
4420
4421     trace("test IUri_HasProperty...\n");
4422     test_IUri_HasProperty();
4423
4424     trace("test IUri_IsEqual...\n");
4425     test_IUri_IsEqual();
4426 }