urlmon/tests: Added some more test URIs.
[wine] / dlls / urlmon / tests / uri.c
1 /*
2  * UrlMon IUri tests
3  *
4  * Copyright 2010 Thomas Mullaly
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /*
22  * IUri testing framework goals:
23  *  - Test invalid args
24  *      - invalid flags
25  *      - invalid args (IUri, uri string)
26  *  - Test parsing for components when no canonicalization occurs
27  *  - Test parsing for components when canonicalization occurs.
28  *  - More tests...
29  */
30
31 #include <wine/test.h>
32 #include <stdarg.h>
33 #include <stddef.h>
34
35 #define COBJMACROS
36
37 #include "windef.h"
38 #include "winbase.h"
39 #include "urlmon.h"
40 #include "shlwapi.h"
41
42 #define URI_STR_PROPERTY_COUNT Uri_PROPERTY_STRING_LAST+1
43 #define URI_DWORD_PROPERTY_COUNT (Uri_PROPERTY_DWORD_LAST - Uri_PROPERTY_DWORD_START)+1
44
45 static HRESULT (WINAPI *pCreateUri)(LPCWSTR, DWORD, DWORD_PTR, IUri**);
46
47 static const WCHAR http_urlW[] = { 'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q',
48         '.','o','r','g','/',0};
49
50 typedef struct _uri_create_flag_test {
51     DWORD   flags;
52     HRESULT expected;
53 } uri_create_flag_test;
54
55 static const uri_create_flag_test invalid_flag_tests[] = {
56     /* Set of invalid flag combinations to test for. */
57     {Uri_CREATE_DECODE_EXTRA_INFO | Uri_CREATE_NO_DECODE_EXTRA_INFO, E_INVALIDARG},
58     {Uri_CREATE_CANONICALIZE | Uri_CREATE_NO_CANONICALIZE, E_INVALIDARG},
59     {Uri_CREATE_CRACK_UNKNOWN_SCHEMES | Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES, E_INVALIDARG},
60     {Uri_CREATE_PRE_PROCESS_HTML_URI | Uri_CREATE_NO_PRE_PROCESS_HTML_URI, E_INVALIDARG},
61     {Uri_CREATE_IE_SETTINGS | Uri_CREATE_NO_IE_SETTINGS, E_INVALIDARG}
62 };
63
64 typedef struct _uri_str_property {
65     const char* value;
66     HRESULT     expected;
67     BOOL        todo;
68     const char* broken_value;
69 } uri_str_property;
70
71 typedef struct _uri_dword_property {
72     DWORD   value;
73     HRESULT expected;
74     BOOL    todo;
75 } uri_dword_property;
76
77 typedef struct _uri_properties {
78     const char*         uri;
79     DWORD               create_flags;
80     HRESULT             create_expected;
81     BOOL                create_todo;
82     DWORD               props;
83     BOOL                props_todo;
84
85     uri_str_property    str_props[URI_STR_PROPERTY_COUNT];
86     uri_dword_property  dword_props[URI_DWORD_PROPERTY_COUNT];
87 } uri_properties;
88
89 static const uri_properties uri_tests[] = {
90     {   "http://www.winehq.org/tests/../tests/../..", 0, S_OK, FALSE,
91         /* A flag bitmap containing all the Uri_HAS_* flags that correspond to this uri. */
92         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
93         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|
94         Uri_HAS_PORT|Uri_HAS_SCHEME,
95         TRUE,
96         {
97             {"http://www.winehq.org/",S_OK,TRUE},                       /* ABSOLUTE_URI */
98             {"www.winehq.org",S_OK,TRUE},                               /* AUTHORITY */
99             {"http://www.winehq.org/",S_OK,TRUE},                       /* DISPLAY_URI */
100             {"winehq.org",S_OK,TRUE},                                   /* DOMAIN */
101             {"",S_FALSE,TRUE},                                          /* EXTENSION */
102             {"",S_FALSE,TRUE},                                          /* FRAGMENT */
103             {"www.winehq.org",S_OK,FALSE},                              /* HOST */
104             {"",S_FALSE,FALSE},                                         /* PASSWORD */
105             {"/",S_OK,TRUE},                                            /* PATH */
106             {"/",S_OK,TRUE},                                            /* PATH_AND_QUERY */
107             {"",S_FALSE,TRUE},                                          /* 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,TRUE},                                   /* HOST_TYPE */
115             {80,S_OK,FALSE},                                            /* PORT */
116             {URL_SCHEME_HTTP,S_OK,FALSE},                               /* SCHEME */
117             {URLZONE_INVALID,E_NOTIMPL,FALSE}                           /* ZONE */
118         }
119     },
120     {   "http://winehq.org/tests/.././tests", 0, S_OK, FALSE,
121         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
122         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|
123         Uri_HAS_PORT|Uri_HAS_SCHEME,
124         TRUE,
125         {
126             {"http://winehq.org/tests",S_OK,TRUE},
127             {"winehq.org",S_OK,TRUE},
128             {"http://winehq.org/tests",S_OK,TRUE},
129             {"winehq.org",S_OK,TRUE},
130             {"",S_FALSE,TRUE},
131             {"",S_FALSE,TRUE},
132             {"winehq.org",S_OK,FALSE},
133             {"",S_FALSE,FALSE},
134             {"/tests",S_OK,TRUE},
135             {"/tests",S_OK,TRUE},
136             {"",S_FALSE,TRUE},
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,TRUE},
144             {80,S_OK,FALSE},
145             {URL_SCHEME_HTTP,S_OK,FALSE},
146             {URLZONE_INVALID,E_NOTIMPL,FALSE}
147         }
148     },
149     {   "HtTp://www.winehq.org/tests/..?query=x&return=y", 0, S_OK, FALSE,
150         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
151         Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
152         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
153         TRUE,
154         {
155             {"http://www.winehq.org/?query=x&return=y",S_OK,TRUE},
156             {"www.winehq.org",S_OK,TRUE},
157             {"http://www.winehq.org/?query=x&return=y",S_OK,TRUE},
158             {"winehq.org",S_OK,TRUE},
159             {"",S_FALSE,TRUE},
160             {"",S_FALSE,TRUE},
161             {"www.winehq.org",S_OK,FALSE},
162             {"",S_FALSE,FALSE},
163             {"/",S_OK,TRUE},
164             {"/?query=x&return=y",S_OK,TRUE},
165             {"?query=x&return=y",S_OK,TRUE},
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,TRUE},
173             {80,S_OK,FALSE},
174             {URL_SCHEME_HTTP,S_OK,FALSE},
175             {URLZONE_INVALID,E_NOTIMPL,FALSE},
176         }
177     },
178     {   "hTTp://us%45r%3Ainfo@examp%4CE.com:80/path/a/b/./c/../%2E%2E/Forbidden'<|> Characters", 0, S_OK, FALSE,
179         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|Uri_HAS_PATH|
180         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|
181         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
182         TRUE,
183         {
184             {"http://usEr%3Ainfo@example.com/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,TRUE},
185             {"usEr%3Ainfo@example.com",S_OK,TRUE},
186             {"http://example.com/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,TRUE},
187             {"example.com",S_OK,TRUE},
188             {"",S_FALSE,TRUE},
189             {"",S_FALSE,TRUE},
190             {"example.com",S_OK,FALSE},
191             {"",S_FALSE,FALSE},
192             {"/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,TRUE},
193             {"/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,TRUE},
194             {"",S_FALSE,TRUE},
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,TRUE},
202             {80,S_OK,FALSE},
203             {URL_SCHEME_HTTP,S_OK,FALSE},
204             {URLZONE_INVALID,E_NOTIMPL,FALSE},
205         }
206     },
207     {   "ftp://winepass:wine@ftp.winehq.org:9999/dir/foo bar.txt", 0, S_OK, FALSE,
208         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_EXTENSION|
209         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
210         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
211         Uri_HAS_SCHEME,
212         TRUE,
213         {
214             {"ftp://winepass:wine@ftp.winehq.org:9999/dir/foo%20bar.txt",S_OK,TRUE},
215             {"winepass:wine@ftp.winehq.org:9999",S_OK,TRUE},
216             {"ftp://ftp.winehq.org:9999/dir/foo%20bar.txt",S_OK,TRUE},
217             {"winehq.org",S_OK,TRUE},
218             {".txt",S_OK,TRUE},
219             {"",S_FALSE,TRUE},
220             {"ftp.winehq.org",S_OK,FALSE},
221             {"wine",S_OK,FALSE},
222             {"/dir/foo%20bar.txt",S_OK,TRUE},
223             {"/dir/foo%20bar.txt",S_OK,TRUE},
224             {"",S_FALSE,TRUE},
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,TRUE},
232             {9999,S_OK,FALSE},
233             {URL_SCHEME_FTP,S_OK,FALSE},
234             {URLZONE_INVALID,E_NOTIMPL,FALSE}
235         }
236     },
237     {   "file://c:\\tests\\../tests/foo%20bar.mp3", 0, S_OK, FALSE,
238         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
239         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
240         TRUE,
241         {
242             {"file:///c:/tests/foo%2520bar.mp3",S_OK,TRUE},
243             {"",S_FALSE,TRUE},
244             {"file:///c:/tests/foo%2520bar.mp3",S_OK,TRUE},
245             {"",S_FALSE,TRUE},
246             {".mp3",S_OK,TRUE},
247             {"",S_FALSE,TRUE},
248             {"",S_FALSE,FALSE},
249             {"",S_FALSE,FALSE},
250             {"/c:/tests/foo%2520bar.mp3",S_OK,TRUE},
251             {"/c:/tests/foo%2520bar.mp3",S_OK,TRUE},
252             {"",S_FALSE,TRUE},
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,TRUE},
260             {0,S_FALSE,FALSE},
261             {URL_SCHEME_FILE,S_OK,FALSE},
262             {URLZONE_INVALID,E_NOTIMPL,FALSE}
263         }
264     },
265     {   "FILE://localhost/test dir\\../tests/test%20file.README.txt", 0, S_OK, FALSE,
266         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
267         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
268         TRUE,
269         {
270             {"file:///tests/test%20file.README.txt",S_OK,TRUE},
271             {"",S_FALSE,TRUE},
272             {"file:///tests/test%20file.README.txt",S_OK,TRUE},
273             {"",S_FALSE,TRUE},
274             {".txt",S_OK,TRUE},
275             {"",S_FALSE,TRUE},
276             {"",S_FALSE,FALSE},
277             {"",S_FALSE,FALSE},
278             {"/tests/test%20file.README.txt",S_OK,TRUE},
279             {"/tests/test%20file.README.txt",S_OK,TRUE},
280             {"",S_FALSE,TRUE},
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,TRUE},
288             {0,S_FALSE,FALSE},
289             {URL_SCHEME_FILE,S_OK,FALSE},
290             {URLZONE_INVALID,E_NOTIMPL,FALSE}
291         }
292     },
293     {   "urn:nothing:should:happen here", 0, S_OK, FALSE,
294         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|
295         Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
296         TRUE,
297         {
298             {"urn:nothing:should:happen here",S_OK,TRUE},
299             {"",S_FALSE,TRUE},
300             {"urn:nothing:should:happen here",S_OK,TRUE},
301             {"",S_FALSE,TRUE},
302             {"",S_FALSE,TRUE},
303             {"",S_FALSE,TRUE},
304             {"",S_FALSE,FALSE},
305             {"",S_FALSE,FALSE},
306             {"nothing:should:happen here",S_OK,TRUE},
307             {"nothing:should:happen here",S_OK,TRUE},
308             {"",S_FALSE,TRUE},
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,TRUE},
316             {0,S_FALSE,FALSE},
317             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
318             {URLZONE_INVALID,E_NOTIMPL,FALSE}
319         }
320     },
321     {   "http://127.0.0.1/tests/../test dir/./test.txt", 0, S_OK, FALSE,
322         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|
323         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
324         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
325         TRUE,
326         {
327             {"http://127.0.0.1/test%20dir/test.txt",S_OK,TRUE},
328             {"127.0.0.1",S_OK,TRUE},
329             {"http://127.0.0.1/test%20dir/test.txt",S_OK,TRUE},
330             {"",S_FALSE,TRUE},
331             {".txt",S_OK,TRUE},
332             {"",S_FALSE,TRUE},
333             {"127.0.0.1",S_OK,FALSE},
334             {"",S_FALSE,FALSE},
335             {"/test%20dir/test.txt",S_OK,TRUE},
336             {"/test%20dir/test.txt",S_OK,TRUE},
337             {"",S_FALSE,TRUE},
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,TRUE},
345             {80,S_OK,FALSE},
346             {URL_SCHEME_HTTP,S_OK,FALSE},
347             {URLZONE_INVALID,E_NOTIMPL,FALSE}
348         }
349     },
350     {   "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]", 0, S_OK, FALSE,
351         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
352         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
353         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
354         TRUE,
355         {
356             {"http://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]/",S_OK,TRUE},
357             {"[fedc:ba98:7654:3210:fedc:ba98:7654:3210]",S_OK,TRUE},
358             {"http://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]/",S_OK,TRUE},
359             {"",S_FALSE,TRUE},
360             {"",S_FALSE,TRUE},
361             {"",S_FALSE,TRUE},
362             {"fedc:ba98:7654:3210:fedc:ba98:7654:3210",S_OK,FALSE},
363             {"",S_FALSE,FALSE},
364             {"/",S_OK,TRUE},
365             {"/",S_OK,TRUE},
366             {"",S_FALSE,TRUE},
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,TRUE},
374             {80,S_OK,FALSE},
375             {URL_SCHEME_HTTP,S_OK,FALSE},
376             {URLZONE_INVALID,E_NOTIMPL,FALSE}
377         }
378     },
379     {   "ftp://[::13.1.68.3]", 0, S_OK, FALSE,
380         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
381         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
382         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
383         TRUE,
384         {
385             {"ftp://[::13.1.68.3]/",S_OK,TRUE},
386             {"[::13.1.68.3]",S_OK,TRUE},
387             {"ftp://[::13.1.68.3]/",S_OK,TRUE},
388             {"",S_FALSE,TRUE},
389             {"",S_FALSE,TRUE},
390             {"",S_FALSE,TRUE},
391             {"::13.1.68.3",S_OK,FALSE},
392             {"",S_FALSE,FALSE},
393             {"/",S_OK,TRUE},
394             {"/",S_OK,TRUE},
395             {"",S_FALSE,TRUE},
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,TRUE},
403             {21,S_OK,FALSE},
404             {URL_SCHEME_FTP,S_OK,FALSE},
405             {URLZONE_INVALID,E_NOTIMPL,FALSE}
406         }
407     },
408     {   "http://[FEDC:BA98:0:0:0:0:0:3210]", 0, S_OK, FALSE,
409         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
410         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
411         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
412         TRUE,
413         {
414             {"http://[fedc:ba98::3210]/",S_OK,TRUE},
415             {"[fedc:ba98::3210]",S_OK,TRUE},
416             {"http://[fedc:ba98::3210]/",S_OK,TRUE},
417             {"",S_FALSE,TRUE},
418             {"",S_FALSE,TRUE},
419             {"",S_FALSE,TRUE},
420             {"fedc:ba98::3210",S_OK,FALSE},
421             {"",S_FALSE,FALSE},
422             {"/",S_OK,TRUE},
423             {"/",S_OK,TRUE},
424             {"",S_FALSE,TRUE},
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,TRUE},
432             {80,S_OK,FALSE},
433             {URL_SCHEME_HTTP,S_OK,FALSE},
434             {URLZONE_INVALID,E_NOTIMPL,FALSE}
435         }
436     },
437     {   "1234://www.winehq.org", 0, S_OK, FALSE,
438         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
439         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
440         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
441         TRUE,
442         {
443             {"1234://www.winehq.org/",S_OK,TRUE},
444             {"www.winehq.org",S_OK,TRUE},
445             {"1234://www.winehq.org/",S_OK,TRUE},
446             {"winehq.org",S_OK,TRUE},
447             {"",S_FALSE,TRUE},
448             {"",S_FALSE,TRUE},
449             {"www.winehq.org",S_OK,FALSE},
450             {"",S_FALSE,FALSE},
451             {"/",S_OK,TRUE},
452             {"/",S_OK,TRUE},
453             {"",S_FALSE,TRUE},
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,TRUE},
461             {0,S_FALSE,FALSE},
462             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
463             {URLZONE_INVALID,E_NOTIMPL,FALSE}
464         }
465     },
466     /* Test's to make sure the parser/canonicalizer handles implicit file schemes correctly. */
467     {   "C:/test/test.mp3", Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, S_OK, FALSE,
468         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
469         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
470         TRUE,
471         {
472             {"file:///C:/test/test.mp3",S_OK,TRUE},
473             {"",S_FALSE,TRUE},
474             {"file:///C:/test/test.mp3",S_OK,TRUE},
475             {"",S_FALSE,TRUE},
476             {".mp3",S_OK,TRUE},
477             {"",S_FALSE,TRUE},
478             {"",S_FALSE,FALSE},
479             {"",S_FALSE,FALSE},
480             {"/C:/test/test.mp3",S_OK,TRUE},
481             {"/C:/test/test.mp3",S_OK,TRUE},
482             {"",S_FALSE,TRUE},
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,TRUE},
490             {0,S_FALSE,FALSE},
491             {URL_SCHEME_FILE,S_OK,FALSE},
492             {URLZONE_INVALID,E_NOTIMPL,FALSE}
493         }
494     },
495     /* Test's to make sure the parser/canonicalizer handles implicit file schemes correctly. */
496     {   "\\\\Server/test.mp3", Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, S_OK, FALSE,
497         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|
498         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_HOST|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
499         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
500         TRUE,
501         {
502             {"file://server/test.mp3",S_OK,TRUE},
503             {"server",S_OK,TRUE},
504             {"file://server/test.mp3",S_OK,TRUE},
505             {"",S_FALSE,TRUE},
506             {".mp3",S_OK,TRUE},
507             {"",S_FALSE,TRUE},
508             {"server",S_OK,FALSE},
509             {"",S_FALSE,FALSE},
510             {"/test.mp3",S_OK,TRUE},
511             {"/test.mp3",S_OK,TRUE},
512             {"",S_FALSE,TRUE},
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,TRUE},
520             {0,S_FALSE,FALSE},
521             {URL_SCHEME_FILE,S_OK,FALSE},
522             {URLZONE_INVALID,E_NOTIMPL,FALSE}
523         }
524     },
525     {   "www.winehq.org/test", Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME, S_OK, FALSE,
526         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
527         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|
528         Uri_HAS_SCHEME,
529         TRUE,
530         {
531             {"*:www.winehq.org/test",S_OK,TRUE},
532             {"www.winehq.org",S_OK,TRUE},
533             {"*:www.winehq.org/test",S_OK,TRUE},
534             {"winehq.org",S_OK,TRUE},
535             {"",S_FALSE,TRUE},
536             {"",S_FALSE,TRUE},
537             {"www.winehq.org",S_OK,FALSE},
538             {"",S_FALSE,FALSE},
539             {"/test",S_OK,TRUE},
540             {"/test",S_OK,TRUE},
541             {"",S_FALSE,TRUE},
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,TRUE},
549             {0,S_FALSE,FALSE},
550             {URL_SCHEME_WILDCARD,S_OK,FALSE},
551             {URLZONE_INVALID,E_NOTIMPL,FALSE}
552         }
553     },
554     /* Valid since the '*' is the only character in the scheme name. */
555     {   "*:www.winehq.org/test", 0, S_OK, FALSE,
556         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
557         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|
558         Uri_HAS_SCHEME,
559         TRUE,
560         {
561             {"*:www.winehq.org/test",S_OK,TRUE},
562             {"www.winehq.org",S_OK,TRUE},
563             {"*:www.winehq.org/test",S_OK,TRUE},
564             {"winehq.org",S_OK,TRUE},
565             {"",S_FALSE,TRUE},
566             {"",S_FALSE,TRUE},
567             {"www.winehq.org",S_OK,FALSE},
568             {"",S_FALSE,FALSE},
569             {"/test",S_OK,TRUE},
570             {"/test",S_OK,TRUE},
571             {"",S_FALSE,TRUE},
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,TRUE},
579             {0,S_FALSE,FALSE},
580             {URL_SCHEME_WILDCARD,S_OK,FALSE},
581             {URLZONE_INVALID,E_NOTIMPL,FALSE}
582         }
583     },
584     {   "/../some dir/test.ext", Uri_CREATE_ALLOW_RELATIVE, S_OK, FALSE,
585         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
586         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
587         TRUE,
588         {
589             {"/../some dir/test.ext",S_OK,TRUE},
590             {"",S_FALSE,TRUE},
591             {"/../some dir/test.ext",S_OK,TRUE},
592             {"",S_FALSE,TRUE},
593             {".ext",S_OK,TRUE},
594             {"",S_FALSE,TRUE},
595             {"",S_FALSE,FALSE},
596             {"",S_FALSE,FALSE},
597             {"/../some dir/test.ext",S_OK,TRUE},
598             {"/../some dir/test.ext",S_OK,TRUE},
599             {"",S_FALSE,TRUE},
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,TRUE},
607             {0,S_FALSE,FALSE},
608             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
609             {URLZONE_INVALID,E_NOTIMPL,FALSE}
610         }
611     },
612     {   "//implicit/wildcard/uri scheme", Uri_CREATE_ALLOW_RELATIVE|Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME, S_OK, FALSE,
613         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|Uri_HAS_PATH|
614         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
615         TRUE,
616         {
617             {"*://implicit/wildcard/uri%20scheme",S_OK,TRUE},
618             {"",S_OK,TRUE},
619             {"*://implicit/wildcard/uri%20scheme",S_OK,TRUE},
620             {"",S_FALSE,TRUE},
621             {"",S_FALSE,TRUE},
622             {"",S_FALSE,TRUE},
623             {"",S_OK,FALSE},
624             {"",S_FALSE,FALSE},
625             {"//implicit/wildcard/uri%20scheme",S_OK,TRUE},
626             {"//implicit/wildcard/uri%20scheme",S_OK,TRUE},
627             {"",S_FALSE,TRUE},
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,TRUE},
635             {0,S_FALSE,FALSE},
636             {URL_SCHEME_WILDCARD,S_OK,FALSE},
637             {URLZONE_INVALID,E_NOTIMPL,FALSE}
638         }
639     },
640     /* URI is considered opaque since CREATE_NO_CRACK_UNKNOWN_SCHEMES is set and its an unknown scheme. */
641     {   "zip://google.com", Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES, S_OK, FALSE,
642         Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
643         Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME_NAME|
644         Uri_HAS_SCHEME,
645         TRUE,
646         {
647             {"zip:/.//google.com",S_OK,TRUE},
648             {"",S_FALSE,TRUE},
649             {"zip:/.//google.com",S_OK,TRUE},
650             {"",S_FALSE,TRUE},
651             {".com",S_OK,TRUE},
652             {"",S_FALSE,TRUE},
653             {"",S_FALSE,FALSE},
654             {"",S_FALSE,FALSE},
655             {"/.//google.com",S_OK,TRUE},
656             {"/.//google.com",S_OK,TRUE},
657             {"",S_FALSE,TRUE},
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,TRUE},
665             {0,S_FALSE,FALSE},
666             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
667             {URLZONE_INVALID,E_NOTIMPL,FALSE}
668         }
669     },
670     /* Windows uses the first occurence of ':' to delimit the userinfo. */
671     {   "ftp://user:pass:word@winehq.org/", 0, S_OK, FALSE,
672         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
673         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
674         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
675         Uri_HAS_SCHEME,
676         TRUE,
677         {
678             {"ftp://user:pass:word@winehq.org/",S_OK,TRUE},
679             {"user:pass:word@winehq.org",S_OK,TRUE},
680             {"ftp://winehq.org/",S_OK,TRUE},
681             {"winehq.org",S_OK,TRUE},
682             {"",S_FALSE,TRUE},
683             {"",S_FALSE,TRUE},
684             {"winehq.org",S_OK,FALSE},
685             {"pass:word",S_OK,FALSE},
686             {"/",S_OK,TRUE},
687             {"/",S_OK,TRUE},
688             {"",S_FALSE,TRUE},
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,TRUE},
696             {21,S_OK,FALSE},
697             {URL_SCHEME_FTP,S_OK,FALSE},
698             {URLZONE_INVALID,E_NOTIMPL,FALSE}
699         }
700     },
701     /* Make sure % encoded unreserved characters are decoded. */
702     {   "ftp://w%49%4Ee:PA%53%53@ftp.google.com/", 0, S_OK, FALSE,
703         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
704         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
705         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
706         Uri_HAS_SCHEME,
707         TRUE,
708         {
709             {"ftp://wINe:PASS@ftp.google.com/",S_OK,TRUE},
710             {"wINe:PASS@ftp.google.com",S_OK,TRUE},
711             {"ftp://ftp.google.com/",S_OK,TRUE},
712             {"google.com",S_OK,TRUE},
713             {"",S_FALSE,TRUE},
714             {"",S_FALSE,TRUE},
715             {"ftp.google.com",S_OK,FALSE},
716             {"PASS",S_OK,FALSE},
717             {"/",S_OK,TRUE},
718             {"/",S_OK,TRUE},
719             {"",S_FALSE,TRUE},
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,TRUE},
727             {21,S_OK,FALSE},
728             {URL_SCHEME_FTP,S_OK,FALSE},
729             {URLZONE_INVALID,E_NOTIMPL,FALSE}
730         }
731     },
732     /* Make sure % encoded characters which are NOT unreserved are NOT decoded. */
733     {   "ftp://w%5D%5Be:PA%7B%7D@ftp.google.com/", 0, S_OK, FALSE,
734         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
735         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
736         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
737         Uri_HAS_SCHEME,
738         TRUE,
739         {
740             {"ftp://w%5D%5Be:PA%7B%7D@ftp.google.com/",S_OK,TRUE},
741             {"w%5D%5Be:PA%7B%7D@ftp.google.com",S_OK,TRUE},
742             {"ftp://ftp.google.com/",S_OK,TRUE},
743             {"google.com",S_OK,TRUE},
744             {"",S_FALSE,TRUE},
745             {"",S_FALSE,TRUE},
746             {"ftp.google.com",S_OK,FALSE},
747             {"PA%7B%7D",S_OK,FALSE},
748             {"/",S_OK,TRUE},
749             {"/",S_OK,TRUE},
750             {"",S_FALSE,TRUE},
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,TRUE},
758             {21,S_OK,FALSE},
759             {URL_SCHEME_FTP,S_OK,FALSE},
760             {URLZONE_INVALID,E_NOTIMPL,FALSE}
761         }
762     },
763     /* You're allowed to have an empty password portion in the userinfo section. */
764     {   "ftp://empty:@ftp.google.com/", 0, S_OK, FALSE,
765         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
766         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
767         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
768         Uri_HAS_SCHEME,
769         TRUE,
770         {
771             {"ftp://empty:@ftp.google.com/",S_OK,TRUE},
772             {"empty:@ftp.google.com",S_OK,TRUE},
773             {"ftp://ftp.google.com/",S_OK,TRUE},
774             {"google.com",S_OK,TRUE},
775             {"",S_FALSE,TRUE},
776             {"",S_FALSE,TRUE},
777             {"ftp.google.com",S_OK,FALSE},
778             {"",S_OK,FALSE},
779             {"/",S_OK,TRUE},
780             {"/",S_OK,TRUE},
781             {"",S_FALSE,TRUE},
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,TRUE},
789             {21,S_OK,FALSE},
790             {URL_SCHEME_FTP,S_OK,FALSE},
791             {URLZONE_INVALID,E_NOTIMPL,FALSE}
792         }
793     },
794     /* Make sure forbidden characters in "userinfo" get encoded. */
795     {   "ftp://\" \"weird@ftp.google.com/", 0, S_OK, FALSE,
796         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
797         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
798         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
799         Uri_HAS_SCHEME,
800         TRUE,
801         {
802             {"ftp://%22%20%22weird@ftp.google.com/",S_OK,TRUE},
803             {"%22%20%22weird@ftp.google.com",S_OK,TRUE},
804             {"ftp://ftp.google.com/",S_OK,TRUE},
805             {"google.com",S_OK,TRUE},
806             {"",S_FALSE,TRUE},
807             {"",S_FALSE,TRUE},
808             {"ftp.google.com",S_OK,FALSE},
809             {"",S_FALSE,FALSE},
810             {"/",S_OK,TRUE},
811             {"/",S_OK,TRUE},
812             {"",S_FALSE,TRUE},
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,TRUE},
820             {21,S_OK,FALSE},
821             {URL_SCHEME_FTP,S_OK,FALSE},
822             {URLZONE_INVALID,E_NOTIMPL,FALSE}
823         }
824     },
825     /* Make sure the forbidden characters don't get percent encoded. */
826     {   "ftp://\" \"weird@ftp.google.com/", Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS, S_OK, FALSE,
827         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
828         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
829         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
830         Uri_HAS_SCHEME,
831         TRUE,
832         {
833             {"ftp://\" \"weird@ftp.google.com/",S_OK,TRUE},
834             {"\" \"weird@ftp.google.com",S_OK,TRUE},
835             {"ftp://ftp.google.com/",S_OK,TRUE},
836             {"google.com",S_OK,TRUE},
837             {"",S_FALSE,TRUE},
838             {"",S_FALSE,TRUE},
839             {"ftp.google.com",S_OK,FALSE},
840             {"",S_FALSE,FALSE},
841             {"/",S_OK,TRUE},
842             {"/",S_OK,TRUE},
843             {"",S_FALSE,TRUE},
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,TRUE},
851             {21,S_OK,FALSE},
852             {URL_SCHEME_FTP,S_OK,FALSE},
853             {URLZONE_INVALID,E_NOTIMPL,FALSE}
854         }
855     },
856     /* Allowed to have invalid % encoded because its an unknown scheme type. */
857     {   "zip://%xy:word@winehq.org/", 0, S_OK, FALSE,
858         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
859         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
860         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
861         TRUE,
862         {
863             {"zip://%xy:word@winehq.org/",S_OK,TRUE},
864             {"%xy:word@winehq.org",S_OK,TRUE},
865             {"zip://%xy:word@winehq.org/",S_OK,TRUE},
866             {"winehq.org",S_OK,TRUE},
867             {"",S_FALSE,TRUE},
868             {"",S_FALSE,TRUE},
869             {"winehq.org",S_OK,FALSE},
870             {"word",S_OK,FALSE},
871             {"/",S_OK,TRUE},
872             {"/",S_OK,TRUE},
873             {"",S_FALSE,TRUE},
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,TRUE},
881             {0,S_FALSE,FALSE},
882             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
883             {URLZONE_INVALID,E_NOTIMPL,FALSE}
884         }
885     },
886     /* Unreserved, percent encoded characters aren't decoded in the userinfo becuase the scheme
887      * isn't known.
888      */
889     {   "zip://%2E:%52%53ord@winehq.org/", 0, S_OK, FALSE,
890         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
891         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
892         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
893         TRUE,
894         {
895             {"zip://%2E:%52%53ord@winehq.org/",S_OK,TRUE},
896             {"%2E:%52%53ord@winehq.org",S_OK,TRUE},
897             {"zip://%2E:%52%53ord@winehq.org/",S_OK,TRUE},
898             {"winehq.org",S_OK,TRUE},
899             {"",S_FALSE,TRUE},
900             {"",S_FALSE,TRUE},
901             {"winehq.org",S_OK,FALSE},
902             {"%52%53ord",S_OK,FALSE},
903             {"/",S_OK,TRUE},
904             {"/",S_OK,TRUE},
905             {"",S_FALSE,TRUE},
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,TRUE},
913             {0,S_FALSE,FALSE},
914             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
915             {URLZONE_INVALID,E_NOTIMPL,FALSE}
916         }
917     },
918     {   "ftp://[](),'test':word@winehq.org/", 0, S_OK, FALSE,
919         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
920         Uri_HAS_HOST|Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
921         Uri_HAS_SCHEME_NAME|Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|
922         Uri_HAS_SCHEME,
923         TRUE,
924         {
925             {"ftp://[](),'test':word@winehq.org/",S_OK,TRUE},
926             {"[](),'test':word@winehq.org",S_OK,TRUE},
927             {"ftp://winehq.org/",S_OK,TRUE},
928             {"winehq.org",S_OK,TRUE},
929             {"",S_FALSE,TRUE},
930             {"",S_FALSE,TRUE},
931             {"winehq.org",S_OK,FALSE},
932             {"word",S_OK,FALSE},
933             {"/",S_OK,TRUE},
934             {"/",S_OK,TRUE},
935             {"",S_FALSE,TRUE},
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,TRUE},
943             {21,S_OK,FALSE},
944             {URL_SCHEME_FTP,S_OK,FALSE},
945             {URLZONE_INVALID,E_NOTIMPL,FALSE}
946         }
947     },
948     {   "ftp://test?:word@winehq.org/", 0, S_OK, FALSE,
949         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
950         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
951         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
952         TRUE,
953         {
954             {"ftp://test/?:word@winehq.org/",S_OK,TRUE},
955             {"test",S_OK,TRUE},
956             {"ftp://test/?:word@winehq.org/",S_OK,TRUE},
957             {"",S_FALSE,TRUE},
958             {"",S_FALSE,TRUE},
959             {"",S_FALSE,TRUE},
960             {"test",S_OK,FALSE},
961             {"",S_FALSE,FALSE},
962             {"/",S_OK,TRUE},
963             {"/?:word@winehq.org/",S_OK,TRUE},
964             {"?:word@winehq.org/",S_OK,TRUE},
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,TRUE},
972             {21,S_OK,FALSE},
973             {URL_SCHEME_FTP,S_OK,FALSE},
974             {URLZONE_INVALID,E_NOTIMPL,FALSE}
975         }
976     },
977     {   "ftp://test#:word@winehq.org/", 0, S_OK, FALSE,
978         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_FRAGMENT|Uri_HAS_HOST|
979         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
980         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
981         TRUE,
982         {
983             {"ftp://test/#:word@winehq.org/",S_OK,TRUE},
984             {"test",S_OK,TRUE},
985             {"ftp://test/#:word@winehq.org/",S_OK,TRUE},
986             {"",S_FALSE,TRUE},
987             {"",S_FALSE,TRUE},
988             {"#:word@winehq.org/",S_OK,TRUE},
989             {"test",S_OK,FALSE},
990             {"",S_FALSE,FALSE},
991             {"/",S_OK,TRUE},
992             {"/",S_OK,TRUE},
993             {"",S_FALSE,TRUE},
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,TRUE},
1001             {21,S_OK,FALSE},
1002             {URL_SCHEME_FTP,S_OK,FALSE},
1003             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1004         }
1005     },
1006     /* Allowed to have a backslash in the userinfo since it's an unknown scheme. */
1007     {   "zip://test\\:word@winehq.org/", 0, S_OK, FALSE,
1008         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
1009         Uri_HAS_PASSWORD|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1010         Uri_HAS_USER_INFO|Uri_HAS_USER_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1011         TRUE,
1012         {
1013             {"zip://test\\:word@winehq.org/",S_OK,TRUE},
1014             {"test\\:word@winehq.org",S_OK,TRUE},
1015             {"zip://test\\:word@winehq.org/",S_OK,TRUE},
1016             {"winehq.org",S_OK,TRUE},
1017             {"",S_FALSE,TRUE},
1018             {"",S_FALSE,TRUE},
1019             {"winehq.org",S_OK,FALSE},
1020             {"word",S_OK,FALSE},
1021             {"/",S_OK,TRUE},
1022             {"/",S_OK,TRUE},
1023             {"",S_FALSE,TRUE},
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,TRUE},
1031             {0,S_FALSE,FALSE},
1032             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1033             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1034         }
1035     },
1036     /* It normalizes IPv4 addresses correctly. */
1037     {   "http://127.000.000.100/", 0, S_OK, FALSE,
1038         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1039         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1040         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1041         TRUE,
1042         {
1043             {"http://127.0.0.100/",S_OK,TRUE},
1044             {"127.0.0.100",S_OK,TRUE},
1045             {"http://127.0.0.100/",S_OK,TRUE},
1046             {"",S_FALSE,TRUE},
1047             {"",S_FALSE,TRUE},
1048             {"",S_FALSE,TRUE},
1049             {"127.0.0.100",S_OK,FALSE},
1050             {"",S_FALSE,FALSE},
1051             {"/",S_OK,TRUE},
1052             {"/",S_OK,TRUE},
1053             {"",S_FALSE,TRUE},
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,TRUE},
1061             {80,S_OK,FALSE},
1062             {URL_SCHEME_HTTP,S_OK,FALSE},
1063             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1064         }
1065     },
1066     /* Make sure it normalizes partial IPv4 addresses correctly. */
1067     {   "http://127.0/", 0, S_OK, FALSE,
1068         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1069         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1070         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1071         TRUE,
1072         {
1073             {"http://127.0.0.0/",S_OK,TRUE},
1074             {"127.0.0.0",S_OK,TRUE},
1075             {"http://127.0.0.0/",S_OK,TRUE},
1076             {"",S_FALSE,TRUE},
1077             {"",S_FALSE,TRUE},
1078             {"",S_FALSE,TRUE},
1079             {"127.0.0.0",S_OK,FALSE},
1080             {"",S_FALSE,FALSE},
1081             {"/",S_OK,TRUE},
1082             {"/",S_OK,TRUE},
1083             {"",S_FALSE,TRUE},
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,TRUE},
1091             {80,S_OK,FALSE},
1092             {URL_SCHEME_HTTP,S_OK,FALSE},
1093             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1094         }
1095     },
1096     /* Make sure it converts implicit IPv4's correctly. */
1097     {   "http://123456/", 0, S_OK, FALSE,
1098         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1099         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1100         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1101         TRUE,
1102         {
1103             {"http://0.1.226.64/",S_OK,TRUE},
1104             {"0.1.226.64",S_OK,TRUE},
1105             {"http://0.1.226.64/",S_OK,TRUE},
1106             {"",S_FALSE,TRUE},
1107             {"",S_FALSE,TRUE},
1108             {"",S_FALSE,TRUE},
1109             {"0.1.226.64",S_OK,FALSE},
1110             {"",S_FALSE,FALSE},
1111             {"/",S_OK,TRUE},
1112             {"/",S_OK,TRUE},
1113             {"",S_FALSE,TRUE},
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,TRUE},
1121             {80,S_OK,FALSE},
1122             {URL_SCHEME_HTTP,S_OK,FALSE},
1123             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1124         }
1125     },
1126     /* UINT_MAX */
1127     {   "http://4294967295/", 0, S_OK, FALSE,
1128         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1129         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1130         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1131         TRUE,
1132         {
1133             {"http://255.255.255.255/",S_OK,TRUE},
1134             {"255.255.255.255",S_OK,TRUE},
1135             {"http://255.255.255.255/",S_OK,TRUE},
1136             {"",S_FALSE,TRUE},
1137             {"",S_FALSE,TRUE},
1138             {"",S_FALSE,TRUE},
1139             {"255.255.255.255",S_OK,FALSE},
1140             {"",S_FALSE,FALSE},
1141             {"/",S_OK,TRUE},
1142             {"/",S_OK,TRUE},
1143             {"",S_FALSE,TRUE},
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,TRUE},
1151             {80,S_OK,FALSE},
1152             {URL_SCHEME_HTTP,S_OK,FALSE},
1153             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1154         }
1155     },
1156     /* UINT_MAX+1 */
1157     {   "http://4294967296/", 0, S_OK, FALSE,
1158         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1159         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1160         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1161         TRUE,
1162         {
1163             {"http://4294967296/",S_OK,TRUE},
1164             {"4294967296",S_OK,TRUE},
1165             {"http://4294967296/",S_OK,TRUE},
1166             {"",S_FALSE,TRUE},
1167             {"",S_FALSE,TRUE},
1168             {"",S_FALSE,TRUE},
1169             {"4294967296",S_OK,FALSE},
1170             {"",S_FALSE,FALSE},
1171             {"/",S_OK,TRUE},
1172             {"/",S_OK,TRUE},
1173             {"",S_FALSE,TRUE},
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,TRUE},
1181             {80,S_OK,FALSE},
1182             {URL_SCHEME_HTTP,S_OK,FALSE},
1183             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1184         }
1185     },
1186     /* Window's doesn't normalize IP address for unknown schemes. */
1187     {   "1234://4294967295/", 0, S_OK, FALSE,
1188         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1189         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1190         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1191         TRUE,
1192         {
1193             {"1234://4294967295/",S_OK,TRUE},
1194             {"4294967295",S_OK,TRUE},
1195             {"1234://4294967295/",S_OK,TRUE},
1196             {"",S_FALSE,TRUE},
1197             {"",S_FALSE,TRUE},
1198             {"",S_FALSE,TRUE},
1199             {"4294967295",S_OK,FALSE},
1200             {"",S_FALSE,FALSE},
1201             {"/",S_OK,TRUE},
1202             {"/",S_OK,TRUE},
1203             {"",S_FALSE,TRUE},
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,TRUE},
1211             {0,S_FALSE,FALSE},
1212             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1213             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1214         }
1215     },
1216     /* Window's doesn't normalize IP address for unknown schemes. */
1217     {   "1234://127.001/", 0, S_OK, FALSE,
1218         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1219         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1220         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1221         TRUE,
1222         {
1223             {"1234://127.001/",S_OK,TRUE},
1224             {"127.001",S_OK,TRUE},
1225             {"1234://127.001/",S_OK,TRUE},
1226             {"",S_FALSE,TRUE},
1227             {"",S_FALSE,TRUE},
1228             {"",S_FALSE,TRUE},
1229             {"127.001",S_OK,FALSE},
1230             {"",S_FALSE,FALSE},
1231             {"/",S_OK,TRUE},
1232             {"/",S_OK,TRUE},
1233             {"",S_FALSE,TRUE},
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,TRUE},
1241             {0,S_FALSE,FALSE},
1242             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1243             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1244         }
1245     },
1246     {   "http://[FEDC:BA98::3210]", 0, S_OK, FALSE,
1247         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1248         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1249         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1250         TRUE,
1251         {
1252             {"http://[fedc:ba98::3210]/",S_OK,TRUE},
1253             {"[fedc:ba98::3210]",S_OK,TRUE},
1254             {"http://[fedc:ba98::3210]/",S_OK,TRUE},
1255             {"",S_FALSE,TRUE},
1256             {"",S_FALSE,TRUE},
1257             {"",S_FALSE,TRUE},
1258             {"fedc:ba98::3210",S_OK,FALSE},
1259             {"",S_FALSE,FALSE},
1260             {"/",S_OK,TRUE},
1261             {"/",S_OK,TRUE},
1262             {"",S_FALSE,TRUE},
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,TRUE},
1270             {80,S_OK,FALSE},
1271             {URL_SCHEME_HTTP,S_OK,FALSE},
1272             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1273         }
1274     },
1275     {   "http://[::]", 0, S_OK, FALSE,
1276         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1277         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1278         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1279         TRUE,
1280         {
1281             {"http://[::]/",S_OK,TRUE},
1282             {"[::]",S_OK,TRUE},
1283             {"http://[::]/",S_OK,TRUE},
1284             {"",S_FALSE,TRUE},
1285             {"",S_FALSE,TRUE},
1286             {"",S_FALSE,TRUE},
1287             {"::",S_OK,FALSE},
1288             {"",S_FALSE,FALSE},
1289             {"/",S_OK,TRUE},
1290             {"/",S_OK,TRUE},
1291             {"",S_FALSE,TRUE},
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,TRUE},
1299             {80,S_OK,FALSE},
1300             {URL_SCHEME_HTTP,S_OK,FALSE},
1301             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1302         }
1303     },
1304     {   "http://[FEDC:BA98::]", 0, S_OK, FALSE,
1305         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1306         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1307         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1308         TRUE,
1309         {
1310             {"http://[fedc:ba98::]/",S_OK,TRUE},
1311             {"[fedc:ba98::]",S_OK,TRUE},
1312             {"http://[fedc:ba98::]/",S_OK,TRUE},
1313             {"",S_FALSE,TRUE},
1314             {"",S_FALSE,TRUE},
1315             {"",S_FALSE,TRUE},
1316             {"fedc:ba98::",S_OK,FALSE},
1317             {"",S_FALSE,FALSE},
1318             {"/",S_OK,TRUE},
1319             {"/",S_OK,TRUE},
1320             {"",S_FALSE,TRUE},
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,TRUE},
1328             {80,S_OK,FALSE},
1329             {URL_SCHEME_HTTP,S_OK,FALSE},
1330             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1331         }
1332     },
1333     /* Valid even with 2 byte elision because it doesn't appear the beginning or end. */
1334     {   "http://[1::3:4:5:6:7:8]", 0, S_OK, FALSE,
1335         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1336         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1337         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1338         TRUE,
1339         {
1340             {"http://[1:0:3:4:5:6:7:8]/",S_OK,TRUE},
1341             {"[1:0:3:4:5:6:7:8]",S_OK,TRUE},
1342             {"http://[1:0:3:4:5:6:7:8]/",S_OK,TRUE},
1343             {"",S_FALSE,TRUE},
1344             {"",S_FALSE,TRUE},
1345             {"",S_FALSE,TRUE},
1346             {"1:0:3:4:5:6:7:8",S_OK,FALSE},
1347             {"",S_FALSE,FALSE},
1348             {"/",S_OK,TRUE},
1349             {"/",S_OK,TRUE},
1350             {"",S_FALSE,TRUE},
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,TRUE},
1358             {80,S_OK,FALSE},
1359             {URL_SCHEME_HTTP,S_OK,FALSE},
1360             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1361         }
1362     },
1363     {   "http://[v2.34]/", 0, S_OK, FALSE,
1364         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1365         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1366         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1367         TRUE,
1368         {
1369             {"http://[v2.34]/",S_OK,TRUE},
1370             {"[v2.34]",S_OK,TRUE},
1371             {"http://[v2.34]/",S_OK,TRUE},
1372             {"",S_FALSE,TRUE},
1373             {"",S_FALSE,TRUE},
1374             {"",S_FALSE,TRUE},
1375             {"[v2.34]",S_OK,FALSE},
1376             {"",S_FALSE,FALSE},
1377             {"/",S_OK,TRUE},
1378             {"/",S_OK,TRUE},
1379             {"",S_FALSE,TRUE},
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,TRUE},
1387             {80,S_OK,FALSE},
1388             {URL_SCHEME_HTTP,S_OK,FALSE},
1389             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1390         }
1391     },
1392     /* Windows ignores ':' if they appear after a '[' on a non-IPLiteral host. */
1393     {   "http://[xyz:12345.com/test", 0, S_OK, FALSE,
1394         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1395         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1396         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1397         TRUE,
1398         {
1399             {"http://[xyz:12345.com/test",S_OK,TRUE},
1400             {"[xyz:12345.com",S_OK,TRUE},
1401             {"http://[xyz:12345.com/test",S_OK,TRUE},
1402             {"[xyz:12345.com",S_OK,TRUE},
1403             {"",S_FALSE,TRUE},
1404             {"",S_FALSE,TRUE},
1405             {"[xyz:12345.com",S_OK,FALSE},
1406             {"",S_FALSE,FALSE},
1407             {"/test",S_OK,TRUE},
1408             {"/test",S_OK,TRUE},
1409             {"",S_FALSE,TRUE},
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,TRUE},
1417             {80,S_OK,FALSE},
1418             {URL_SCHEME_HTTP,S_OK,FALSE},
1419             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1420         }
1421     },
1422     /* Valid URI since the '[' and ']' don't appear at the begining and end
1423      * of the host name (respectively).
1424      */
1425     {   "ftp://www.[works].com/", 0, S_OK, FALSE,
1426         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1427         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1428         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1429         TRUE,
1430         {
1431             {"ftp://www.[works].com/",S_OK,TRUE},
1432             {"www.[works].com",S_OK,TRUE},
1433             {"ftp://www.[works].com/",S_OK,TRUE},
1434             {"[works].com",S_OK,TRUE},
1435             {"",S_FALSE,TRUE},
1436             {"",S_FALSE,TRUE},
1437             {"www.[works].com",S_OK,FALSE},
1438             {"",S_FALSE,FALSE},
1439             {"/",S_OK,TRUE},
1440             {"/",S_OK,TRUE},
1441             {"",S_FALSE,TRUE},
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,TRUE},
1449             {21,S_OK,FALSE},
1450             {URL_SCHEME_FTP,S_OK,FALSE},
1451             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1452         }
1453     },
1454     /* Considers ':' a delimiter since it appears after the ']'. */
1455     {   "http://www.google.com]:12345/", 0, S_OK, FALSE,
1456         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1457         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1458         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1459         TRUE,
1460         {
1461             {"http://www.google.com]:12345/",S_OK,TRUE},
1462             {"www.google.com]:12345",S_OK,TRUE},
1463             {"http://www.google.com]:12345/",S_OK,TRUE},
1464             {"google.com]",S_OK,TRUE},
1465             {"",S_FALSE,TRUE},
1466             {"",S_FALSE,TRUE},
1467             {"www.google.com]",S_OK,FALSE},
1468             {"",S_FALSE,FALSE},
1469             {"/",S_OK,TRUE},
1470             {"/",S_OK,TRUE},
1471             {"",S_FALSE,TRUE},
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,TRUE},
1479             {12345,S_OK,FALSE},
1480             {URL_SCHEME_HTTP,S_OK,FALSE},
1481             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1482         }
1483     },
1484     /* Unknown scheme types can have invalid % encoded data in the hostname. */
1485     {   "zip://w%XXw%GEw.google.com/", 0, S_OK, FALSE,
1486         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1487         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1488         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1489         TRUE,
1490         {
1491             {"zip://w%XXw%GEw.google.com/",S_OK,TRUE},
1492             {"w%XXw%GEw.google.com",S_OK,TRUE},
1493             {"zip://w%XXw%GEw.google.com/",S_OK,TRUE},
1494             {"google.com",S_OK,TRUE},
1495             {"",S_FALSE,TRUE},
1496             {"",S_FALSE,TRUE},
1497             {"w%XXw%GEw.google.com",S_OK,FALSE},
1498             {"",S_FALSE,FALSE},
1499             {"/",S_OK,TRUE},
1500             {"/",S_OK,TRUE},
1501             {"",S_FALSE,TRUE},
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,TRUE},
1509             {0,S_FALSE,FALSE},
1510             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1511             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1512         }
1513     },
1514     /* Unknown scheme types hostname doesn't get lower cased. */
1515     {   "zip://GOOGLE.com/", 0, S_OK, FALSE,
1516         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1517         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1518         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1519         TRUE,
1520         {
1521             {"zip://GOOGLE.com/",S_OK,TRUE},
1522             {"GOOGLE.com",S_OK,TRUE},
1523             {"zip://GOOGLE.com/",S_OK,TRUE},
1524             {"GOOGLE.com",S_OK,TRUE},
1525             {"",S_FALSE,TRUE},
1526             {"",S_FALSE,TRUE},
1527             {"GOOGLE.com",S_OK,FALSE},
1528             {"",S_FALSE,FALSE},
1529             {"/",S_OK,TRUE},
1530             {"/",S_OK,TRUE},
1531             {"",S_FALSE,TRUE},
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,TRUE},
1539             {0,S_FALSE,FALSE},
1540             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1541             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1542         }
1543     },
1544     /* Hostname get's lower cased for known scheme types. */
1545     {   "http://WWW.GOOGLE.com/", 0, S_OK, FALSE,
1546         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1547         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1548         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1549         TRUE,
1550         {
1551             {"http://www.google.com/",S_OK,TRUE},
1552             {"www.google.com",S_OK,TRUE},
1553             {"http://www.google.com/",S_OK,TRUE},
1554             {"google.com",S_OK,TRUE},
1555             {"",S_FALSE,TRUE},
1556             {"",S_FALSE,TRUE},
1557             {"www.google.com",S_OK,FALSE},
1558             {"",S_FALSE,FALSE},
1559             {"/",S_OK,TRUE},
1560             {"/",S_OK,TRUE},
1561             {"",S_FALSE,TRUE},
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,TRUE},
1569             {80,S_OK,FALSE},
1570             {URL_SCHEME_HTTP,S_OK,FALSE},
1571             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1572         }
1573     },
1574     /* Characters that get % encoded in the hostname also have their percent
1575      * encoded forms lower cased.
1576      */
1577     {   "http://www.%7Cgoogle|.com/", 0, S_OK, FALSE,
1578         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1579         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
1580         Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1581         TRUE,
1582         {
1583             {"http://www.%7cgoogle%7c.com/",S_OK,TRUE},
1584             {"www.%7cgoogle%7c.com",S_OK,TRUE},
1585             {"http://www.%7cgoogle%7c.com/",S_OK,TRUE},
1586             {"%7cgoogle%7c.com",S_OK,TRUE},
1587             {"",S_FALSE,TRUE},
1588             {"",S_FALSE,TRUE},
1589             {"www.%7cgoogle%7c.com",S_OK,FALSE},
1590             {"",S_FALSE,FALSE},
1591             {"/",S_OK,TRUE},
1592             {"/",S_OK,TRUE},
1593             {"",S_FALSE,TRUE},
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,TRUE},
1601             {80,S_OK,FALSE},
1602             {URL_SCHEME_HTTP,S_OK,FALSE},
1603             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1604         }
1605     },
1606     /* IPv4 addresses attached to IPv6 can be included in elisions. */
1607     {   "http://[1:2:3:4:5:6:0.0.0.0]", 0, S_OK, FALSE,
1608         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1609         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1610         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1611         TRUE,
1612         {
1613             {"http://[1:2:3:4:5:6::]/",S_OK,TRUE},
1614             {"[1:2:3:4:5:6::]",S_OK,TRUE},
1615             {"http://[1:2:3:4:5:6::]/",S_OK,TRUE},
1616             {"",S_FALSE,TRUE},
1617             {"",S_FALSE,TRUE},
1618             {"",S_FALSE,TRUE},
1619             {"1:2:3:4:5:6::",S_OK,FALSE},
1620             {"",S_FALSE,FALSE},
1621             {"/",S_OK,TRUE},
1622             {"/",S_OK,TRUE},
1623             {"",S_FALSE,TRUE},
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,TRUE},
1631             {80,S_OK,FALSE},
1632             {URL_SCHEME_HTTP,S_OK,FALSE},
1633             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1634         }
1635     },
1636     /* IPv4 addresses get normalized. */
1637     {   "http://[::001.002.003.000]", 0, S_OK, FALSE,
1638         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1639         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1640         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1641         TRUE,
1642         {
1643             {"http://[::1.2.3.0]/",S_OK,TRUE},
1644             {"[::1.2.3.0]",S_OK,TRUE},
1645             {"http://[::1.2.3.0]/",S_OK,TRUE},
1646             {"",S_FALSE,TRUE},
1647             {"",S_FALSE,TRUE},
1648             {"",S_FALSE,TRUE},
1649             {"::1.2.3.0",S_OK,FALSE},
1650             {"",S_FALSE,FALSE},
1651             {"/",S_OK,TRUE},
1652             {"/",S_OK,TRUE},
1653             {"",S_FALSE,TRUE},
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,TRUE},
1661             {80,S_OK,FALSE},
1662             {URL_SCHEME_HTTP,S_OK,FALSE},
1663             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1664         }
1665     },
1666     /* Windows doesn't do anything to IPv6's in unknown schemes. */
1667     {   "zip://[0001:0:000:0004:0005:0006:001.002.003.000]", 0, S_OK, FALSE,
1668         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1669         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1670         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1671         TRUE,
1672         {
1673             {"zip://[0001:0:000:0004:0005:0006:001.002.003.000]/",S_OK,TRUE},
1674             {"[0001:0:000:0004:0005:0006:001.002.003.000]",S_OK,TRUE},
1675             {"zip://[0001:0:000:0004:0005:0006:001.002.003.000]/",S_OK,TRUE},
1676             {"",S_FALSE,TRUE},
1677             {"",S_FALSE,TRUE},
1678             {"",S_FALSE,TRUE},
1679             {"0001:0:000:0004:0005:0006:001.002.003.000",S_OK,FALSE},
1680             {"",S_FALSE,FALSE},
1681             {"/",S_OK,TRUE},
1682             {"/",S_OK,TRUE},
1683             {"",S_FALSE,TRUE},
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,TRUE},
1691             {0,S_FALSE,FALSE},
1692             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1693             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1694         }
1695     },
1696     /* IPv4 address is converted into 2 h16 components. */
1697     {   "http://[ffff::192.222.111.32]", 0, S_OK, FALSE,
1698         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_HOST|
1699         Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1700         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1701         TRUE,
1702         {
1703             {"http://[ffff::c0de:6f20]/",S_OK,TRUE},
1704             {"[ffff::c0de:6f20]",S_OK,TRUE},
1705             {"http://[ffff::c0de:6f20]/",S_OK,TRUE},
1706             {"",S_FALSE,TRUE},
1707             {"",S_FALSE,TRUE},
1708             {"",S_FALSE,TRUE},
1709             {"ffff::c0de:6f20",S_OK,FALSE},
1710             {"",S_FALSE,FALSE},
1711             {"/",S_OK,TRUE},
1712             {"/",S_OK,TRUE},
1713             {"",S_FALSE,TRUE},
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,TRUE},
1721             {80,S_OK,FALSE},
1722             {URL_SCHEME_HTTP,S_OK,FALSE},
1723             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1724         }
1725     },
1726     /* Max value for a port. */
1727     {   "http://google.com:65535", 0, S_OK, FALSE,
1728         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1729         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1730         Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1731         TRUE,
1732         {
1733             {"http://google.com:65535/",S_OK,TRUE},
1734             {"google.com:65535",S_OK,TRUE},
1735             {"http://google.com:65535/",S_OK,TRUE},
1736             {"google.com",S_OK,TRUE},
1737             {"",S_FALSE,TRUE},
1738             {"",S_FALSE,TRUE},
1739             {"google.com",S_OK,FALSE},
1740             {"",S_FALSE,FALSE},
1741             {"/",S_OK,TRUE},
1742             {"/",S_OK,TRUE},
1743             {"",S_FALSE,TRUE},
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,TRUE},
1751             {65535,S_OK,FALSE},
1752             {URL_SCHEME_HTTP,S_OK,FALSE},
1753             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1754         }
1755     },
1756     {   "zip://google.com:65536", 0, S_OK, FALSE,
1757         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1758         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1759         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1760         TRUE,
1761         {
1762             {"zip://google.com:65536/",S_OK,TRUE},
1763             {"google.com:65536",S_OK,TRUE},
1764             {"zip://google.com:65536/",S_OK,TRUE},
1765             {"google.com:65536",S_OK,TRUE},
1766             {"",S_FALSE,TRUE},
1767             {"",S_FALSE,TRUE},
1768             {"google.com:65536",S_OK,FALSE},
1769             {"",S_FALSE,FALSE},
1770             {"/",S_OK,TRUE},
1771             {"/",S_OK,TRUE},
1772             {"",S_FALSE,TRUE},
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,TRUE},
1780             {0,S_FALSE,FALSE},
1781             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1782             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1783         }
1784     },
1785     {   "zip://google.com:65536:25", 0, S_OK, FALSE,
1786         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1787         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1788         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1789         TRUE,
1790         {
1791             {"zip://google.com:65536:25/",S_OK,TRUE},
1792             {"google.com:65536:25",S_OK,TRUE},
1793             {"zip://google.com:65536:25/",S_OK,TRUE},
1794             {"google.com:65536:25",S_OK,TRUE},
1795             {"",S_FALSE,TRUE},
1796             {"",S_FALSE,TRUE},
1797             {"google.com:65536:25",S_OK,FALSE},
1798             {"",S_FALSE,FALSE},
1799             {"/",S_OK,TRUE},
1800             {"/",S_OK,TRUE},
1801             {"",S_FALSE,TRUE},
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,TRUE},
1809             {0,S_FALSE,FALSE},
1810             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1811             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1812         }
1813     },
1814     {   "zip://[::ffff]:abcd", 0, S_OK, FALSE,
1815         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|
1816         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1817         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1818         TRUE,
1819         {
1820             {"zip://[::ffff]:abcd/",S_OK,TRUE},
1821             {"[::ffff]:abcd",S_OK,TRUE},
1822             {"zip://[::ffff]:abcd/",S_OK,TRUE},
1823             {"",S_FALSE,TRUE},
1824             {"",S_FALSE,TRUE},
1825             {"",S_FALSE,TRUE},
1826             {"[::ffff]:abcd",S_OK,FALSE},
1827             {"",S_FALSE,FALSE},
1828             {"/",S_OK,TRUE},
1829             {"/",S_OK,TRUE},
1830             {"",S_FALSE,TRUE},
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,TRUE},
1838             {0,S_FALSE,FALSE},
1839             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1840             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1841         }
1842     },
1843     {   "zip://127.0.0.1:abcd", 0, S_OK, FALSE,
1844         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1845         Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
1846         Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
1847         TRUE,
1848         {
1849             {"zip://127.0.0.1:abcd/",S_OK,TRUE},
1850             {"127.0.0.1:abcd",S_OK,TRUE},
1851             {"zip://127.0.0.1:abcd/",S_OK,TRUE},
1852             {"0.1:abcd",S_OK,TRUE},
1853             {"",S_FALSE,TRUE},
1854             {"",S_FALSE,TRUE},
1855             {"127.0.0.1:abcd",S_OK,FALSE},
1856             {"",S_FALSE,FALSE},
1857             {"/",S_OK,TRUE},
1858             {"/",S_OK,TRUE},
1859             {"",S_FALSE,TRUE},
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,TRUE},
1867             {0,S_FALSE,FALSE},
1868             {URL_SCHEME_UNKNOWN,S_OK,FALSE},
1869             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1870         }
1871     },
1872     /* Port is just copied over. */
1873     {   "http://google.com:00035", Uri_CREATE_NO_CANONICALIZE, S_OK, FALSE,
1874         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1875         Uri_HAS_HOST|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1876         TRUE,
1877         {
1878             {"http://google.com:00035",S_OK,TRUE},
1879             {"google.com:00035",S_OK,TRUE},
1880             {"http://google.com:00035",S_OK,TRUE,"http://google.com:35"},
1881             {"google.com",S_OK,TRUE},
1882             {"",S_FALSE,TRUE},
1883             {"",S_FALSE,TRUE},
1884             {"google.com",S_OK,FALSE},
1885             {"",S_FALSE,FALSE},
1886             {"",S_FALSE,TRUE},
1887             {"",S_FALSE,TRUE},
1888             {"",S_FALSE,TRUE},
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,TRUE},
1896             {35,S_OK,FALSE},
1897             {URL_SCHEME_HTTP,S_OK,FALSE},
1898             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1899         }
1900     },
1901     /* Default port is copied over. */
1902     {   "http://google.com:80", Uri_CREATE_NO_CANONICALIZE, S_OK, FALSE,
1903         Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
1904         Uri_HAS_HOST|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
1905         TRUE,
1906         {
1907             {"http://google.com:80",S_OK,TRUE},
1908             {"google.com:80",S_OK,TRUE},
1909             {"http://google.com:80",S_OK,TRUE},
1910             {"google.com",S_OK,TRUE},
1911             {"",S_FALSE,TRUE},
1912             {"",S_FALSE,TRUE},
1913             {"google.com",S_OK,FALSE},
1914             {"",S_FALSE,FALSE},
1915             {"",S_FALSE,TRUE},
1916             {"",S_FALSE,TRUE},
1917             {"",S_FALSE,TRUE},
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,TRUE},
1925             {80,S_OK,FALSE},
1926             {URL_SCHEME_HTTP,S_OK,FALSE},
1927             {URLZONE_INVALID,E_NOTIMPL,FALSE}
1928         }
1929     }
1930 };
1931
1932 typedef struct _invalid_uri {
1933     const char* uri;
1934     DWORD       flags;
1935     BOOL        todo;
1936 } invalid_uri;
1937
1938 static const invalid_uri invalid_uri_tests[] = {
1939     /* Has to have a scheme name. */
1940     {"://www.winehq.org",0,FALSE},
1941     /* Window's doesn't like URI's which are implicitly file paths without the
1942      * ALLOW_IMPLICIT_FILE_SCHEME flag set.
1943      */
1944     {"C:/test/test.mp3",0,FALSE},
1945     {"\\\\Server/test/test.mp3",0,FALSE},
1946     {"C:/test/test.mp3",Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME,FALSE},
1947     {"\\\\Server/test/test.mp3",Uri_CREATE_ALLOW_RELATIVE,FALSE},
1948     /* Invalid schemes. */
1949     {"*abcd://not.valid.com",0,FALSE},
1950     {"*a*b*c*d://not.valid.com",0,FALSE},
1951     /* Not allowed to have invalid % encoded data. */
1952     {"ftp://google.co%XX/",0,FALSE},
1953     /* To many h16 components. */
1954     {"http://[1:2:3:4:5:6:7:8:9]",0,FALSE},
1955     /* Not enough room for IPv4 address. */
1956     {"http://[1:2:3:4:5:6:7:192.0.1.0]",0,FALSE},
1957     /* Not enough h16 components. */
1958     {"http://[1:2:3:4]",0,FALSE},
1959     /* Not enough components including IPv4. */
1960     {"http://[1:192.0.1.0]",0,FALSE},
1961     /* Not allowed to have partial IPv4 in IPv6. */
1962     {"http://[::192.0]",0,FALSE},
1963     /* Can't have elision of 1 h16 at beginning of address. */
1964     {"http://[::2:3:4:5:6:7:8]",0,FALSE},
1965     /* Can't have elision of 1 h16 at end of address. */
1966     {"http://[1:2:3:4:5:6:7::]",0,FALSE},
1967     /* Expects a valid IP Literal. */
1968     {"ftp://[not.valid.uri]/",0,FALSE},
1969     /* Expects valid port for a known scheme type. */
1970     {"ftp://www.winehq.org:123fgh",0,FALSE},
1971     /* Port exceeds USHORT_MAX for known scheme type. */
1972     {"ftp://www.winehq.org:65536",0,FALSE},
1973     /* Invalid port with IPv4 address. */
1974     {"http://www.winehq.org:1abcd",0,FALSE},
1975     /* Invalid port with IPv6 address. */
1976     {"http://[::ffff]:32xy",0,FALSE}
1977 };
1978
1979 typedef struct _uri_equality {
1980     const char* a;
1981     DWORD       create_flags_a;
1982     BOOL        create_todo_a;
1983     const char* b;
1984     DWORD       create_flags_b;
1985     BOOL        create_todo_b;
1986     BOOL        equal;
1987     BOOL        todo;
1988 } uri_equality;
1989
1990 static const uri_equality equality_tests[] = {
1991     {
1992         "HTTP://www.winehq.org/test dir/./",0,FALSE,
1993         "http://www.winehq.org/test dir/../test dir/",0,FALSE,
1994         TRUE, TRUE
1995     },
1996     {
1997         /* http://www.winehq.org/test%20dir */
1998         "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,
1999         "http://www.winehq.org/test dir",0,FALSE,
2000         TRUE, TRUE,
2001     },
2002     {
2003         "c:\\test.mp3",Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME,FALSE,
2004         "file:///c:/test.mp3",0,FALSE,
2005         TRUE,TRUE
2006     },
2007     {
2008         "ftp://ftp.winehq.org/",0,FALSE,
2009         "ftp://ftp.winehq.org",0,FALSE,
2010         TRUE, TRUE
2011     },
2012     {
2013         "ftp://ftp.winehq.org/test/test2/../../testB/",0,FALSE,
2014         "ftp://ftp.winehq.org/t%45stB/",0,FALSE,
2015         FALSE, TRUE
2016     }
2017 };
2018
2019 static inline LPWSTR a2w(LPCSTR str) {
2020     LPWSTR ret = NULL;
2021
2022     if(str) {
2023         DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2024         ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
2025         MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
2026     }
2027
2028     return ret;
2029 }
2030
2031 static inline BOOL heap_free(void* mem) {
2032     return HeapFree(GetProcessHeap(), 0, mem);
2033 }
2034
2035 static inline DWORD strcmp_aw(LPCSTR strA, LPCWSTR strB) {
2036     LPWSTR strAW = a2w(strA);
2037     DWORD ret = lstrcmpW(strAW, strB);
2038     heap_free(strAW);
2039     return ret;
2040 }
2041
2042 /*
2043  * Simple tests to make sure the CreateUri function handles invalid flag combinations
2044  * correctly.
2045  */
2046 static void test_CreateUri_InvalidFlags(void) {
2047     DWORD i;
2048
2049     for(i = 0; i < sizeof(invalid_flag_tests)/sizeof(invalid_flag_tests[0]); ++i) {
2050         HRESULT hr;
2051         IUri *uri = (void*) 0xdeadbeef;
2052
2053         hr = pCreateUri(http_urlW, invalid_flag_tests[i].flags, 0, &uri);
2054         todo_wine {
2055             ok(hr == invalid_flag_tests[i].expected, "Error: CreateUri returned 0x%08x, expected 0x%08x, flags=0x%08x\n",
2056                     hr, invalid_flag_tests[i].expected, invalid_flag_tests[i].flags);
2057         }
2058         todo_wine { ok(uri == NULL, "Error: expected the IUri to be NULL, but it was %p instead\n", uri); }
2059     }
2060 }
2061
2062 static void test_CreateUri_InvalidArgs(void) {
2063     HRESULT hr;
2064     IUri *uri = (void*) 0xdeadbeef;
2065
2066     const WCHAR invalidW[] = {'i','n','v','a','l','i','d',0};
2067
2068     hr = pCreateUri(http_urlW, 0, 0, NULL);
2069     ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x\n", hr, E_INVALIDARG);
2070
2071     hr = pCreateUri(NULL, 0, 0, &uri);
2072     ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x\n", hr, E_INVALIDARG);
2073     ok(uri == NULL, "Error: Expected the IUri to be NULL, but it was %p instead\n", uri);
2074
2075     uri = (void*) 0xdeadbeef;
2076     hr = pCreateUri(invalidW, 0, 0, &uri);
2077     ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
2078     ok(uri == NULL, "Error: Expected the IUri to be NULL, but it was %p instead\n", uri);
2079 }
2080
2081 static void test_CreateUri_InvalidUri(void) {
2082     DWORD i;
2083
2084     for(i = 0; i < sizeof(invalid_uri_tests)/sizeof(invalid_uri_tests[0]); ++i) {
2085         invalid_uri test = invalid_uri_tests[i];
2086         IUri *uri = NULL;
2087         LPWSTR uriW;
2088         HRESULT hr;
2089
2090         uriW = a2w(test.uri);
2091         hr = pCreateUri(uriW, test.flags, 0, &uri);
2092         if(test.todo) {
2093             todo_wine {
2094                 ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x on invalid_uri_tests[%d].\n",
2095                     hr, E_INVALIDARG, i);
2096             }
2097         } else {
2098             ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x on invalid_uri_tests[%d].\n",
2099                 hr, E_INVALIDARG, i);
2100         }
2101         if(uri) IUri_Release(uri);
2102
2103         heap_free(uriW);
2104     }
2105 }
2106
2107 static void test_IUri_GetPropertyBSTR(void) {
2108     IUri *uri = NULL;
2109     HRESULT hr;
2110     DWORD i;
2111
2112     /* Make sure GetPropertyBSTR handles invalid args correctly. */
2113     hr = pCreateUri(http_urlW, 0, 0, &uri);
2114     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
2115     if(SUCCEEDED(hr)) {
2116         BSTR received = NULL;
2117
2118         hr = IUri_GetPropertyBSTR(uri, Uri_PROPERTY_RAW_URI, NULL, 0);
2119         ok(hr == E_POINTER, "Error: GetPropertyBSTR returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2120
2121         /* Make sure it handles a invalid Uri_PROPERTY's correctly. */
2122         hr = IUri_GetPropertyBSTR(uri, Uri_PROPERTY_PORT, &received, 0);
2123         ok(hr == S_OK, "Error: GetPropertyBSTR returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
2124         ok(received != NULL, "Error: Expected the string not to be NULL.\n");
2125         ok(!SysStringLen(received), "Error: Expected the string to be of len=0 but it was %d instead.\n", SysStringLen(received));
2126         SysFreeString(received);
2127
2128         /* Make sure it handles the ZONE property correctly. */
2129         received = NULL;
2130         hr = IUri_GetPropertyBSTR(uri, Uri_PROPERTY_ZONE, &received, 0);
2131         ok(hr == S_FALSE, "Error: GetPropertyBSTR returned 0x%08x, expected 0x%08x.\n", hr, S_FALSE);
2132         ok(received != NULL, "Error: Expected the string not to be NULL.\n");
2133         ok(!SysStringLen(received), "Error: Expected the string to be of len=0 but it was %d instead.\n", SysStringLen(received));
2134         SysFreeString(received);
2135     }
2136     if(uri) IUri_Release(uri);
2137
2138     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
2139         uri_properties test = uri_tests[i];
2140         LPWSTR uriW;
2141         uri = NULL;
2142
2143         uriW = a2w(test.uri);
2144         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
2145         if(test.create_todo) {
2146             todo_wine {
2147                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
2148                         hr, test.create_expected, i);
2149             }
2150         } else {
2151             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
2152                     hr, test.create_expected, i);
2153         }
2154
2155         if(SUCCEEDED(hr)) {
2156             DWORD j;
2157
2158             /* Checks all the string properties of the uri. */
2159             for(j = Uri_PROPERTY_STRING_START; j <= Uri_PROPERTY_STRING_LAST; ++j) {
2160                 BSTR received = NULL;
2161                 uri_str_property prop = test.str_props[j];
2162
2163                 hr = IUri_GetPropertyBSTR(uri, j, &received, 0);
2164                 if(prop.todo) {
2165                     todo_wine {
2166                         ok(hr == prop.expected, "GetPropertyBSTR returned 0x%08x, expected 0x%08x. On uri_tests[%d].str_props[%d].\n",
2167                                 hr, prop.expected, i, j);
2168                     }
2169                     todo_wine {
2170                         ok(!strcmp_aw(prop.value, received) || broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
2171                                 "Expected %s but got %s on uri_tests[%d].str_props[%d].\n",
2172                                 prop.value, wine_dbgstr_w(received), i, j);
2173                     }
2174                     if (hr == E_NOTIMPL)  /* no point in continuing */
2175                     {
2176                         if(uri) IUri_Release(uri);
2177                         heap_free(uriW);
2178                         return;
2179                     }
2180                 } else {
2181                     ok(hr == prop.expected, "GetPropertyBSTR returned 0x%08x, expected 0x%08x. On uri_tests[%d].str_props[%d].\n",
2182                             hr, prop.expected, i, j);
2183                     ok(!strcmp_aw(prop.value, received) || broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
2184                             "Expected %s but got %s on uri_tests[%d].str_props[%d].\n",
2185                             prop.value, wine_dbgstr_w(received), i, j);
2186                 }
2187
2188                 SysFreeString(received);
2189             }
2190         }
2191
2192         if(uri) IUri_Release(uri);
2193
2194         heap_free(uriW);
2195     }
2196 }
2197
2198 static void test_IUri_GetPropertyDWORD(void) {
2199     IUri *uri = NULL;
2200     HRESULT hr;
2201     DWORD i;
2202
2203     hr = pCreateUri(http_urlW, 0, 0, &uri);
2204     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
2205     if(SUCCEEDED(hr)) {
2206         DWORD received = 0xdeadbeef;
2207
2208         hr = IUri_GetPropertyDWORD(uri, Uri_PROPERTY_DWORD_START, NULL, 0);
2209         ok(hr == E_INVALIDARG, "Error: GetPropertyDWORD returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
2210
2211         hr = IUri_GetPropertyDWORD(uri, Uri_PROPERTY_ABSOLUTE_URI, &received, 0);
2212         ok(hr == E_INVALIDARG, "Error: GetPropertyDWORD returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
2213         ok(received == 0, "Error: Expected received=%d but instead received=%d.\n", 0, received);
2214     }
2215     if(uri) IUri_Release(uri);
2216
2217     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
2218         uri_properties test = uri_tests[i];
2219         LPWSTR uriW;
2220         uri = NULL;
2221
2222         uriW = a2w(test.uri);
2223         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
2224         if(test.create_todo) {
2225             todo_wine {
2226                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
2227                         hr, test.create_expected, i);
2228             }
2229         } else {
2230             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
2231                     hr, test.create_expected, i);
2232         }
2233
2234         if(SUCCEEDED(hr)) {
2235             DWORD j;
2236
2237             /* Checks all the DWORD properties of the uri. */
2238             for(j = 0; j < sizeof(test.dword_props)/sizeof(test.dword_props[0]); ++j) {
2239                 DWORD received;
2240                 uri_dword_property prop = test.dword_props[j];
2241
2242                 hr = IUri_GetPropertyDWORD(uri, j+Uri_PROPERTY_DWORD_START, &received, 0);
2243                 if(prop.todo) {
2244                     todo_wine {
2245                         ok(hr == prop.expected, "GetPropertyDWORD returned 0x%08x, expected 0x%08x. On uri_tests[%d].dword_props[%d].\n",
2246                                 hr, prop.expected, i, j);
2247                     }
2248                     todo_wine {
2249                         ok(prop.value == received, "Expected %d but got %d on uri_tests[%d].dword_props[%d].\n",
2250                                 prop.value, received, i, j);
2251                     }
2252                     if (hr == E_NOTIMPL)  /* no point in continuing */
2253                     {
2254                         if(uri) IUri_Release(uri);
2255                         heap_free(uriW);
2256                         return;
2257                     }
2258                 } else {
2259                     ok(hr == prop.expected, "GetPropertyDWORD returned 0x%08x, expected 0x%08x. On uri_tests[%d].dword_props[%d].\n",
2260                             hr, prop.expected, i, j);
2261                     ok(prop.value == received, "Expected %d but got %d on uri_tests[%d].dword_props[%d].\n",
2262                             prop.value, received, i, j);
2263                 }
2264             }
2265         }
2266
2267         if(uri) IUri_Release(uri);
2268
2269         heap_free(uriW);
2270     }
2271 }
2272
2273 /* Tests all the 'Get*' property functions which deal with strings. */
2274 static void test_IUri_GetStrProperties(void) {
2275     IUri *uri = NULL;
2276     HRESULT hr;
2277     DWORD i;
2278
2279     /* Make sure all the 'Get*' string property functions handle invalid args correctly. */
2280     hr = pCreateUri(http_urlW, 0, 0, &uri);
2281     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
2282     if(SUCCEEDED(hr)) {
2283         hr = IUri_GetAbsoluteUri(uri, NULL);
2284         ok(hr == E_POINTER, "Error: GetAbsoluteUri returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2285
2286         hr = IUri_GetAuthority(uri, NULL);
2287         ok(hr == E_POINTER, "Error: GetAuthority returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2288
2289         hr = IUri_GetDisplayUri(uri, NULL);
2290         ok(hr == E_POINTER, "Error: GetDisplayUri returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2291
2292         hr = IUri_GetDomain(uri, NULL);
2293         ok(hr == E_POINTER, "Error: GetDomain returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2294
2295         hr = IUri_GetExtension(uri, NULL);
2296         ok(hr == E_POINTER, "Error: GetExtension returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2297
2298         hr = IUri_GetFragment(uri, NULL);
2299         ok(hr == E_POINTER, "Error: GetFragment returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2300
2301         hr = IUri_GetHost(uri, NULL);
2302         ok(hr == E_POINTER, "Error: GetHost returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2303
2304         hr = IUri_GetPassword(uri, NULL);
2305         ok(hr == E_POINTER, "Error: GetPassword returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2306
2307         hr = IUri_GetPath(uri, NULL);
2308         ok(hr == E_POINTER, "Error: GetPath returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2309
2310         hr = IUri_GetPathAndQuery(uri, NULL);
2311         ok(hr == E_POINTER, "Error: GetPathAndQuery returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2312
2313         hr = IUri_GetQuery(uri, NULL);
2314         ok(hr == E_POINTER, "Error: GetQuery returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2315
2316         hr = IUri_GetRawUri(uri, NULL);
2317         ok(hr == E_POINTER, "Error: GetRawUri returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2318
2319         hr = IUri_GetSchemeName(uri, NULL);
2320         ok(hr == E_POINTER, "Error: GetSchemeName returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2321
2322         hr = IUri_GetUserInfo(uri, NULL);
2323         ok(hr == E_POINTER, "Error: GetUserInfo returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2324
2325         hr = IUri_GetUserName(uri, NULL);
2326         ok(hr == E_POINTER, "Error: GetUserName returned 0x%08x, expected 0x%08x.\n", hr, E_POINTER);
2327     }
2328     if(uri) IUri_Release(uri);
2329
2330     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
2331         uri_properties test = uri_tests[i];
2332         LPWSTR uriW;
2333         uri = NULL;
2334
2335         uriW = a2w(test.uri);
2336         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
2337         if(test.create_todo) {
2338             todo_wine {
2339                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2340                         hr, test.create_expected, i);
2341             }
2342         } else {
2343             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2344                     hr, test.create_expected, i);
2345         }
2346
2347         if(SUCCEEDED(hr)) {
2348             uri_str_property prop;
2349             BSTR received = NULL;
2350
2351             /* GetAbsoluteUri() tests. */
2352             prop = test.str_props[Uri_PROPERTY_ABSOLUTE_URI];
2353             hr = IUri_GetAbsoluteUri(uri, &received);
2354             if (hr == E_NOTIMPL) goto skip_unimplemented;
2355             if(prop.todo) {
2356                 todo_wine {
2357                     ok(hr == prop.expected, "Error: GetAbsoluteUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2358                             hr, prop.expected, i);
2359                 }
2360                 todo_wine {
2361                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2362                             prop.value, wine_dbgstr_w(received), i);
2363                 }
2364             } else {
2365                 ok(hr == prop.expected, "Error: GetAbsoluteUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2366                         hr, prop.expected, i);
2367                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2368                         prop.value, wine_dbgstr_w(received), i);
2369             }
2370             SysFreeString(received);
2371             received = NULL;
2372
2373             /* GetAuthority() tests. */
2374             prop = test.str_props[Uri_PROPERTY_AUTHORITY];
2375             hr = IUri_GetAuthority(uri, &received);
2376             if(prop.todo) {
2377                 todo_wine {
2378                     ok(hr == prop.expected, "Error: GetAuthority returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2379                             hr, prop.expected, i);
2380                 }
2381                 todo_wine {
2382                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2383                             prop.value, wine_dbgstr_w(received), i);
2384                 }
2385             } else {
2386                 ok(hr == prop.expected, "Error: GetAuthority returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2387                         hr, prop.expected, i);
2388                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2389                         prop.value, wine_dbgstr_w(received), i);
2390             }
2391             SysFreeString(received);
2392             received = NULL;
2393
2394             /* GetDisplayUri() tests. */
2395             prop = test.str_props[Uri_PROPERTY_DISPLAY_URI];
2396             hr = IUri_GetDisplayUri(uri, &received);
2397             if(prop.todo) {
2398                 todo_wine {
2399                     ok(hr == prop.expected, "Error: GetDisplayUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2400                             hr, prop.expected, i);
2401                 }
2402                 todo_wine {
2403                     ok(!strcmp_aw(prop.value, received) || broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
2404                             "Error: Expected %s but got %s on uri_test[%d].\n",
2405                             prop.value, wine_dbgstr_w(received), i);
2406                 }
2407             } else {
2408                 ok(hr == prop.expected, "Error: GetDisplayUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2409                         hr, prop.expected, i);
2410                 ok(!strcmp_aw(prop.value, received) || broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
2411                         "Error: Expected %s but got %s on uri_tests[%d].\n",
2412                         prop.value, wine_dbgstr_w(received), i);
2413             }
2414             SysFreeString(received);
2415             received = NULL;
2416
2417             /* GetDomain() tests. */
2418             prop = test.str_props[Uri_PROPERTY_DOMAIN];
2419             hr = IUri_GetDomain(uri, &received);
2420             if(prop.todo) {
2421                 todo_wine {
2422                     ok(hr == prop.expected, "Error: GetDomain returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2423                             hr, prop.expected, i);
2424                 }
2425                 todo_wine {
2426                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2427                             prop.value, wine_dbgstr_w(received), i);
2428                 }
2429             } else {
2430                 ok(hr == prop.expected, "Error: GetDomain returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2431                         hr, prop.expected, i);
2432                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2433                         prop.value, wine_dbgstr_w(received), i);
2434             }
2435             SysFreeString(received);
2436             received = NULL;
2437
2438             /* GetExtension() tests. */
2439             prop = test.str_props[Uri_PROPERTY_EXTENSION];
2440             hr = IUri_GetExtension(uri, &received);
2441             if(prop.todo) {
2442                 todo_wine {
2443                     ok(hr == prop.expected, "Error: GetExtension returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2444                             hr, prop.expected, i);
2445                 }
2446                 todo_wine {
2447                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2448                             prop.value, wine_dbgstr_w(received), i);
2449                 }
2450             } else {
2451                 ok(hr == prop.expected, "Error: GetExtension returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2452                         hr, prop.expected, i);
2453                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2454                         prop.value, wine_dbgstr_w(received), i);
2455             }
2456             SysFreeString(received);
2457             received = NULL;
2458
2459             /* GetFragment() tests. */
2460             prop = test.str_props[Uri_PROPERTY_FRAGMENT];
2461             hr = IUri_GetFragment(uri, &received);
2462             if(prop.todo) {
2463                 todo_wine {
2464                     ok(hr == prop.expected, "Error: GetFragment returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2465                             hr, prop.expected, i);
2466                 }
2467                 todo_wine {
2468                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2469                             prop.value, wine_dbgstr_w(received), i);
2470                 }
2471             } else {
2472                 ok(hr == prop.expected, "Error: GetFragment returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2473                         hr, prop.expected, i);
2474                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2475                         prop.value, wine_dbgstr_w(received), i);
2476             }
2477             SysFreeString(received);
2478             received = NULL;
2479
2480             /* GetPassword() tests. */
2481             prop = test.str_props[Uri_PROPERTY_PASSWORD];
2482             hr = IUri_GetPassword(uri, &received);
2483             if(prop.todo) {
2484                 todo_wine {
2485                     ok(hr == prop.expected, "Error: GetPassword returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2486                             hr, prop.expected, i);
2487                 }
2488                 todo_wine {
2489                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2490                             prop.value, wine_dbgstr_w(received), i);
2491                 }
2492             } else {
2493                 ok(hr == prop.expected, "Error: GetPassword returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2494                         hr, prop.expected, i);
2495                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2496                         prop.value, wine_dbgstr_w(received), i);
2497             }
2498             SysFreeString(received);
2499             received = NULL;
2500
2501         skip_unimplemented:
2502             /* GetHost() tests. */
2503             prop = test.str_props[Uri_PROPERTY_HOST];
2504             hr = IUri_GetHost(uri, &received);
2505             if(prop.todo) {
2506                 todo_wine {
2507                     ok(hr == prop.expected, "Error: GetHost returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2508                             hr, prop.expected, i);
2509                 }
2510                 todo_wine {
2511                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2512                             prop.value, wine_dbgstr_w(received), i);
2513                 }
2514             } else {
2515                 ok(hr == prop.expected, "Error: GetHost returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2516                         hr, prop.expected, i);
2517                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2518                         prop.value, wine_dbgstr_w(received), i);
2519             }
2520             SysFreeString(received);
2521             received = NULL;
2522
2523             /* GetPath() tests. */
2524             prop = test.str_props[Uri_PROPERTY_PATH];
2525             hr = IUri_GetPath(uri, &received);
2526             if(prop.todo) {
2527                 todo_wine {
2528                     ok(hr == prop.expected, "Error: GetPath returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2529                             hr, prop.expected, i);
2530                 }
2531                 todo_wine {
2532                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2533                             prop.value, wine_dbgstr_w(received), i);
2534                 }
2535             } else {
2536                 ok(hr == prop.expected, "Error: GetPath returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2537                         hr, prop.expected, i);
2538                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2539                         prop.value, wine_dbgstr_w(received), i);
2540             }
2541             SysFreeString(received);
2542             received = NULL;
2543
2544             /* GetPathAndQuery() tests. */
2545             prop = test.str_props[Uri_PROPERTY_PATH_AND_QUERY];
2546             hr = IUri_GetPathAndQuery(uri, &received);
2547             if(prop.todo) {
2548                 todo_wine {
2549                     ok(hr == prop.expected, "Error: GetPathAndQuery returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2550                             hr, prop.expected, i);
2551                 }
2552                 todo_wine {
2553                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2554                             prop.value, wine_dbgstr_w(received), i);
2555                 }
2556             } else {
2557                 ok(hr == prop.expected, "Error: GetPathAndQuery returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2558                         hr, prop.expected, i);
2559                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2560                         prop.value, wine_dbgstr_w(received), i);
2561             }
2562             SysFreeString(received);
2563             received = NULL;
2564
2565             /* GetQuery() tests. */
2566             prop = test.str_props[Uri_PROPERTY_QUERY];
2567             hr = IUri_GetQuery(uri, &received);
2568             if(prop.todo) {
2569                 todo_wine {
2570                     ok(hr == prop.expected, "Error: GetQuery returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2571                             hr, prop.expected, i);
2572                 }
2573                 todo_wine {
2574                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2575                             prop.value, wine_dbgstr_w(received), i);
2576                 }
2577             } else {
2578                 ok(hr == prop.expected, "Error: GetQuery returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2579                         hr, prop.expected, i);
2580                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2581                         prop.value, wine_dbgstr_w(received), i);
2582             }
2583             SysFreeString(received);
2584             received = NULL;
2585
2586             /* GetRawUri() tests. */
2587             prop = test.str_props[Uri_PROPERTY_RAW_URI];
2588             hr = IUri_GetRawUri(uri, &received);
2589             if(prop.todo) {
2590                 todo_wine {
2591                     ok(hr == prop.expected, "Error: GetRawUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2592                             hr, prop.expected, i);
2593                 }
2594                 todo_wine {
2595                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2596                             prop.value, wine_dbgstr_w(received), i);
2597                 }
2598             } else {
2599                 ok(hr == prop.expected, "Error: GetRawUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2600                         hr, prop.expected, i);
2601                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2602                         prop.value, wine_dbgstr_w(received), i);
2603             }
2604             SysFreeString(received);
2605             received = NULL;
2606
2607             /* GetSchemeName() tests. */
2608             prop = test.str_props[Uri_PROPERTY_SCHEME_NAME];
2609             hr = IUri_GetSchemeName(uri, &received);
2610             if(prop.todo) {
2611                 todo_wine {
2612                     ok(hr == prop.expected, "Error: GetSchemeName returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2613                             hr, prop.expected, i);
2614                 }
2615                 todo_wine {
2616                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2617                             prop.value, wine_dbgstr_w(received), i);
2618                 }
2619             } else {
2620                 ok(hr == prop.expected, "Error: GetSchemeName returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2621                         hr, prop.expected, i);
2622                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2623                         prop.value, wine_dbgstr_w(received), i);
2624             }
2625             SysFreeString(received);
2626             received = NULL;
2627
2628             /* GetUserInfo() tests. */
2629             prop = test.str_props[Uri_PROPERTY_USER_INFO];
2630             hr = IUri_GetUserInfo(uri, &received);
2631             if(prop.todo) {
2632                 todo_wine {
2633                     ok(hr == prop.expected, "Error: GetUserInfo returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2634                             hr, prop.expected, i);
2635                 }
2636                 todo_wine {
2637                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2638                             prop.value, wine_dbgstr_w(received), i);
2639                 }
2640             } else {
2641                 ok(hr == prop.expected, "Error: GetUserInfo returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2642                         hr, prop.expected, i);
2643                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2644                         prop.value, wine_dbgstr_w(received), i);
2645             }
2646             SysFreeString(received);
2647             received = NULL;
2648
2649             /* GetUserName() tests. */
2650             prop = test.str_props[Uri_PROPERTY_USER_NAME];
2651             hr = IUri_GetUserName(uri, &received);
2652             if(prop.todo) {
2653                 todo_wine {
2654                     ok(hr == prop.expected, "Error: GetUserName returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2655                             hr, prop.expected, i);
2656                 }
2657                 todo_wine {
2658                     ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2659                             prop.value, wine_dbgstr_w(received), i);
2660                 }
2661             } else {
2662                 ok(hr == prop.expected, "Error: GetUserName returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2663                         hr, prop.expected, i);
2664                 ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
2665                         prop.value, wine_dbgstr_w(received), i);
2666             }
2667             SysFreeString(received);
2668         }
2669
2670         if(uri) IUri_Release(uri);
2671
2672         heap_free(uriW);
2673     }
2674 }
2675
2676 static void test_IUri_GetDwordProperties(void) {
2677     IUri *uri = NULL;
2678     HRESULT hr;
2679     DWORD i;
2680
2681     /* Make sure all the 'Get*' dword property functions handle invalid args correctly. */
2682     hr = pCreateUri(http_urlW, 0, 0, &uri);
2683     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
2684     if(SUCCEEDED(hr)) {
2685         hr = IUri_GetHostType(uri, NULL);
2686         ok(hr == E_INVALIDARG, "Error: GetHostType returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
2687
2688         hr = IUri_GetPort(uri, NULL);
2689         ok(hr == E_INVALIDARG, "Error: GetPort returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
2690
2691         hr = IUri_GetScheme(uri, NULL);
2692         ok(hr == E_INVALIDARG, "Error: GetScheme returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
2693
2694         hr = IUri_GetZone(uri, NULL);
2695         ok(hr == E_INVALIDARG, "Error: GetZone returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
2696     }
2697     if(uri) IUri_Release(uri);
2698
2699     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
2700         uri_properties test = uri_tests[i];
2701         LPWSTR uriW;
2702         uri = NULL;
2703
2704         uriW = a2w(test.uri);
2705         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
2706         if(test.create_todo) {
2707             todo_wine {
2708                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2709                         hr, test.create_expected, i);
2710             }
2711         } else {
2712             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2713                     hr, test.create_expected, i);
2714         }
2715
2716         if(SUCCEEDED(hr)) {
2717             uri_dword_property prop;
2718             DWORD received;
2719
2720             /* Assign an insane value so tests don't accidentally pass when
2721              * they shouldn't!
2722              */
2723             received = -9999999;
2724
2725             /* GetHostType() tests. */
2726             prop = test.dword_props[Uri_PROPERTY_HOST_TYPE-Uri_PROPERTY_DWORD_START];
2727             hr = IUri_GetHostType(uri, &received);
2728             if (hr == E_NOTIMPL) goto skip_unimplemented;
2729             if(prop.todo) {
2730                 todo_wine {
2731                     ok(hr == prop.expected, "Error: GetHostType returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2732                             hr, prop.expected, i);
2733                 }
2734                 todo_wine {
2735                     ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
2736                 }
2737             } else {
2738                 ok(hr == prop.expected, "Error: GetHostType returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2739                         hr, prop.expected, i);
2740                 ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
2741             }
2742             received = -9999999;
2743
2744         skip_unimplemented:
2745             /* GetPort() tests. */
2746             prop = test.dword_props[Uri_PROPERTY_PORT-Uri_PROPERTY_DWORD_START];
2747             hr = IUri_GetPort(uri, &received);
2748             if(prop.todo) {
2749                 todo_wine {
2750                     ok(hr == prop.expected, "Error: GetPort returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2751                             hr, prop.expected, i);
2752                 }
2753                 todo_wine {
2754                     ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
2755                 }
2756             } else {
2757                 ok(hr == prop.expected, "Error: GetPort returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2758                         hr, prop.expected, i);
2759                 ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
2760             }
2761             received = -9999999;
2762
2763             /* GetScheme() tests. */
2764             prop = test.dword_props[Uri_PROPERTY_SCHEME-Uri_PROPERTY_DWORD_START];
2765             hr = IUri_GetScheme(uri, &received);
2766             if(prop.todo) {
2767                 todo_wine {
2768                     ok(hr == prop.expected, "Error: GetScheme returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2769                             hr, prop.expected, i);
2770                 }
2771                 todo_wine {
2772                     ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
2773                 }
2774             } else {
2775                 ok(hr == prop.expected, "Error: GetScheme returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2776                         hr, prop.expected, i);
2777                 ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
2778             }
2779             received = -9999999;
2780
2781             /* GetZone() tests. */
2782             prop = test.dword_props[Uri_PROPERTY_ZONE-Uri_PROPERTY_DWORD_START];
2783             hr = IUri_GetZone(uri, &received);
2784             if(prop.todo) {
2785                 todo_wine {
2786                     ok(hr == prop.expected, "Error: GetZone returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2787                             hr, prop.expected, i);
2788                 }
2789                 todo_wine {
2790                     ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
2791                 }
2792             } else {
2793                 ok(hr == prop.expected, "Error: GetZone returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2794                         hr, prop.expected, i);
2795                 ok(received == prop.value, "Error: Expected %d but got %d on uri_tests[%d].\n", prop.value, received, i);
2796             }
2797         }
2798
2799         if(uri) IUri_Release(uri);
2800
2801         heap_free(uriW);
2802     }
2803 }
2804
2805 static void test_IUri_GetPropertyLength(void) {
2806     IUri *uri = NULL;
2807     HRESULT hr;
2808     DWORD i;
2809
2810     /* Make sure it handles invalid args correctly. */
2811     hr = pCreateUri(http_urlW, 0, 0, &uri);
2812     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
2813     if(SUCCEEDED(hr)) {
2814         DWORD received = 0xdeadbeef;
2815
2816         hr = IUri_GetPropertyLength(uri, Uri_PROPERTY_STRING_START, NULL, 0);
2817         ok(hr == E_INVALIDARG, "Error: GetPropertyLength returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
2818
2819         hr = IUri_GetPropertyLength(uri, Uri_PROPERTY_DWORD_START, &received, 0);
2820         ok(hr == E_INVALIDARG, "Error: GetPropertyLength return 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
2821         ok(received == 0xdeadbeef, "Error: Expected 0xdeadbeef but got 0x%08x.\n", received);
2822     }
2823     if(uri) IUri_Release(uri);
2824
2825     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
2826         uri_properties test = uri_tests[i];
2827         LPWSTR uriW;
2828         uri = NULL;
2829
2830         uriW = a2w(test.uri);
2831         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
2832         if(test.create_todo) {
2833             todo_wine {
2834                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
2835                         hr, test.create_expected, i);
2836             }
2837         } else {
2838             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x on uri_test[%d].\n",
2839                     hr, test.create_expected, i);
2840         }
2841
2842         if(SUCCEEDED(hr)) {
2843             DWORD j;
2844
2845             for(j = Uri_PROPERTY_STRING_START; j <= Uri_PROPERTY_STRING_LAST; ++j) {
2846                 DWORD expectedLen, brokenLen, receivedLen;
2847                 uri_str_property prop = test.str_props[j];
2848
2849                 expectedLen = lstrlen(prop.value);
2850                 brokenLen = lstrlen(prop.broken_value);
2851
2852                 /* This won't be necessary once GetPropertyLength is implemented. */
2853                 receivedLen = -1;
2854
2855                 hr = IUri_GetPropertyLength(uri, j, &receivedLen, 0);
2856                 if(prop.todo) {
2857                     todo_wine {
2858                         ok(hr == prop.expected, "Error: GetPropertyLength returned 0x%08x, expected 0x%08x on uri_tests[%d].str_props[%d].\n",
2859                                 hr, prop.expected, i, j);
2860                     }
2861                     todo_wine {
2862                         ok(receivedLen == expectedLen || broken(receivedLen == brokenLen),
2863                                 "Error: Expected a length of %d but got %d on uri_tests[%d].str_props[%d].\n",
2864                                 expectedLen, receivedLen, i, j);
2865                     }
2866                     if (hr == E_NOTIMPL)  /* no point in continuing */
2867                     {
2868                         if(uri) IUri_Release(uri);
2869                         heap_free(uriW);
2870                         return;
2871                     }
2872                 } else {
2873                     ok(hr == prop.expected, "Error: GetPropertyLength returned 0x%08x, expected 0x%08x on uri_tests[%d].str_props[%d].\n",
2874                             hr, prop.expected, i, j);
2875                     ok(receivedLen == expectedLen || broken(receivedLen == brokenLen),
2876                             "Error: Expected a length of %d but got %d on uri_tests[%d].str_props[%d].\n",
2877                             expectedLen, receivedLen, i, j);
2878                 }
2879             }
2880         }
2881
2882         if(uri) IUri_Release(uri);
2883
2884         heap_free(uriW);
2885     }
2886 }
2887
2888 static void test_IUri_GetProperties(void) {
2889     IUri *uri = NULL;
2890     HRESULT hr;
2891     DWORD i;
2892
2893     hr = pCreateUri(http_urlW, 0, 0, &uri);
2894     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
2895     if(SUCCEEDED(hr)) {
2896         hr = IUri_GetProperties(uri, NULL);
2897         ok(hr == E_INVALIDARG, "Error: GetProperties returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
2898     }
2899     if(uri) IUri_Release(uri);
2900
2901     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
2902         uri_properties test = uri_tests[i];
2903         LPWSTR uriW;
2904         uri = NULL;
2905
2906         uriW = a2w(test.uri);
2907         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
2908         if(test.create_todo) {
2909             todo_wine {
2910                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
2911             }
2912         } else {
2913             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
2914         }
2915
2916         if(SUCCEEDED(hr)) {
2917             DWORD received = 0;
2918             DWORD j;
2919
2920             hr = IUri_GetProperties(uri, &received);
2921             if(test.props_todo) {
2922                 todo_wine {
2923                     ok(hr == S_OK, "Error: GetProperties returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
2924                 }
2925                 if (hr == E_NOTIMPL)  /* no point in continuing */
2926                 {
2927                     if(uri) IUri_Release(uri);
2928                     heap_free(uriW);
2929                     return;
2930                 }
2931             } else {
2932                 ok(hr == S_OK, "Error: GetProperties returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
2933             }
2934
2935             for(j = 0; j <= Uri_PROPERTY_DWORD_LAST; ++j) {
2936                 /* (1 << j) converts a Uri_PROPERTY to its corresponding Uri_HAS_* flag mask. */
2937                 if(test.props & (1 << j)) {
2938                     if(test.props_todo) {
2939                         todo_wine {
2940                             ok(received & (1 << j), "Error: Expected flag for property %d on uri_tests[%d].\n", j, i);
2941                         }
2942                     } else {
2943                         ok(received & (1 << j), "Error: Expected flag for property %d on uri_tests[%d].\n", j, i);
2944                     }
2945                 } else {
2946                     /* NOTE: Since received is initialized to 0, this test will always pass while
2947                      * GetProperties is unimplemented.
2948                      */
2949                     ok(!(received & (1 << j)), "Error: Received flag for property %d when not expected on uri_tests[%d].\n", j, i);
2950                 }
2951             }
2952         }
2953
2954         if(uri) IUri_Release(uri);
2955
2956         heap_free(uriW);
2957     }
2958 }
2959
2960 static void test_IUri_HasProperty(void) {
2961     IUri *uri = NULL;
2962     HRESULT hr;
2963     DWORD i;
2964
2965     hr = pCreateUri(http_urlW, 0, 0, &uri);
2966     ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
2967     if(SUCCEEDED(hr)) {
2968         hr = IUri_HasProperty(uri, Uri_PROPERTY_RAW_URI, NULL);
2969         ok(hr == E_INVALIDARG, "Error: HasProperty returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
2970     }
2971     if(uri) IUri_Release(uri);
2972
2973     for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
2974         uri_properties test = uri_tests[i];
2975         LPWSTR uriW;
2976         uri = NULL;
2977
2978         uriW = a2w(test.uri);
2979
2980         hr = pCreateUri(uriW, test.create_flags, 0, &uri);
2981         if(test.create_todo) {
2982             todo_wine {
2983                 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
2984             }
2985         } else {
2986             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
2987         }
2988
2989         if(SUCCEEDED(hr)) {
2990             DWORD j;
2991
2992             for(j = 0; j <= Uri_PROPERTY_DWORD_LAST; ++j) {
2993                 /* Assign -1, then explicitly test for TRUE or FALSE later. */
2994                 BOOL received = -1;
2995
2996                 hr = IUri_HasProperty(uri, j, &received);
2997                 if(test.props_todo) {
2998                     todo_wine {
2999                         ok(hr == S_OK, "Error: HasProperty returned 0x%08x, expected 0x%08x for property %d on uri_tests[%d].\n",
3000                                 hr, S_OK, j, i);
3001                     }
3002                     if (hr == E_NOTIMPL)  /* no point in continuing */
3003                     {
3004                         if(uri) IUri_Release(uri);
3005                         heap_free(uriW);
3006                         return;
3007                     }
3008
3009                     /* Check if the property should be true. */
3010                     if(test.props & (1 << j)) {
3011                         todo_wine {
3012                             ok(received == TRUE, "Error: Expected to have property %d on uri_tests[%d].\n", j, i);
3013                         }
3014                     } else {
3015                         todo_wine {
3016                             ok(received == FALSE, "Error: Wasn't expecting to have property %d on uri_tests[%d].\n", j, i);
3017                         }
3018                     }
3019                 } else {
3020                     ok(hr == S_OK, "Error: HasProperty returned 0x%08x, expected 0x%08x for property %d on uri_tests[%d].\n",
3021                             hr, S_OK, j, i);
3022
3023                     if(test.props & (1 << j)) {
3024                         ok(received == TRUE, "Error: Expected to have property %d on uri_tests[%d].\n", j, i);
3025                     } else {
3026                         ok(received == FALSE, "Error: Wasn't expecting to have property %d on uri_tests[%d].\n", j, i);
3027                     }
3028                 }
3029             }
3030         }
3031
3032         if(uri) IUri_Release(uri);
3033
3034         heap_free(uriW);
3035     }
3036 }
3037
3038 static void test_IUri_IsEqual(void) {
3039     IUri *uriA, *uriB;
3040     HRESULT hrA, hrB;
3041     DWORD i;
3042
3043     uriA = uriB = NULL;
3044
3045     /* Make sure IsEqual handles invalid args correctly. */
3046     hrA = pCreateUri(http_urlW, 0, 0, &uriA);
3047     hrB = pCreateUri(http_urlW, 0, 0, &uriB);
3048     ok(hrA == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hrA, S_OK);
3049     ok(hrB == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hrB, S_OK);
3050     if(SUCCEEDED(hrA) && SUCCEEDED(hrB)) {
3051         BOOL equal = -1;
3052         hrA = IUri_IsEqual(uriA, NULL, &equal);
3053         ok(hrA == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x.\n", hrA, S_OK);
3054         ok(equal == FALSE, "Error: Expected equal to be FALSE, but was %d instead.\n", equal);
3055
3056         hrA = IUri_IsEqual(uriA, uriB, NULL);
3057         ok(hrA == E_POINTER, "Error: IsEqual returned 0x%08x, expected 0x%08x.\n", hrA, E_POINTER);
3058     }
3059     if(uriA) IUri_Release(uriA);
3060     if(uriB) IUri_Release(uriB);
3061
3062     for(i = 0; i < sizeof(equality_tests)/sizeof(equality_tests[0]); ++i) {
3063         uri_equality test = equality_tests[i];
3064         LPWSTR uriA_W, uriB_W;
3065
3066         uriA = uriB = NULL;
3067
3068         uriA_W = a2w(test.a);
3069         uriB_W = a2w(test.b);
3070
3071         hrA = pCreateUri(uriA_W, test.create_flags_a, 0, &uriA);
3072         if(test.create_todo_a) {
3073             todo_wine {
3074                 ok(hrA == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].a\n",
3075                         hrA, S_OK, i);
3076             }
3077         } else {
3078             ok(hrA == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].a\n",
3079                     hrA, S_OK, i);
3080         }
3081
3082         hrB = pCreateUri(uriB_W, test.create_flags_b, 0, &uriB);
3083         if(test.create_todo_b) {
3084             todo_wine {
3085                 ok(hrB == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].b\n",
3086                         hrB, S_OK, i);
3087             }
3088         } else {
3089             ok(hrB == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].b\n",
3090                     hrB, S_OK, i);
3091         }
3092
3093         if(SUCCEEDED(hrA) && SUCCEEDED(hrB)) {
3094             BOOL equal = -1;
3095
3096             hrA = IUri_IsEqual(uriA, uriB, &equal);
3097             if(test.todo) {
3098                 todo_wine {
3099                     ok(hrA == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x on equality_tests[%d].\n",
3100                             hrA, S_OK, i);
3101                 }
3102                 todo_wine {
3103                     ok(equal == test.equal, "Error: Expected the comparison to be %d on equality_tests[%d].\n", test.equal, i);
3104                 }
3105             } else {
3106                 ok(hrA == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x on equality_tests[%d].\n", hrA, S_OK, i);
3107                 ok(equal == test.equal, "Error: Expected the comparison to be %d on equality_tests[%d].\n", test.equal, i);
3108             }
3109         }
3110         if(uriA) IUri_Release(uriA);
3111         if(uriB) IUri_Release(uriB);
3112
3113         heap_free(uriA_W);
3114         heap_free(uriB_W);
3115     }
3116 }
3117
3118 START_TEST(uri) {
3119     HMODULE hurlmon;
3120
3121     hurlmon = GetModuleHandle("urlmon.dll");
3122     pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
3123
3124     if(!pCreateUri) {
3125         win_skip("CreateUri is not present, skipping tests.\n");
3126         return;
3127     }
3128
3129     trace("test CreateUri invalid flags...\n");
3130     test_CreateUri_InvalidFlags();
3131
3132     trace("test CreateUri invalid args...\n");
3133     test_CreateUri_InvalidArgs();
3134
3135     trace("test CreateUri invalid URIs...\n");
3136     test_CreateUri_InvalidUri();
3137
3138     trace("test IUri_GetPropertyBSTR...\n");
3139     test_IUri_GetPropertyBSTR();
3140
3141     trace("test IUri_GetPropertyDWORD...\n");
3142     test_IUri_GetPropertyDWORD();
3143
3144     trace("test IUri_GetStrProperties...\n");
3145     test_IUri_GetStrProperties();
3146
3147     trace("test IUri_GetDwordProperties...\n");
3148     test_IUri_GetDwordProperties();
3149
3150     trace("test IUri_GetPropertyLength...\n");
3151     test_IUri_GetPropertyLength();
3152
3153     trace("test IUri_GetProperties...\n");
3154     test_IUri_GetProperties();
3155
3156     trace("test IUri_HasProperty...\n");
3157     test_IUri_HasProperty();
3158
3159     trace("test IUri_IsEqual...\n");
3160     test_IUri_IsEqual();
3161 }