- Fix more dlls.
[reactos.git] / dll / win32 / urlmon / internet.c
1 /*
2 * Copyright 2005 Jacek Caban
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include "urlmon_main.h"
20 #include "winreg.h"
21 #include "shlwapi.h"
22
23 #include "wine/debug.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
26
27 static HRESULT parse_schema(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
28 {
29 WCHAR *ptr;
30 DWORD len = 0;
31
32 TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
33
34 if(flags)
35 ERR("wrong flags\n");
36
37 ptr = strchrW(url, ':');
38 if(ptr)
39 len = ptr-url;
40
41 if(rsize)
42 *rsize = len;
43
44 if(len >= size)
45 return E_POINTER;
46
47 if(len)
48 memcpy(result, url, len*sizeof(WCHAR));
49 result[len] = 0;
50
51 return S_OK;
52 }
53
54 static HRESULT parse_canonicalize_url(LPCWSTR url, DWORD flags, LPWSTR result,
55 DWORD size, DWORD *rsize)
56 {
57 IInternetProtocolInfo *protocol_info;
58 DWORD prsize = size;
59 HRESULT hres;
60
61 TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
62
63 protocol_info = get_protocol_info(url);
64
65 if(protocol_info) {
66 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_CANONICALIZE,
67 flags, result, size, rsize, 0);
68 IInternetProtocolInfo_Release(protocol_info);
69 if(SUCCEEDED(hres))
70 return hres;
71 }
72
73 hres = UrlCanonicalizeW(url, result, &prsize, flags);
74
75 if(rsize)
76 *rsize = prsize;
77 return hres;
78 }
79
80 static HRESULT parse_security_url(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
81 {
82 IInternetProtocolInfo *protocol_info;
83 HRESULT hres;
84
85 TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
86
87 protocol_info = get_protocol_info(url);
88
89 if(protocol_info) {
90 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL,
91 flags, result, size, rsize, 0);
92 IInternetProtocolInfo_Release(protocol_info);
93 return hres;
94 }
95
96 return E_FAIL;
97 }
98
99 static HRESULT parse_encode(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
100 {
101 IInternetProtocolInfo *protocol_info;
102 DWORD prsize;
103 HRESULT hres;
104
105 TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
106
107 protocol_info = get_protocol_info(url);
108
109 if(protocol_info) {
110 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_ENCODE,
111 flags, result, size, rsize, 0);
112 IInternetProtocolInfo_Release(protocol_info);
113 if(SUCCEEDED(hres))
114 return hres;
115 }
116
117 prsize = size;
118 hres = UrlUnescapeW((LPWSTR)url, result, &prsize, flags);
119
120 if(rsize)
121 *rsize = prsize;
122
123 return hres;
124 }
125
126 static HRESULT parse_path_from_url(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
127 {
128 IInternetProtocolInfo *protocol_info;
129 DWORD prsize;
130 HRESULT hres;
131
132 TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
133
134 protocol_info = get_protocol_info(url);
135
136 if(protocol_info) {
137 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_PATH_FROM_URL,
138 flags, result, size, rsize, 0);
139 IInternetProtocolInfo_Release(protocol_info);
140 if(SUCCEEDED(hres))
141 return hres;
142 }
143
144 prsize = size;
145 hres = PathCreateFromUrlW(url, result, &prsize, 0);
146
147 if(rsize)
148 *rsize = prsize;
149 return hres;
150 }
151
152 static HRESULT parse_security_domain(LPCWSTR url, DWORD flags, LPWSTR result,
153 DWORD size, DWORD *rsize)
154 {
155 IInternetProtocolInfo *protocol_info;
156 HRESULT hres;
157
158 TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
159
160 protocol_info = get_protocol_info(url);
161
162 if(protocol_info) {
163 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN,
164 flags, result, size, rsize, 0);
165 IInternetProtocolInfo_Release(protocol_info);
166 if(SUCCEEDED(hres))
167 return hres;
168 }
169
170 return E_FAIL;
171 }
172
173 static HRESULT parse_domain(LPCWSTR url, DWORD flags, LPWSTR result,
174 DWORD size, DWORD *rsize)
175 {
176 IInternetProtocolInfo *protocol_info;
177 HRESULT hres;
178
179 TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
180
181 protocol_info = get_protocol_info(url);
182
183 if(protocol_info) {
184 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_DOMAIN,
185 flags, result, size, rsize, 0);
186 IInternetProtocolInfo_Release(protocol_info);
187 if(SUCCEEDED(hres))
188 return hres;
189 }
190
191 hres = UrlGetPartW(url, result, &size, URL_PART_HOSTNAME, flags);
192 if(rsize)
193 *rsize = size;
194
195 if(hres == E_POINTER)
196 return S_FALSE;
197
198 if(FAILED(hres))
199 return E_FAIL;
200 return S_OK;
201 }
202
203 static HRESULT parse_rootdocument(LPCWSTR url, DWORD flags, LPWSTR result,
204 DWORD size, DWORD *rsize)
205 {
206 IInternetProtocolInfo *protocol_info;
207 PARSEDURLW url_info;
208 HRESULT hres;
209
210 TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
211
212 protocol_info = get_protocol_info(url);
213
214 if(protocol_info) {
215 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_ROOTDOCUMENT,
216 flags, result, size, rsize, 0);
217 IInternetProtocolInfo_Release(protocol_info);
218 if(SUCCEEDED(hres))
219 return hres;
220 }
221
222 url_info.cbSize = sizeof(url_info);
223 if(FAILED(ParseURLW(url, &url_info)))
224 return E_FAIL;
225
226 switch(url_info.nScheme) {
227 case URL_SCHEME_FTP:
228 case URL_SCHEME_HTTP:
229 case URL_SCHEME_HTTPS:
230 if(url_info.cchSuffix<3 || *(url_info.pszSuffix)!='/'
231 || *(url_info.pszSuffix+1)!='/')
232 return E_FAIL;
233
234 if(size < url_info.cchProtocol+3) {
235 size = 0;
236 hres = UrlGetPartW(url, result, &size, URL_PART_HOSTNAME, flags);
237
238 if(rsize)
239 *rsize = size+url_info.cchProtocol+3;
240
241 if(hres == E_POINTER)
242 return S_FALSE;
243
244 return hres;
245 }
246
247 size -= url_info.cchProtocol+3;
248 hres = UrlGetPartW(url, result+url_info.cchProtocol+3,
249 &size, URL_PART_HOSTNAME, flags);
250
251 if(hres == E_POINTER)
252 return S_FALSE;
253
254 if(FAILED(hres))
255 return E_FAIL;
256
257 if(rsize)
258 *rsize = size+url_info.cchProtocol+3;
259
260 memcpy(result, url, (url_info.cchProtocol+3)*sizeof(WCHAR));
261 return hres;
262 default:
263 return E_FAIL;
264 }
265 }
266
267 /**************************************************************************
268 * CoInternetParseUrl (URLMON.@)
269 */
270 HRESULT WINAPI CoInternetParseUrl(LPCWSTR pwzUrl, PARSEACTION ParseAction, DWORD dwFlags,
271 LPWSTR pszResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
272 {
273 if(dwReserved)
274 WARN("dwReserved = %d\n", dwReserved);
275
276 switch(ParseAction) {
277 case PARSE_CANONICALIZE:
278 return parse_canonicalize_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
279 case PARSE_SECURITY_URL:
280 return parse_security_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
281 case PARSE_ENCODE:
282 return parse_encode(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
283 case PARSE_PATH_FROM_URL:
284 return parse_path_from_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
285 case PARSE_SCHEMA:
286 return parse_schema(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
287 case PARSE_SECURITY_DOMAIN:
288 return parse_security_domain(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
289 case PARSE_DOMAIN:
290 return parse_domain(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
291 case PARSE_ROOTDOCUMENT:
292 return parse_rootdocument(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
293 default:
294 FIXME("not supported action %d\n", ParseAction);
295 }
296
297 return E_NOTIMPL;
298 }
299
300 /**************************************************************************
301 * CoInternetCombineUrl (URLMON.@)
302 */
303 HRESULT WINAPI CoInternetCombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl,
304 DWORD dwCombineFlags, LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult,
305 DWORD dwReserved)
306 {
307 IInternetProtocolInfo *protocol_info;
308 DWORD size = cchResult;
309 HRESULT hres;
310
311 TRACE("(%s,%s,0x%08x,%p,%d,%p,%d)\n", debugstr_w(pwzBaseUrl),
312 debugstr_w(pwzRelativeUrl), dwCombineFlags, pwzResult, cchResult, pcchResult,
313 dwReserved);
314
315 protocol_info = get_protocol_info(pwzBaseUrl);
316
317 if(protocol_info) {
318 hres = IInternetProtocolInfo_CombineUrl(protocol_info, pwzBaseUrl, pwzRelativeUrl,
319 dwCombineFlags, pwzResult, cchResult, pcchResult, dwReserved);
320 IInternetProtocolInfo_Release(protocol_info);
321 if(SUCCEEDED(hres))
322 return hres;
323 }
324
325
326 hres = UrlCombineW(pwzBaseUrl, pwzRelativeUrl, pwzResult, &size, dwCombineFlags);
327
328 if(pcchResult)
329 *pcchResult = size;
330
331 return hres;
332 }
333
334 /**************************************************************************
335 * CoInternetCompareUrl (URLMON.@)
336 */
337 HRESULT WINAPI CoInternetCompareUrl(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
338 {
339 IInternetProtocolInfo *protocol_info;
340 HRESULT hres;
341
342 TRACE("(%s,%s,%08x)\n", debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
343
344 protocol_info = get_protocol_info(pwzUrl1);
345
346 if(protocol_info) {
347 hres = IInternetProtocolInfo_CompareUrl(protocol_info, pwzUrl1, pwzUrl2, dwCompareFlags);
348 IInternetProtocolInfo_Release(protocol_info);
349 if(SUCCEEDED(hres))
350 return hres;
351 }
352
353 return UrlCompareW(pwzUrl1, pwzUrl2, dwCompareFlags) ? S_FALSE : S_OK;
354 }
355
356 /***********************************************************************
357 * CoInternetQueryInfo (URLMON.@)
358 *
359 * Retrieves information relevant to a specified URL
360 *
361 */
362 HRESULT WINAPI CoInternetQueryInfo(LPCWSTR pwzUrl, QUERYOPTION QueryOption,
363 DWORD dwQueryFlags, LPVOID pvBuffer, DWORD cbBuffer, DWORD *pcbBuffer,
364 DWORD dwReserved)
365 {
366 IInternetProtocolInfo *protocol_info;
367 HRESULT hres;
368
369 TRACE("(%s, %x, %x, %p, %x, %p, %x): stub\n", debugstr_w(pwzUrl),
370 QueryOption, dwQueryFlags, pvBuffer, cbBuffer, pcbBuffer, dwReserved);
371
372 protocol_info = get_protocol_info(pwzUrl);
373
374 if(protocol_info) {
375 hres = IInternetProtocolInfo_QueryInfo(protocol_info, pwzUrl, QueryOption, dwQueryFlags,
376 pvBuffer, cbBuffer, pcbBuffer, dwReserved);
377 IInternetProtocolInfo_Release(protocol_info);
378
379 return SUCCEEDED(hres) ? hres : E_FAIL;
380 }
381
382 switch(QueryOption) {
383 case QUERY_USES_NETWORK:
384 if(!pvBuffer || cbBuffer < sizeof(DWORD))
385 return E_FAIL;
386
387 *(DWORD*)pvBuffer = 0;
388 if(pcbBuffer)
389 *pcbBuffer = sizeof(DWORD);
390 break;
391
392 default:
393 FIXME("Not supported option %d\n", QueryOption);
394 return E_NOTIMPL;
395 }
396
397 return S_OK;
398 }
399
400 /***********************************************************************
401 * CoInternetSetFeatureEnabled (URLMON.@)
402 */
403 HRESULT WINAPI CoInternetSetFeatureEnabled(INTERNETFEATURELIST feature, DWORD flags, BOOL enable)
404 {
405 FIXME("%d, 0x%08x, %x, stub\n", feature, flags, enable);
406 return E_NOTIMPL;
407 }
408
409 /***********************************************************************
410 * CoInternetIsFeatureEnabled (URLMON.@)
411 */
412 HRESULT WINAPI CoInternetIsFeatureEnabled(INTERNETFEATURELIST feature, DWORD flags)
413 {
414 FIXME("%d, 0x%08x, stub\n", feature, flags);
415 return E_NOTIMPL;
416 }