urlmon: Implemented IUri_GetAbsoluteUri.
[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,FALSE},                      /* 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,FALSE},                                         /* 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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
299             {"",S_FALSE,FALSE},
300             {"urn:nothing:should:happen here",S_OK,TRUE},
301             {"",S_FALSE,FALSE},
302             {"",S_FALSE,FALSE},
303             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
590             {"",S_FALSE,FALSE},
591             {"/../some dir/test.ext",S_OK,TRUE},
592             {"",S_FALSE,FALSE},
593             {".ext",S_OK,FALSE},
594             {"",S_FALSE,FALSE},
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,FALSE},
618             {"",S_OK,FALSE},
619             {"*://implicit/wildcard/uri%20scheme",S_OK,TRUE},
620             {"",S_FALSE,FALSE},
621             {"",S_FALSE,FALSE},
622             {"",S_FALSE,FALSE},
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,FALSE},
648             {"",S_FALSE,FALSE},
649             {"zip:/.//google.com",S_OK,TRUE},
650             {"",S_FALSE,FALSE},
651             {".com",S_OK,FALSE},
652             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
1164             {"4294967296",S_OK,FALSE},
1165             {"http://4294967296/",S_OK,TRUE},
1166             {"",S_FALSE,FALSE},
1167             {"",S_FALSE,FALSE},
1168             {"",S_FALSE,FALSE},
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,FALSE},
1194             {"4294967295",S_OK,FALSE},
1195             {"1234://4294967295/",S_OK,TRUE},
1196             {"",S_FALSE,FALSE},
1197             {"",S_FALSE,FALSE},
1198             {"",S_FALSE,FALSE},
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,FALSE},
1224             {"127.001",S_OK,FALSE},
1225             {"1234://127.001/",S_OK,TRUE},
1226             {"",S_FALSE,FALSE},
1227             {"",S_FALSE,FALSE},
1228             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
1282             {"[::]",S_OK,FALSE},
1283             {"http://[::]/",S_OK,TRUE},
1284             {"",S_FALSE,FALSE},
1285             {"",S_FALSE,FALSE},
1286             {"",S_FALSE,FALSE},
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,FALSE},
1311             {"[fedc:ba98::]",S_OK,FALSE},
1312             {"http://[fedc:ba98::]/",S_OK,TRUE},
1313             {"",S_FALSE,FALSE},
1314             {"",S_FALSE,FALSE},
1315             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
1370             {"[v2.34]",S_OK,FALSE},
1371             {"http://[v2.34]/",S_OK,TRUE},
1372             {"",S_FALSE,FALSE},
1373             {"",S_FALSE,FALSE},
1374             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
1821             {"[::ffff]:abcd",S_OK,FALSE},
1822             {"zip://[::ffff]:abcd/",S_OK,TRUE},
1823             {"",S_FALSE,FALSE},
1824             {"",S_FALSE,FALSE},
1825             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
2054             {".com",S_OK,FALSE},
2055             {"http://.com/",S_OK,TRUE},
2056             {".com",S_OK,FALSE},
2057             {"",S_FALSE,FALSE},
2058             {"",S_FALSE,FALSE},
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,FALSE},
2083             {".uk",S_OK,FALSE},
2084             {"http://.uk/",S_OK,TRUE},
2085             {"",S_FALSE,FALSE},
2086             {"",S_FALSE,FALSE},
2087             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
2141             {"co.uk",S_OK,FALSE},
2142             {"http://co.uk/",S_OK,TRUE},
2143             {"",S_FALSE,FALSE},
2144             {"",S_FALSE,FALSE},
2145             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
2199             {"gov.uk",S_OK,FALSE},
2200             {"http://gov.uk/",S_OK,TRUE},
2201             {"",S_FALSE,FALSE},
2202             {"",S_FALSE,FALSE},
2203             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
2255             {"",S_FALSE,FALSE},
2256             {"urn:excepts:bad:%XY:encoded",S_OK,TRUE},
2257             {"",S_FALSE,FALSE},
2258             {"",S_FALSE,FALSE},
2259             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
2406             {"4294967295",S_OK,FALSE},
2407             {"1234://4294967295/<|>\" test<|>",S_OK,TRUE},
2408             {"",S_FALSE,FALSE},
2409             {"",S_FALSE,FALSE},
2410             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
2465             {"gov.uk",S_OK,FALSE},
2466             {"http://gov.uk/",S_OK,TRUE},
2467             {"",S_FALSE,FALSE},
2468             {"",S_FALSE,FALSE},
2469             {"",S_FALSE,FALSE},
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,FALSE},
2494             {"gov.uk",S_OK,FALSE},
2495             {"http://gov.uk/",S_OK,TRUE},
2496             {"",S_FALSE,FALSE},
2497             {"",S_FALSE,FALSE},
2498             {"",S_FALSE,FALSE},
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,FALSE},
2523             {"gov.uk",S_OK,FALSE},
2524             {"http://gov.uk/",S_OK,TRUE},
2525             {"",S_FALSE,FALSE},
2526             {"",S_FALSE,FALSE},
2527             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
2581             {"gov.uk",S_OK,FALSE},
2582             {"zip://gov.uk/",S_OK,TRUE},
2583             {"",S_FALSE,FALSE},
2584             {"",S_FALSE,FALSE},
2585             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
2785             {"",S_FALSE,FALSE},
2786             {"news:test.test.com",S_OK,TRUE},
2787             {"",S_FALSE,FALSE},
2788             {".com",S_OK,FALSE},
2789             {"",S_FALSE,FALSE},
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,FALSE},
2814             {"",S_FALSE,FALSE},
2815             {"news:test.test.com",S_OK,TRUE},
2816             {"",S_FALSE,FALSE},
2817             {".com",S_OK,FALSE},
2818             {"",S_FALSE,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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,FALSE},
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     /* Forbidden characters in fragment aren't encoded for unknown schemes. */
3195     {   "zip://www.winehq.org/tests/#Te<|>", 0, S_OK, FALSE,
3196         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
3197         Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
3198         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
3199         TRUE,
3200         {
3201             {"zip://www.winehq.org/tests/#Te<|>",S_OK,FALSE},
3202             {"www.winehq.org",S_OK,FALSE},
3203             {"zip://www.winehq.org/tests/#Te<|>",S_OK,TRUE},
3204             {"winehq.org",S_OK,FALSE},
3205             {"",S_FALSE,FALSE},
3206             {"#Te<|>",S_OK,FALSE},
3207             {"www.winehq.org",S_OK,FALSE},
3208             {"",S_FALSE,FALSE},
3209             {"/tests/",S_OK,FALSE},
3210             {"/tests/",S_OK,FALSE},
3211             {"",S_FALSE,FALSE},
3212             {"zip://www.winehq.org/tests/#Te<|>",S_OK,FALSE},
3213             {"zip",S_OK,FALSE},
3214             {"",S_FALSE,FALSE},
3215             {"",S_FALSE,FALSE}
3216         },
3217         {
3218             {Uri_HOST_DNS,S_OK,FALSE},
3219             {0,S_FALSE,FALSE},
3220             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
3221             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3222         }
3223     },
3224     /* Forbidden characters in the fragment are percent encoded for known schemes. */
3225     {   "http://www.winehq.org/tests/#Te<|>", 0, S_OK, FALSE,
3226         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
3227         Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
3228         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
3229         TRUE,
3230         {
3231             {"http://www.winehq.org/tests/#Te%3C%7C%3E",S_OK,FALSE},
3232             {"www.winehq.org",S_OK,FALSE},
3233             {"http://www.winehq.org/tests/#Te%3C%7C%3E",S_OK,TRUE},
3234             {"winehq.org",S_OK,FALSE},
3235             {"",S_FALSE,FALSE},
3236             {"#Te%3C%7C%3E",S_OK,FALSE},
3237             {"www.winehq.org",S_OK,FALSE},
3238             {"",S_FALSE,FALSE},
3239             {"/tests/",S_OK,FALSE},
3240             {"/tests/",S_OK,FALSE},
3241             {"",S_FALSE,FALSE},
3242             {"http://www.winehq.org/tests/#Te<|>",S_OK,FALSE},
3243             {"http",S_OK,FALSE},
3244             {"",S_FALSE,FALSE},
3245             {"",S_FALSE,FALSE}
3246         },
3247         {
3248             {Uri_HOST_DNS,S_OK,FALSE},
3249             {80,S_OK,FALSE},
3250             {URL_SCHEME_HTTP,S_OK,FALSE},
3251             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3252         }
3253     },
3254     /* Forbidden characters aren't encoded in the fragment with this flag. */
3255     {   "http://www.winehq.org/tests/#Te<|>", Uri_CREATE_NO_DECODE_EXTRA_INFO, S_OK, FALSE,
3256         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
3257         Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
3258         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
3259         TRUE,
3260         {
3261             {"http://www.winehq.org/tests/#Te<|>",S_OK,FALSE},
3262             {"www.winehq.org",S_OK,FALSE},
3263             {"http://www.winehq.org/tests/#Te<|>",S_OK,TRUE},
3264             {"winehq.org",S_OK,FALSE},
3265             {"",S_FALSE,FALSE},
3266             {"#Te<|>",S_OK,FALSE},
3267             {"www.winehq.org",S_OK,FALSE},
3268             {"",S_FALSE,FALSE},
3269             {"/tests/",S_OK,FALSE},
3270             {"/tests/",S_OK,FALSE},
3271             {"",S_FALSE,FALSE},
3272             {"http://www.winehq.org/tests/#Te<|>",S_OK,FALSE},
3273             {"http",S_OK,FALSE},
3274             {"",S_FALSE,FALSE},
3275             {"",S_FALSE,FALSE}
3276         },
3277         {
3278             {Uri_HOST_DNS,S_OK,FALSE},
3279             {80,S_OK,FALSE},
3280             {URL_SCHEME_HTTP,S_OK,FALSE},
3281             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3282         }
3283     },
3284     /* Forbidden characters aren't encoded in the fragment with this flag. */
3285     {   "http://www.winehq.org/tests/#Te<|>", Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS, S_OK, FALSE,
3286         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
3287         Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
3288         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
3289         TRUE,
3290         {
3291             {"http://www.winehq.org/tests/#Te<|>",S_OK,FALSE},
3292             {"www.winehq.org",S_OK,FALSE},
3293             {"http://www.winehq.org/tests/#Te<|>",S_OK,TRUE},
3294             {"winehq.org",S_OK,FALSE},
3295             {"",S_FALSE,FALSE},
3296             {"#Te<|>",S_OK,FALSE},
3297             {"www.winehq.org",S_OK,FALSE},
3298             {"",S_FALSE,FALSE},
3299             {"/tests/",S_OK,FALSE},
3300             {"/tests/",S_OK,FALSE},
3301             {"",S_FALSE,FALSE},
3302             {"http://www.winehq.org/tests/#Te<|>",S_OK,FALSE},
3303             {"http",S_OK,FALSE},
3304             {"",S_FALSE,FALSE},
3305             {"",S_FALSE,FALSE}
3306         },
3307         {
3308             {Uri_HOST_DNS,S_OK,FALSE},
3309             {80,S_OK,FALSE},
3310             {URL_SCHEME_HTTP,S_OK,FALSE},
3311             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3312         }
3313     },
3314     /* Percent encoded, unreserved characters aren't decoded for known scheme types. */
3315     {   "zip://www.winehq.org/tests/#Te%30%31%32", 0, S_OK, FALSE,
3316         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
3317         Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
3318         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
3319         TRUE,
3320         {
3321             {"zip://www.winehq.org/tests/#Te%30%31%32",S_OK,FALSE},
3322             {"www.winehq.org",S_OK,FALSE},
3323             {"zip://www.winehq.org/tests/#Te%30%31%32",S_OK,TRUE},
3324             {"winehq.org",S_OK,FALSE},
3325             {"",S_FALSE,FALSE},
3326             {"#Te%30%31%32",S_OK,FALSE},
3327             {"www.winehq.org",S_OK,FALSE},
3328             {"",S_FALSE,FALSE},
3329             {"/tests/",S_OK,FALSE},
3330             {"/tests/",S_OK,FALSE},
3331             {"",S_FALSE,FALSE},
3332             {"zip://www.winehq.org/tests/#Te%30%31%32",S_OK,FALSE},
3333             {"zip",S_OK,FALSE},
3334             {"",S_FALSE,FALSE},
3335             {"",S_FALSE,FALSE}
3336         },
3337         {
3338             {Uri_HOST_DNS,S_OK,FALSE},
3339             {0,S_FALSE,FALSE},
3340             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
3341             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3342         }
3343     },
3344     /* Percent encoded, unreserved characters are decoded for known schemes. */
3345     {   "http://www.winehq.org/tests/#Te%30%31%32", 0, S_OK, FALSE,
3346         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
3347         Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
3348         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
3349         TRUE,
3350         {
3351             {"http://www.winehq.org/tests/#Te012",S_OK,FALSE},
3352             {"www.winehq.org",S_OK,FALSE},
3353             {"http://www.winehq.org/tests/#Te012",S_OK,TRUE},
3354             {"winehq.org",S_OK,FALSE},
3355             {"",S_FALSE,FALSE},
3356             {"#Te012",S_OK,FALSE},
3357             {"www.winehq.org",S_OK,FALSE},
3358             {"",S_FALSE,FALSE},
3359             {"/tests/",S_OK,FALSE},
3360             {"/tests/",S_OK,FALSE},
3361             {"",S_FALSE,FALSE},
3362             {"http://www.winehq.org/tests/#Te%30%31%32",S_OK,FALSE},
3363             {"http",S_OK,FALSE},
3364             {"",S_FALSE,FALSE},
3365             {"",S_FALSE,FALSE}
3366         },
3367         {
3368             {Uri_HOST_DNS,S_OK,FALSE},
3369             {80,S_OK,FALSE},
3370             {URL_SCHEME_HTTP,S_OK,FALSE},
3371             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3372         }
3373     },
3374     /* Percent encoded, unreserved characters are decoded even if NO_CANONICALIZE is set. */
3375     {   "http://www.winehq.org/tests/#Te%30%31%32", Uri_CREATE_NO_CANONICALIZE, S_OK, FALSE,
3376         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
3377         Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
3378         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
3379         TRUE,
3380         {
3381             {"http://www.winehq.org/tests/#Te012",S_OK,FALSE},
3382             {"www.winehq.org",S_OK,FALSE},
3383             {"http://www.winehq.org/tests/#Te012",S_OK,TRUE},
3384             {"winehq.org",S_OK,FALSE},
3385             {"",S_FALSE,FALSE},
3386             {"#Te012",S_OK,FALSE},
3387             {"www.winehq.org",S_OK,FALSE},
3388             {"",S_FALSE,FALSE},
3389             {"/tests/",S_OK,FALSE},
3390             {"/tests/",S_OK,FALSE},
3391             {"",S_FALSE,FALSE},
3392             {"http://www.winehq.org/tests/#Te%30%31%32",S_OK,FALSE},
3393             {"http",S_OK,FALSE},
3394             {"",S_FALSE,FALSE},
3395             {"",S_FALSE,FALSE}
3396         },
3397         {
3398             {Uri_HOST_DNS,S_OK,FALSE},
3399             {80,S_OK,FALSE},
3400             {URL_SCHEME_HTTP,S_OK,FALSE},
3401             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3402         }
3403     },
3404     /* Percent encoded, unreserved characters aren't decoded when NO_DECODE_EXTRA is set. */
3405     {   "http://www.winehq.org/tests/#Te%30%31%32", Uri_CREATE_NO_DECODE_EXTRA_INFO, S_OK, FALSE,
3406         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
3407         Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
3408         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
3409         TRUE,
3410         {
3411             {"http://www.winehq.org/tests/#Te%30%31%32",S_OK,FALSE},
3412             {"www.winehq.org",S_OK,FALSE},
3413             {"http://www.winehq.org/tests/#Te%30%31%32",S_OK,TRUE},
3414             {"winehq.org",S_OK,FALSE},
3415             {"",S_FALSE,FALSE},
3416             {"#Te%30%31%32",S_OK,FALSE},
3417             {"www.winehq.org",S_OK,FALSE},
3418             {"",S_FALSE,FALSE},
3419             {"/tests/",S_OK,FALSE},
3420             {"/tests/",S_OK,FALSE},
3421             {"",S_FALSE,FALSE},
3422             {"http://www.winehq.org/tests/#Te%30%31%32",S_OK,FALSE},
3423             {"http",S_OK,FALSE},
3424             {"",S_FALSE,FALSE},
3425             {"",S_FALSE,FALSE}
3426         },
3427         {
3428             {Uri_HOST_DNS,S_OK,FALSE},
3429             {80,S_OK,FALSE},
3430             {URL_SCHEME_HTTP,S_OK,FALSE},
3431             {URLZONE_INVALID,E_NOTIMPL,FALSE},
3432         }
3433     }
3434 };
3435
3436 typedef struct _invalid_uri {
3437     const char* uri;
3438     DWORD       flags;
3439     BOOL        todo;
3440 } invalid_uri;
3441
3442 static const invalid_uri invalid_uri_tests[] = {
3443     /* Has to have a scheme name. */
3444     {"://www.winehq.org",0,FALSE},
3445     /* Window's doesn't like URI's which are implicitly file paths without the
3446      * ALLOW_IMPLICIT_FILE_SCHEME flag set.
3447      */
3448     {"C:/test/test.mp3",0,FALSE},
3449     {"\\\\Server/test/test.mp3",0,FALSE},
3450     {"C:/test/test.mp3",Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME,FALSE},
3451     {"\\\\Server/test/test.mp3",Uri_CREATE_ALLOW_RELATIVE,FALSE},
3452     /* Invalid schemes. */
3453     {"*abcd://not.valid.com",0,FALSE},
3454     {"*a*b*c*d://not.valid.com",0,FALSE},
3455     /* Not allowed to have invalid % encoded data. */
3456     {"ftp://google.co%XX/",0,FALSE},
3457     /* To many h16 components. */
3458     {"http://[1:2:3:4:5:6:7:8:9]",0,FALSE},
3459     /* Not enough room for IPv4 address. */
3460     {"http://[1:2:3:4:5:6:7:192.0.1.0]",0,FALSE},
3461     /* Not enough h16 components. */
3462     {"http://[1:2:3:4]",0,FALSE},
3463     /* Not enough components including IPv4. */
3464     {"http://[1:192.0.1.0]",0,FALSE},
3465     /* Not allowed to have partial IPv4 in IPv6. */
3466     {"http://[::192.0]",0,FALSE},
3467     /* Can't have elision of 1 h16 at beginning of address. */
3468     {"http://[::2:3:4:5:6:7:8]",0,FALSE},
3469     /* Can't have elision of 1 h16 at end of address. */
3470     {"http://[1:2:3:4:5:6:7::]",0,FALSE},
3471     /* Expects a valid IP Literal. */
3472     {"ftp://[not.valid.uri]/",0,FALSE},
3473     /* Expects valid port for a known scheme type. */
3474     {"ftp://www.winehq.org:123fgh",0,FALSE},
3475     /* Port exceeds USHORT_MAX for known scheme type. */
3476     {"ftp://www.winehq.org:65536",0,FALSE},
3477     /* Invalid port with IPv4 address. */
3478     {"http://www.winehq.org:1abcd",0,FALSE},
3479     /* Invalid port with IPv6 address. */
3480     {"http://[::ffff]:32xy",0,FALSE},
3481     /* Not allowed to have backslashes with NO_CANONICALIZE. */
3482     {"gopher://www.google.com\\test",Uri_CREATE_NO_CANONICALIZE,FALSE},
3483     /* Not allowed to have invalid % encoded data in opaque URI path. */
3484     {"news:test%XX",0,FALSE},
3485     {"mailto:wine@winehq%G8.com",0,FALSE},
3486     /* Known scheme types can't have invalid % encoded data in query string. */
3487     {"http://google.com/?query=te%xx",0,FALSE},
3488     /* Invalid % encoded data in fragment of know scheme type. */
3489     {"ftp://google.com/#Test%xx",0,FALSE}
3490 };
3491
3492 typedef struct _uri_equality {
3493     const char* a;
3494     DWORD       create_flags_a;
3495     BOOL        create_todo_a;
3496     const char* b;
3497     DWORD       create_flags_b;
3498     BOOL        create_todo_b;
3499     BOOL        equal;
3500     BOOL        todo;
3501 } uri_equality;
3502
3503 static const uri_equality equality_tests[] = {
3504     {
3505         "HTTP://www.winehq.org/test dir/./",0,FALSE,
3506         "http://www.winehq.org/test dir/../test dir/",0,FALSE,
3507         TRUE, TRUE
3508     },
3509     {
3510         /* http://www.winehq.org/test%20dir */
3511         "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,
3512         "http://www.winehq.org/test dir",0,FALSE,
3513         TRUE, TRUE,
3514     },
3515     {
3516         "c:\\test.mp3",Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME,FALSE,
3517         "file:///c:/test.mp3",0,FALSE,
3518         TRUE,TRUE
3519     },
3520     {
3521         "ftp://ftp.winehq.org/",0,FALSE,
3522         "ftp://ftp.winehq.org",0,FALSE,
3523         TRUE, TRUE
3524     },
3525     {
3526         "ftp://ftp.winehq.org/test/test2/../../testB/",0,FALSE,
3527         "ftp://ftp.winehq.org/t%45stB/",0,FALSE,
3528         FALSE, TRUE
3529     }
3530 };
3531
3532 static inline LPWSTR a2w(LPCSTR str) {
3533     LPWSTR ret = NULL;
3534
3535     if(str) {
3536         DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
3537         ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
3538         MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
3539     }
3540
3541     return ret;
3542 }
3543
3544 static inline BOOL heap_free(void* mem) {
3545     return HeapFree(GetProcessHeap(), 0, mem);
3546 }
3547
3548 static inline DWORD strcmp_aw(LPCSTR strA, LPCWSTR strB) {
3549     LPWSTR strAW = a2w(strA);
3550     DWORD ret = lstrcmpW(strAW, strB);
3551     heap_free(strAW);
3552     return ret;
3553 }
3554
3555 /*
3556  * Simple tests to make sure the CreateUri function handles invalid flag combinations
3557  * correctly.
3558  */
3559 static void test_CreateUri_InvalidFlags(void) {
3560     DWORD i;
3561
3562     for(i = 0; i < sizeof(invalid_flag_tests)/sizeof(invalid_flag_tests[0]); ++i) {
3563         HRESULT hr;
3564         IUri *uri = (void*) 0xdeadbeef;
3565
3566         hr = pCreateUri(http_urlW, invalid_flag_tests[i].flags, 0, &uri);
3567         todo_wine {
3568             ok(hr == invalid_flag_tests[i].expected, "Error: CreateUri returned 0x%08x, expected 0x%08x, flags=0x%08x\n",
3569                     hr, invalid_flag_tests[i].expected, invalid_flag_tests[i].flags);
3570         }
3571         todo_wine { ok(uri == NULL, "Error: expected the IUri to be NULL, but it was %p instead\n", uri); }
3572     }
3573 }
3574
3575 static void test_CreateUri_InvalidArgs(void) {
3576     HRESULT hr;
3577     IUri *uri = (void*) 0xdeadbeef;
3578
3579     const WCHAR invalidW[] = {'i','n','v','a','l','i','d',0};
3580
3581     hr = pCreateUri(http_urlW, 0, 0, NULL);
3582     ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x\n", hr, E_INVALIDARG);
3583
3584     hr = pCreateUri(NULL, 0, 0, &uri);
3585     ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x\n", hr, E_INVALIDARG);
3586     ok(uri == NULL, "Error: Expected the IUri to be NULL, but it was %p instead\n", uri);
3587
3588     uri = (void*) 0xdeadbeef;
3589     hr = pCreateUri(invalidW, 0, 0, &uri);
3590     ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
3591     ok(uri == NULL, "Error: Expected the IUri to be NULL, but it was %p instead\n", uri);
3592 }
3593
3594 static void test_CreateUri_InvalidUri(void) {
3595     DWORD i;
3596
3597     for(i = 0; i < sizeof(invalid_uri_tests)/sizeof(invalid_uri_tests[0]); ++i) {
3598         invalid_uri test = invalid_uri_tests[i];
3599         IUri *uri = NULL;
3600         LPWSTR uriW;
3601         HRESULT hr;
3602
3603         uriW = a2w(test.uri);
3604         hr = pCreateUri(uriW, test.flags, 0, &uri);
3605         if(test.todo) {
3606             todo_wine {
3607                 ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x on invalid_uri_tests[%d].\n",
3608                     hr, E_INVALIDARG, i);
3609             }
3610         } else {
3611             ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x on invalid_uri_tests[%d].\n",
3612                 hr, E_INVALIDARG, i);
3613         }
3614         if(uri) IUri_Release(uri);
3615
3616         heap_free(uriW);
3617     }
3618 }
3619
3620 static void test_IUri_GetPropertyBSTR(void) {
3621     IUri *uri = NULL;
3622     HRESULT hr;
3623     DWORD i;
3624
3625     /* Make sure GetPropertyBSTR handles invalid args correctly. */
3626     hr = pCreateUri(http_urlW, 0, 0, &uri);
3627     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
3628     if(SUCCEEDED(hr)) {
3629         BSTR received = NULL;
3630
3631         hr = IUri_GetPropertyBSTR(uri, Uri_PROPERTY_RAW_URI, NULL, 0);
3632         ok(hr == E_POINTER, "Error: GetPropertyBSTR returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3633
3634         /* Make sure it handles a invalid Uri_PROPERTY's correctly. */
3635         hr = IUri_GetPropertyBSTR(uri, Uri_PROPERTY_PORT, &received, 0);
3636         ok(hr == S_OK, "Error: GetPropertyBSTR returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
3637         ok(received != NULL, "Error: Expected the string not to be NULL.\n");
3638         ok(!SysStringLen(received), "Error: Expected the string to be of len=0 but it was %d instead.\n", SysStringLen(received));
3639         SysFreeString(received);
3640
3641         /* Make sure it handles the ZONE property correctly. */
3642         received = NULL;
3643         hr = IUri_GetPropertyBSTR(uri, Uri_PROPERTY_ZONE, &received, 0);
3644         ok(hr == S_FALSE, "Error: GetPropertyBSTR returned 0x%08x, expected 0x%08x.\n", hr, S_FALSE);
3645         ok(received != NULL, "Error: Expected the string not to be NULL.\n");
3646         ok(!SysStringLen(received), "Error: Expected the string to be of len=0 but it was %d instead.\n", SysStringLen(received));
3647         SysFreeString(received);
3648     }
3649     if(uri) IUri_Release(uri);
3650
3651     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
3652         uri_properties test = uri_tests[i];
3653         LPWSTR uriW;
3654         uri = NULL;
3655
3656         uriW = a2w(test.uri);
3657         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
3658         if(test.create_todo) {
3659             todo_wine {
3660                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
3661                         hr, test.create_expected, i);
3662             }
3663         } else {
3664             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
3665                     hr, test.create_expected, i);
3666         }
3667
3668         if(SUCCEEDED(hr)) {
3669             DWORD j;
3670
3671             /* Checks all the string properties of the uri. */
3672             for(j = Uri_PROPERTY_STRING_START; j <= Uri_PROPERTY_STRING_LAST; ++j) {
3673                 BSTR received = NULL;
3674                 uri_str_property prop = test.str_props[j];
3675
3676                 hr = IUri_GetPropertyBSTR(uri, j, &received, 0);
3677                 if(prop.todo) {
3678                     todo_wine {
3679                         ok(hr == prop.expected, "GetPropertyBSTR returned 0x%08x, expected 0x%08x. On uri_tests[%d].str_props[%d].\n",
3680                                 hr, prop.expected, i, j);
3681                     }
3682                     todo_wine {
3683                         ok(!strcmp_aw(prop.value, received) || broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
3684                                 "Expected %s but got %s on uri_tests[%d].str_props[%d].\n",
3685                                 prop.value, wine_dbgstr_w(received), i, j);
3686                     }
3687                     if (hr == E_NOTIMPL)  /* no point in continuing */
3688                     {
3689                         if(uri) IUri_Release(uri);
3690                         heap_free(uriW);
3691                         return;
3692                     }
3693                 } else {
3694                     ok(hr == prop.expected, "GetPropertyBSTR returned 0x%08x, expected 0x%08x. On uri_tests[%d].str_props[%d].\n",
3695                             hr, prop.expected, i, j);
3696                     ok(!strcmp_aw(prop.value, received) || broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
3697                             "Expected %s but got %s on uri_tests[%d].str_props[%d].\n",
3698                             prop.value, wine_dbgstr_w(received), i, j);
3699                 }
3700
3701                 SysFreeString(received);
3702             }
3703         }
3704
3705         if(uri) IUri_Release(uri);
3706
3707         heap_free(uriW);
3708     }
3709 }
3710
3711 static void test_IUri_GetPropertyDWORD(void) {
3712     IUri *uri = NULL;
3713     HRESULT hr;
3714     DWORD i;
3715
3716     hr = pCreateUri(http_urlW, 0, 0, &uri);
3717     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
3718     if(SUCCEEDED(hr)) {
3719         DWORD received = 0xdeadbeef;
3720
3721         hr = IUri_GetPropertyDWORD(uri, Uri_PROPERTY_DWORD_START, NULL, 0);
3722         ok(hr == E_INVALIDARG, "Error: GetPropertyDWORD returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
3723
3724         hr = IUri_GetPropertyDWORD(uri, Uri_PROPERTY_ABSOLUTE_URI, &received, 0);
3725         ok(hr == E_INVALIDARG, "Error: GetPropertyDWORD returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
3726         ok(received == 0, "Error: Expected received=%d but instead received=%d.\n", 0, received);
3727     }
3728     if(uri) IUri_Release(uri);
3729
3730     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
3731         uri_properties test = uri_tests[i];
3732         LPWSTR uriW;
3733         uri = NULL;
3734
3735         uriW = a2w(test.uri);
3736         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
3737         if(test.create_todo) {
3738             todo_wine {
3739                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
3740                         hr, test.create_expected, i);
3741             }
3742         } else {
3743             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
3744                     hr, test.create_expected, i);
3745         }
3746
3747         if(SUCCEEDED(hr)) {
3748             DWORD j;
3749
3750             /* Checks all the DWORD properties of the uri. */
3751             for(j = 0; j < sizeof(test.dword_props)/sizeof(test.dword_props[0]); ++j) {
3752                 DWORD received;
3753                 uri_dword_property prop = test.dword_props[j];
3754
3755                 hr = IUri_GetPropertyDWORD(uri, j+Uri_PROPERTY_DWORD_START, &received, 0);
3756                 if(prop.todo) {
3757                     todo_wine {
3758                         ok(hr == prop.expected, "GetPropertyDWORD returned 0x%08x, expected 0x%08x. On uri_tests[%d].dword_props[%d].\n",
3759                                 hr, prop.expected, i, j);
3760                     }
3761                     todo_wine {
3762                         ok(prop.value == received, "Expected %d but got %d on uri_tests[%d].dword_props[%d].\n",
3763                                 prop.value, received, i, j);
3764                     }
3765                 } else {
3766                     ok(hr == prop.expected, "GetPropertyDWORD returned 0x%08x, expected 0x%08x. On uri_tests[%d].dword_props[%d].\n",
3767                             hr, prop.expected, i, j);
3768                     ok(prop.value == received, "Expected %d but got %d on uri_tests[%d].dword_props[%d].\n",
3769                             prop.value, received, i, j);
3770                 }
3771             }
3772         }
3773
3774         if(uri) IUri_Release(uri);
3775
3776         heap_free(uriW);
3777     }
3778 }
3779
3780 /* Tests all the 'Get*' property functions which deal with strings. */
3781 static void test_IUri_GetStrProperties(void) {
3782     IUri *uri = NULL;
3783     HRESULT hr;
3784     DWORD i;
3785
3786     /* Make sure all the 'Get*' string property functions handle invalid args correctly. */
3787     hr = pCreateUri(http_urlW, 0, 0, &uri);
3788     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
3789     if(SUCCEEDED(hr)) {
3790         hr = IUri_GetAbsoluteUri(uri, NULL);
3791         ok(hr == E_POINTER, "Error: GetAbsoluteUri returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3792
3793         hr = IUri_GetAuthority(uri, NULL);
3794         ok(hr == E_POINTER, "Error: GetAuthority returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3795
3796         hr = IUri_GetDisplayUri(uri, NULL);
3797         ok(hr == E_POINTER, "Error: GetDisplayUri returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3798
3799         hr = IUri_GetDomain(uri, NULL);
3800         ok(hr == E_POINTER, "Error: GetDomain returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3801
3802         hr = IUri_GetExtension(uri, NULL);
3803         ok(hr == E_POINTER, "Error: GetExtension returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3804
3805         hr = IUri_GetFragment(uri, NULL);
3806         ok(hr == E_POINTER, "Error: GetFragment returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3807
3808         hr = IUri_GetHost(uri, NULL);
3809         ok(hr == E_POINTER, "Error: GetHost returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3810
3811         hr = IUri_GetPassword(uri, NULL);
3812         ok(hr == E_POINTER, "Error: GetPassword returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3813
3814         hr = IUri_GetPath(uri, NULL);
3815         ok(hr == E_POINTER, "Error: GetPath returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3816
3817         hr = IUri_GetPathAndQuery(uri, NULL);
3818         ok(hr == E_POINTER, "Error: GetPathAndQuery returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3819
3820         hr = IUri_GetQuery(uri, NULL);
3821         ok(hr == E_POINTER, "Error: GetQuery returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3822
3823         hr = IUri_GetRawUri(uri, NULL);
3824         ok(hr == E_POINTER, "Error: GetRawUri returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3825
3826         hr = IUri_GetSchemeName(uri, NULL);
3827         ok(hr == E_POINTER, "Error: GetSchemeName returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3828
3829         hr = IUri_GetUserInfo(uri, NULL);
3830         ok(hr == E_POINTER, "Error: GetUserInfo returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3831
3832         hr = IUri_GetUserName(uri, NULL);
3833         ok(hr == E_POINTER, "Error: GetUserName returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
3834     }
3835     if(uri) IUri_Release(uri);
3836
3837     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
3838         uri_properties test = uri_tests[i];
3839         LPWSTR uriW;
3840         uri = NULL;
3841
3842         uriW = a2w(test.uri);
3843         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
3844         if(test.create_todo) {
3845             todo_wine {
3846                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3847                         hr, test.create_expected, i);
3848             }
3849         } else {
3850             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3851                     hr, test.create_expected, i);
3852         }
3853
3854         if(SUCCEEDED(hr)) {
3855             uri_str_property prop;
3856             BSTR received = NULL;
3857
3858             /* GetDisplayUri() tests. */
3859             prop = test.str_props[Uri_PROPERTY_DISPLAY_URI];
3860             hr = IUri_GetDisplayUri(uri, &received);
3861             if (hr == E_NOTIMPL) goto skip_unimplemented;
3862             if(prop.todo) {
3863                 todo_wine {
3864                     ok(hr == prop.expected, "Error: GetDisplayUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3865                             hr, prop.expected, i);
3866                 }
3867                 todo_wine {
3868                     ok(!strcmp_aw(prop.value, received) || broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
3869                             "Error: Expected %s but got %s on uri_test[%d].\n",
3870                             prop.value, wine_dbgstr_w(received), i);
3871                 }
3872             } else {
3873                 ok(hr == prop.expected, "Error: GetDisplayUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3874                         hr, prop.expected, i);
3875                 ok(!strcmp_aw(prop.value, received) || broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
3876                         "Error: Expected %s but got %s on uri_tests[%d].\n",
3877                         prop.value, wine_dbgstr_w(received), i);
3878             }
3879             SysFreeString(received);
3880             received = NULL;
3881
3882         skip_unimplemented:
3883             /* GetAbsoluteUri() tests. */
3884             prop = test.str_props[Uri_PROPERTY_ABSOLUTE_URI];
3885             hr = IUri_GetAbsoluteUri(uri, &received);
3886             if(prop.todo) {
3887                 todo_wine {
3888                     ok(hr == prop.expected, "Error: GetAbsoluteUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3889                             hr, prop.expected, i);
3890                 }
3891                 todo_wine {
3892                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3893                             prop.value, wine_dbgstr_w(received), i);
3894                 }
3895             } else {
3896                 ok(hr == prop.expected, "Error: GetAbsoluteUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3897                         hr, prop.expected, i);
3898                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3899                         prop.value, wine_dbgstr_w(received), i);
3900             }
3901             SysFreeString(received);
3902             received = NULL;
3903
3904             /* GetAuthority() tests. */
3905             prop = test.str_props[Uri_PROPERTY_AUTHORITY];
3906             hr = IUri_GetAuthority(uri, &received);
3907             if(prop.todo) {
3908                 todo_wine {
3909                     ok(hr == prop.expected, "Error: GetAuthority returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3910                             hr, prop.expected, i);
3911                 }
3912                 todo_wine {
3913                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3914                             prop.value, wine_dbgstr_w(received), i);
3915                 }
3916             } else {
3917                 ok(hr == prop.expected, "Error: GetAuthority returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3918                         hr, prop.expected, i);
3919                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3920                         prop.value, wine_dbgstr_w(received), i);
3921             }
3922             SysFreeString(received);
3923             received = NULL;
3924
3925             /* GetDomain() tests. */
3926             prop = test.str_props[Uri_PROPERTY_DOMAIN];
3927             hr = IUri_GetDomain(uri, &received);
3928             if(prop.todo) {
3929                 todo_wine {
3930                     ok(hr == prop.expected, "Error: GetDomain returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3931                             hr, prop.expected, i);
3932                 }
3933                 todo_wine {
3934                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3935                             prop.value, wine_dbgstr_w(received), i);
3936                 }
3937             } else {
3938                 ok(hr == prop.expected, "Error: GetDomain returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3939                         hr, prop.expected, i);
3940                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3941                         prop.value, wine_dbgstr_w(received), i);
3942             }
3943             SysFreeString(received);
3944             received = NULL;
3945
3946             /* GetExtension() tests. */
3947             prop = test.str_props[Uri_PROPERTY_EXTENSION];
3948             hr = IUri_GetExtension(uri, &received);
3949             if(prop.todo) {
3950                 todo_wine {
3951                     ok(hr == prop.expected, "Error: GetExtension returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3952                             hr, prop.expected, i);
3953                 }
3954                 todo_wine {
3955                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3956                             prop.value, wine_dbgstr_w(received), i);
3957                 }
3958             } else {
3959                 ok(hr == prop.expected, "Error: GetExtension returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3960                         hr, prop.expected, i);
3961                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3962                         prop.value, wine_dbgstr_w(received), i);
3963             }
3964             SysFreeString(received);
3965             received = NULL;
3966
3967             /* GetFragment() tests. */
3968             prop = test.str_props[Uri_PROPERTY_FRAGMENT];
3969             hr = IUri_GetFragment(uri, &received);
3970             if(prop.todo) {
3971                 todo_wine {
3972                     ok(hr == prop.expected, "Error: GetFragment returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3973                             hr, prop.expected, i);
3974                 }
3975                 todo_wine {
3976                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3977                             prop.value, wine_dbgstr_w(received), i);
3978                 }
3979             } else {
3980                 ok(hr == prop.expected, "Error: GetFragment returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3981                         hr, prop.expected, i);
3982                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3983                         prop.value, wine_dbgstr_w(received), i);
3984             }
3985             SysFreeString(received);
3986             received = NULL;
3987
3988             /* GetHost() tests. */
3989             prop = test.str_props[Uri_PROPERTY_HOST];
3990             hr = IUri_GetHost(uri, &received);
3991             if(prop.todo) {
3992                 todo_wine {
3993                     ok(hr == prop.expected, "Error: GetHost returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
3994                             hr, prop.expected, i);
3995                 }
3996                 todo_wine {
3997                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
3998                             prop.value, wine_dbgstr_w(received), i);
3999                 }
4000             } else {
4001                 ok(hr == prop.expected, "Error: GetHost returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4002                         hr, prop.expected, i);
4003                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4004                         prop.value, wine_dbgstr_w(received), i);
4005             }
4006             SysFreeString(received);
4007             received = NULL;
4008
4009             /* GetPassword() tests. */
4010             prop = test.str_props[Uri_PROPERTY_PASSWORD];
4011             hr = IUri_GetPassword(uri, &received);
4012             if(prop.todo) {
4013                 todo_wine {
4014                     ok(hr == prop.expected, "Error: GetPassword returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4015                             hr, prop.expected, i);
4016                 }
4017                 todo_wine {
4018                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4019                             prop.value, wine_dbgstr_w(received), i);
4020                 }
4021             } else {
4022                 ok(hr == prop.expected, "Error: GetPassword returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4023                         hr, prop.expected, i);
4024                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4025                         prop.value, wine_dbgstr_w(received), i);
4026             }
4027             SysFreeString(received);
4028             received = NULL;
4029
4030             /* GetPath() tests. */
4031             prop = test.str_props[Uri_PROPERTY_PATH];
4032             hr = IUri_GetPath(uri, &received);
4033             if(prop.todo) {
4034                 todo_wine {
4035                     ok(hr == prop.expected, "Error: GetPath returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4036                             hr, prop.expected, i);
4037                 }
4038                 todo_wine {
4039                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4040                             prop.value, wine_dbgstr_w(received), i);
4041                 }
4042             } else {
4043                 ok(hr == prop.expected, "Error: GetPath returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4044                         hr, prop.expected, i);
4045                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4046                         prop.value, wine_dbgstr_w(received), i);
4047             }
4048             SysFreeString(received);
4049             received = NULL;
4050
4051             /* GetPathAndQuery() tests. */
4052             prop = test.str_props[Uri_PROPERTY_PATH_AND_QUERY];
4053             hr = IUri_GetPathAndQuery(uri, &received);
4054             if(prop.todo) {
4055                 todo_wine {
4056                     ok(hr == prop.expected, "Error: GetPathAndQuery returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4057                             hr, prop.expected, i);
4058                 }
4059                 todo_wine {
4060                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4061                             prop.value, wine_dbgstr_w(received), i);
4062                 }
4063             } else {
4064                 ok(hr == prop.expected, "Error: GetPathAndQuery returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4065                         hr, prop.expected, i);
4066                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4067                         prop.value, wine_dbgstr_w(received), i);
4068             }
4069             SysFreeString(received);
4070             received = NULL;
4071
4072             /* GetQuery() tests. */
4073             prop = test.str_props[Uri_PROPERTY_QUERY];
4074             hr = IUri_GetQuery(uri, &received);
4075             if(prop.todo) {
4076                 todo_wine {
4077                     ok(hr == prop.expected, "Error: GetQuery returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4078                             hr, prop.expected, i);
4079                 }
4080                 todo_wine {
4081                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4082                             prop.value, wine_dbgstr_w(received), i);
4083                 }
4084             } else {
4085                 ok(hr == prop.expected, "Error: GetQuery returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4086                         hr, prop.expected, i);
4087                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4088                         prop.value, wine_dbgstr_w(received), i);
4089             }
4090             SysFreeString(received);
4091             received = NULL;
4092
4093             /* GetRawUri() tests. */
4094             prop = test.str_props[Uri_PROPERTY_RAW_URI];
4095             hr = IUri_GetRawUri(uri, &received);
4096             if(prop.todo) {
4097                 todo_wine {
4098                     ok(hr == prop.expected, "Error: GetRawUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4099                             hr, prop.expected, i);
4100                 }
4101                 todo_wine {
4102                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4103                             prop.value, wine_dbgstr_w(received), i);
4104                 }
4105             } else {
4106                 ok(hr == prop.expected, "Error: GetRawUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4107                         hr, prop.expected, i);
4108                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4109                         prop.value, wine_dbgstr_w(received), i);
4110             }
4111             SysFreeString(received);
4112             received = NULL;
4113
4114             /* GetSchemeName() tests. */
4115             prop = test.str_props[Uri_PROPERTY_SCHEME_NAME];
4116             hr = IUri_GetSchemeName(uri, &received);
4117             if(prop.todo) {
4118                 todo_wine {
4119                     ok(hr == prop.expected, "Error: GetSchemeName returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4120                             hr, prop.expected, i);
4121                 }
4122                 todo_wine {
4123                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4124                             prop.value, wine_dbgstr_w(received), i);
4125                 }
4126             } else {
4127                 ok(hr == prop.expected, "Error: GetSchemeName returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4128                         hr, prop.expected, i);
4129                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4130                         prop.value, wine_dbgstr_w(received), i);
4131             }
4132             SysFreeString(received);
4133             received = NULL;
4134
4135             /* GetUserInfo() tests. */
4136             prop = test.str_props[Uri_PROPERTY_USER_INFO];
4137             hr = IUri_GetUserInfo(uri, &received);
4138             if(prop.todo) {
4139                 todo_wine {
4140                     ok(hr == prop.expected, "Error: GetUserInfo returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4141                             hr, prop.expected, i);
4142                 }
4143                 todo_wine {
4144                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4145                             prop.value, wine_dbgstr_w(received), i);
4146                 }
4147             } else {
4148                 ok(hr == prop.expected, "Error: GetUserInfo returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4149                         hr, prop.expected, i);
4150                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4151                         prop.value, wine_dbgstr_w(received), i);
4152             }
4153             SysFreeString(received);
4154             received = NULL;
4155
4156             /* GetUserName() tests. */
4157             prop = test.str_props[Uri_PROPERTY_USER_NAME];
4158             hr = IUri_GetUserName(uri, &received);
4159             if(prop.todo) {
4160                 todo_wine {
4161                     ok(hr == prop.expected, "Error: GetUserName returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4162                             hr, prop.expected, i);
4163                 }
4164                 todo_wine {
4165                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4166                             prop.value, wine_dbgstr_w(received), i);
4167                 }
4168             } else {
4169                 ok(hr == prop.expected, "Error: GetUserName returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4170                         hr, prop.expected, i);
4171                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
4172                         prop.value, wine_dbgstr_w(received), i);
4173             }
4174             SysFreeString(received);
4175         }
4176
4177         if(uri) IUri_Release(uri);
4178
4179         heap_free(uriW);
4180     }
4181 }
4182
4183 static void test_IUri_GetDwordProperties(void) {
4184     IUri *uri = NULL;
4185     HRESULT hr;
4186     DWORD i;
4187
4188     /* Make sure all the 'Get*' dword property functions handle invalid args correctly. */
4189     hr = pCreateUri(http_urlW, 0, 0, &uri);
4190     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
4191     if(SUCCEEDED(hr)) {
4192         hr = IUri_GetHostType(uri, NULL);
4193         ok(hr == E_INVALIDARG, "Error: GetHostType returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
4194
4195         hr = IUri_GetPort(uri, NULL);
4196         ok(hr == E_INVALIDARG, "Error: GetPort returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
4197
4198         hr = IUri_GetScheme(uri, NULL);
4199         ok(hr == E_INVALIDARG, "Error: GetScheme returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
4200
4201         hr = IUri_GetZone(uri, NULL);
4202         ok(hr == E_INVALIDARG, "Error: GetZone returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
4203     }
4204     if(uri) IUri_Release(uri);
4205
4206     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
4207         uri_properties test = uri_tests[i];
4208         LPWSTR uriW;
4209         uri = NULL;
4210
4211         uriW = a2w(test.uri);
4212         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
4213         if(test.create_todo) {
4214             todo_wine {
4215                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4216                         hr, test.create_expected, i);
4217             }
4218         } else {
4219             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4220                     hr, test.create_expected, i);
4221         }
4222
4223         if(SUCCEEDED(hr)) {
4224             uri_dword_property prop;
4225             DWORD received;
4226
4227             /* Assign an insane value so tests don't accidentally pass when
4228              * they shouldn't!
4229              */
4230             received = -9999999;
4231
4232             /* GetHostType() tests. */
4233             prop = test.dword_props[Uri_PROPERTY_HOST_TYPE-Uri_PROPERTY_DWORD_START];
4234             hr = IUri_GetHostType(uri, &received);
4235             if(prop.todo) {
4236                 todo_wine {
4237                     ok(hr == prop.expected, "Error: GetHostType returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4238                             hr, prop.expected, i);
4239                 }
4240                 todo_wine {
4241                     ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4242                 }
4243             } else {
4244                 ok(hr == prop.expected, "Error: GetHostType returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4245                         hr, prop.expected, i);
4246                 ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4247             }
4248             received = -9999999;
4249
4250             /* GetPort() tests. */
4251             prop = test.dword_props[Uri_PROPERTY_PORT-Uri_PROPERTY_DWORD_START];
4252             hr = IUri_GetPort(uri, &received);
4253             if(prop.todo) {
4254                 todo_wine {
4255                     ok(hr == prop.expected, "Error: GetPort returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4256                             hr, prop.expected, i);
4257                 }
4258                 todo_wine {
4259                     ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4260                 }
4261             } else {
4262                 ok(hr == prop.expected, "Error: GetPort returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4263                         hr, prop.expected, i);
4264                 ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4265             }
4266             received = -9999999;
4267
4268             /* GetScheme() tests. */
4269             prop = test.dword_props[Uri_PROPERTY_SCHEME-Uri_PROPERTY_DWORD_START];
4270             hr = IUri_GetScheme(uri, &received);
4271             if(prop.todo) {
4272                 todo_wine {
4273                     ok(hr == prop.expected, "Error: GetScheme returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4274                             hr, prop.expected, i);
4275                 }
4276                 todo_wine {
4277                     ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4278                 }
4279             } else {
4280                 ok(hr == prop.expected, "Error: GetScheme returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4281                         hr, prop.expected, i);
4282                 ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4283             }
4284             received = -9999999;
4285
4286             /* GetZone() tests. */
4287             prop = test.dword_props[Uri_PROPERTY_ZONE-Uri_PROPERTY_DWORD_START];
4288             hr = IUri_GetZone(uri, &received);
4289             if(prop.todo) {
4290                 todo_wine {
4291                     ok(hr == prop.expected, "Error: GetZone returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4292                             hr, prop.expected, i);
4293                 }
4294                 todo_wine {
4295                     ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4296                 }
4297             } else {
4298                 ok(hr == prop.expected, "Error: GetZone returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4299                         hr, prop.expected, i);
4300                 ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
4301             }
4302         }
4303
4304         if(uri) IUri_Release(uri);
4305
4306         heap_free(uriW);
4307     }
4308 }
4309
4310 static void test_IUri_GetPropertyLength(void) {
4311     IUri *uri = NULL;
4312     HRESULT hr;
4313     DWORD i;
4314
4315     /* Make sure it handles invalid args correctly. */
4316     hr = pCreateUri(http_urlW, 0, 0, &uri);
4317     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
4318     if(SUCCEEDED(hr)) {
4319         DWORD received = 0xdeadbeef;
4320
4321         hr = IUri_GetPropertyLength(uri, Uri_PROPERTY_STRING_START, NULL, 0);
4322         ok(hr == E_INVALIDARG, "Error: GetPropertyLength returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
4323
4324         hr = IUri_GetPropertyLength(uri, Uri_PROPERTY_DWORD_START, &received, 0);
4325         ok(hr == E_INVALIDARG, "Error: GetPropertyLength return 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
4326         ok(received == 0xdeadbeef, "Error: Expected 0xdeadbeef but got 0x%08x.\n", received);
4327     }
4328     if(uri) IUri_Release(uri);
4329
4330     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
4331         uri_properties test = uri_tests[i];
4332         LPWSTR uriW;
4333         uri = NULL;
4334
4335         uriW = a2w(test.uri);
4336         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
4337         if(test.create_todo) {
4338             todo_wine {
4339                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
4340                         hr, test.create_expected, i);
4341             }
4342         } else {
4343             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_test[%d].\n",
4344                     hr, test.create_expected, i);
4345         }
4346
4347         if(SUCCEEDED(hr)) {
4348             DWORD j;
4349
4350             for(j = Uri_PROPERTY_STRING_START; j <= Uri_PROPERTY_STRING_LAST; ++j) {
4351                 DWORD expectedLen, brokenLen, receivedLen;
4352                 uri_str_property prop = test.str_props[j];
4353
4354                 expectedLen = lstrlen(prop.value);
4355                 brokenLen = lstrlen(prop.broken_value);
4356
4357                 /* This won't be necessary once GetPropertyLength is implemented. */
4358                 receivedLen = -1;
4359
4360                 hr = IUri_GetPropertyLength(uri, j, &receivedLen, 0);
4361                 if(prop.todo) {
4362                     todo_wine {
4363                         ok(hr == prop.expected, "Error: GetPropertyLength returned 0x%08x, expected 0x%08x on uri_tests[%d].str_props[%d].\n",
4364                                 hr, prop.expected, i, j);
4365                     }
4366                     todo_wine {
4367                         ok(receivedLen == expectedLen || broken(receivedLen == brokenLen),
4368                                 "Error: Expected a length of %d but got %d on uri_tests[%d].str_props[%d].\n",
4369                                 expectedLen, receivedLen, i, j);
4370                     }
4371                 } else {
4372                     ok(hr == prop.expected, "Error: GetPropertyLength returned 0x%08x, expected 0x%08x on uri_tests[%d].str_props[%d].\n",
4373                             hr, prop.expected, i, j);
4374                     ok(receivedLen == expectedLen || broken(receivedLen == brokenLen),
4375                             "Error: Expected a length of %d but got %d on uri_tests[%d].str_props[%d].\n",
4376                             expectedLen, receivedLen, i, j);
4377                 }
4378             }
4379         }
4380
4381         if(uri) IUri_Release(uri);
4382
4383         heap_free(uriW);
4384     }
4385 }
4386
4387 static void test_IUri_GetProperties(void) {
4388     IUri *uri = NULL;
4389     HRESULT hr;
4390     DWORD i;
4391
4392     hr = pCreateUri(http_urlW, 0, 0, &uri);
4393     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
4394     if(SUCCEEDED(hr)) {
4395         hr = IUri_GetProperties(uri, NULL);
4396         ok(hr == E_INVALIDARG, "Error: GetProperties returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
4397     }
4398     if(uri) IUri_Release(uri);
4399
4400     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
4401         uri_properties test = uri_tests[i];
4402         LPWSTR uriW;
4403         uri = NULL;
4404
4405         uriW = a2w(test.uri);
4406         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
4407         if(test.create_todo) {
4408             todo_wine {
4409                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
4410             }
4411         } else {
4412             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
4413         }
4414
4415         if(SUCCEEDED(hr)) {
4416             DWORD received = 0;
4417             DWORD j;
4418
4419             hr = IUri_GetProperties(uri, &received);
4420             if(test.props_todo) {
4421                 todo_wine {
4422                     ok(hr == S_OK, "Error: GetProperties returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
4423                 }
4424                 if (hr == E_NOTIMPL)  /* no point in continuing */
4425                 {
4426                     if(uri) IUri_Release(uri);
4427                     heap_free(uriW);
4428                     return;
4429                 }
4430             } else {
4431                 ok(hr == S_OK, "Error: GetProperties returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
4432             }
4433
4434             for(j = 0; j <= Uri_PROPERTY_DWORD_LAST; ++j) {
4435                 /* (1 << j) converts a Uri_PROPERTY to its corresponding Uri_HAS_* flag mask. */
4436                 if(test.props & (1 << j)) {
4437                     if(test.props_todo) {
4438                         todo_wine {
4439                             ok(received & (1 << j), "Error: Expected flag for property %d on uri_tests[%d].\n", j, i);
4440                         }
4441                     } else {
4442                         ok(received & (1 << j), "Error: Expected flag for property %d on uri_tests[%d].\n", j, i);
4443                     }
4444                 } else {
4445                     /* NOTE: Since received is initialized to 0, this test will always pass while
4446                      * GetProperties is unimplemented.
4447                      */
4448                     ok(!(received & (1 << j)), "Error: Received flag for property %d when not expected on uri_tests[%d].\n", j, i);
4449                 }
4450             }
4451         }
4452
4453         if(uri) IUri_Release(uri);
4454
4455         heap_free(uriW);
4456     }
4457 }
4458
4459 static void test_IUri_HasProperty(void) {
4460     IUri *uri = NULL;
4461     HRESULT hr;
4462     DWORD i;
4463
4464     hr = pCreateUri(http_urlW, 0, 0, &uri);
4465     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
4466     if(SUCCEEDED(hr)) {
4467         hr = IUri_HasProperty(uri, Uri_PROPERTY_RAW_URI, NULL);
4468         ok(hr == E_INVALIDARG, "Error: HasProperty returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
4469     }
4470     if(uri) IUri_Release(uri);
4471
4472     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
4473         uri_properties test = uri_tests[i];
4474         LPWSTR uriW;
4475         uri = NULL;
4476
4477         uriW = a2w(test.uri);
4478
4479         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
4480         if(test.create_todo) {
4481             todo_wine {
4482                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
4483             }
4484         } else {
4485             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
4486         }
4487
4488         if(SUCCEEDED(hr)) {
4489             DWORD j;
4490
4491             for(j = 0; j <= Uri_PROPERTY_DWORD_LAST; ++j) {
4492                 /* Assign -1, then explicitly test for TRUE or FALSE later. */
4493                 BOOL received = -1;
4494
4495                 hr = IUri_HasProperty(uri, j, &received);
4496                 if(test.props_todo) {
4497                     todo_wine {
4498                         ok(hr == S_OK, "Error: HasProperty returned 0x%08x, expected 0x%08x for property %d on uri_tests[%d].\n",
4499                                 hr, S_OK, j, i);
4500                     }
4501                     if (hr == E_NOTIMPL)  /* no point in continuing */
4502                     {
4503                         if(uri) IUri_Release(uri);
4504                         heap_free(uriW);
4505                         return;
4506                     }
4507
4508                     /* Check if the property should be true. */
4509                     if(test.props & (1 << j)) {
4510                         todo_wine {
4511                             ok(received == TRUE, "Error: Expected to have property %d on uri_tests[%d].\n", j, i);
4512                         }
4513                     } else {
4514                         todo_wine {
4515                             ok(received == FALSE, "Error: Wasn't expecting to have property %d on uri_tests[%d].\n", j, i);
4516                         }
4517                     }
4518                 } else {
4519                     ok(hr == S_OK, "Error: HasProperty returned 0x%08x, expected 0x%08x for property %d on uri_tests[%d].\n",
4520                             hr, S_OK, j, i);
4521
4522                     if(test.props & (1 << j)) {
4523                         ok(received == TRUE, "Error: Expected to have property %d on uri_tests[%d].\n", j, i);
4524                     } else {
4525                         ok(received == FALSE, "Error: Wasn't expecting to have property %d on uri_tests[%d].\n", j, i);
4526                     }
4527                 }
4528             }
4529         }
4530
4531         if(uri) IUri_Release(uri);
4532
4533         heap_free(uriW);
4534     }
4535 }
4536
4537 static void test_IUri_IsEqual(void) {
4538     IUri *uriA, *uriB;
4539     HRESULT hrA, hrB;
4540     DWORD i;
4541
4542     uriA = uriB = NULL;
4543
4544     /* Make sure IsEqual handles invalid args correctly. */
4545     hrA = pCreateUri(http_urlW, 0, 0, &uriA);
4546     hrB = pCreateUri(http_urlW, 0, 0, &uriB);
4547     ok(hrA == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hrA, S_OK);
4548     ok(hrB == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hrB, S_OK);
4549     if(SUCCEEDED(hrA) && SUCCEEDED(hrB)) {
4550         BOOL equal = -1;
4551         hrA = IUri_IsEqual(uriA, NULL, &equal);
4552         ok(hrA == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x.\n", hrA, S_OK);
4553         ok(equal == FALSE, "Error: Expected equal to be FALSE, but was %d instead.\n", equal);
4554
4555         hrA = IUri_IsEqual(uriA, uriB, NULL);
4556         ok(hrA == E_POINTER, "Error: IsEqual returned 0x%08x, expected 0x%08x.\n", hrA, E_POINTER);
4557     }
4558     if(uriA) IUri_Release(uriA);
4559     if(uriB) IUri_Release(uriB);
4560
4561     for(i = 0; i < sizeof(equality_tests)/sizeof(equality_tests[0]); ++i) {
4562         uri_equality test = equality_tests[i];
4563         LPWSTR uriA_W, uriB_W;
4564
4565         uriA = uriB = NULL;
4566
4567         uriA_W = a2w(test.a);
4568         uriB_W = a2w(test.b);
4569
4570         hrA = pCreateUri(uriA_W, test.create_flags_a, 0, &uriA);
4571         if(test.create_todo_a) {
4572             todo_wine {
4573                 ok(hrA == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].a\n",
4574                         hrA, S_OK, i);
4575             }
4576         } else {
4577             ok(hrA == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].a\n",
4578                     hrA, S_OK, i);
4579         }
4580
4581         hrB = pCreateUri(uriB_W, test.create_flags_b, 0, &uriB);
4582         if(test.create_todo_b) {
4583             todo_wine {
4584                 ok(hrB == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].b\n",
4585                         hrB, S_OK, i);
4586             }
4587         } else {
4588             ok(hrB == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].b\n",
4589                     hrB, S_OK, i);
4590         }
4591
4592         if(SUCCEEDED(hrA) && SUCCEEDED(hrB)) {
4593             BOOL equal = -1;
4594
4595             hrA = IUri_IsEqual(uriA, uriB, &equal);
4596             if(test.todo) {
4597                 todo_wine {
4598                     ok(hrA == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x on equality_tests[%d].\n",
4599                             hrA, S_OK, i);
4600                 }
4601                 todo_wine {
4602                     ok(equal == test.equal, "Error: Expected the comparison to be %d on equality_tests[%d].\n", test.equal, i);
4603                 }
4604             } else {
4605                 ok(hrA == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x on equality_tests[%d].\n", hrA, S_OK, i);
4606                 ok(equal == test.equal, "Error: Expected the comparison to be %d on equality_tests[%d].\n", test.equal, i);
4607             }
4608         }
4609         if(uriA) IUri_Release(uriA);
4610         if(uriB) IUri_Release(uriB);
4611
4612         heap_free(uriA_W);
4613         heap_free(uriB_W);
4614     }
4615 }
4616
4617 START_TEST(uri) {
4618     HMODULE hurlmon;
4619
4620     hurlmon = GetModuleHandle("urlmon.dll");
4621     pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
4622
4623     if(!pCreateUri) {
4624         win_skip("CreateUri is not present, skipping tests.\n");
4625         return;
4626     }
4627
4628     trace("test CreateUri invalid flags...\n");
4629     test_CreateUri_InvalidFlags();
4630
4631     trace("test CreateUri invalid args...\n");
4632     test_CreateUri_InvalidArgs();
4633
4634     trace("test CreateUri invalid URIs...\n");
4635     test_CreateUri_InvalidUri();
4636
4637     trace("test IUri_GetPropertyBSTR...\n");
4638     test_IUri_GetPropertyBSTR();
4639
4640     trace("test IUri_GetPropertyDWORD...\n");
4641     test_IUri_GetPropertyDWORD();
4642
4643     trace("test IUri_GetStrProperties...\n");
4644     test_IUri_GetStrProperties();
4645
4646     trace("test IUri_GetDwordProperties...\n");
4647     test_IUri_GetDwordProperties();
4648
4649     trace("test IUri_GetPropertyLength...\n");
4650     test_IUri_GetPropertyLength();
4651
4652     trace("test IUri_GetProperties...\n");
4653     test_IUri_GetProperties();
4654
4655     trace("test IUri_HasProperty...\n");
4656     test_IUri_HasProperty();
4657
4658     trace("test IUri_IsEqual...\n");
4659     test_IUri_IsEqual();
4660 }