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