windows.applicationmodel/tests: Use PathRemoveFileSpecW() instead of PathCchRemoveFil...
[wine.git] / dlls / urlmon / internet.c
blobd38bba1d3764fcd929cad7dd27d12ed55da4cc35
1 /*
2 * Copyright 2005 Jacek Caban
3 * Copyright 2011 Thomas Mullaly for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "urlmon_main.h"
21 #include "winreg.h"
22 #include "shlwapi.h"
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
28 static const WCHAR feature_control_keyW[] =
29 L"Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl";
31 static CRITICAL_SECTION process_features_cs;
32 static CRITICAL_SECTION_DEBUG process_features_cs_dbg =
34 0, 0, &process_features_cs,
35 { &process_features_cs_dbg.ProcessLocksList, &process_features_cs_dbg.ProcessLocksList },
36 0, 0, { (DWORD_PTR)(__FILE__ ": process features") }
38 static CRITICAL_SECTION process_features_cs = { &process_features_cs_dbg, -1, 0, 0, 0, 0 };
40 typedef struct feature_control {
41 LPCWSTR feature_name;
42 BOOL enabled;
43 BOOL check_registry;
44 } feature_control;
46 /* IMPORTANT!!!
48 * This array is indexed using INTERNETFEATURELIST values, so everything must
49 * appear in the same order as it does in INTERNETFEATURELIST.
51 static feature_control process_feature_controls[FEATURE_ENTRY_COUNT] = {
52 {L"FEATURE_OBJECT_CACHING", TRUE ,TRUE},
53 {L"FEATURE_ZONE_ELEVATION", FALSE,TRUE},
54 {L"FEATURE_MIME_HANDLING", FALSE,TRUE},
55 {L"FEATURE_MIME_SNIFFING", FALSE,TRUE},
56 {L"FEATURE_WINDOW_RESTRICTIONS", FALSE,TRUE},
57 {L"FEATURE_WEBOC_POPUPMANAGEMENT", FALSE,TRUE},
58 {L"FEATURE_BEHAVIORS", TRUE ,TRUE},
59 {L"FEATURE_DISABLE_MK_PROTOCOL", TRUE ,TRUE},
60 {L"FEATURE_LOCALMACHINE_LOCKDOWN", FALSE,TRUE},
61 {L"FEATURE_SECURITYBAND", FALSE,TRUE},
62 {L"FEATURE_RESTRICT_ACTIVEXINSTALL", FALSE,TRUE},
63 {L"FEATURE_VALIDATE_NAVIGATE_URL", FALSE,TRUE},
64 {L"FEATURE_RESTRICT_FILEDOWNLOAD", FALSE,TRUE},
65 {L"FEATURE_ADDON_MANAGEMENT", FALSE,TRUE},
66 {L"FEATURE_PROTOCOL_LOCKDOWN", FALSE,TRUE},
67 {L"FEATURE_HTTP_USERNAME_PASSWORD_DISABLE", FALSE,TRUE},
68 {L"FEATURE_SAFE_BINDTOOBJECT", FALSE,TRUE},
69 {L"FEATURE_UNC_SAVEDFILECHECK", FALSE,TRUE},
70 {L"FEATURE_GET_URL_DOM_FILEPATH_UNENCODED", TRUE ,TRUE},
71 {L"FEATURE_TABBED_BROWSING", FALSE,TRUE},
72 {L"FEATURE_SSLUX", FALSE,TRUE},
73 {L"FEATURE_DISABLE_NAVIGATION_SOUNDS", FALSE,TRUE},
74 {L"FEATURE_DISABLE_LEGACY_COMPRESSION", TRUE ,TRUE},
75 {L"FEATURE_FORCE_ADDR_AND_STATUS", FALSE,TRUE},
76 {L"FEATURE_XMLHTTP", TRUE ,TRUE},
77 {L"FEATURE_DISABLE_TELNET_PROTOCOL", FALSE,TRUE},
78 {L"FEATURE_FEEDS", FALSE,TRUE},
79 {L"FEATURE_BLOCK_INPUT_PROMPTS", FALSE,TRUE}
82 static HRESULT parse_schema(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
84 WCHAR *ptr;
85 DWORD len = 0;
87 TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
89 if(flags)
90 ERR("wrong flags\n");
92 ptr = wcschr(url, ':');
93 if(ptr)
94 len = ptr-url;
96 if(rsize)
97 *rsize = len;
99 if(len >= size)
100 return E_POINTER;
102 if(len)
103 memcpy(result, url, len*sizeof(WCHAR));
104 result[len] = 0;
106 return S_OK;
109 static HRESULT parse_canonicalize_url(LPCWSTR url, DWORD flags, LPWSTR result,
110 DWORD size, DWORD *rsize)
112 IInternetProtocolInfo *protocol_info;
113 DWORD prsize = size;
114 HRESULT hres;
116 TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
118 protocol_info = get_protocol_info(url);
120 if(protocol_info) {
121 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_CANONICALIZE,
122 flags, result, size, rsize, 0);
123 IInternetProtocolInfo_Release(protocol_info);
124 if(SUCCEEDED(hres))
125 return hres;
128 hres = UrlCanonicalizeW(url, result, &prsize, flags);
130 if(rsize)
131 *rsize = prsize;
132 return hres;
135 static HRESULT parse_security_url(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
137 IInternetProtocolInfo *protocol_info;
138 HRESULT hres;
140 TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
142 protocol_info = get_protocol_info(url);
144 if(protocol_info) {
145 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL,
146 flags, result, size, rsize, 0);
147 IInternetProtocolInfo_Release(protocol_info);
148 return hres;
151 return E_FAIL;
154 static HRESULT parse_encode(LPCWSTR url, PARSEACTION action, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
156 IInternetProtocolInfo *protocol_info;
157 DWORD prsize;
158 HRESULT hres;
160 TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
162 protocol_info = get_protocol_info(url);
164 if(protocol_info) {
165 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, action,
166 flags, result, size, rsize, 0);
167 IInternetProtocolInfo_Release(protocol_info);
168 if(SUCCEEDED(hres))
169 return hres;
172 prsize = size;
173 hres = UrlUnescapeW((LPWSTR)url, result, &prsize, flags);
175 if(rsize)
176 *rsize = prsize;
178 return hres;
181 static HRESULT parse_path_from_url(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
183 IInternetProtocolInfo *protocol_info;
184 DWORD prsize;
185 HRESULT hres;
187 TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
189 protocol_info = get_protocol_info(url);
191 if(protocol_info) {
192 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_PATH_FROM_URL,
193 flags, result, size, rsize, 0);
194 IInternetProtocolInfo_Release(protocol_info);
195 if(SUCCEEDED(hres))
196 return hres;
199 prsize = size;
200 hres = PathCreateFromUrlW(url, result, &prsize, 0);
202 if(rsize)
203 *rsize = prsize;
204 return hres;
207 static HRESULT parse_security_domain(LPCWSTR url, DWORD flags, LPWSTR result,
208 DWORD size, DWORD *rsize)
210 IInternetProtocolInfo *protocol_info;
211 HRESULT hres;
213 TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
215 protocol_info = get_protocol_info(url);
217 if(protocol_info) {
218 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN,
219 flags, result, size, rsize, 0);
220 IInternetProtocolInfo_Release(protocol_info);
221 if(SUCCEEDED(hres))
222 return hres;
225 return E_FAIL;
228 static HRESULT parse_domain(LPCWSTR url, DWORD flags, LPWSTR result,
229 DWORD size, DWORD *rsize)
231 IInternetProtocolInfo *protocol_info;
232 HRESULT hres;
234 TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
236 protocol_info = get_protocol_info(url);
238 if(protocol_info) {
239 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_DOMAIN,
240 flags, result, size, rsize, 0);
241 IInternetProtocolInfo_Release(protocol_info);
242 if(SUCCEEDED(hres))
243 return hres;
246 hres = UrlGetPartW(url, result, &size, URL_PART_HOSTNAME, flags);
247 if(rsize)
248 *rsize = size;
250 if(hres == E_POINTER)
251 return S_FALSE;
253 if(FAILED(hres))
254 return E_FAIL;
255 return S_OK;
258 static HRESULT parse_rootdocument(LPCWSTR url, DWORD flags, LPWSTR result,
259 DWORD size, DWORD *rsize)
261 IInternetProtocolInfo *protocol_info;
262 PARSEDURLW url_info;
263 HRESULT hres;
265 TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
267 protocol_info = get_protocol_info(url);
269 if(protocol_info) {
270 hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_ROOTDOCUMENT,
271 flags, result, size, rsize, 0);
272 IInternetProtocolInfo_Release(protocol_info);
273 if(SUCCEEDED(hres))
274 return hres;
277 url_info.cbSize = sizeof(url_info);
278 if(FAILED(ParseURLW(url, &url_info)))
279 return E_FAIL;
281 switch(url_info.nScheme) {
282 case URL_SCHEME_FTP:
283 case URL_SCHEME_HTTP:
284 case URL_SCHEME_HTTPS:
285 if(url_info.cchSuffix<3 || *(url_info.pszSuffix)!='/'
286 || *(url_info.pszSuffix+1)!='/')
287 return E_FAIL;
289 if(size < url_info.cchProtocol+3) {
290 size = 0;
291 hres = UrlGetPartW(url, result, &size, URL_PART_HOSTNAME, flags);
293 if(rsize)
294 *rsize = size+url_info.cchProtocol+3;
296 if(hres == E_POINTER)
297 return S_FALSE;
299 return hres;
302 size -= url_info.cchProtocol+3;
303 hres = UrlGetPartW(url, result+url_info.cchProtocol+3,
304 &size, URL_PART_HOSTNAME, flags);
306 if(hres == E_POINTER)
307 return S_FALSE;
309 if(FAILED(hres))
310 return E_FAIL;
312 if(rsize)
313 *rsize = size+url_info.cchProtocol+3;
315 memcpy(result, url, (url_info.cchProtocol+3)*sizeof(WCHAR));
316 return hres;
317 default:
318 return E_FAIL;
322 /**************************************************************************
323 * CoInternetParseUrl (URLMON.@)
325 HRESULT WINAPI CoInternetParseUrl(LPCWSTR pwzUrl, PARSEACTION ParseAction, DWORD dwFlags,
326 LPWSTR pszResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
328 if(dwReserved)
329 WARN("dwReserved = %ld\n", dwReserved);
331 switch(ParseAction) {
332 case PARSE_CANONICALIZE:
333 return parse_canonicalize_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
334 case PARSE_SECURITY_URL:
335 return parse_security_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
336 case PARSE_ENCODE:
337 case PARSE_UNESCAPE:
338 return parse_encode(pwzUrl, ParseAction, dwFlags, pszResult, cchResult, pcchResult);
339 case PARSE_PATH_FROM_URL:
340 return parse_path_from_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
341 case PARSE_SCHEMA:
342 return parse_schema(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
343 case PARSE_SECURITY_DOMAIN:
344 return parse_security_domain(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
345 case PARSE_DOMAIN:
346 return parse_domain(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
347 case PARSE_ROOTDOCUMENT:
348 return parse_rootdocument(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
349 default:
350 FIXME("not supported action %d\n", ParseAction);
353 return E_NOTIMPL;
356 /**************************************************************************
357 * CoInternetCombineUrl (URLMON.@)
359 HRESULT WINAPI CoInternetCombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl,
360 DWORD dwCombineFlags, LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult,
361 DWORD dwReserved)
363 IInternetProtocolInfo *protocol_info;
364 DWORD size = cchResult;
365 HRESULT hres;
367 TRACE("(%s,%s,0x%08lx,%p,%ld,%p,%ld)\n", debugstr_w(pwzBaseUrl),
368 debugstr_w(pwzRelativeUrl), dwCombineFlags, pwzResult, cchResult, pcchResult,
369 dwReserved);
371 protocol_info = get_protocol_info(pwzBaseUrl);
373 if(protocol_info) {
374 hres = IInternetProtocolInfo_CombineUrl(protocol_info, pwzBaseUrl, pwzRelativeUrl,
375 dwCombineFlags, pwzResult, cchResult, pcchResult, dwReserved);
376 IInternetProtocolInfo_Release(protocol_info);
377 if(SUCCEEDED(hres))
378 return hres;
382 hres = UrlCombineW(pwzBaseUrl, pwzRelativeUrl, pwzResult, &size, dwCombineFlags);
384 if(pcchResult)
385 *pcchResult = size;
387 return hres;
390 /**************************************************************************
391 * CoInternetCompareUrl (URLMON.@)
393 HRESULT WINAPI CoInternetCompareUrl(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
395 IInternetProtocolInfo *protocol_info;
396 HRESULT hres;
398 TRACE("(%s,%s,%08lx)\n", debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
400 protocol_info = get_protocol_info(pwzUrl1);
402 if(protocol_info) {
403 hres = IInternetProtocolInfo_CompareUrl(protocol_info, pwzUrl1, pwzUrl2, dwCompareFlags);
404 IInternetProtocolInfo_Release(protocol_info);
405 if(SUCCEEDED(hres))
406 return hres;
409 return UrlCompareW(pwzUrl1, pwzUrl2, dwCompareFlags) ? S_FALSE : S_OK;
412 /***********************************************************************
413 * CoInternetQueryInfo (URLMON.@)
415 * Retrieves information relevant to a specified URL
418 HRESULT WINAPI CoInternetQueryInfo(LPCWSTR pwzUrl, QUERYOPTION QueryOption,
419 DWORD dwQueryFlags, LPVOID pvBuffer, DWORD cbBuffer, DWORD *pcbBuffer,
420 DWORD dwReserved)
422 IInternetProtocolInfo *protocol_info;
423 HRESULT hres;
425 TRACE("(%s, %x, %lx, %p, %lx, %p, %lx)\n", debugstr_w(pwzUrl),
426 QueryOption, dwQueryFlags, pvBuffer, cbBuffer, pcbBuffer, dwReserved);
428 protocol_info = get_protocol_info(pwzUrl);
430 if(protocol_info) {
431 hres = IInternetProtocolInfo_QueryInfo(protocol_info, pwzUrl, QueryOption, dwQueryFlags,
432 pvBuffer, cbBuffer, pcbBuffer, dwReserved);
433 IInternetProtocolInfo_Release(protocol_info);
435 return SUCCEEDED(hres) ? hres : E_FAIL;
438 switch(QueryOption) {
439 case QUERY_USES_NETWORK:
440 if(!pvBuffer || cbBuffer < sizeof(DWORD))
441 return E_FAIL;
443 *(DWORD*)pvBuffer = 0;
444 if(pcbBuffer)
445 *pcbBuffer = sizeof(DWORD);
446 break;
448 default:
449 FIXME("Not supported option %d\n", QueryOption);
450 return E_NOTIMPL;
453 return S_OK;
456 static void set_feature_on_process(INTERNETFEATURELIST feature, BOOL enable)
458 EnterCriticalSection(&process_features_cs);
460 process_feature_controls[feature].enabled = enable;
461 process_feature_controls[feature].check_registry = FALSE;
463 LeaveCriticalSection(&process_features_cs);
466 static HRESULT set_internet_feature(INTERNETFEATURELIST feature, DWORD flags, BOOL enable)
468 const DWORD supported_flags = SET_FEATURE_ON_PROCESS;
470 if(feature >= FEATURE_ENTRY_COUNT)
471 return E_FAIL;
473 if(flags & ~supported_flags)
474 FIXME("Unsupported flags: %08lx\n", flags & ~supported_flags);
476 if(flags & SET_FEATURE_ON_PROCESS)
477 set_feature_on_process(feature, enable);
479 return S_OK;
482 static BOOL get_feature_from_reg(HKEY feature_control, LPCWSTR feature_name, LPCWSTR process_name, BOOL *enabled)
484 DWORD type, value, size;
485 HKEY feature;
486 DWORD res;
488 res = RegOpenKeyW(feature_control, feature_name, &feature);
489 if(res != ERROR_SUCCESS)
490 return FALSE;
492 size = sizeof(DWORD);
493 res = RegQueryValueExW(feature, process_name, NULL, &type, (BYTE*)&value, &size);
494 if(res != ERROR_SUCCESS || type != REG_DWORD) {
495 size = sizeof(DWORD);
496 res = RegQueryValueExW(feature, L"*", NULL, &type, (BYTE*)&value, &size);
499 RegCloseKey(feature);
500 if(res != ERROR_SUCCESS)
501 return FALSE;
503 if(type != REG_DWORD) {
504 WARN("Unexpected registry value type %ld (expected REG_DWORD) for %s\n", type, debugstr_w(L"*"));
505 return FALSE;
508 *enabled = value == 1;
509 return TRUE;
512 /* Assumes 'process_features_cs' is held. */
513 static HRESULT load_process_feature(INTERNETFEATURELIST feature)
515 DWORD res;
516 HKEY feature_control;
517 WCHAR module_name[MAX_PATH];
518 LPCWSTR process_name, feature_name;
519 HRESULT hres = S_FALSE;
520 BOOL check_hklm = FALSE;
521 BOOL enabled;
523 if (!GetModuleFileNameW(NULL, module_name, ARRAY_SIZE(module_name))) {
524 ERR("Failed to get module file name: %lu\n", GetLastError());
525 return E_UNEXPECTED;
528 process_name = wcsrchr(module_name, '\\');
529 if(!process_name) {
530 ERR("Invalid module file name: %s\n", debugstr_w(module_name));
531 return E_UNEXPECTED;
534 /* Skip past the '\\' in front of the filename. */
535 ++process_name;
537 feature_name = process_feature_controls[feature].feature_name;
539 res = RegOpenKeyW(HKEY_CURRENT_USER, feature_control_keyW, &feature_control);
540 if(res == ERROR_SUCCESS) {
541 if(get_feature_from_reg(feature_control, feature_name, process_name, &enabled)) {
542 hres = enabled ? S_OK : S_FALSE;
543 process_feature_controls[feature].enabled = enabled;
544 } else
545 /* We didn't find anything in HKCU, so check HKLM. */
546 check_hklm = TRUE;
548 RegCloseKey(feature_control);
551 if(check_hklm) {
552 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, feature_control_keyW, &feature_control);
553 if(res == ERROR_SUCCESS) {
554 if(get_feature_from_reg(feature_control, feature_name, process_name, &enabled)) {
555 hres = enabled ? S_OK : S_FALSE;
556 process_feature_controls[feature].enabled = enabled;
558 RegCloseKey(feature_control);
562 /* Don't bother checking the registry again for this feature. */
563 process_feature_controls[feature].check_registry = FALSE;
565 return hres;
568 static HRESULT get_feature_from_process(INTERNETFEATURELIST feature)
570 HRESULT hres = S_OK;
572 EnterCriticalSection(&process_features_cs);
574 /* Try loading the feature from the registry, if it hasn't already
575 * been done.
577 if(process_feature_controls[feature].check_registry)
578 hres = load_process_feature(feature);
579 if(SUCCEEDED(hres))
580 hres = process_feature_controls[feature].enabled ? S_OK : S_FALSE;
582 LeaveCriticalSection(&process_features_cs);
584 return hres;
587 static HRESULT get_internet_feature(INTERNETFEATURELIST feature, DWORD flags)
589 HRESULT hres;
591 if(feature >= FEATURE_ENTRY_COUNT)
592 return E_FAIL;
594 if(flags == GET_FEATURE_FROM_PROCESS)
595 hres = get_feature_from_process(feature);
596 else {
597 FIXME("Unsupported flags: %08lx\n", flags);
598 hres = E_NOTIMPL;
601 return hres;
604 /***********************************************************************
605 * CoInternetSetFeatureEnabled (URLMON.@)
607 HRESULT WINAPI CoInternetSetFeatureEnabled(INTERNETFEATURELIST FeatureEntry, DWORD dwFlags, BOOL fEnable)
609 TRACE("(%d, %08lx, %x)\n", FeatureEntry, dwFlags, fEnable);
610 return set_internet_feature(FeatureEntry, dwFlags, fEnable);
613 /***********************************************************************
614 * CoInternetIsFeatureEnabled (URLMON.@)
616 HRESULT WINAPI CoInternetIsFeatureEnabled(INTERNETFEATURELIST FeatureEntry, DWORD dwFlags)
618 TRACE("(%d, %08lx)\n", FeatureEntry, dwFlags);
619 return get_internet_feature(FeatureEntry, dwFlags);
622 /***********************************************************************
623 * CoInternetIsFeatureEnabledForUrl (URLMON.@)
625 HRESULT WINAPI CoInternetIsFeatureEnabledForUrl(INTERNETFEATURELIST FeatureEntry, DWORD dwFlags, LPCWSTR szURL,
626 IInternetSecurityManager *pSecMgr)
628 DWORD urlaction = 0;
629 HRESULT hres;
631 TRACE("(%d %08lx %s %p)\n", FeatureEntry, dwFlags, debugstr_w(szURL), pSecMgr);
633 if(FeatureEntry == FEATURE_MIME_SNIFFING)
634 urlaction = URLACTION_FEATURE_MIME_SNIFFING;
635 else if(FeatureEntry == FEATURE_WINDOW_RESTRICTIONS)
636 urlaction = URLACTION_FEATURE_WINDOW_RESTRICTIONS;
637 else if(FeatureEntry == FEATURE_ZONE_ELEVATION)
638 urlaction = URLACTION_FEATURE_ZONE_ELEVATION;
640 if(!szURL || !urlaction || !pSecMgr)
641 return CoInternetIsFeatureEnabled(FeatureEntry, dwFlags);
643 switch(dwFlags) {
644 case GET_FEATURE_FROM_THREAD:
645 case GET_FEATURE_FROM_THREAD_LOCALMACHINE:
646 case GET_FEATURE_FROM_THREAD_INTRANET:
647 case GET_FEATURE_FROM_THREAD_TRUSTED:
648 case GET_FEATURE_FROM_THREAD_INTERNET:
649 case GET_FEATURE_FROM_THREAD_RESTRICTED:
650 FIXME("unsupported flags %lx\n", dwFlags);
651 return E_NOTIMPL;
653 case GET_FEATURE_FROM_PROCESS:
654 hres = CoInternetIsFeatureEnabled(FeatureEntry, dwFlags);
655 if(hres != S_OK)
656 return hres;
657 /* fall through */
659 default: {
660 DWORD policy = URLPOLICY_DISALLOW;
662 hres = IInternetSecurityManager_ProcessUrlAction(pSecMgr, szURL, urlaction,
663 (BYTE*)&policy, sizeof(DWORD), NULL, 0, PUAF_NOUI, 0);
664 if(hres!=S_OK || policy!=URLPOLICY_ALLOW)
665 return S_OK;
666 return S_FALSE;
671 /***********************************************************************
672 * CoInternetIsFeatureZoneElevationEnabled (URLMON.@)
674 HRESULT WINAPI CoInternetIsFeatureZoneElevationEnabled(LPCWSTR szFromURL, LPCWSTR szToURL,
675 IInternetSecurityManager *pSecMgr, DWORD dwFlags)
677 HRESULT hres;
679 TRACE("(%s %s %p %lx)\n", debugstr_w(szFromURL), debugstr_w(szToURL), pSecMgr, dwFlags);
681 if(!pSecMgr || !szToURL)
682 return CoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, dwFlags);
684 switch(dwFlags) {
685 case GET_FEATURE_FROM_THREAD:
686 case GET_FEATURE_FROM_THREAD_LOCALMACHINE:
687 case GET_FEATURE_FROM_THREAD_INTRANET:
688 case GET_FEATURE_FROM_THREAD_TRUSTED:
689 case GET_FEATURE_FROM_THREAD_INTERNET:
690 case GET_FEATURE_FROM_THREAD_RESTRICTED:
691 FIXME("unsupported flags %lx\n", dwFlags);
692 return E_NOTIMPL;
694 case GET_FEATURE_FROM_PROCESS:
695 hres = CoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, dwFlags);
696 if(hres != S_OK)
697 return hres;
698 /* fall through */
700 default: {
701 DWORD policy = URLPOLICY_DISALLOW;
703 hres = IInternetSecurityManager_ProcessUrlAction(pSecMgr, szToURL,
704 URLACTION_FEATURE_ZONE_ELEVATION, (BYTE*)&policy, sizeof(DWORD),
705 NULL, 0, PUAF_NOUI, 0);
706 if(FAILED(hres))
707 return S_OK;
709 switch(policy) {
710 case URLPOLICY_ALLOW:
711 return S_FALSE;
712 case URLPOLICY_QUERY:
713 FIXME("Ask user dialog not implemented\n");
714 default:
715 return S_OK;