ReactOS  0.4.15-dev-1207-g698a8e6
url.c
Go to the documentation of this file.
1 /* Unit test suite for Path functions
2  *
3  * Copyright 2002 Matthew Mastracci
4  * Copyright 2007-2010 Detlef Riekenberg
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 #include <stdarg.h>
22 #include <stdio.h>
23 
24 #include "wine/test.h"
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winreg.h"
28 #include "shlwapi.h"
29 #include "wininet.h"
30 #include "intshcut.h"
31 
32 /* ################ */
34 static HRESULT (WINAPI *pUrlUnescapeA)(LPSTR,LPSTR,LPDWORD,DWORD);
35 static HRESULT (WINAPI *pUrlUnescapeW)(LPWSTR,LPWSTR,LPDWORD,DWORD);
36 static BOOL (WINAPI *pUrlIsA)(LPCSTR,URLIS);
37 static BOOL (WINAPI *pUrlIsW)(LPCWSTR,URLIS);
38 static HRESULT (WINAPI *pUrlHashA)(LPCSTR,LPBYTE,DWORD);
39 static HRESULT (WINAPI *pUrlHashW)(LPCWSTR,LPBYTE,DWORD);
40 static HRESULT (WINAPI *pUrlGetPartA)(LPCSTR,LPSTR,LPDWORD,DWORD,DWORD);
41 static HRESULT (WINAPI *pUrlGetPartW)(LPCWSTR,LPWSTR,LPDWORD,DWORD,DWORD);
42 static HRESULT (WINAPI *pUrlEscapeA)(LPCSTR,LPSTR,LPDWORD,DWORD);
43 static HRESULT (WINAPI *pUrlEscapeW)(LPCWSTR,LPWSTR,LPDWORD,DWORD);
44 static HRESULT (WINAPI *pUrlCreateFromPathA)(LPCSTR,LPSTR,LPDWORD,DWORD);
45 static HRESULT (WINAPI *pUrlCreateFromPathW)(LPCWSTR,LPWSTR,LPDWORD,DWORD);
46 static HRESULT (WINAPI *pUrlCombineA)(LPCSTR,LPCSTR,LPSTR,LPDWORD,DWORD);
47 static HRESULT (WINAPI *pUrlCombineW)(LPCWSTR,LPCWSTR,LPWSTR,LPDWORD,DWORD);
48 static HRESULT (WINAPI *pUrlCanonicalizeA)(LPCSTR, LPSTR, LPDWORD, DWORD);
49 static HRESULT (WINAPI *pUrlCanonicalizeW)(LPCWSTR, LPWSTR, LPDWORD, DWORD);
50 static HRESULT (WINAPI *pUrlApplySchemeA)(LPCSTR,LPSTR,LPDWORD,DWORD);
51 static HRESULT (WINAPI *pUrlApplySchemeW)(LPCWSTR,LPWSTR,LPDWORD,DWORD);
52 static HRESULT (WINAPI *pParseURLA)(LPCSTR,PARSEDURLA*);
53 static HRESULT (WINAPI *pParseURLW)(LPCWSTR,PARSEDURLW*);
54 static HRESULT (WINAPI *pHashData)(LPBYTE, DWORD, LPBYTE, DWORD);
55 
56 static const char* TEST_URL_1 = "http://www.winehq.org/tests?date=10/10/1923";
57 static const char* TEST_URL_2 = "http://localhost:8080/tests%2e.html?date=Mon%2010/10/1923";
58 static const char* TEST_URL_3 = "http://foo:bar@localhost:21/internal.php?query=x&return=y";
59 static const char* TEST_URL_4 = "http://foo:bar@google.*.com:21/internal.php?query=x&return=y";
60 
61 static const WCHAR winehqW[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/',0};
62 static const CHAR winehqA[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/',0};
63 
64 /* ################ */
65 
66 static const CHAR untouchedA[] = "untouched";
67 
68 #define TEST_APPLY_MAX_LENGTH INTERNET_MAX_URL_LENGTH
69 
70 typedef struct _TEST_URL_APPLY {
71  const char * url;
75  const char * newurl;
77 
78 static const TEST_URL_APPLY TEST_APPLY[] = {
79  {"www.winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_OK, 21, "http://www.winehq.org"},
80  {"www.winehq.org", URL_APPLY_GUESSSCHEME, S_OK, 21, "http://www.winehq.org"},
81  {"www.winehq.org", URL_APPLY_DEFAULT, S_OK, 21, "http://www.winehq.org"},
82  {"ftp.winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_OK, 20, "ftp://ftp.winehq.org"},
83  {"ftp.winehq.org", URL_APPLY_GUESSSCHEME, S_OK, 20, "ftp://ftp.winehq.org"},
84  {"ftp.winehq.org", URL_APPLY_DEFAULT, S_OK, 21, "http://ftp.winehq.org"},
85  {"winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_OK, 17, "http://winehq.org"},
87  {"winehq.org", URL_APPLY_DEFAULT, S_OK, 17, "http://winehq.org"},
88  {"http://www.winehq.org", URL_APPLY_GUESSSCHEME , S_FALSE, TEST_APPLY_MAX_LENGTH, untouchedA},
90  {"http://www.winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_FORCEAPPLY | URL_APPLY_DEFAULT, S_OK, 28, "http://http://www.winehq.org"},
92  {"", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_OK, 7, "http://"},
94  {"", URL_APPLY_DEFAULT, S_OK, 7, "http://"},
95  {"u:\\windows", URL_APPLY_GUESSFILE | URL_APPLY_DEFAULT, S_OK, 18, "file:///u:/windows"},
96  {"u:\\windows", URL_APPLY_GUESSFILE, S_OK, 18, "file:///u:/windows"},
97  {"u:\\windows", URL_APPLY_DEFAULT, S_OK, 17, "http://u:\\windows"},
98  {"file:///c:/windows", URL_APPLY_GUESSFILE , S_FALSE, TEST_APPLY_MAX_LENGTH, untouchedA},
100 };
101 
102 /* ################ */
103 
104 typedef struct _TEST_URL_CANONICALIZE {
105  const char *url;
108  const char *expecturl;
111 
113  {"http://www.winehq.org/tests/../tests/../..", 0, S_OK, "http://www.winehq.org/", TRUE},
114  {"http://www.winehq.org/..", 0, S_OK, "http://www.winehq.org/..", FALSE},
115  {"http://www.winehq.org/tests/tests2/../../tests", 0, S_OK, "http://www.winehq.org/tests", FALSE},
116  {"http://www.winehq.org/tests/../tests", 0, S_OK, "http://www.winehq.org/tests", FALSE},
117  {"http://www.winehq.org/tests\n", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests", FALSE},
118  {"http://www.winehq.org/tests\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests", FALSE},
119  {"http://www.winehq.org/tests\r", 0, S_OK, "http://www.winehq.org/tests", FALSE},
120  {"http://www.winehq.org/tests\r", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests", FALSE},
121  {"http://www.winehq.org/tests/../tests/", 0, S_OK, "http://www.winehq.org/tests/", FALSE},
122  {"http://www.winehq.org/tests/../tests/..", 0, S_OK, "http://www.winehq.org/", FALSE},
123  {"http://www.winehq.org/tests/../tests/../", 0, S_OK, "http://www.winehq.org/", FALSE},
124  {"http://www.winehq.org/tests/..", 0, S_OK, "http://www.winehq.org/", FALSE},
125  {"http://www.winehq.org/tests/../", 0, S_OK, "http://www.winehq.org/", FALSE},
126  {"http://www.winehq.org/tests/..?query=x&return=y", 0, S_OK, "http://www.winehq.org/?query=x&return=y", FALSE},
127  {"http://www.winehq.org/tests/../?query=x&return=y", 0, S_OK, "http://www.winehq.org/?query=x&return=y", FALSE},
128  {"\tht\ttp\t://www\t.w\tineh\t\tq.or\tg\t/\ttests/..\t?\tquer\ty=x\t\t&re\tturn=y\t\t", 0, S_OK, "http://www.winehq.org/?query=x&return=y", FALSE},
129  {"http://www.winehq.org/tests/..#example", 0, S_OK, "http://www.winehq.org/#example", FALSE},
130  {"http://www.winehq.org/tests/../#example", 0, S_OK, "http://www.winehq.org/#example", FALSE},
131  {"http://www.winehq.org/tests\\../#example", 0, S_OK, "http://www.winehq.org/#example", FALSE},
132  {"http://www.winehq.org/tests/..\\#example", 0, S_OK, "http://www.winehq.org/#example", FALSE},
133  {"http://www.winehq.org\\tests/../#example", 0, S_OK, "http://www.winehq.org/#example", FALSE},
134  {"http://www.winehq.org/tests/../#example", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../#example", FALSE},
135  {"http://www.winehq.org/tests/foo bar", URL_ESCAPE_SPACES_ONLY| URL_DONT_ESCAPE_EXTRA_INFO , S_OK, "http://www.winehq.org/tests/foo%20bar", FALSE},
136  {"http://www.winehq.org/tests/foo%20bar", URL_UNESCAPE , S_OK, "http://www.winehq.org/tests/foo bar", FALSE},
137  {"http://www.winehq.org", 0, S_OK, "http://www.winehq.org/", FALSE},
138  {"http:///www.winehq.org", 0, S_OK, "http:///www.winehq.org", FALSE},
139  {"http:////www.winehq.org", 0, S_OK, "http:////www.winehq.org", FALSE},
140  {"file:///c:/tests/foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar", FALSE},
141  {"file:///c:/tests\\foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar", FALSE},
142  {"file:///c:/tests/foo%20bar", 0, S_OK, "file:///c:/tests/foo%20bar", FALSE},
143  {"file:///c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE},
144  {"file://localhost/c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE},
145  {"file://localhost\\c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE},
146  {"file://localhost\\\\c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE},
147  {"file://localhost\\c:\\tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE},
148  {"file://c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE},
149  {"file://c:/tests\\../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE},
150  {"file://c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE},
151  {"file:///c://tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\\\tests\\foo bar", FALSE},
152  {"file:///c:\\tests\\foo bar", 0, S_OK, "file:///c:/tests/foo bar", FALSE},
153  {"file:///c:\\tests\\foo bar", URL_DONT_SIMPLIFY, S_OK, "file:///c:/tests/foo bar", FALSE},
154  {"file:///c:\\tests\\foobar", 0, S_OK, "file:///c:/tests/foobar", FALSE},
155  {"file:///c:\\tests\\foobar", URL_WININET_COMPATIBILITY, S_OK, "file://c:\\tests\\foobar", FALSE},
156  {"file://home/user/file", 0, S_OK, "file://home/user/file", FALSE},
157  {"file:///home/user/file", 0, S_OK, "file:///home/user/file", FALSE},
158  {"file:////home/user/file", 0, S_OK, "file://home/user/file", FALSE},
159  {"file://home/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://\\\\home\\user\\file", FALSE},
160  {"file:///home/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://\\home\\user\\file", FALSE},
161  {"file:////home/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://\\\\home\\user\\file", FALSE},
162  {"file://///home/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://\\\\home\\user\\file", FALSE},
163  {"file://C:/user/file", 0, S_OK, "file:///C:/user/file", FALSE},
164  {"file://C:/user/file/../asdf", 0, S_OK, "file:///C:/user/asdf", FALSE},
165  {"file:///C:/user/file", 0, S_OK, "file:///C:/user/file", FALSE},
166  {"file:////C:/user/file", 0, S_OK, "file:///C:/user/file", FALSE},
167  {"file://C:/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://C:\\user\\file", FALSE},
168  {"file:///C:/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://C:\\user\\file", FALSE},
169  {"file:////C:/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://C:\\user\\file", FALSE},
170  {"http:///www.winehq.org", 0, S_OK, "http:///www.winehq.org", FALSE},
171  {"http:///www.winehq.org", URL_WININET_COMPATIBILITY, S_OK, "http:///www.winehq.org", FALSE},
172  {"http://www.winehq.org/site/about", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org/site/about", FALSE},
173  {"file_://www.winehq.org/site/about", URL_FILE_USE_PATHURL, S_OK, "file_://www.winehq.org/site/about", FALSE},
174  {"c:\\dir\\file", 0, S_OK, "file:///c:/dir/file", FALSE},
175  {"file:///c:\\dir\\file", 0, S_OK, "file:///c:/dir/file", FALSE},
176  {"c:dir\\file", 0, S_OK, "file:///c:dir/file", FALSE},
177  {"c:\\tests\\foo bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE},
178  {"c:\\tests\\foo bar", 0, S_OK, "file:///c:/tests/foo%20bar", FALSE},
179  {"c\t:\t\\te\tsts\\fo\to \tbar\t", 0, S_OK, "file:///c:/tests/foo%20bar", FALSE},
180  {"res://file", 0, S_OK, "res://file/", FALSE},
181  {"res://file", URL_FILE_USE_PATHURL, S_OK, "res://file/", FALSE},
182  {"res:///c:/tests/foo%20bar", URL_UNESCAPE , S_OK, "res:///c:/tests/foo bar", FALSE},
183  {"res:///c:/tests\\foo%20bar", URL_UNESCAPE , S_OK, "res:///c:/tests\\foo bar", FALSE},
184  {"res:///c:/tests/foo%20bar", 0, S_OK, "res:///c:/tests/foo%20bar", FALSE},
185  {"res:///c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res:///c:/tests/foo%20bar", FALSE},
186  {"res://c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res://c:/tests/foo%20bar", FALSE},
187  {"res://c:/tests\\../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res://c:/tests/foo%20bar", FALSE},
188  {"res://c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res://c:/tests/foo%20bar", FALSE},
189  {"res:///c://tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res:///c://tests/foo%20bar", FALSE},
190  {"res:///c:\\tests\\foo bar", 0, S_OK, "res:///c:\\tests\\foo bar", FALSE},
191  {"res:///c:\\tests\\foo bar", URL_DONT_SIMPLIFY, S_OK, "res:///c:\\tests\\foo bar", FALSE},
192  {"res://c:\\tests\\foo bar/res", URL_FILE_USE_PATHURL, S_OK, "res://c:\\tests\\foo bar/res", FALSE},
193  {"res://c:\\tests/res\\foo%20bar/strange\\sth", 0, S_OK, "res://c:\\tests/res\\foo%20bar/strange\\sth", FALSE},
194  {"res://c:\\tests/res\\foo%20bar/strange\\sth", URL_FILE_USE_PATHURL, S_OK, "res://c:\\tests/res\\foo%20bar/strange\\sth", FALSE},
195  {"res://c:\\tests/res\\foo%20bar/strange\\sth", URL_UNESCAPE, S_OK, "res://c:\\tests/res\\foo bar/strange\\sth", FALSE},
196  {"/A/../B/./C/../../test_remove_dot_segments", 0, S_OK, "/test_remove_dot_segments", FALSE},
197  {"/A/../B/./C/../../test_remove_dot_segments", URL_FILE_USE_PATHURL, S_OK, "/test_remove_dot_segments", FALSE},
198  {"/A/../B/./C/../../test_remove_dot_segments", URL_WININET_COMPATIBILITY, S_OK, "/test_remove_dot_segments", FALSE},
199  {"/A/B\\C/D\\E", 0, S_OK, "/A/B\\C/D\\E", FALSE},
200  {"/A/B\\C/D\\E", URL_FILE_USE_PATHURL, S_OK, "/A/B\\C/D\\E", FALSE},
201  {"/A/B\\C/D\\E", URL_WININET_COMPATIBILITY, S_OK, "/A/B\\C/D\\E", FALSE},
202  {"///A/../B", 0, S_OK, "///B", FALSE},
203  {"///A/../B", URL_FILE_USE_PATHURL, S_OK, "///B", FALSE},
204  {"///A/../B", URL_WININET_COMPATIBILITY, S_OK, "///B", FALSE},
205  {"A", 0, S_OK, "A", FALSE},
206  {"../A", 0, S_OK, "../A", FALSE},
207  {"./A", 0, S_OK, "A", FALSE},
208  {"./A/./B", 0, S_OK, "A/B", FALSE},
209  {"./A", URL_DONT_SIMPLIFY, S_OK, "./A", FALSE},
210  {"A/./B", 0, S_OK, "A/B", TRUE},
211  {"A/../B", 0, S_OK, "B", TRUE},
212  {"A/../B/./../C", 0, S_OK, "C", TRUE},
213  {"A/../B/./../C", URL_DONT_SIMPLIFY, S_OK, "A/../B/./../C", FALSE},
214  {".\\A", 0, S_OK, ".\\A", FALSE},
215  {"A\\.\\B", 0, S_OK, "A\\.\\B", FALSE},
216  {".", 0, S_OK, "/", TRUE},
217  {"./A", 0, S_OK, "A", TRUE},
218  {"A/./B", 0, S_OK, "A/B", TRUE},
219  {"/:test\\", 0, S_OK, "/:test\\", TRUE},
220  {"/uri-res/N2R?urn:sha1:B3K", URL_DONT_ESCAPE_EXTRA_INFO | URL_WININET_COMPATIBILITY /*0x82000000*/, S_OK, "/uri-res/N2R?urn:sha1:B3K", FALSE} /*LimeWire online installer calls this*/,
221  {"http:www.winehq.org/dir/../index.html", 0, S_OK, "http:www.winehq.org/index.html"},
222  {"http://localhost/test.html", URL_FILE_USE_PATHURL, S_OK, "http://localhost/test.html"},
223  {"http://localhost/te%20st.html", URL_FILE_USE_PATHURL, S_OK, "http://localhost/te%20st.html"},
224  {"http://www.winehq.org/%E6%A1%9C.html", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org/%E6%A1%9C.html"},
225  {"mk:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm", 0, S_OK, "mk:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm"},
226  {"ftp:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm", 0, S_OK, "ftp:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm"},
227  {"file:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm", 0, S_OK, "file:@MSITStore:C:/Program Files/AutoCAD 2008/Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm"},
228  {"http:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm", 0, S_OK, "http:@MSITStore:C:/Program Files/AutoCAD 2008/Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm"},
229  {"http:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm", URL_FILE_USE_PATHURL, S_OK, "http:@MSITStore:C:/Program Files/AutoCAD 2008/Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm"},
230  {"mk:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm", URL_FILE_USE_PATHURL, S_OK, "mk:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm"},
231 };
232 
233 /* ################ */
234 
235 typedef struct _TEST_URL_ESCAPE {
236  const char *url;
240  const char *expecturl;
242 
243 static const TEST_URL_ESCAPE TEST_ESCAPE[] = {
244  {"http://www.winehq.org/tests0", 0, 0, S_OK, "http://www.winehq.org/tests0"},
245  {"http://www.winehq.org/tests1\n", 0, 0, S_OK, "http://www.winehq.org/tests1%0A"},
246  {"http://www.winehq.org/tests2\r", 0, 0, S_OK, "http://www.winehq.org/tests2%0D"},
247  {"http://www.winehq.org/tests3\r", URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, 0, S_OK, "http://www.winehq.org/tests3\r"},
248  {"http://www.winehq.org/tests4\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests4\r"},
249  {"http://www.winehq.org/tests5\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests5\r"},
250  {"/direct/swhelp/series6/6.2i_latestservicepack.dat\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "/direct/swhelp/series6/6.2i_latestservicepack.dat\r"},
251 
252  {"file://////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
253  {"file://///foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
254  {"file:////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
255  {"file:///localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"},
256  {"file:///foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
257  {"file://loCalHost/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
258  {"file://foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
259  {"file:/localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"},
260  {"file:/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
261  {"file:foo/bar\\baz", 0, 0, S_OK, "file:foo/bar/baz"},
262  {"file:\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
263  {"file:\\\\foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
264  {"file:\\\\\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
265  {"file:\\\\localhost\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
266  {"file:///f oo/b?a r\\baz", 0, 0, S_OK, "file:///f%20oo/b?a r\\baz"},
267  {"file:///foo/b#a r\\baz", 0, 0, S_OK, "file:///foo/b%23a%20r/baz"},
268  {"file:///f o^&`{}|][\"<>\\%o/b#a r\\baz", 0, 0, S_OK, "file:///f%20o%5E%26%60%7B%7D%7C%5D%5B%22%3C%3E/%o/b%23a%20r/baz"},
269  {"file:///f o%o/b?a r\\b%az", URL_ESCAPE_PERCENT, 0, S_OK, "file:///f%20o%25o/b?a r\\b%az"},
270  {"file:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "file:%2Ffoo%2Fbar%5Cbaz"},
271 
272  {"foo/b%ar\\ba?z\\", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%ar%5Cba%3Fz%5C"},
273  {"foo/b%ar\\ba?z\\", URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%25ar%5Cba%3Fz%5C"},
274  {"foo/bar\\ba?z\\", 0, 0, S_OK, "foo/bar%5Cba?z\\"},
275  {"/foo/bar\\ba?z\\", 0, 0, S_OK, "/foo/bar%5Cba?z\\"},
276  {"/foo/bar\\ba#z\\", 0, 0, S_OK, "/foo/bar%5Cba#z\\"},
277  {"/foo/%5C", 0, 0, S_OK, "/foo/%5C"},
278  {"/foo/%5C", URL_ESCAPE_PERCENT, 0, S_OK, "/foo/%255C"},
279 
280  {"http://////foo/bar\\baz", 0, 0, S_OK, "http://////foo/bar/baz"},
281  {"http://///foo/bar\\baz", 0, 0, S_OK, "http://///foo/bar/baz"},
282  {"http:////foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"},
283  {"http:///foo/bar\\baz", 0, 0, S_OK, "http:///foo/bar/baz"},
284  {"http://localhost/foo/bar\\baz", 0, 0, S_OK, "http://localhost/foo/bar/baz"},
285  {"http://foo/bar\\baz", 0, 0, S_OK, "http://foo/bar/baz"},
286  {"http:/foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"},
287  {"http:foo/bar\\ba?z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba?z\\"},
288  {"http:foo/bar\\ba#z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba#z\\"},
289  {"http:\\foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"},
290  {"http:\\\\foo/bar\\baz", 0, 0, S_OK, "http://foo/bar/baz"},
291  {"http:\\\\\\foo/bar\\baz", 0, 0, S_OK, "http:///foo/bar/baz"},
292  {"http:\\\\\\\\foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"},
293  {"http:/fo ?o/b ar\\baz", 0, 0, S_OK, "http:/fo%20?o/b ar\\baz"},
294  {"http:fo ?o/b ar\\baz", 0, 0, S_OK, "http:fo%20?o/b ar\\baz"},
295  {"http:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "http:%2Ffoo%2Fbar%5Cbaz"},
296 
297  {"https://foo/bar\\baz", 0, 0, S_OK, "https://foo/bar/baz"},
298  {"https:/foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"},
299  {"https:\\foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"},
300 
301  {"foo:////foo/bar\\baz", 0, 0, S_OK, "foo:////foo/bar%5Cbaz"},
302  {"foo:///foo/bar\\baz", 0, 0, S_OK, "foo:///foo/bar%5Cbaz"},
303  {"foo://localhost/foo/bar\\baz", 0, 0, S_OK, "foo://localhost/foo/bar%5Cbaz"},
304  {"foo://foo/bar\\baz", 0, 0, S_OK, "foo://foo/bar%5Cbaz"},
305  {"foo:/foo/bar\\baz", 0, 0, S_OK, "foo:/foo/bar%5Cbaz"},
306  {"foo:foo/bar\\baz", 0, 0, S_OK, "foo:foo%2Fbar%5Cbaz"},
307  {"foo:\\foo/bar\\baz", 0, 0, S_OK, "foo:%5Cfoo%2Fbar%5Cbaz"},
308  {"foo:/foo/bar\\ba?\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba?\\z"},
309  {"foo:/foo/bar\\ba#\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba#\\z"},
310 
311  {"mailto:/fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:%2Ffo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
312  {"mailto:fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:fo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
313  {"mailto:fo/o@b\\%a?\\r.b#\\az", URL_ESCAPE_PERCENT, 0, S_OK, "mailto:fo%2Fo@b%5C%25a%3F%5Cr.b%23%5Caz"},
314 
315  {"ftp:fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:fo%2Fo@bar.baz%2Ffoo%2Fbar"},
316  {"ftp:/fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:/fo/o@bar.baz/foo/bar"},
317  {"ftp://fo/o@bar.baz/fo?o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo?o\\bar"},
318  {"ftp://fo/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo#o\\bar"},
319  {"ftp://localhost/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://localhost/o@bar.baz/fo#o\\bar"},
320  {"ftp:///fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:///fo/o@bar.baz/foo/bar"},
321  {"ftp:////fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:////fo/o@bar.baz/foo/bar"},
322 
323  {"ftp\x1f\1end/", 0, 0, S_OK, "ftp%1F%01end/"}
324 };
325 
326 typedef struct _TEST_URL_ESCAPEW {
331  const WCHAR win7url[INTERNET_MAX_URL_LENGTH]; /* <= Win7 */
332  const WCHAR vistaurl[INTERNET_MAX_URL_LENGTH]; /* <= Vista/2k8 */
334 
335 static const TEST_URL_ESCAPEW TEST_ESCAPEW[] = {
336  {{' ','<','>','"',0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','2','0','%','3','C','%','3','E','%','2','2',0}},
337  {{'{','}','|','\\',0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','7','B','%','7','D','%','7','C','%','5','C',0}},
338  {{'^',']','[','`',0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','5','E','%','5','D','%','5','B','%','6','0',0}},
339  {{'&','/','?','#',0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','2','6','/','?','#',0}},
340  {{'M','a','s','s',0}, URL_ESCAPE_AS_UTF8, S_OK, {'M','a','s','s',0}},
341 
342  /* broken < Win8/10 */
343 
344  {{'M','a',0xdf,0}, URL_ESCAPE_AS_UTF8, S_OK, {'M','a','%','C','3','%','9','F',0},
345  {'M','a','%','D','F',0}},
346  /* 0x2070E */
347  {{0xd841,0xdf0e,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','F','0','%','A','0','%','9','C','%','8','E',0},
348  {'%','E','F','%','B','F','%','B','D','%','E','F','%','B','F','%','B','D',0},
349  {0xd841,0xdf0e,0}},
350  /* 0x27A3E */
351  {{0xd85e,0xde3e,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','F','0','%','A','7','%','A','8','%','B','E',0},
352  {'%','E','F','%','B','F','%','B','D','%','E','F','%','B','F','%','B','D',0},
353  {0xd85e,0xde3e,0}},
354 
355  {{0xd85e,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','E','F','%','B','F','%','B','D',0},
356  {0xd85e,0}},
357  {{0xd85e,0x41}, URL_ESCAPE_AS_UTF8, S_OK, {'%','E','F','%','B','F','%','B','D','A',0},
358  {0xd85e,'A',0}},
359  {{0xdc00,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','E','F','%','B','F','%','B','D',0},
360  {0xdc00,0}},
361  {{0xffff,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','E','F','%','B','F','%','B','F',0},
362  {0xffff,0}},
363 };
364 
365 /* ################ */
366 
367 typedef struct _TEST_URL_COMBINE {
368  const char *url1;
369  const char *url2;
372  const char *expecturl;
375 
376 static const TEST_URL_COMBINE TEST_COMBINE[] = {
377  {"http://www.winehq.org/tests", "tests1", 0, S_OK, "http://www.winehq.org/tests1"},
378  {"http://www.%77inehq.org/tests", "tests1", 0, S_OK, "http://www.%77inehq.org/tests1"},
379  /*FIXME {"http://www.winehq.org/tests", "../tests2", 0, S_OK, "http://www.winehq.org/tests2"},*/
380  {"http://www.winehq.org/tests/", "../tests3", 0, S_OK, "http://www.winehq.org/tests3"},
381  {"http://www.winehq.org/tests/test1", "test2", 0, S_OK, "http://www.winehq.org/tests/test2"},
382  {"http://www.winehq.org/tests/../tests", "tests4", 0, S_OK, "http://www.winehq.org/tests4"},
383  {"http://www.winehq.org/tests/../tests/", "tests5", 0, S_OK, "http://www.winehq.org/tests/tests5"},
384  {"http://www.winehq.org/tests/../tests/", "/tests6/..", 0, S_OK, "http://www.winehq.org/"},
385  {"http://www.winehq.org/tests/../tests/..", "tests7/..", 0, S_OK, "http://www.winehq.org/"},
386  {"http://www.winehq.org/tests/?query=x&return=y", "tests8", 0, S_OK, "http://www.winehq.org/tests/tests8"},
387  {"http://www.winehq.org/tests/#example", "tests9", 0, S_OK, "http://www.winehq.org/tests/tests9"},
388  {"http://www.winehq.org/tests/../tests/", "/tests10/..", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests10/.."},
389  {"http://www.winehq.org/tests/../", "tests11", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../tests11"},
390  {"http://www.winehq.org/test12", "#", 0, S_OK, "http://www.winehq.org/test12#"},
391  {"http://www.winehq.org/test13#aaa", "#bbb", 0, S_OK, "http://www.winehq.org/test13#bbb"},
392  {"http://www.winehq.org/test14#aaa/bbb#ccc", "#", 0, S_OK, "http://www.winehq.org/test14#"},
393  {"http://www.winehq.org/tests/?query=x/y/z", "tests15", 0, S_OK, "http://www.winehq.org/tests/tests15"},
394  {"http://www.winehq.org/tests/?query=x/y/z#example", "tests16", 0, S_OK, "http://www.winehq.org/tests/tests16"},
395  {"http://www.winehq.org/tests17", ".", 0, S_OK, "http://www.winehq.org/"},
396  {"http://www.winehq.org/tests18/test", ".", 0, S_OK, "http://www.winehq.org/tests18/"},
397  {"http://www.winehq.org/tests19/test", "./", 0, S_OK, "http://www.winehq.org/tests19/", FALSE},
398  {"http://www.winehq.org/tests20/test", "/", 0, S_OK, "http://www.winehq.org/", FALSE},
399  {"http://www.winehq.org/tests/test", "./test21", 0, S_OK, "http://www.winehq.org/tests/test21", FALSE},
400  {"http://www.winehq.org/tests/test", "./test22/../test", 0, S_OK, "http://www.winehq.org/tests/test", FALSE},
401  {"http://www.winehq.org/tests/", "http://www.winehq.org:80/tests23", 0, S_OK, "http://www.winehq.org/tests23", TRUE},
402  {"http://www.winehq.org/tests/", "tests24/./test/../test", 0, S_OK, "http://www.winehq.org/tests/tests24/test", FALSE},
403  {"http://www.winehq.org/tests/./tests25", "./", 0, S_OK, "http://www.winehq.org/tests/", FALSE},
404  {"file:///C:\\dir\\file.txt", "test.txt", 0, S_OK, "file:///C:/dir/test.txt"},
405  {"file:///C:\\dir\\file.txt#hash\\hash", "test.txt", 0, S_OK, "file:///C:/dir/file.txt#hash/test.txt"},
406  {"file:///C:\\dir\\file.html#hash\\hash", "test.html", 0, S_OK, "file:///C:/dir/test.html"},
407  {"file:///C:\\dir\\file.htm#hash\\hash", "test.htm", 0, S_OK, "file:///C:/dir/test.htm"},
408  {"file:///C:\\dir\\file.hTmL#hash\\hash", "test.hTmL", 0, S_OK, "file:///C:/dir/test.hTmL"},
409  {"file:///C:\\dir.html\\file.txt#hash\\hash", "test.txt", 0, S_OK, "file:///C:/dir.html/file.txt#hash/test.txt"},
410  {"C:\\winehq\\winehq.txt", "C:\\Test\\test.txt", 0, S_OK, "file:///C:/Test/test.txt"},
411  {"http://www.winehq.org/test/", "test%20file.txt", 0, S_OK, "http://www.winehq.org/test/test%20file.txt"},
412  {"http://www.winehq.org/test/", "test%20file.txt", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org/test/test%20file.txt"},
413  {"http://www.winehq.org%2ftest/", "test%20file.txt", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org%2ftest/test%20file.txt"},
414  {"xxx:@MSITStore:file.chm/file.html", "dir/file", 0, S_OK, "xxx:dir/file"},
415  {"mk:@MSITStore:file.chm::/file.html", "/dir/file", 0, S_OK, "mk:@MSITStore:file.chm::/dir/file"},
416  {"mk:@MSITStore:file.chm::/file.html", "mk:@MSITStore:file.chm::/dir/file", 0, S_OK, "mk:@MSITStore:file.chm::/dir/file"},
417  {"foo:today", "foo:calendar", 0, S_OK, "foo:calendar"},
418  {"foo:today", "bar:calendar", 0, S_OK, "bar:calendar"},
419  {"foo:/today", "foo:calendar", 0, S_OK, "foo:/calendar"},
420  {"Foo:/today/", "fOo:calendar", 0, S_OK, "foo:/today/calendar"},
421  {"mk:@MSITStore:dir/test.chm::dir/index.html", "image.jpg", 0, S_OK, "mk:@MSITStore:dir/test.chm::dir/image.jpg"},
422  {"mk:@MSITStore:dir/test.chm::dir/dir2/index.html", "../image.jpg", 0, S_OK, "mk:@MSITStore:dir/test.chm::dir/image.jpg"},
423  /* UrlCombine case 2 tests. Schemes do not match */
424  {"outbind://xxxxxxxxx","http://wine1/dir",0, S_OK,"http://wine1/dir"},
425  {"xxxx://xxxxxxxxx","http://wine2/dir",0, S_OK,"http://wine2/dir"},
426  {"ftp://xxxxxxxxx/","http://wine3/dir",0, S_OK,"http://wine3/dir"},
427  {"outbind://xxxxxxxxx","http://wine4/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"http://wine4/dir"},
428  {"xxx://xxxxxxxxx","http://wine5/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"http://wine5/dir"},
429  {"ftp://xxxxxxxxx/","http://wine6/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"http://wine6/dir"},
430  {"http://xxxxxxxxx","outbind://wine7/dir",0, S_OK,"outbind://wine7/dir"},
431  {"xxx://xxxxxxxxx","ftp://wine8/dir",0, S_OK,"ftp://wine8/dir"},
432  {"ftp://xxxxxxxxx/","xxx://wine9/dir",0, S_OK,"xxx://wine9/dir"},
433  {"http://xxxxxxxxx","outbind://wine10/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"outbind://wine10/dir"},
434  {"xxx://xxxxxxxxx","ftp://wine11/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"ftp://wine11/dir"},
435  {"ftp://xxxxxxxxx/","xxx://wine12/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"xxx://wine12/dir"},
436  {"http://xxxxxxxxx","outbind:wine13/dir",0, S_OK,"outbind:wine13/dir"},
437  {"xxx://xxxxxxxxx","ftp:wine14/dir",0, S_OK,"ftp:wine14/dir"},
438  {"ftp://xxxxxxxxx/","xxx:wine15/dir",0, S_OK,"xxx:wine15/dir"},
439  {"outbind://xxxxxxxxx/","http:wine16/dir",0, S_OK,"http:wine16/dir"},
440  {"http://xxxxxxxxx","outbind:wine17/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"outbind:wine17/dir"},
441  {"xxx://xxxxxxxxx","ftp:wine18/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"ftp:wine18/dir"},
442  {"ftp://xxxxxxxxx/","xXx:wine19/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"xxx:wine19/dir"},
443  {"outbind://xxxxxxxxx/","http:wine20/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"http:wine20/dir"},
444  {"file:///c:/dir/file.txt","index.html?test=c:/abc",URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO,S_OK,"file:///c:/dir/index.html?test=c:/abc"}
445 };
446 
447 /* ################ */
448 
449 static const struct {
450  const char *path;
451  const char *url;
453 } TEST_URLFROMPATH [] = {
454  {"foo", "file:foo", S_OK},
455  {"foo\\bar", "file:foo/bar", S_OK},
456  {"\\foo\\bar", "file:///foo/bar", S_OK},
457  {"c:\\foo\\bar", "file:///c:/foo/bar", S_OK},
458  {"c:foo\\bar", "file:///c:foo/bar", S_OK},
459  {"c:\\foo/b a%r", "file:///c:/foo/b%20a%25r", S_OK},
460  {"c:\\foo\\foo bar", "file:///c:/foo/foo%20bar", S_OK},
461  {"file:///c:/foo/bar", "file:///c:/foo/bar", S_FALSE},
462 #if 0
463  /* The following test fails on native shlwapi as distributed with Win95/98.
464  * Wine matches the behaviour of later versions.
465  */
466  {"xx:c:\\foo\\bar", "xx:c:\\foo\\bar", S_FALSE}
467 #endif
468 };
469 
470 /* ################ */
471 
472 static struct {
473  char url[30];
474  const char *expect;
475 } TEST_URL_UNESCAPE[] = {
476  {"file://foo/bar", "file://foo/bar"},
477  {"file://fo%20o%5Ca/bar", "file://fo o\\a/bar"},
478  {"file://%24%25foobar", "file://$%foobar"}
479 };
480 
481 /* ################ */
482 
483 static const struct {
484  const char *path;
485  BOOL expect;
486 } TEST_PATH_IS_URL[] = {
487  {"http://foo/bar", TRUE},
488  {"c:\\foo\\bar", FALSE},
489  {"foo://foo/bar", TRUE},
490  {"foo\\bar", FALSE},
491  {"foo.bar", FALSE},
492  {"bogusscheme:", TRUE},
493  {"http:partial", TRUE}
494 };
495 
496 /* ################ */
497 
498 static const struct {
499  const char *url;
502 } TEST_URLIS_ATTRIBS[] = {
503  { "ftp:", FALSE, FALSE },
504  { "http:", FALSE, FALSE },
505  { "gopher:", FALSE, FALSE },
506  { "mailto:", TRUE, FALSE },
507  { "news:", FALSE, FALSE },
508  { "nntp:", FALSE, FALSE },
509  { "telnet:", FALSE, FALSE },
510  { "wais:", FALSE, FALSE },
511  { "file:", FALSE, TRUE },
512  { "mk:", FALSE, FALSE },
513  { "https:", FALSE, FALSE },
514  { "shell:", TRUE, FALSE },
515  { "https:", FALSE, FALSE },
516  { "snews:", FALSE, FALSE },
517  { "local:", FALSE, FALSE },
518  { "javascript:", TRUE, FALSE },
519  { "vbscript:", TRUE, FALSE },
520  { "about:", TRUE, FALSE },
521  { "res:", FALSE, FALSE },
522  { "bogusscheme:", FALSE, FALSE },
523  { "file:\\\\e:\\b\\c", FALSE, TRUE },
524  { "file://e:/b/c", FALSE, TRUE },
525  { "http:partial", FALSE, FALSE },
526  { "mailto://www.winehq.org/test.html", TRUE, FALSE },
527  { "file:partial", FALSE, TRUE },
528  { "File:partial", FALSE, TRUE },
529 };
530 
531 /* ########################### */
532 
533 static LPWSTR GetWideString(const char* szString)
534 {
535  LPWSTR wszString = HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
536 
537  MultiByteToWideChar(CP_ACP, 0, szString, -1, wszString, INTERNET_MAX_URL_LENGTH);
538 
539  return wszString;
540 }
541 
542 
543 static void FreeWideString(LPWSTR wszString)
544 {
545  HeapFree(GetProcessHeap(), 0, wszString);
546 }
547 
548 /* ########################### */
549 
550 static void test_UrlApplyScheme(void)
551 {
554  WCHAR newurlW[TEST_APPLY_MAX_LENGTH];
555  HRESULT res;
556  DWORD len;
557  DWORD i;
558 
559  if (!pUrlApplySchemeA) {
560  win_skip("UrlApplySchemeA not found\n");
561  return;
562  }
563 
564  for (i = 0; i < ARRAY_SIZE(TEST_APPLY); i++) {
567  res = pUrlApplySchemeA(TEST_APPLY[i].url, newurl, &len, TEST_APPLY[i].flags);
568  ok( res == TEST_APPLY[i].res,
569  "#%dA: got HRESULT 0x%x (expected 0x%x)\n", i, res, TEST_APPLY[i].res);
570 
571  ok( len == TEST_APPLY[i].newlen,
572  "#%dA: got len %d (expected %d)\n", i, len, TEST_APPLY[i].newlen);
573 
575  "#%dA: got '%s' (expected '%s')\n", i, newurl, TEST_APPLY[i].newurl);
576 
577  /* returned length is in character */
580  MultiByteToWideChar(CP_ACP, 0, newurl, -1, newurlW, len);
581  MultiByteToWideChar(CP_ACP, 0, TEST_APPLY[i].url, -1, urlW, len);
582 
583  res = pUrlApplySchemeW(urlW, newurlW, &len, TEST_APPLY[i].flags);
585  ok( res == TEST_APPLY[i].res,
586  "#%dW: got HRESULT 0x%x (expected 0x%x)\n", i, res, TEST_APPLY[i].res);
587 
588  ok( len == TEST_APPLY[i].newlen,
589  "#%dW: got len %d (expected %d)\n", i, len, TEST_APPLY[i].newlen);
590 
592  "#%dW: got '%s' (expected '%s')\n", i, newurl, TEST_APPLY[i].newurl);
593 
594  }
595 
596  /* buffer too small */
599  res = pUrlApplySchemeA(TEST_APPLY[0].url, newurl, &len, TEST_APPLY[0].flags);
600  ok(res == E_POINTER, "got HRESULT 0x%x (expected E_POINTER)\n", res);
601  /* The returned length include the space for the terminating 0 */
602  i = lstrlenA(TEST_APPLY[0].newurl)+1;
603  ok(len == i, "got len %d (expected %d)\n", len, i);
604  ok(!lstrcmpA(newurl, untouchedA), "got '%s' (expected '%s')\n", newurl, untouchedA);
605 
606  /* NULL as parameter. The length and the buffer are not modified */
609  res = pUrlApplySchemeA(NULL, newurl, &len, TEST_APPLY[0].flags);
610  ok(res == E_INVALIDARG, "got HRESULT 0x%x (expected E_INVALIDARG)\n", res);
611  ok(len == TEST_APPLY_MAX_LENGTH, "got len %d\n", len);
612  ok(!lstrcmpA(newurl, untouchedA), "got '%s' (expected '%s')\n", newurl, untouchedA);
613 
615  res = pUrlApplySchemeA(TEST_APPLY[0].url, NULL, &len, TEST_APPLY[0].flags);
616  ok(res == E_INVALIDARG, "got HRESULT 0x%x (expected E_INVALIDARG)\n", res);
617  ok(len == TEST_APPLY_MAX_LENGTH, "got len %d\n", len);
618 
620  res = pUrlApplySchemeA(TEST_APPLY[0].url, newurl, NULL, TEST_APPLY[0].flags);
621  ok(res == E_INVALIDARG, "got HRESULT 0x%x (expected E_INVALIDARG)\n", res);
622  ok(!lstrcmpA(newurl, untouchedA), "got '%s' (expected '%s')\n", newurl, untouchedA);
623 
624 }
625 
626 /* ########################### */
627 
628 static void hash_url(const char* szUrl)
629 {
630  LPCSTR szTestUrl = szUrl;
631  LPWSTR wszTestUrl = GetWideString(szTestUrl);
632  HRESULT res;
633 
634  DWORD cbSize = sizeof(DWORD);
635  DWORD dwHash1, dwHash2;
636  res = pUrlHashA(szTestUrl, (LPBYTE)&dwHash1, cbSize);
637  ok(res == S_OK, "UrlHashA returned 0x%x (expected S_OK) for %s\n", res, szUrl);
638  if (pUrlHashW) {
639  res = pUrlHashW(wszTestUrl, (LPBYTE)&dwHash2, cbSize);
640  ok(res == S_OK, "UrlHashW returned 0x%x (expected S_OK) for %s\n", res, szUrl);
641  ok(dwHash1 == dwHash2,
642  "Hashes didn't match (A: 0x%x, W: 0x%x) for %s\n", dwHash1, dwHash2, szUrl);
643  }
644  FreeWideString(wszTestUrl);
645 
646 }
647 
648 static void test_UrlHash(void)
649 {
650  if (!pUrlHashA) {
651  win_skip("UrlHashA not found\n");
652  return;
653  }
654 
658 }
659 
660 /* ########################### */
661 
662 static void test_url_part(const char* szUrl, DWORD dwPart, DWORD dwFlags, const char* szExpected)
663 {
666  LPWSTR wszUrl = GetWideString(szUrl);
667  LPWSTR wszConvertedPart;
668  HRESULT res;
669  DWORD dwSize;
670 
671  dwSize = 1;
672  res = pUrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags);
673  ok(res == E_POINTER, "UrlGetPart for \"%s\" gave: 0x%08x\n", szUrl, res);
674  ok(dwSize == strlen(szExpected)+1 ||
675  (*szExpected == '?' && dwSize == strlen(szExpected)),
676  "UrlGetPart for \"%s\" gave size: %u\n", szUrl, dwSize);
677 
679  res = pUrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags);
680  ok(res == S_OK,
681  "UrlGetPartA for \"%s\" part 0x%08x returned 0x%x and \"%s\"\n",
682  szUrl, dwPart, res, szPart);
683  if (pUrlGetPartW) {
685  res = pUrlGetPartW(wszUrl, wszPart, &dwSize, dwPart, dwFlags);
686  ok(res == S_OK,
687  "UrlGetPartW for \"%s\" part 0x%08x returned 0x%x\n",
688  szUrl, dwPart, res);
689 
690  wszConvertedPart = GetWideString(szPart);
691 
692  ok(lstrcmpW(wszPart,wszConvertedPart)==0,
693  "Strings didn't match between ascii and unicode UrlGetPart!\n");
694 
695  FreeWideString(wszConvertedPart);
696  }
697  FreeWideString(wszUrl);
698 
699  /* Note that v6.0 and later don't return '?' with the query */
700  ok(strcmp(szPart,szExpected)==0 ||
701  (*szExpected=='?' && !strcmp(szPart,szExpected+1)),
702  "Expected %s, but got %s\n", szExpected, szPart);
703 }
704 
705 /* ########################### */
706 
707 static void test_UrlGetPart(void)
708 {
709  const char* file_url = "file://h o s t/c:/windows/file";
710  const char* http_url = "http://user:pass 123@www.wine hq.org";
711  const char* res_url = "res://some.dll/find.dlg";
712  const char* about_url = "about:blank";
713  const char* excid_url = "x-excid://36C00000/guid:{048B4E89-2E92-496F-A837-33BA02FF6D32}/Message.htm";
714  const char* foo_url = "foo://bar-url/test";
715  const char* short_url = "ascheme:";
716 
718  DWORD dwSize;
719  HRESULT res;
720 
721  if (!pUrlGetPartA) {
722  win_skip("UrlGetPartA not found\n");
723  return;
724  }
725 
726  res = pUrlGetPartA(NULL, NULL, NULL, URL_PART_SCHEME, 0);
727  ok(res == E_INVALIDARG, "null params gave: 0x%08x\n", res);
728 
729  res = pUrlGetPartA(NULL, szPart, &dwSize, URL_PART_SCHEME, 0);
730  ok(res == E_INVALIDARG, "null URL gave: 0x%08x\n", res);
731 
732  res = pUrlGetPartA(res_url, NULL, &dwSize, URL_PART_SCHEME, 0);
733  ok(res == E_INVALIDARG, "null szPart gave: 0x%08x\n", res);
734 
735  res = pUrlGetPartA(res_url, szPart, NULL, URL_PART_SCHEME, 0);
736  ok(res == E_INVALIDARG, "null URL gave: 0x%08x\n", res);
737 
738  dwSize = 0;
739  szPart[0]='x'; szPart[1]=0;
740  res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_SCHEME, 0);
741  ok(res == E_INVALIDARG, "UrlGetPartA(*pcchOut = 0) returned %08X\n", res);
742  ok(szPart[0] == 'x' && szPart[1] == 0, "UrlGetPartA(*pcchOut = 0) modified szPart: \"%s\"\n", szPart);
743  ok(dwSize == 0, "dwSize = %d\n", dwSize);
744 
745  dwSize = sizeof szPart;
746  szPart[0]='x'; szPart[1]=0;
747  res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_SCHEME, 0);
748  ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res);
749  ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart);
750  ok(dwSize == 0, "dwSize = %d\n", dwSize);
751 
752  if(pUrlGetPartW)
753  {
754  const WCHAR hiW[] = {'h','i',0};
755  WCHAR bufW[5];
756 
757  /* UrlGetPartW returns S_OK instead of S_FALSE */
758  dwSize = sizeof szPart;
759  bufW[0]='x'; bufW[1]=0;
760  res = pUrlGetPartW(hiW, bufW, &dwSize, URL_PART_SCHEME, 0);
761  todo_wine ok(res==S_OK, "UrlGetPartW(\"hi\") returned %08X\n", res);
762  ok(bufW[0] == 0, "UrlGetPartW(\"hi\") return \"%c\"\n", bufW[0]);
763  ok(dwSize == 0, "dwSize = %d\n", dwSize);
764  }
765 
766  dwSize = sizeof szPart;
767  szPart[0]='x'; szPart[1]=0;
768  res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_QUERY, 0);
769  ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res);
770  ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart);
771  ok(dwSize == 0, "dwSize = %d\n", dwSize);
772 
773  test_url_part(TEST_URL_3, URL_PART_HOSTNAME, 0, "localhost");
778  test_url_part(TEST_URL_3, URL_PART_QUERY, 0, "?query=x&return=y");
779 
780  test_url_part(TEST_URL_4, URL_PART_HOSTNAME, 0, "google.*.com");
781 
782  test_url_part(file_url, URL_PART_HOSTNAME, 0, "h o s t");
783 
784  test_url_part(http_url, URL_PART_HOSTNAME, 0, "www.wine hq.org");
785  test_url_part(http_url, URL_PART_PASSWORD, 0, "pass 123");
786 
787  test_url_part(about_url, URL_PART_SCHEME, 0, "about");
788 
789  test_url_part(excid_url, URL_PART_SCHEME, 0, "x-excid");
790  test_url_part(foo_url, URL_PART_SCHEME, 0, "foo");
791  test_url_part(short_url, URL_PART_SCHEME, 0, "ascheme");
792 
793  dwSize = sizeof(szPart);
794  res = pUrlGetPartA(about_url, szPart, &dwSize, URL_PART_HOSTNAME, 0);
795  ok(res==E_FAIL, "returned %08x\n", res);
796 
797  test_url_part(res_url, URL_PART_SCHEME, 0, "res");
798  test_url_part("http://www.winehq.org", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, "http:www.winehq.org");
799 
800  dwSize = sizeof szPart;
801  szPart[0]='x'; szPart[1]=0;
802  res = pUrlGetPartA(res_url, szPart, &dwSize, URL_PART_QUERY, 0);
803  ok(res==S_FALSE, "UrlGetPartA returned %08X\n", res);
804  ok(szPart[0]==0, "UrlGetPartA gave \"%s\" instead of \"\"\n", szPart);
805  ok(dwSize == 0, "dwSize = %d\n", dwSize);
806 
807  dwSize = sizeof(szPart);
808  res = pUrlGetPartA("file://c:\\index.htm", szPart, &dwSize, URL_PART_HOSTNAME, 0);
809  ok(res==S_FALSE, "returned %08x\n", res);
810  ok(dwSize == 0, "dwSize = %d\n", dwSize);
811 
812  dwSize = sizeof(szPart);
813  szPart[0] = 'x'; szPart[1] = '\0';
814  res = pUrlGetPartA("file:some text", szPart, &dwSize, URL_PART_HOSTNAME, 0);
815  ok(res==S_FALSE, "returned %08x\n", res);
816  ok(szPart[0] == '\0', "szPart[0] = %c\n", szPart[0]);
817  ok(dwSize == 0, "dwSize = %d\n", dwSize);
818 
819  dwSize = sizeof(szPart);
820  szPart[0] = 'x'; szPart[1] = '\0';
821  res = pUrlGetPartA("index.htm", szPart, &dwSize, URL_PART_HOSTNAME, 0);
822  ok(res==E_FAIL, "returned %08x\n", res);
823 
824  dwSize = sizeof(szPart);
825  szPart[0] = 'x'; szPart[1] = '\0';
826  res = pUrlGetPartA(excid_url, szPart, &dwSize, URL_PART_HOSTNAME, 0);
827  ok(res==E_FAIL, "returned %08x\n", res);
828  ok(szPart[0] == 'x', "szPart[0] = %c\n", szPart[0]);
829  ok(dwSize == sizeof(szPart), "dwSize = %d\n", dwSize);
830 
831  dwSize = sizeof(szPart);
832  szPart[0] = 'x'; szPart[1] = '\0';
833  res = pUrlGetPartA(excid_url, szPart, &dwSize, URL_PART_QUERY, 0);
834  ok(res==S_FALSE, "returned %08x\n", res);
835  ok(szPart[0] == 0, "szPart[0] = %c\n", szPart[0]);
836  ok(dwSize == 0, "dwSize = %d\n", dwSize);
837 
838  dwSize = sizeof(szPart);
839  szPart[0] = 'x'; szPart[1] = '\0';
840  res = pUrlGetPartA(foo_url, szPart, &dwSize, URL_PART_HOSTNAME, 0);
841  ok(res==E_FAIL, "returned %08x\n", res);
842  ok(szPart[0] == 'x', "szPart[0] = %c\n", szPart[0]);
843  ok(dwSize == sizeof(szPart), "dwSize = %d\n", dwSize);
844 
845  dwSize = sizeof(szPart);
846  szPart[0] = 'x'; szPart[1] = '\0';
847  res = pUrlGetPartA(foo_url, szPart, &dwSize, URL_PART_QUERY, 0);
848  ok(res==S_FALSE, "returned %08x\n", res);
849  ok(szPart[0] == 0, "szPart[0] = %c\n", szPart[0]);
850  ok(dwSize == 0, "dwSize = %d\n", dwSize);
851 }
852 
853 /* ########################### */
854 static void test_url_canonicalize(int index, const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, HRESULT dwExpectReturnAlt, const char *szExpectUrl, BOOL todo)
855 {
856  CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
857  WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
858  LPWSTR wszUrl = GetWideString(szUrl);
859  LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
860  LPWSTR wszConvertedUrl;
861  HRESULT ret;
862 
863  DWORD dwSize;
864 
866  ret = pUrlCanonicalizeA(szUrl, NULL, &dwSize, dwFlags);
867  ok(ret != dwExpectReturn, "got 0s%x: Unexpected return for NULL buffer, index %d\n", ret, index);
868  ret = pUrlCanonicalizeA(szUrl, szReturnUrl, &dwSize, dwFlags);
869  ok(ret == dwExpectReturn || ret == dwExpectReturnAlt,
870  "UrlCanonicalizeA failed: expected=0x%08x or 0x%08x, got=0x%08x, index %d\n",
871  dwExpectReturn, dwExpectReturnAlt, ret, index);
873  ok(strcmp(szReturnUrl,szExpectUrl)==0, "UrlCanonicalizeA dwFlags 0x%08x url '%s' Expected \"%s\", but got \"%s\", index %d\n", dwFlags, szUrl, szExpectUrl, szReturnUrl, index);
874 
875  if (pUrlCanonicalizeW) {
877  ret = pUrlCanonicalizeW(wszUrl, NULL, &dwSize, dwFlags);
878  ok(ret != dwExpectReturn, "got 0x%x: Unexpected return for NULL buffer, index %d\n", ret, index);
879  ret = pUrlCanonicalizeW(wszUrl, wszReturnUrl, &dwSize, dwFlags);
880  ok(ret == dwExpectReturn, "UrlCanonicalizeW failed: expected 0x%08x, got 0x%x, index %d\n",
881  dwExpectReturn, ret, index);
882 
883  wszConvertedUrl = GetWideString(szReturnUrl);
884  ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0,
885  "Strings didn't match between ascii and unicode UrlCanonicalize, index %d!\n", index);
886  FreeWideString(wszConvertedUrl);
887  }
888 
889  FreeWideString(wszUrl);
890  FreeWideString(wszExpectUrl);
891 }
892 
893 
894 static void test_UrlEscapeA(void)
895 {
896  DWORD size = 0;
897  HRESULT ret;
898  unsigned int i;
899  char empty_string[] = "";
900 
901  if (!pUrlEscapeA) {
902  win_skip("UrlEscapeA not found\n");
903  return;
904  }
905 
906  ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", NULL, &size, URL_ESCAPE_SPACES_ONLY);
907  ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG);
908  ok(size == 0, "got %d, expected %d\n", size, 0);
909 
910  size = 0;
911  ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, &size, URL_ESCAPE_SPACES_ONLY);
912  ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG);
913  ok(size == 0, "got %d, expected %d\n", size, 0);
914 
915  size = 1;
916  ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", NULL, &size, URL_ESCAPE_SPACES_ONLY);
917  ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG);
918  ok(size == 1, "got %d, expected %d\n", size, 1);
919 
920  size = 1;
921  ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, NULL, URL_ESCAPE_SPACES_ONLY);
922  ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG);
923  ok(size == 1, "got %d, expected %d\n", size, 1);
924 
925  size = 1;
926  empty_string[0] = 127;
927  ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, &size, URL_ESCAPE_SPACES_ONLY);
928  ok(ret == E_POINTER, "got %x, expected %x\n", ret, E_POINTER);
929  ok(size == 34, "got %d, expected %d\n", size, 34);
930  ok(empty_string[0] == 127, "String has changed, empty_string[0] = %d\n", empty_string[0]);
931 
932  size = 1;
933  empty_string[0] = 127;
934  ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, &size, URL_ESCAPE_AS_UTF8);
935  ok(ret == E_NOTIMPL || broken(ret == E_POINTER), /* < Win7/Win2k8 */
936  "got %x, expected %x\n", ret, E_NOTIMPL);
937  ok(size == 1 || broken(size == 34), /* < Win7/Win2k8 */
938  "got %d, expected %d\n", size, 1);
939  ok(empty_string[0] == 127, "String has changed, empty_string[0] = %d\n", empty_string[0]);
940 
941  for (i = 0; i < ARRAY_SIZE(TEST_ESCAPE); i++) {
942  CHAR ret_url[INTERNET_MAX_URL_LENGTH];
943 
945  ret = pUrlEscapeA(TEST_ESCAPE[i].url, ret_url, &size, TEST_ESCAPE[i].flags);
946  ok(ret == TEST_ESCAPE[i].expectret, "UrlEscapeA returned 0x%08x instead of 0x%08x for \"%s\"\n",
947  ret, TEST_ESCAPE[i].expectret, TEST_ESCAPE[i].url);
948  ok(!strcmp(ret_url, TEST_ESCAPE[i].expecturl), "Expected \"%s\", but got \"%s\" for \"%s\"\n",
949  TEST_ESCAPE[i].expecturl, ret_url, TEST_ESCAPE[i].url);
950  }
951 }
952 
953 static void test_UrlEscapeW(void)
954 {
955  static const WCHAR path_test[] = {'/','t','e','s','t',0};
956  static const WCHAR naW[] = {'f','t','p',31,255,250,0x2122,'e','n','d','/',0};
957  static const WCHAR naescapedW[] = {'f','t','p','%','1','F','%','F','F','%','F','A',0x2122,'e','n','d','/',0};
958  static const WCHAR out[] = {'f','o','o','%','2','0','b','a','r',0};
959  WCHAR overwrite[] = {'f','o','o',' ','b','a','r',0,0,0};
960  WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
961  WCHAR empty_string[] = {0};
962  DWORD size;
963  HRESULT ret;
964  WCHAR wc;
965  int i;
966 
967  if (!pUrlEscapeW) {
968  win_skip("UrlEscapeW not found\n");
969  return;
970  }
971 
972  /* Check error paths */
973 
975  ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG);
976 
977  size = 0;
978  ret = UrlEscapeW(path_test, NULL, &size, URL_ESCAPE_SPACES_ONLY);
979  ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG);
980  ok(size == 0, "got %d, expected %d\n", size, 0);
981 
982  ret = UrlEscapeW(path_test, empty_string, NULL, URL_ESCAPE_SPACES_ONLY);
983  ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG);
984 
985  size = 0;
986  ret = UrlEscapeW(path_test, empty_string, &size, URL_ESCAPE_SPACES_ONLY);
987  ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG);
988  ok(size == 0, "got %d, expected %d\n", size, 0);
989 
991  ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG);
992 
993  size = 1;
994  ret = UrlEscapeW(path_test, NULL, &size, URL_ESCAPE_SPACES_ONLY);
995  ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG);
996  ok(size == 1, "got %d, expected %d\n", size, 1);
997 
998  ret = UrlEscapeW(path_test, empty_string, NULL, URL_ESCAPE_SPACES_ONLY);
999  ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG);
1000 
1001  size = 1;
1002  ret = UrlEscapeW(path_test, empty_string, &size, URL_ESCAPE_SPACES_ONLY);
1003  ok(ret == E_POINTER, "got %x, expected %x\n", ret, E_POINTER);
1004  ok(size == 6, "got %d, expected %d\n", size, 6);
1005 
1006  /* Check actual escaping */
1007 
1008  size = ARRAY_SIZE(overwrite);
1009  ret = pUrlEscapeW(overwrite, overwrite, &size, URL_ESCAPE_SPACES_ONLY);
1010  ok(ret == S_OK, "got %x, expected S_OK\n", ret);
1011  ok(size == 9, "got %d, expected 9\n", size);
1012  ok(!lstrcmpW(overwrite, out), "got %s, expected %s\n", wine_dbgstr_w(overwrite), wine_dbgstr_w(out));
1013 
1014  size = 1;
1015  wc = 127;
1016  ret = pUrlEscapeW(overwrite, &wc, &size, URL_ESCAPE_SPACES_ONLY);
1017  ok(ret == E_POINTER, "got %x, expected %x\n", ret, E_POINTER);
1018  ok(size == 10, "got %d, expected 10\n", size);
1019  ok(wc == 127, "String has changed, wc = %d\n", wc);
1020 
1021  /* non-ASCII range */
1022  size = ARRAY_SIZE(ret_urlW);
1023  ret = pUrlEscapeW(naW, ret_urlW, &size, 0);
1024  ok(ret == S_OK, "got %x, expected S_OK\n", ret);
1025  ok(!lstrcmpW(naescapedW, ret_urlW), "got %s, expected %s\n", wine_dbgstr_w(ret_urlW), wine_dbgstr_w(naescapedW));
1026 
1027  for (i = 0; i < ARRAY_SIZE(TEST_ESCAPE); i++) {
1028 
1029  WCHAR *urlW, *expected_urlW;
1030 
1032  urlW = GetWideString(TEST_ESCAPE[i].url);
1033  expected_urlW = GetWideString(TEST_ESCAPE[i].expecturl);
1034  ret = pUrlEscapeW(urlW, ret_urlW, &size, TEST_ESCAPE[i].flags);
1035  ok(ret == TEST_ESCAPE[i].expectret, "UrlEscapeW returned 0x%08x instead of 0x%08x for %s\n",
1036  ret, TEST_ESCAPE[i].expectret, wine_dbgstr_w(urlW));
1037  ok(!lstrcmpW(ret_urlW, expected_urlW), "Expected %s, but got %s for %s flags %08x\n",
1038  wine_dbgstr_w(expected_urlW), wine_dbgstr_w(ret_urlW), wine_dbgstr_w(urlW), TEST_ESCAPE[i].flags);
1039  FreeWideString(urlW);
1040  FreeWideString(expected_urlW);
1041  }
1042 
1043  for (i = 0; i < ARRAY_SIZE(TEST_ESCAPEW); i++) {
1044  WCHAR ret_url[INTERNET_MAX_URL_LENGTH];
1045 
1047  ret = pUrlEscapeW(TEST_ESCAPEW[i].url, ret_url, &size, TEST_ESCAPEW[i].flags);
1048  ok(ret == TEST_ESCAPEW[i].expectret, "UrlEscapeW returned 0x%08x instead of 0x%08x for \"%s\"\n",
1049  ret, TEST_ESCAPEW[i].expectret, wine_dbgstr_w(TEST_ESCAPEW[i].url));
1050  ok(!lstrcmpW(ret_url, TEST_ESCAPEW[i].expecturl) ||
1051  broken(!lstrcmpW(ret_url, TEST_ESCAPEW[i].vistaurl)) ||
1052  broken(!lstrcmpW(ret_url, TEST_ESCAPEW[i].win7url)),
1053  "Expected \"%s\" or \"%s\" or \"%s\", but got \"%s\" for \"%s\"\n",
1054  wine_dbgstr_w(TEST_ESCAPEW[i].expecturl), wine_dbgstr_w(TEST_ESCAPEW[i].vistaurl),
1056  }
1057 }
1058 
1059 /* ########################### */
1060 
1061 static void test_UrlCanonicalizeA(void)
1062 {
1063  unsigned int i;
1064  CHAR szReturnUrl[4*INTERNET_MAX_URL_LENGTH];
1065  CHAR longurl[4*INTERNET_MAX_URL_LENGTH];
1066  DWORD dwSize;
1067  DWORD urllen;
1068  HRESULT hr;
1069 
1070  if (!pUrlCanonicalizeA) {
1071  win_skip("UrlCanonicalizeA not found\n");
1072  return;
1073  }
1074 
1075  urllen = lstrlenA(winehqA);
1076 
1077  /* buffer has no space for the result */
1078  dwSize=urllen-1;
1079  memset(szReturnUrl, '#', urllen+4);
1080  szReturnUrl[urllen+4] = '\0';
1081  SetLastError(0xdeadbeef);
1082  hr = pUrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE);
1083  ok( (hr == E_POINTER) && (dwSize == (urllen + 1)),
1084  "got 0x%x with %u and size %u for '%s' and %u (expected 'E_POINTER' and size %u)\n",
1085  hr, GetLastError(), dwSize, szReturnUrl, lstrlenA(szReturnUrl), urllen+1);
1086 
1087  /* buffer has no space for the terminating '\0' */
1088  dwSize=urllen;
1089  memset(szReturnUrl, '#', urllen+4);
1090  szReturnUrl[urllen+4] = '\0';
1091  SetLastError(0xdeadbeef);
1092  hr = pUrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE);
1093  ok( (hr == E_POINTER) && (dwSize == (urllen + 1)),
1094  "got 0x%x with %u and size %u for '%s' and %u (expected 'E_POINTER' and size %u)\n",
1095  hr, GetLastError(), dwSize, szReturnUrl, lstrlenA(szReturnUrl), urllen+1);
1096 
1097  /* buffer has the required size */
1098  dwSize=urllen+1;
1099  memset(szReturnUrl, '#', urllen+4);
1100  szReturnUrl[urllen+4] = '\0';
1101  SetLastError(0xdeadbeef);
1102  hr = pUrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE);
1103  ok( (hr == S_OK) && (dwSize == urllen),
1104  "got 0x%x with %u and size %u for '%s' and %u (expected 'S_OK' and size %u)\n",
1105  hr, GetLastError(), dwSize, szReturnUrl, lstrlenA(szReturnUrl), urllen);
1106 
1107  /* buffer is larger as the required size */
1108  dwSize=urllen+2;
1109  memset(szReturnUrl, '#', urllen+4);
1110  szReturnUrl[urllen+4] = '\0';
1111  SetLastError(0xdeadbeef);
1112  hr = pUrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE);
1113  ok( (hr == S_OK) && (dwSize == urllen),
1114  "got 0x%x with %u and size %u for '%s' and %u (expected 'S_OK' and size %u)\n",
1115  hr, GetLastError(), dwSize, szReturnUrl, lstrlenA(szReturnUrl), urllen);
1116 
1117  /* length is set to 0 */
1118  dwSize=0;
1119  memset(szReturnUrl, '#', urllen+4);
1120  szReturnUrl[urllen+4] = '\0';
1121  SetLastError(0xdeadbeef);
1122  hr = pUrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE);
1123  ok( (hr == E_INVALIDARG) && (dwSize == 0),
1124  "got 0x%x with %u and size %u for '%s' and %u (expected 'E_INVALIDARG' and size %u)\n",
1125  hr, GetLastError(), dwSize, szReturnUrl, lstrlenA(szReturnUrl), 0);
1126 
1127  /* url length > INTERNET_MAX_URL_SIZE */
1128  dwSize=sizeof(szReturnUrl);
1129  memset(longurl, 'a', sizeof(longurl));
1130  memcpy(longurl, winehqA, sizeof(winehqA)-1);
1131  longurl[sizeof(longurl)-1] = '\0';
1132  hr = pUrlCanonicalizeA(longurl, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE);
1133  ok(hr == S_OK, "hr = %x\n", hr);
1134 
1135  test_url_canonicalize(-1, "", 0, S_OK, S_FALSE /* Vista/win2k8 */, "", FALSE);
1136 
1137  /* test url-modification */
1138  for (i = 0; i < ARRAY_SIZE(TEST_CANONICALIZE); i++) {
1140  TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expecturl,
1142  }
1143 }
1144 
1145 /* ########################### */
1146 
1147 static void test_UrlCanonicalizeW(void)
1148 {
1149  WCHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
1150  DWORD dwSize;
1151  DWORD urllen;
1152  HRESULT hr;
1153  int i;
1154 
1155 
1156  if (!pUrlCanonicalizeW) {
1157  win_skip("UrlCanonicalizeW not found\n");
1158  return;
1159  }
1160  urllen = lstrlenW(winehqW);
1161 
1162  /* buffer has no space for the result */
1163  dwSize = (urllen-1);
1164  memset(szReturnUrl, '#', (urllen+4) * sizeof(WCHAR));
1165  szReturnUrl[urllen+4] = '\0';
1166  SetLastError(0xdeadbeef);
1167  hr = pUrlCanonicalizeW(winehqW, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE);
1168  ok( (hr == E_POINTER) && (dwSize == (urllen + 1)),
1169  "got 0x%x with %u and size %u for %u (expected 'E_POINTER' and size %u)\n",
1170  hr, GetLastError(), dwSize, lstrlenW(szReturnUrl), urllen+1);
1171 
1172 
1173  /* buffer has no space for the terminating '\0' */
1174  dwSize = urllen;
1175  memset(szReturnUrl, '#', (urllen+4) * sizeof(WCHAR));
1176  szReturnUrl[urllen+4] = '\0';
1177  SetLastError(0xdeadbeef);
1178  hr = pUrlCanonicalizeW(winehqW, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE);
1179  ok( (hr == E_POINTER) && (dwSize == (urllen + 1)),
1180  "got 0x%x with %u and size %u for %u (expected 'E_POINTER' and size %u)\n",
1181  hr, GetLastError(), dwSize, lstrlenW(szReturnUrl), urllen+1);
1182 
1183  /* buffer has the required size */
1184  dwSize = urllen +1;
1185  memset(szReturnUrl, '#', (urllen+4) * sizeof(WCHAR));
1186  szReturnUrl[urllen+4] = '\0';
1187  SetLastError(0xdeadbeef);
1188  hr = pUrlCanonicalizeW(winehqW, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE);
1189  ok( (hr == S_OK) && (dwSize == urllen),
1190  "got 0x%x with %u and size %u for %u (expected 'S_OK' and size %u)\n",
1191  hr, GetLastError(), dwSize, lstrlenW(szReturnUrl), urllen);
1192 
1193  /* buffer is larger as the required size */
1194  dwSize = (urllen+2);
1195  memset(szReturnUrl, '#', (urllen+4) * sizeof(WCHAR));
1196  szReturnUrl[urllen+4] = '\0';
1197  SetLastError(0xdeadbeef);
1198  hr = pUrlCanonicalizeW(winehqW, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE);
1199  ok( (hr == S_OK) && (dwSize == urllen),
1200  "got 0x%x with %u and size %u for %u (expected 'S_OK' and size %u)\n",
1201  hr, GetLastError(), dwSize, lstrlenW(szReturnUrl), urllen);
1202 
1203  /* check that the characters 1..32 are chopped from the end of the string */
1204  for (i = 1; i < 65536; i++)
1205  {
1206  WCHAR szUrl[128];
1207  BOOL choped;
1208  int pos;
1209 
1210  MultiByteToWideChar(CP_ACP, 0, "http://www.winehq.org/X", -1, szUrl, ARRAY_SIZE(szUrl));
1211  pos = lstrlenW(szUrl) - 1;
1212  szUrl[pos] = i;
1213  urllen = INTERNET_MAX_URL_LENGTH;
1214  pUrlCanonicalizeW(szUrl, szReturnUrl, &urllen, 0);
1215  choped = lstrlenW(szReturnUrl) < lstrlenW(szUrl);
1216  ok(choped == (i <= 32), "Incorrect char chopping for char %d\n", i);
1217  }
1218 }
1219 
1220 /* ########################### */
1221 
1222 static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl, BOOL todo)
1223 {
1224  HRESULT hr;
1225  CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
1226  WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
1227  LPWSTR wszUrl1, wszUrl2, wszExpectUrl, wszConvertedUrl;
1228 
1229  DWORD dwSize;
1230  DWORD dwExpectLen = lstrlenA(szExpectUrl);
1231 
1232  if (!pUrlCombineA) {
1233  win_skip("UrlCombineA not found\n");
1234  return;
1235  }
1236 
1237  wszUrl1 = GetWideString(szUrl1);
1238  wszUrl2 = GetWideString(szUrl2);
1239  wszExpectUrl = GetWideString(szExpectUrl);
1240 
1241  hr = pUrlCombineA(szUrl1, szUrl2, NULL, NULL, dwFlags);
1242  ok(hr == E_INVALIDARG, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_INVALIDARG);
1243 
1244  dwSize = 0;
1245  hr = pUrlCombineA(szUrl1, szUrl2, NULL, &dwSize, dwFlags);
1246  ok(hr == E_POINTER, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr, E_POINTER);
1247  ok(todo || dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
1248 
1249  dwSize--;
1250  hr = pUrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
1251  ok(hr == E_POINTER, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_POINTER);
1252  ok(todo || dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
1253 
1254  hr = pUrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
1255  ok(hr == dwExpectReturn, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, dwExpectReturn);
1256 
1257  if (todo)
1258  {
1259  todo_wine ok(dwSize == dwExpectLen && (FAILED(hr) || strcmp(szReturnUrl, szExpectUrl)==0),
1260  "Expected %s (len=%d), but got %s (len=%d)\n", szExpectUrl, dwExpectLen, SUCCEEDED(hr) ? szReturnUrl : "(null)", dwSize);
1261  }
1262  else
1263  {
1264  ok(dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen);
1265  if (SUCCEEDED(hr))
1266  ok(strcmp(szReturnUrl, szExpectUrl)==0, "Expected %s, but got %s\n", szExpectUrl, szReturnUrl);
1267  }
1268 
1269  if (pUrlCombineW) {
1270  dwSize = 0;
1271  hr = pUrlCombineW(wszUrl1, wszUrl2, NULL, &dwSize, dwFlags);
1272  ok(hr == E_POINTER, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr, E_POINTER);
1273  ok(todo || dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
1274 
1275  dwSize--;
1276  hr = pUrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
1277  ok(hr == E_POINTER, "UrlCombineW returned 0x%08x, expected 0x%08x\n", hr, E_POINTER);
1278  ok(todo || dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
1279 
1280  hr = pUrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
1281  ok(hr == dwExpectReturn, "UrlCombineW returned 0x%08x, expected 0x%08x\n", hr, dwExpectReturn);
1282  ok(todo || dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen);
1283  if(SUCCEEDED(hr)) {
1284  wszConvertedUrl = GetWideString(szReturnUrl);
1285  ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCombine!\n");
1286  FreeWideString(wszConvertedUrl);
1287  }
1288  }
1289 
1290  FreeWideString(wszUrl1);
1291  FreeWideString(wszUrl2);
1292  FreeWideString(wszExpectUrl);
1293 }
1294 
1295 /* ########################### */
1296 
1297 static void test_UrlCombine(void)
1298 {
1299  unsigned int i;
1300  for (i = 0; i < ARRAY_SIZE(TEST_COMBINE); i++) {
1302  TEST_COMBINE[i].expectret, TEST_COMBINE[i].expecturl, TEST_COMBINE[i].todo);
1303  }
1304 }
1305 
1306 /* ########################### */
1307 
1308 static void test_UrlCreateFromPath(void)
1309 {
1310  size_t i;
1311  char ret_url[INTERNET_MAX_URL_LENGTH];
1312  DWORD len, ret;
1313  WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
1314  WCHAR *pathW, *urlW;
1315 
1316  if (!pUrlCreateFromPathA) {
1317  win_skip("UrlCreateFromPathA not found\n");
1318  return;
1319  }
1320 
1321  for (i = 0; i < ARRAY_SIZE(TEST_URLFROMPATH); i++) {
1323  ret = pUrlCreateFromPathA(TEST_URLFROMPATH[i].path, ret_url, &len, 0);
1324  ok(ret == TEST_URLFROMPATH[i].ret, "ret %08x from path %s\n", ret, TEST_URLFROMPATH[i].path);
1325  ok(!lstrcmpiA(ret_url, TEST_URLFROMPATH[i].url), "url %s from path %s\n", ret_url, TEST_URLFROMPATH[i].path);
1326  ok(len == strlen(ret_url), "ret len %d from path %s\n", len, TEST_URLFROMPATH[i].path);
1327 
1328  if (pUrlCreateFromPathW) {
1332  ret = pUrlCreateFromPathW(pathW, ret_urlW, &len, 0);
1333  WideCharToMultiByte(CP_ACP, 0, ret_urlW, -1, ret_url, sizeof(ret_url),0,0);
1334  ok(ret == TEST_URLFROMPATH[i].ret, "ret %08x from path L\"%s\", expected %08x\n",
1336  ok(!lstrcmpiW(ret_urlW, urlW), "got %s expected %s from path L\"%s\"\n",
1338  ok(len == lstrlenW(ret_urlW), "ret len %d from path L\"%s\"\n", len, TEST_URLFROMPATH[i].path);
1339  FreeWideString(urlW);
1340  FreeWideString(pathW);
1341  }
1342  }
1343 }
1344 
1345 /* ########################### */
1346 
1348 {
1349  BOOL ret;
1350  ret = pUrlIsA(NULL, flag);
1351  ok(ret == FALSE, "pUrlIsA(NULL, %d) failed\n", flag);
1352  ret = pUrlIsW(NULL, flag);
1353  ok(ret == FALSE, "pUrlIsW(NULL, %d) failed\n", flag);
1354 }
1355 
1356 static void test_UrlIs(void)
1357 {
1358  BOOL ret;
1359  size_t i;
1360  WCHAR wurl[80];
1361 
1362  if (!pUrlIsA) {
1363  win_skip("UrlIsA not found\n");
1364  return;
1365  }
1366 
1374 
1375  for (i = 0; i < ARRAY_SIZE(TEST_PATH_IS_URL); i++) {
1377 
1378  ret = pUrlIsA( TEST_PATH_IS_URL[i].path, URLIS_URL );
1380  "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
1382 
1383  if (pUrlIsW) {
1384  ret = pUrlIsW( wurl, URLIS_URL );
1386  "returned %d from path (UrlIsW) %s, expected %d\n", ret,
1388  }
1389  }
1390  for (i = 0; i < ARRAY_SIZE(TEST_URLIS_ATTRIBS); i++) {
1392 
1393  ret = pUrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_OPAQUE);
1395  "returned %d for URLIS_OPAQUE, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
1397  ret = pUrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_FILEURL);
1399  "returned %d for URLIS_FILEURL, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
1401 
1402  if (pUrlIsW) {
1403  ret = pUrlIsW( wurl, URLIS_OPAQUE);
1405  "returned %d for URLIS_OPAQUE (UrlIsW), url \"%s\", expected %d\n",
1407  ret = pUrlIsW( wurl, URLIS_FILEURL);
1409  "returned %d for URLIS_FILEURL (UrlIsW), url \"%s\", expected %d\n",
1411  }
1412  }
1413 }
1414 
1415 /* ########################### */
1416 
1417 static void test_UrlUnescape(void)
1418 {
1419  CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
1420  WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
1421  WCHAR *urlW, *expected_urlW;
1422  DWORD dwEscaped;
1423  size_t i;
1424  static char inplace[] = "file:///C:/Program%20Files";
1425  static char another_inplace[] = "file:///C:/Program%20Files";
1426  static const char expected[] = "file:///C:/Program Files";
1427  static WCHAR inplaceW[] = {'f','i','l','e',':','/','/','/','C',':','/','P','r','o','g','r','a','m',' ','F','i','l','e','s',0};
1428  static WCHAR another_inplaceW[] ={'f','i','l','e',':','/','/','/',
1429  'C',':','/','P','r','o','g','r','a','m','%','2','0','F','i','l','e','s',0};
1430  HRESULT res;
1431 
1432  if (!pUrlUnescapeA) {
1433  win_skip("UrlUnescapeA not found\n");
1434  return;
1435  }
1436  for (i = 0; i < ARRAY_SIZE(TEST_URL_UNESCAPE); i++) {
1437  dwEscaped=INTERNET_MAX_URL_LENGTH;
1438  res = pUrlUnescapeA(TEST_URL_UNESCAPE[i].url, szReturnUrl, &dwEscaped, 0);
1439  ok(res == S_OK,
1440  "UrlUnescapeA returned 0x%x (expected S_OK) for \"%s\"\n",
1442  ok(strcmp(szReturnUrl,TEST_URL_UNESCAPE[i].expect)==0, "Expected \"%s\", but got \"%s\" from \"%s\"\n", TEST_URL_UNESCAPE[i].expect, szReturnUrl, TEST_URL_UNESCAPE[i].url);
1443 
1444  ZeroMemory(szReturnUrl, sizeof(szReturnUrl));
1445  /* if we set the buffer pointer to NULL here, UrlUnescape fails and the string is not converted */
1446  res = pUrlUnescapeA(TEST_URL_UNESCAPE[i].url, szReturnUrl, NULL, 0);
1447  ok(res == E_INVALIDARG,
1448  "UrlUnescapeA returned 0x%x (expected E_INVALIDARG) for \"%s\"\n",
1450  ok(strcmp(szReturnUrl,"")==0, "Expected empty string\n");
1451 
1452  if (pUrlUnescapeW) {
1453  dwEscaped = INTERNET_MAX_URL_LENGTH;
1455  expected_urlW = GetWideString(TEST_URL_UNESCAPE[i].expect);
1456  res = pUrlUnescapeW(urlW, ret_urlW, &dwEscaped, 0);
1457  ok(res == S_OK,
1458  "UrlUnescapeW returned 0x%x (expected S_OK) for \"%s\"\n",
1460 
1461  WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
1462  ok(lstrcmpW(ret_urlW, expected_urlW)==0,
1463  "Expected \"%s\", but got \"%s\" from \"%s\" flags %08lx\n",
1464  TEST_URL_UNESCAPE[i].expect, szReturnUrl, TEST_URL_UNESCAPE[i].url, 0L);
1465  FreeWideString(urlW);
1466  FreeWideString(expected_urlW);
1467  }
1468  }
1469 
1470  dwEscaped = sizeof(inplace);
1471  res = pUrlUnescapeA(inplace, NULL, &dwEscaped, URL_UNESCAPE_INPLACE);
1472  ok(res == S_OK, "UrlUnescapeA returned 0x%x (expected S_OK)\n", res);
1473  ok(!strcmp(inplace, expected), "got %s expected %s\n", inplace, expected);
1474  ok(dwEscaped == 27, "got %d expected 27\n", dwEscaped);
1475 
1476  /* if we set the buffer pointer to NULL, the string apparently still gets converted (Google Lively does this) */
1477  res = pUrlUnescapeA(another_inplace, NULL, NULL, URL_UNESCAPE_INPLACE);
1478  ok(res == S_OK, "UrlUnescapeA returned 0x%x (expected S_OK)\n", res);
1479  ok(!strcmp(another_inplace, expected), "got %s expected %s\n", another_inplace, expected);
1480 
1481  if (pUrlUnescapeW) {
1482  dwEscaped = sizeof(inplaceW);
1483  res = pUrlUnescapeW(inplaceW, NULL, &dwEscaped, URL_UNESCAPE_INPLACE);
1484  ok(res == S_OK, "UrlUnescapeW returned 0x%x (expected S_OK)\n", res);
1485  ok(dwEscaped == 50, "got %d expected 50\n", dwEscaped);
1486 
1487  /* if we set the buffer pointer to NULL, the string apparently still gets converted (Google Lively does this) */
1488  res = pUrlUnescapeW(another_inplaceW, NULL, NULL, URL_UNESCAPE_INPLACE);
1489  ok(res == S_OK, "UrlUnescapeW returned 0x%x (expected S_OK)\n", res);
1490 
1491  ok(lstrlenW(another_inplaceW) == 24, "got %d expected 24\n", lstrlenW(another_inplaceW));
1492  }
1493 }
1494 
1495 static const struct parse_url_test_t {
1496  const char *url;
1500 } parse_url_tests[] = {
1501  {"http://www.winehq.org/",S_OK,4,URL_SCHEME_HTTP},
1502  {"https://www.winehq.org/",S_OK,5,URL_SCHEME_HTTPS},
1503  {"ftp://www.winehq.org/",S_OK,3,URL_SCHEME_FTP},
1504  {"test.txt?test=c:/dir",URL_E_INVALID_SYNTAX},
1505  {"test.txt",URL_E_INVALID_SYNTAX},
1506  {"xxx://www.winehq.org/",S_OK,3,URL_SCHEME_UNKNOWN},
1507  {"1xx://www.winehq.org/",S_OK,3,URL_SCHEME_UNKNOWN},
1508  {"-xx://www.winehq.org/",S_OK,3,URL_SCHEME_UNKNOWN},
1509  {"xx0://www.winehq.org/",S_OK,3,URL_SCHEME_UNKNOWN},
1510  {"x://www.winehq.org/",URL_E_INVALID_SYNTAX},
1511  {"xx$://www.winehq.org/",URL_E_INVALID_SYNTAX},
1512  {"htt?p://www.winehq.org/",URL_E_INVALID_SYNTAX},
1513  {"ab-://www.winehq.org/",S_OK,3,URL_SCHEME_UNKNOWN},
1514  {" http://www.winehq.org/",URL_E_INVALID_SYNTAX},
1515  {"HTTP://www.winehq.org/",S_OK,4,URL_SCHEME_HTTP},
1516  {"a+-.://www.winehq.org/",S_OK,4,URL_SCHEME_UNKNOWN},
1517 };
1518 
1519 static void test_ParseURL(void)
1520 {
1521  const struct parse_url_test_t *test;
1523  PARSEDURLA parseda;
1524  PARSEDURLW parsedw;
1525  HRESULT hres;
1526 
1528  memset(&parseda, 0xd0, sizeof(parseda));
1529  parseda.cbSize = sizeof(parseda);
1530  hres = pParseURLA(test->url, &parseda);
1531  ok(hres == test->hres, "ParseURL failed: %08x, expected %08x\n", hres, test->hres);
1532  if(hres == S_OK) {
1533  ok(parseda.pszProtocol == test->url, "parseda.pszProtocol = %s, expected %s\n",
1534  parseda.pszProtocol, test->url);
1535  ok(parseda.cchProtocol == test->protocol_len, "parseda.cchProtocol = %d, expected %d\n",
1536  parseda.cchProtocol, test->protocol_len);
1537  ok(parseda.pszSuffix == test->url+test->protocol_len+1, "parseda.pszSuffix = %s, expected %s\n",
1538  parseda.pszSuffix, test->url+test->protocol_len+1);
1539  ok(parseda.cchSuffix == strlen(test->url+test->protocol_len+1),
1540  "parseda.pszSuffix = %d, expected %d\n",
1541  parseda.cchSuffix, lstrlenA(test->url+test->protocol_len+1));
1542  ok(parseda.nScheme == test->scheme, "parseda.nScheme = %d, expected %d\n",
1543  parseda.nScheme, test->scheme);
1544  }else {
1545  ok(!parseda.pszProtocol, "parseda.pszProtocol = %p\n", parseda.pszProtocol);
1546  ok(parseda.nScheme == 0xd0d0d0d0, "nScheme = %d\n", parseda.nScheme);
1547  }
1548 
1549  MultiByteToWideChar(CP_ACP, 0, test->url, -1, url, ARRAY_SIZE(url));
1550 
1551  memset(&parsedw, 0xd0, sizeof(parsedw));
1552  parsedw.cbSize = sizeof(parsedw);
1553  hres = pParseURLW(url, &parsedw);
1554  ok(hres == test->hres, "ParseURL failed: %08x, expected %08x\n", hres, test->hres);
1555  if(hres == S_OK) {
1556  ok(parsedw.pszProtocol == url, "parsedw.pszProtocol = %s, expected %s\n",
1558  ok(parsedw.cchProtocol == test->protocol_len, "parsedw.cchProtocol = %d, expected %d\n",
1559  parsedw.cchProtocol, test->protocol_len);
1560  ok(parsedw.pszSuffix == url+test->protocol_len+1, "parsedw.pszSuffix = %s, expected %s\n",
1561  wine_dbgstr_w(parsedw.pszSuffix), wine_dbgstr_w(url+test->protocol_len+1));
1562  ok(parsedw.cchSuffix == strlen(test->url+test->protocol_len+1),
1563  "parsedw.pszSuffix = %d, expected %d\n",
1564  parsedw.cchSuffix, lstrlenA(test->url+test->protocol_len+1));
1565  ok(parsedw.nScheme == test->scheme, "parsedw.nScheme = %d, expected %d\n",
1566  parsedw.nScheme, test->scheme);
1567  }else {
1568  ok(!parsedw.pszProtocol, "parsedw.pszProtocol = %p\n", parseda.pszProtocol);
1569  ok(parsedw.nScheme == 0xd0d0d0d0, "nScheme = %d\n", parsedw.nScheme);
1570  }
1571  }
1572 }
1573 
1574 static void test_HashData(void)
1575 {
1576  HRESULT res;
1577  BYTE input[16] = {0x51, 0x33, 0x4F, 0xA7, 0x45, 0x15, 0xF0, 0x52, 0x90,
1578  0x2B, 0xE7, 0xF5, 0xFD, 0xE1, 0xA6, 0xA7};
1579  BYTE output[32];
1580  static const BYTE expected[] = {0x54, 0x9C, 0x92, 0x55, 0xCD, 0x82, 0xFF,
1581  0xA1, 0x8E, 0x0F, 0xCF, 0x93, 0x14, 0xAA,
1582  0xE3, 0x2D};
1583  static const BYTE expected2[] = {0x54, 0x9C, 0x92, 0x55, 0xCD, 0x82, 0xFF,
1584  0xA1, 0x8E, 0x0F, 0xCF, 0x93, 0x14, 0xAA,
1585  0xE3, 0x2D, 0x47, 0xFC, 0x80, 0xB8, 0xD0,
1586  0x49, 0xE6, 0x13, 0x2A, 0x30, 0x51, 0x8D,
1587  0xF9, 0x4B, 0x07, 0xA6};
1588  static const BYTE expected3[] = {0x2B, 0xDC, 0x9A, 0x1B, 0xF0, 0x5A, 0xF9,
1589  0xC6, 0xBE, 0x94, 0x6D, 0xF3, 0x33, 0xC1,
1590  0x36, 0x07};
1591  int i;
1592 
1593  /* Test hashing with identically sized input/output buffers. */
1594  res = pHashData(input, 16, output, 16);
1595  ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08x\n", res);
1596  if(res == S_OK)
1597  ok(!memcmp(output, expected, sizeof(expected)),
1598  "Output buffer did not match expected contents\n");
1599 
1600  /* Test hashing with larger output buffer. */
1601  res = pHashData(input, 16, output, 32);
1602  ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08x\n", res);
1603  if(res == S_OK)
1604  ok(!memcmp(output, expected2, sizeof(expected2)),
1605  "Output buffer did not match expected contents\n");
1606 
1607  /* Test hashing with smaller input buffer. */
1608  res = pHashData(input, 8, output, 16);
1609  ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08x\n", res);
1610  if(res == S_OK)
1611  ok(!memcmp(output, expected3, sizeof(expected3)),
1612  "Output buffer did not match expected contents\n");
1613 
1614  /* Test passing NULL pointers for input/output parameters. */
1615  res = pHashData(NULL, 0, NULL, 0);
1616  ok(res == E_INVALIDARG || broken(res == S_OK), /* Windows 2000 */
1617  "Expected HashData to return E_INVALIDARG, got 0x%08x\n", res);
1618 
1619  res = pHashData(input, 0, NULL, 0);
1620  ok(res == E_INVALIDARG || broken(res == S_OK), /* Windows 2000 */
1621  "Expected HashData to return E_INVALIDARG, got 0x%08x\n", res);
1622 
1623  res = pHashData(NULL, 0, output, 0);
1624  ok(res == E_INVALIDARG || broken(res == S_OK), /* Windows 2000 */
1625  "Expected HashData to return E_INVALIDARG, got 0x%08x\n", res);
1626 
1627  /* Test passing valid pointers with sizes of zero. */
1628  for (i = 0; i < ARRAY_SIZE(input); i++)
1629  input[i] = 0x00;
1630 
1631  for (i = 0; i < ARRAY_SIZE(output); i++)
1632  output[i] = 0xFF;
1633 
1634  res = pHashData(input, 0, output, 0);
1635  ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08x\n", res);
1636 
1637  /* The buffers should be unchanged. */
1638  for (i = 0; i < ARRAY_SIZE(input); i++)
1639  {
1640  ok(input[i] == 0x00, "Expected the input buffer to be unchanged\n");
1641  if(input[i] != 0x00) break;
1642  }
1643 
1644  for (i = 0; i < ARRAY_SIZE(output); i++)
1645  {
1646  ok(output[i] == 0xFF, "Expected the output buffer to be unchanged\n");
1647  if(output[i] != 0xFF) break;
1648  }
1649 
1650  /* Input/output parameters are not validated. */
1651  res = pHashData((BYTE *)0xdeadbeef, 0, (BYTE *)0xdeadbeef, 0);
1652  ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08x\n", res);
1653 
1654  if (0)
1655  {
1656  res = pHashData((BYTE *)0xdeadbeef, 1, (BYTE *)0xdeadbeef, 1);
1657  trace("HashData returned 0x%08x\n", res);
1658  }
1659 }
1660 
1661 /* ########################### */
1662 
1664 {
1665  char *pFunc;
1666 
1667  hShlwapi = GetModuleHandleA("shlwapi.dll");
1668 
1669  /* SHCreateStreamOnFileEx was introduced in shlwapi v6.0 */
1670  pFunc = (void*)GetProcAddress(hShlwapi, "SHCreateStreamOnFileEx");
1671  if(!pFunc){
1672  win_skip("Too old shlwapi version\n");
1673  return;
1674  }
1675 
1676  pUrlUnescapeA = (void *) GetProcAddress(hShlwapi, "UrlUnescapeA");
1677  pUrlUnescapeW = (void *) GetProcAddress(hShlwapi, "UrlUnescapeW");
1678  pUrlIsA = (void *) GetProcAddress(hShlwapi, "UrlIsA");
1679  pUrlIsW = (void *) GetProcAddress(hShlwapi, "UrlIsW");
1680  pUrlHashA = (void *) GetProcAddress(hShlwapi, "UrlHashA");
1681  pUrlHashW = (void *) GetProcAddress(hShlwapi, "UrlHashW");
1682  pUrlGetPartA = (void *) GetProcAddress(hShlwapi, "UrlGetPartA");
1683  pUrlGetPartW = (void *) GetProcAddress(hShlwapi, "UrlGetPartW");
1684  pUrlEscapeA = (void *) GetProcAddress(hShlwapi, "UrlEscapeA");
1685  pUrlEscapeW = (void *) GetProcAddress(hShlwapi, "UrlEscapeW");
1686  pUrlCreateFromPathA = (void *) GetProcAddress(hShlwapi, "UrlCreateFromPathA");
1687  pUrlCreateFromPathW = (void *) GetProcAddress(hShlwapi, "UrlCreateFromPathW");
1688  pUrlCombineA = (void *) GetProcAddress(hShlwapi, "UrlCombineA");
1689  pUrlCombineW = (void *) GetProcAddress(hShlwapi, "UrlCombineW");
1690  pUrlCanonicalizeA = (void *) GetProcAddress(hShlwapi, "UrlCanonicalizeA");
1691  pUrlCanonicalizeW = (void *) GetProcAddress(hShlwapi, "UrlCanonicalizeW");
1692  pUrlApplySchemeA = (void *) GetProcAddress(hShlwapi, "UrlApplySchemeA");
1693  pUrlApplySchemeW = (void *) GetProcAddress(hShlwapi, "UrlApplySchemeW");
1694  pParseURLA = (void*)GetProcAddress(hShlwapi, (LPCSTR)1);
1695  pParseURLW = (void*)GetProcAddress(hShlwapi, (LPCSTR)2);
1696  pHashData = (void*)GetProcAddress(hShlwapi, "HashData");
1697 
1699  test_UrlHash();
1700  test_UrlGetPart();
1703  test_UrlEscapeA();
1704  test_UrlEscapeW();
1705  test_UrlCombine();
1707  test_UrlIs();
1708  test_UrlUnescape();
1709  test_ParseURL();
1710  test_HashData();
1711 }
#define URL_APPLY_FORCEAPPLY
Definition: shlwapi.h:1201
static WCHAR file_url[INTERNET_MAX_URL_LENGTH]
Definition: url.c:196
BOOL expectFile
Definition: url.c:501
const char * url
Definition: url.c:236
LPCSTR pszSuffix
Definition: shlwapi.h:1426
static void test_UrlIs_null(DWORD flag)
Definition: url.c:1347
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
struct _TEST_URL_APPLY TEST_URL_APPLY
HRESULT WINAPI UrlEscapeW(LPCWSTR pszUrl, LPWSTR pszEscaped, LPDWORD pcchEscaped, DWORD dwFlags)
Definition: url.c:1076
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
DWORD ret
Definition: url.c:452
#define WideCharToMultiByte
Definition: compat.h:111
UINT cchSuffix
Definition: shlwapi.h:1427
HRESULT hr
Definition: shlfolder.c:183
static void test_UrlEscapeW(void)
Definition: url.c:953
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static const CHAR winehqA[]
Definition: url.c:62
#define TRUE
Definition: types.h:120
#define URL_UNESCAPE_INPLACE
Definition: shlwapi.h:1224
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
#define CP_ACP
Definition: compat.h:109
DWORD cbSize
Definition: shlwapi.h:1432
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
char CHAR
Definition: xmlstorage.h:175
static LPSTR
Definition: url.c:34
const char * newurl
Definition: shdocvw.c:51
static void test_UrlCanonicalizeW(void)
Definition: url.c:1147
static void FreeWideString(LPWSTR wszString)
Definition: url.c:543
BOOL todo
Definition: filedlg.c:313
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
static HMODULE hShlwapi
Definition: url.c:33
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
#define ZeroMemory
Definition: winbase.h:1648
LPCSTR pszProtocol
Definition: shlwapi.h:1424
#define URL_ESCAPE_AS_UTF8
Definition: shlwapi.h:1227
UINT protocol_len
Definition: url.c:1498
#define test
Definition: rosglue.h:37
LPCWSTR pszSuffix
Definition: shlwapi.h:1435
static const WCHAR expected2[]
Definition: dir.c:143
static LPBYTE
Definition: url.c:38
static const char * TEST_URL_4
Definition: url.c:59
const WCHAR vistaurl[INTERNET_MAX_URL_LENGTH]
Definition: url.c:332
const char * expecturl
Definition: url.c:240
#define lstrlenW
Definition: compat.h:609
#define E_FAIL
Definition: ddrawi.h:102
const char * expecturl
Definition: url.c:108
static BOOL(WINAPI *pUrlIsA)(LPCSTR
HRESULT expectret
Definition: url.c:371
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
static LPCWSTR
Definition: url.c:47
static const CHAR untouchedA[]
Definition: url.c:66
static struct @1683 TEST_URL_UNESCAPE[]
static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl, BOOL todo)
Definition: url.c:1222
struct _TEST_URL_CANONICALIZE TEST_URL_CANONICALIZE
static const WCHAR url2[]
Definition: url.c:44
const char * url
Definition: url.c:71
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const char * expecturl
Definition: url.c:372
unsigned char * LPBYTE
Definition: typedefs.h:53
BOOL expectOpaque
Definition: url.c:500
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
static const TEST_URL_ESCAPE TEST_ESCAPE[]
Definition: url.c:243
static void test_UrlIs(void)
Definition: url.c:1356
START_TEST(url)
Definition: url.c:1663
struct _TEST_URL_ESCAPE TEST_URL_ESCAPE
DWORD flags
Definition: url.c:237
static const struct @1684 TEST_PATH_IS_URL[]
static LPCWSTR http_url
Definition: protocol.c:147
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
#define INTERNET_MAX_URL_LENGTH
Definition: session.c:1418
#define URL_WININET_COMPATIBILITY
Definition: shlwapi.h:1209
static void test_url_part(const char *szUrl, DWORD dwPart, DWORD dwFlags, const char *szExpected)
Definition: url.c:662
#define URL_E_INVALID_SYNTAX
Definition: intshcut.h:32
GLuint index
Definition: glext.h:6031
#define URL_PARTFLAG_KEEPSCHEME
Definition: shlwapi.h:1187
static void test_UrlCombine(void)
Definition: url.c:1297
const char * LPCSTR
Definition: xmlstorage.h:183
#define URL_ESCAPE_SEGMENT_ONLY
Definition: shlwapi.h:1229
static void test_HashData(void)
Definition: url.c:1574
#define todo_wine_if(is_todo)
Definition: test.h:163
static const struct @1685 TEST_URLIS_ATTRIBS[]
#define TEST_APPLY_MAX_LENGTH
Definition: url.c:68
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
static const struct parse_url_test_t parse_url_tests[]
#define GetProcessHeap()
Definition: compat.h:595
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD flags
Definition: url.c:370
HRESULT expectret
Definition: url.c:329
static const WCHAR winehqW[]
Definition: url.c:61
HRESULT expectret
Definition: url.c:239
__wchar_t WCHAR
Definition: xmlstorage.h:180
struct _TEST_URL_COMBINE TEST_URL_COMBINE
#define URL_APPLY_DEFAULT
Definition: shlwapi.h:1204
LONG HRESULT
Definition: typedefs.h:79
static const TEST_URL_COMBINE TEST_COMBINE[]
Definition: url.c:376
DWORD flags
Definition: url.c:72
HRESULT hres
Definition: url.c:1497
#define WINAPI
Definition: msvc.h:6
static FILE * out
Definition: regtests2xml.c:44
static LPCSTR
Definition: url.c:46
const char * expect
Definition: url.c:474
unsigned long DWORD
Definition: ntddk_ex.h:95
static LPDWORD
Definition: url.c:34
static HRESULT(WINAPI *pUrlUnescapeA)(LPSTR
#define SetLastError(x)
Definition: compat.h:611
UINT cchSuffix
Definition: shlwapi.h:1436
const char * newurl
Definition: url.c:75
UINT scheme
Definition: url.c:1499
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
GLbitfield flags
Definition: glext.h:7161
#define URL_FILE_USE_PATHURL
Definition: shlwapi.h:1226
UINT cchProtocol
Definition: shlwapi.h:1434
UINT nScheme
Definition: shlwapi.h:1437
UINT cchProtocol
Definition: shlwapi.h:1425
static const WCHAR L[]
Definition: oid.c:1250
#define todo_wine
Definition: test.h:162
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
const char * url
Definition: url.c:451
static void test_UrlCreateFromPath(void)
Definition: url.c:1308
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define URL_DONT_SIMPLIFY
Definition: shlwapi.h:1214
static void test_url_canonicalize(int index, const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, HRESULT dwExpectReturnAlt, const char *szExpectUrl, BOOL todo)
Definition: url.c:854
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
static LPWSTR
Definition: url.c:35
const WCHAR url[INTERNET_MAX_URL_LENGTH]
Definition: url.c:327
static const WCHAR expected3[]
Definition: dir.c:144
HRESULT res
Definition: url.c:73
unsigned char BYTE
Definition: xxhash.c:193
#define URL_ESCAPE_PERCENT
Definition: shlwapi.h:1230
#define broken(x)
Definition: _sntprintf.h:21
#define URL_ESCAPE_UNSAFE
Definition: shlwapi.h:1211
const WCHAR win7url[INTERNET_MAX_URL_LENGTH]
Definition: url.c:331
static const WCHAR url1[]
Definition: url.c:41
static const char * TEST_URL_3
Definition: url.c:58
#define S_OK
Definition: intsafe.h:51
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
GLenum GLenum GLenum input
Definition: glext.h:9031
static void test_UrlApplyScheme(void)
Definition: url.c:550
static const TEST_URL_CANONICALIZE TEST_CANONICALIZE[]
Definition: url.c:112
#define ARRAY_SIZE(a)
Definition: main.h:24
static const char * TEST_URL_2
Definition: url.c:57
static const TEST_URL_APPLY TEST_APPLY[]
Definition: url.c:78
#define ok(value,...)
Definition: atltest.h:57
LPCWSTR pszProtocol
Definition: shlwapi.h:1433
struct _TEST_URL_ESCAPEW TEST_URL_ESCAPEW
#define E_NOTIMPL
Definition: ddrawi.h:99
DWORD expectescaped
Definition: url.c:238
#define URL_UNESCAPE
Definition: shlwapi.h:1212
unsigned int UINT
Definition: ndis.h:50
static LPWSTR GetWideString(const char *szString)
Definition: url.c:533
static void test_UrlCanonicalizeA(void)
Definition: url.c:1061
#define MultiByteToWideChar
Definition: compat.h:110
#define URL_APPLY_GUESSSCHEME
Definition: shlwapi.h:1203
DWORD cbSize
Definition: shlwapi.h:1423
static void test_UrlGetPart(void)
Definition: url.c:707
GLuint res
Definition: glext.h:9613
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static void test_ParseURL(void)
Definition: url.c:1519
#define GetProcAddress(x, y)
Definition: compat.h:612
static URLIS
Definition: url.c:36
static void test_UrlUnescape(void)
Definition: url.c:1417
static const struct @1682 TEST_URLFROMPATH[]
static void hash_url(const char *szUrl)
Definition: url.c:628
const WCHAR expecturl[INTERNET_MAX_URL_LENGTH]
Definition: url.c:330
static DWORD
Definition: url.c:34
#define URL_ESCAPE_SPACES_ONLY
Definition: shlwapi.h:1216
#define URL_APPLY_GUESSFILE
Definition: shlwapi.h:1202
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define URL_PLUGGABLE_PROTOCOL
Definition: shlwapi.h:1210
const char * url1
Definition: url.c:368
#define E_POINTER
Definition: winerror.h:2365
const char * path
Definition: url.c:450
#define memset(x, y, z)
Definition: compat.h:39
HRESULT expectret
Definition: url.c:107
#define win_skip
Definition: test.h:149
static const TEST_URL_ESCAPEW TEST_ESCAPEW[]
Definition: url.c:335
const char * url2
Definition: url.c:369
DWORD flags
Definition: url.c:328
#define HeapFree(x, y, z)
Definition: compat.h:594
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
const char * url
Definition: url.c:105
BOOL expected
Definition: store.c:2063
DWORD newlen
Definition: url.c:74
const char * url
Definition: url.c:1496
#define SUCCEEDED(hr)
Definition: intsafe.h:49
static const char * TEST_URL_1
Definition: url.c:56
#define URL_DONT_ESCAPE_EXTRA_INFO
Definition: shlwapi.h:1217
static void test_UrlHash(void)
Definition: url.c:648
UINT nScheme
Definition: shlwapi.h:1428
static void test_UrlEscapeA(void)
Definition: url.c:894