2 * Internet Security and Zone Manager
4 * Copyright (c) 2004 Huw D M Davies
5 * Copyright 2004 Jacek Caban
6 * Copyright 2009 Detlef Riekenberg
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "urlmon_main.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
33 static const WCHAR currentlevelW[] = {'C','u','r','r','e','n','t','L','e','v','e','l',0};
34 static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
35 static const WCHAR displaynameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
36 static const WCHAR fileW[] = {'f','i','l','e',0};
37 static const WCHAR flagsW[] = {'F','l','a','g','s',0};
38 static const WCHAR iconW[] = {'I','c','o','n',0};
39 static const WCHAR minlevelW[] = {'M','i','n','L','e','v','e','l',0};
40 static const WCHAR recommendedlevelW[] = {'R','e','c','o','m','m','e','n','d','e','d',
41 'L','e','v','e','l',0};
42 static const WCHAR wszZonesKey[] = {'S','o','f','t','w','a','r','e','\\',
43 'M','i','c','r','o','s','o','f','t','\\',
44 'W','i','n','d','o','w','s','\\',
45 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
46 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
47 'Z','o','n','e','s','\\',0};
49 /********************************************************************
50 * get_string_from_reg [internal]
52 * helper to get a string from the reg.
55 static void get_string_from_reg(HKEY hcu, HKEY hklm, LPCWSTR name, LPWSTR out, DWORD maxlen)
58 DWORD len = maxlen * sizeof(WCHAR);
61 res = RegQueryValueExW(hcu, name, NULL, &type, (LPBYTE) out, &len);
64 len = maxlen * sizeof(WCHAR);
66 res = RegQueryValueExW(hklm, name, NULL, &type, (LPBYTE) out, &len);
70 TRACE("%s failed: %d\n", debugstr_w(name), res);
75 /********************************************************************
76 * get_dword_from_reg [internal]
78 * helper to get a dword from the reg.
81 static void get_dword_from_reg(HKEY hcu, HKEY hklm, LPCWSTR name, LPDWORD out)
83 DWORD type = REG_DWORD;
84 DWORD len = sizeof(DWORD);
87 res = RegQueryValueExW(hcu, name, NULL, &type, (LPBYTE) out, &len);
92 res = RegQueryValueExW(hklm, name, NULL, &type, (LPBYTE) out, &len);
96 TRACE("%s failed: %d\n", debugstr_w(name), res);
101 static HRESULT get_zone_from_reg(LPCWSTR schema, DWORD *zone)
106 static const WCHAR wszZoneMapProtocolKey[] =
107 {'S','o','f','t','w','a','r','e','\\',
108 'M','i','c','r','o','s','o','f','t','\\',
109 'W','i','n','d','o','w','s','\\',
110 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
111 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
112 'Z','o','n','e','M','a','p','\\',
113 'P','r','o','t','o','c','o','l','D','e','f','a','u','l','t','s',0};
115 res = RegOpenKeyW(HKEY_CURRENT_USER, wszZoneMapProtocolKey, &hkey);
116 if(res != ERROR_SUCCESS) {
117 ERR("Could not open key %s\n", debugstr_w(wszZoneMapProtocolKey));
121 size = sizeof(DWORD);
122 res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size);
124 if(res == ERROR_SUCCESS)
127 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszZoneMapProtocolKey, &hkey);
128 if(res != ERROR_SUCCESS) {
129 ERR("Could not open key %s\n", debugstr_w(wszZoneMapProtocolKey));
133 size = sizeof(DWORD);
134 res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size);
136 if(res == ERROR_SUCCESS)
143 static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone, LPWSTR *ret_url)
152 hres = CoInternetGetSecurityUrl(url, &secur_url, PSU_SECURITY_URL_ONLY, 0);
154 size = strlenW(url)*sizeof(WCHAR);
156 secur_url = heap_alloc(size);
158 return E_OUTOFMEMORY;
160 memcpy(secur_url, url, size);
163 hres = CoInternetParseUrl(secur_url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(WCHAR), &size, 0);
164 if(FAILED(hres) || !*schema) {
165 heap_free(secur_url);
169 /* file protocol is a special case */
170 if(!strcmpW(schema, fileW)) {
171 WCHAR path[MAX_PATH], root[20];
174 hres = CoInternetParseUrl(secur_url, PARSE_PATH_FROM_URL, 0, path,
175 sizeof(path)/sizeof(WCHAR), &size, 0);
177 if(SUCCEEDED(hres) && (ptr = strchrW(path, '\\')) && ptr-path < sizeof(root)/sizeof(WCHAR)) {
180 memcpy(root, path, (ptr-path)*sizeof(WCHAR));
183 type = GetDriveTypeW(root);
187 case DRIVE_NO_ROOT_DIR:
189 case DRIVE_REMOVABLE:
201 FIXME("unsupported drive type %d\n", type);
207 WARN("domains are not yet implemented\n");
208 hres = get_zone_from_reg(schema, zone);
211 if(FAILED(hres) || !ret_url)
212 heap_free(secur_url);
214 *ret_url = secur_url;
219 static HRESULT open_zone_key(HKEY parent_key, DWORD zone, HKEY *hkey)
221 static const WCHAR wszFormat[] = {'%','s','%','l','d',0};
223 WCHAR key_name[sizeof(wszZonesKey)/sizeof(WCHAR)+8];
226 wsprintfW(key_name, wszFormat, wszZonesKey, zone);
228 res = RegOpenKeyW(parent_key, key_name, hkey);
230 if(res != ERROR_SUCCESS) {
231 WARN("RegOpenKey failed\n");
238 static HRESULT get_action_policy(DWORD zone, DWORD action, BYTE *policy, DWORD size, URLZONEREG zone_reg)
246 case URLACTION_SCRIPT_OVERRIDE_SAFETY:
247 case URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY:
248 *(DWORD*)policy = URLPOLICY_DISALLOW;
253 case URLZONEREG_DEFAULT:
254 case URLZONEREG_HKCU:
255 parent_key = HKEY_CURRENT_USER;
257 case URLZONEREG_HKLM:
258 parent_key = HKEY_LOCAL_MACHINE;
261 WARN("Unknown URLZONEREG: %d\n", zone_reg);
265 hres = open_zone_key(parent_key, zone, &hkey);
266 if(SUCCEEDED(hres)) {
267 WCHAR action_str[16];
270 static const WCHAR formatW[] = {'%','X',0};
272 wsprintfW(action_str, formatW, action);
274 res = RegQueryValueExW(hkey, action_str, NULL, NULL, policy, &len);
275 if(res == ERROR_MORE_DATA) {
277 }else if(res == ERROR_FILE_NOT_FOUND) {
279 }else if(res != ERROR_SUCCESS) {
280 ERR("RegQueryValue failed: %d\n", res);
287 if(FAILED(hres) && zone_reg == URLZONEREG_DEFAULT)
288 return get_action_policy(zone, action, policy, size, URLZONEREG_HKLM);
293 /***********************************************************************
294 * InternetSecurityManager implementation
298 IInternetSecurityManager IInternetSecurityManager_iface;
302 IInternetSecurityMgrSite *mgrsite;
303 IInternetSecurityManager *custom_manager;
306 static inline SecManagerImpl *impl_from_IInternetSecurityManager(IInternetSecurityManager *iface)
308 return CONTAINING_RECORD(iface, SecManagerImpl, IInternetSecurityManager_iface);
311 static HRESULT WINAPI SecManagerImpl_QueryInterface(IInternetSecurityManager* iface,REFIID riid,void** ppvObject)
313 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
315 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject);
317 /* Perform a sanity check on the parameters.*/
318 if ( (This==0) || (ppvObject==0) )
321 /* Initialize the return parameter */
324 /* Compare the riid with the interface IDs implemented by this object.*/
325 if (IsEqualIID(&IID_IUnknown, riid) ||
326 IsEqualIID(&IID_IInternetSecurityManager, riid))
329 /* Check that we obtained an interface.*/
331 WARN("not supported interface %s\n", debugstr_guid(riid));
332 return E_NOINTERFACE;
335 /* Query Interface always increases the reference count by one when it is successful */
336 IInternetSecurityManager_AddRef(iface);
341 static ULONG WINAPI SecManagerImpl_AddRef(IInternetSecurityManager* iface)
343 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
344 ULONG refCount = InterlockedIncrement(&This->ref);
346 TRACE("(%p) ref=%u\n", This, refCount);
351 static ULONG WINAPI SecManagerImpl_Release(IInternetSecurityManager* iface)
353 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
354 ULONG refCount = InterlockedDecrement(&This->ref);
356 TRACE("(%p) ref=%u\n", This, refCount);
358 /* destroy the object if there's no more reference on it */
361 IInternetSecurityMgrSite_Release(This->mgrsite);
362 if(This->custom_manager)
363 IInternetSecurityManager_Release(This->custom_manager);
367 URLMON_UnlockModule();
373 static HRESULT WINAPI SecManagerImpl_SetSecuritySite(IInternetSecurityManager *iface,
374 IInternetSecurityMgrSite *pSite)
376 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
378 TRACE("(%p)->(%p)\n", This, pSite);
381 IInternetSecurityMgrSite_Release(This->mgrsite);
383 if(This->custom_manager) {
384 IInternetSecurityManager_Release(This->custom_manager);
385 This->custom_manager = NULL;
388 This->mgrsite = pSite;
391 IServiceProvider *servprov;
394 IInternetSecurityMgrSite_AddRef(pSite);
396 hres = IInternetSecurityMgrSite_QueryInterface(pSite, &IID_IServiceProvider,
398 if(SUCCEEDED(hres)) {
399 IServiceProvider_QueryService(servprov, &SID_SInternetSecurityManager,
400 &IID_IInternetSecurityManager, (void**)&This->custom_manager);
401 IServiceProvider_Release(servprov);
408 static HRESULT WINAPI SecManagerImpl_GetSecuritySite(IInternetSecurityManager *iface,
409 IInternetSecurityMgrSite **ppSite)
411 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
413 TRACE("(%p)->(%p)\n", This, ppSite);
419 IInternetSecurityMgrSite_AddRef(This->mgrsite);
421 *ppSite = This->mgrsite;
425 static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManager *iface,
426 LPCWSTR pwszUrl, DWORD *pdwZone,
429 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
432 TRACE("(%p)->(%s %p %08x)\n", iface, debugstr_w(pwszUrl), pdwZone, dwFlags);
434 if(This->custom_manager) {
435 hres = IInternetSecurityManager_MapUrlToZone(This->custom_manager,
436 pwszUrl, pdwZone, dwFlags);
437 if(hres != INET_E_DEFAULT_ACTION)
447 FIXME("not supported flags: %08x\n", dwFlags);
449 return map_url_to_zone(pwszUrl, pdwZone, NULL);
452 static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *iface,
453 LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
455 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
456 LPWSTR url, ptr, ptr2;
460 static const WCHAR wszFile[] = {'f','i','l','e',':'};
462 TRACE("(%p)->(%s %p %p %08lx)\n", iface, debugstr_w(pwszUrl), pbSecurityId,
463 pcbSecurityId, dwReserved);
465 if(This->custom_manager) {
466 hres = IInternetSecurityManager_GetSecurityId(This->custom_manager,
467 pwszUrl, pbSecurityId, pcbSecurityId, dwReserved);
468 if(hres != INET_E_DEFAULT_ACTION)
472 if(!pwszUrl || !pbSecurityId || !pcbSecurityId)
476 FIXME("dwReserved is not supported\n");
478 hres = map_url_to_zone(pwszUrl, &zone, &url);
480 return hres == 0x80041001 ? E_INVALIDARG : hres;
482 /* file protocol is a special case */
483 if(strlenW(url) >= sizeof(wszFile)/sizeof(WCHAR)
484 && !memcmp(url, wszFile, sizeof(wszFile)) && strchrW(url, '\\')) {
486 static const BYTE secidFile[] = {'f','i','l','e',':'};
490 if(*pcbSecurityId < sizeof(secidFile)+sizeof(zone))
491 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
493 memcpy(pbSecurityId, secidFile, sizeof(secidFile));
494 *(DWORD*)(pbSecurityId+sizeof(secidFile)) = zone;
496 *pcbSecurityId = sizeof(secidFile)+sizeof(zone);
500 ptr = strchrW(url, ':');
505 memmove(ptr, ptr2, (strlenW(ptr2)+1)*sizeof(WCHAR));
507 ptr = strchrW(ptr, '/');
511 len = WideCharToMultiByte(CP_ACP, 0, url, -1, NULL, 0, NULL, NULL)-1;
513 if(len+sizeof(DWORD) > *pcbSecurityId) {
515 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
518 WideCharToMultiByte(CP_ACP, 0, url, -1, (LPSTR)pbSecurityId, len, NULL, NULL);
521 *(DWORD*)(pbSecurityId+len) = zone;
523 *pcbSecurityId = len+sizeof(DWORD);
529 static HRESULT WINAPI SecManagerImpl_ProcessUrlAction(IInternetSecurityManager *iface,
530 LPCWSTR pwszUrl, DWORD dwAction,
531 BYTE *pPolicy, DWORD cbPolicy,
532 BYTE *pContext, DWORD cbContext,
533 DWORD dwFlags, DWORD dwReserved)
535 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
539 TRACE("(%p)->(%s %08x %p %08x %p %08x %08x %08x)\n", iface, debugstr_w(pwszUrl), dwAction,
540 pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved);
542 if(This->custom_manager) {
543 hres = IInternetSecurityManager_ProcessUrlAction(This->custom_manager, pwszUrl, dwAction,
544 pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved);
545 if(hres != INET_E_DEFAULT_ACTION)
549 if(dwFlags || dwReserved)
550 FIXME("Unsupported arguments\n");
555 hres = map_url_to_zone(pwszUrl, &zone, NULL);
559 hres = get_action_policy(zone, dwAction, (BYTE*)&policy, sizeof(policy), URLZONEREG_DEFAULT);
563 TRACE("policy %x\n", policy);
564 if(cbPolicy >= sizeof(DWORD))
565 *(DWORD*)pPolicy = policy;
567 switch(GetUrlPolicyPermissions(policy)) {
568 case URLPOLICY_ALLOW:
569 case URLPOLICY_CHANNEL_SOFTDIST_PRECACHE:
571 case URLPOLICY_DISALLOW:
573 case URLPOLICY_QUERY:
574 FIXME("URLPOLICY_QUERY not implemented\n");
577 FIXME("Not implemented policy %x\n", policy);
584 static HRESULT WINAPI SecManagerImpl_QueryCustomPolicy(IInternetSecurityManager *iface,
585 LPCWSTR pwszUrl, REFGUID guidKey,
586 BYTE **ppPolicy, DWORD *pcbPolicy,
587 BYTE *pContext, DWORD cbContext,
590 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
593 TRACE("(%p)->(%s %s %p %p %p %08x %08x )\n", iface, debugstr_w(pwszUrl), debugstr_guid(guidKey),
594 ppPolicy, pcbPolicy, pContext, cbContext, dwReserved);
596 if(This->custom_manager) {
597 hres = IInternetSecurityManager_QueryCustomPolicy(This->custom_manager, pwszUrl, guidKey,
598 ppPolicy, pcbPolicy, pContext, cbContext, dwReserved);
599 if(hres != INET_E_DEFAULT_ACTION)
603 WARN("Unknown guidKey %s\n", debugstr_guid(guidKey));
604 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
607 static HRESULT WINAPI SecManagerImpl_SetZoneMapping(IInternetSecurityManager *iface,
608 DWORD dwZone, LPCWSTR pwszPattern, DWORD dwFlags)
610 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
613 TRACE("(%p)->(%08x %s %08x)\n", iface, dwZone, debugstr_w(pwszPattern),dwFlags);
615 if(This->custom_manager) {
616 hres = IInternetSecurityManager_SetZoneMapping(This->custom_manager, dwZone,
617 pwszPattern, dwFlags);
618 if(hres != INET_E_DEFAULT_ACTION)
622 FIXME("Default action is not implemented\n");
626 static HRESULT WINAPI SecManagerImpl_GetZoneMappings(IInternetSecurityManager *iface,
627 DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags)
629 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
632 TRACE("(%p)->(%08x %p %08x)\n", iface, dwZone, ppenumString,dwFlags);
634 if(This->custom_manager) {
635 hres = IInternetSecurityManager_GetZoneMappings(This->custom_manager, dwZone,
636 ppenumString, dwFlags);
637 if(hres != INET_E_DEFAULT_ACTION)
641 FIXME("Default action is not implemented\n");
645 static const IInternetSecurityManagerVtbl VT_SecManagerImpl =
647 SecManagerImpl_QueryInterface,
648 SecManagerImpl_AddRef,
649 SecManagerImpl_Release,
650 SecManagerImpl_SetSecuritySite,
651 SecManagerImpl_GetSecuritySite,
652 SecManagerImpl_MapUrlToZone,
653 SecManagerImpl_GetSecurityId,
654 SecManagerImpl_ProcessUrlAction,
655 SecManagerImpl_QueryCustomPolicy,
656 SecManagerImpl_SetZoneMapping,
657 SecManagerImpl_GetZoneMappings
660 HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
662 SecManagerImpl *This;
664 TRACE("(%p,%p)\n",pUnkOuter,ppobj);
665 This = heap_alloc(sizeof(*This));
667 /* Initialize the virtual function table. */
668 This->IInternetSecurityManager_iface.lpVtbl = &VT_SecManagerImpl;
671 This->mgrsite = NULL;
672 This->custom_manager = NULL;
681 /***********************************************************************
682 * InternetZoneManager implementation
686 IInternetZoneManagerEx2 IInternetZoneManagerEx2_iface;
692 static inline ZoneMgrImpl *impl_from_IInternetZoneManagerEx2(IInternetZoneManagerEx2 *iface)
694 return CONTAINING_RECORD(iface, ZoneMgrImpl, IInternetZoneManagerEx2_iface);
698 /***********************************************************************
699 * build_zonemap_from_reg [internal]
701 * Enumerate the Zones in the Registry and return the Zones in a DWORD-array
702 * The number of the Zones is returned in data[0]
704 static LPDWORD build_zonemap_from_reg(void)
709 DWORD allocated = 6; /* space for the zonecount and Zone "0" up to Zone "4" */
715 res = RegOpenKeyW(HKEY_CURRENT_USER, wszZonesKey, &hkey);
719 data = heap_alloc(allocated * sizeof(DWORD));
725 len = sizeof(name) / sizeof(name[0]);
726 res = RegEnumKeyExW(hkey, used, name, &len, NULL, NULL, NULL, NULL);
730 if (used == allocated) {
734 new_data = heap_realloc_zero(data, allocated * sizeof(DWORD));
740 data[used] = atoiW(name);
750 /* something failed */
756 /********************************************************************
757 * IInternetZoneManager_QueryInterface
759 static HRESULT WINAPI ZoneMgrImpl_QueryInterface(IInternetZoneManagerEx2* iface, REFIID riid, void** ppvObject)
761 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
763 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppvObject);
765 if(!This || !ppvObject)
768 if(IsEqualIID(&IID_IUnknown, riid)) {
769 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppvObject);
770 }else if(IsEqualIID(&IID_IInternetZoneManager, riid)) {
771 TRACE("(%p)->(IID_InternetZoneManager %p)\n", This, ppvObject);
772 }else if(IsEqualIID(&IID_IInternetZoneManagerEx, riid)) {
773 TRACE("(%p)->(IID_InternetZoneManagerEx %p)\n", This, ppvObject);
774 }else if(IsEqualIID(&IID_IInternetZoneManagerEx2, riid)) {
775 TRACE("(%p)->(IID_InternetZoneManagerEx2 %p)\n", This, ppvObject);
779 FIXME("Unknown interface: %s\n", debugstr_guid(riid));
781 return E_NOINTERFACE;
785 IInternetZoneManager_AddRef(iface);
789 /********************************************************************
790 * IInternetZoneManager_AddRef
792 static ULONG WINAPI ZoneMgrImpl_AddRef(IInternetZoneManagerEx2* iface)
794 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
795 ULONG refCount = InterlockedIncrement(&This->ref);
797 TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);
802 /********************************************************************
803 * IInternetZoneManager_Release
805 static ULONG WINAPI ZoneMgrImpl_Release(IInternetZoneManagerEx2* iface)
807 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
808 ULONG refCount = InterlockedDecrement(&This->ref);
810 TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);
813 while (This->zonemap_count) heap_free(This->zonemaps[--This->zonemap_count]);
814 heap_free(This->zonemaps);
816 URLMON_UnlockModule();
822 /********************************************************************
823 * IInternetZoneManager_GetZoneAttributes
825 static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributes(IInternetZoneManagerEx2* iface,
827 ZONEATTRIBUTES* pZoneAttributes)
829 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
834 TRACE("(%p)->(%d %p)\n", This, dwZone, pZoneAttributes);
836 if (!pZoneAttributes)
839 hr = open_zone_key(HKEY_CURRENT_USER, dwZone, &hcu);
841 return S_OK; /* IE6 and older returned E_FAIL here */
843 hr = open_zone_key(HKEY_LOCAL_MACHINE, dwZone, &hklm);
845 TRACE("Zone %d not in HKLM\n", dwZone);
847 get_string_from_reg(hcu, hklm, displaynameW, pZoneAttributes->szDisplayName, MAX_ZONE_PATH);
848 get_string_from_reg(hcu, hklm, descriptionW, pZoneAttributes->szDescription, MAX_ZONE_DESCRIPTION);
849 get_string_from_reg(hcu, hklm, iconW, pZoneAttributes->szIconPath, MAX_ZONE_PATH);
850 get_dword_from_reg(hcu, hklm, minlevelW, &pZoneAttributes->dwTemplateMinLevel);
851 get_dword_from_reg(hcu, hklm, currentlevelW, &pZoneAttributes->dwTemplateCurrentLevel);
852 get_dword_from_reg(hcu, hklm, recommendedlevelW, &pZoneAttributes->dwTemplateRecommended);
853 get_dword_from_reg(hcu, hklm, flagsW, &pZoneAttributes->dwFlags);
860 /********************************************************************
861 * IInternetZoneManager_SetZoneAttributes
863 static HRESULT WINAPI ZoneMgrImpl_SetZoneAttributes(IInternetZoneManagerEx2* iface,
865 ZONEATTRIBUTES* pZoneAttributes)
867 FIXME("(%p)->(%08x %p) stub\n", iface, dwZone, pZoneAttributes);
871 /********************************************************************
872 * IInternetZoneManager_GetZoneCustomPolicy
874 static HRESULT WINAPI ZoneMgrImpl_GetZoneCustomPolicy(IInternetZoneManagerEx2* iface,
879 URLZONEREG ulrZoneReg)
881 FIXME("(%p)->(%08x %s %p %p %08x) stub\n", iface, dwZone, debugstr_guid(guidKey),
882 ppPolicy, pcbPolicy, ulrZoneReg);
886 /********************************************************************
887 * IInternetZoneManager_SetZoneCustomPolicy
889 static HRESULT WINAPI ZoneMgrImpl_SetZoneCustomPolicy(IInternetZoneManagerEx2* iface,
894 URLZONEREG ulrZoneReg)
896 FIXME("(%p)->(%08x %s %p %08x %08x) stub\n", iface, dwZone, debugstr_guid(guidKey),
897 ppPolicy, cbPolicy, ulrZoneReg);
901 /********************************************************************
902 * IInternetZoneManager_GetZoneActionPolicy
904 static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicy(IInternetZoneManagerEx2* iface,
905 DWORD dwZone, DWORD dwAction, BYTE* pPolicy, DWORD cbPolicy, URLZONEREG urlZoneReg)
907 TRACE("(%p)->(%d %08x %p %d %d)\n", iface, dwZone, dwAction, pPolicy,
908 cbPolicy, urlZoneReg);
913 return get_action_policy(dwZone, dwAction, pPolicy, cbPolicy, urlZoneReg);
916 /********************************************************************
917 * IInternetZoneManager_SetZoneActionPolicy
919 static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicy(IInternetZoneManagerEx2* iface,
924 URLZONEREG urlZoneReg)
926 FIXME("(%p)->(%08x %08x %p %08x %08x) stub\n", iface, dwZone, dwAction, pPolicy,
927 cbPolicy, urlZoneReg);
931 /********************************************************************
932 * IInternetZoneManager_PromptAction
934 static HRESULT WINAPI ZoneMgrImpl_PromptAction(IInternetZoneManagerEx2* iface,
941 FIXME("%p %08x %p %s %s %08x\n", iface, dwAction, hwndParent,
942 debugstr_w(pwszUrl), debugstr_w(pwszText), dwPromptFlags );
946 /********************************************************************
947 * IInternetZoneManager_LogAction
949 static HRESULT WINAPI ZoneMgrImpl_LogAction(IInternetZoneManagerEx2* iface,
955 FIXME("(%p)->(%08x %s %s %08x) stub\n", iface, dwAction, debugstr_w(pwszUrl),
956 debugstr_w(pwszText), dwLogFlags);
960 /********************************************************************
961 * IInternetZoneManager_CreateZoneEnumerator
963 static HRESULT WINAPI ZoneMgrImpl_CreateZoneEnumerator(IInternetZoneManagerEx2* iface,
968 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
973 TRACE("(%p)->(%p, %p, 0x%08x)\n", This, pdwEnum, pdwCount, dwFlags);
974 if (!pdwEnum || !pdwCount || (dwFlags != 0))
977 data = build_zonemap_from_reg();
978 TRACE("found %d zones\n", data ? data[0] : -1);
983 for (i = 0; i < This->zonemap_count; i++) {
984 if (This->zonemaps && !This->zonemaps[i]) {
985 This->zonemaps[i] = data;
992 if (This->zonemaps) {
993 /* try to double the nr. of pointers in the array */
994 new_maps = heap_realloc_zero(This->zonemaps, This->zonemap_count * 2 * sizeof(LPDWORD));
996 This->zonemap_count *= 2;
1000 This->zonemap_count = 2;
1001 new_maps = heap_alloc_zero(This->zonemap_count * sizeof(LPDWORD));
1008 This->zonemaps = new_maps;
1009 This->zonemaps[i] = data;
1011 *pdwCount = data[0];
1015 /********************************************************************
1016 * IInternetZoneManager_GetZoneAt
1018 static HRESULT WINAPI ZoneMgrImpl_GetZoneAt(IInternetZoneManagerEx2* iface,
1023 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
1026 TRACE("(%p)->(0x%08x, %d, %p)\n", This, dwEnum, dwIndex, pdwZone);
1028 /* make sure, that dwEnum and dwIndex are in the valid range */
1029 if (dwEnum < This->zonemap_count) {
1030 if ((data = This->zonemaps[dwEnum])) {
1031 if (dwIndex < data[0]) {
1032 *pdwZone = data[dwIndex + 1];
1037 return E_INVALIDARG;
1040 /********************************************************************
1041 * IInternetZoneManager_DestroyZoneEnumerator
1043 static HRESULT WINAPI ZoneMgrImpl_DestroyZoneEnumerator(IInternetZoneManagerEx2* iface,
1046 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
1049 TRACE("(%p)->(0x%08x)\n", This, dwEnum);
1050 /* make sure, that dwEnum is valid */
1051 if (dwEnum < This->zonemap_count) {
1052 if ((data = This->zonemaps[dwEnum])) {
1053 This->zonemaps[dwEnum] = NULL;
1058 return E_INVALIDARG;
1061 /********************************************************************
1062 * IInternetZoneManager_CopyTemplatePoliciesToZone
1064 static HRESULT WINAPI ZoneMgrImpl_CopyTemplatePoliciesToZone(IInternetZoneManagerEx2* iface,
1069 FIXME("(%p)->(%08x %08x %08x) stub\n", iface, dwTemplate, dwZone, dwReserved);
1073 /********************************************************************
1074 * IInternetZoneManagerEx_GetZoneActionPolicyEx
1076 static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicyEx(IInternetZoneManagerEx2* iface,
1081 URLZONEREG urlZoneReg,
1084 TRACE("(%p)->(%d, 0x%x, %p, %d, %d, 0x%x)\n", iface, dwZone,
1085 dwAction, pPolicy, cbPolicy, urlZoneReg, dwFlags);
1088 return E_INVALIDARG;
1091 FIXME("dwFlags 0x%x ignored\n", dwFlags);
1093 return get_action_policy(dwZone, dwAction, pPolicy, cbPolicy, urlZoneReg);
1096 /********************************************************************
1097 * IInternetZoneManagerEx_SetZoneActionPolicyEx
1099 static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicyEx(IInternetZoneManagerEx2* iface,
1104 URLZONEREG urlZoneReg,
1107 FIXME("(%p)->(%d, 0x%x, %p, %d, %d, 0x%x) stub\n", iface, dwZone, dwAction, pPolicy,
1108 cbPolicy, urlZoneReg, dwFlags);
1112 /********************************************************************
1113 * IInternetZoneManagerEx2_GetZoneAttributesEx
1115 static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributesEx(IInternetZoneManagerEx2* iface,
1117 ZONEATTRIBUTES* pZoneAttributes,
1120 TRACE("(%p)->(%d, %p, 0x%x)\n", iface, dwZone, pZoneAttributes, dwFlags);
1123 FIXME("dwFlags 0x%x ignored\n", dwFlags);
1125 return IInternetZoneManager_GetZoneAttributes(iface, dwZone, pZoneAttributes);
1129 /********************************************************************
1130 * IInternetZoneManagerEx2_GetZoneSecurityState
1132 static HRESULT WINAPI ZoneMgrImpl_GetZoneSecurityState(IInternetZoneManagerEx2* iface,
1134 BOOL fRespectPolicy,
1136 BOOL *pfPolicyEncountered)
1138 FIXME("(%p)->(%d, %d, %p, %p) stub\n", iface, dwZoneIndex, fRespectPolicy,
1139 pdwState, pfPolicyEncountered);
1141 *pdwState = SECURITY_IE_STATE_GREEN;
1143 if (pfPolicyEncountered)
1144 *pfPolicyEncountered = FALSE;
1149 /********************************************************************
1150 * IInternetZoneManagerEx2_GetIESecurityState
1152 static HRESULT WINAPI ZoneMgrImpl_GetIESecurityState(IInternetZoneManagerEx2* iface,
1153 BOOL fRespectPolicy,
1155 BOOL *pfPolicyEncountered,
1158 FIXME("(%p)->(%d, %p, %p, %d) stub\n", iface, fRespectPolicy, pdwState,
1159 pfPolicyEncountered, fNoCache);
1161 *pdwState = SECURITY_IE_STATE_GREEN;
1163 if (pfPolicyEncountered)
1164 *pfPolicyEncountered = FALSE;
1169 /********************************************************************
1170 * IInternetZoneManagerEx2_FixInsecureSettings
1172 static HRESULT WINAPI ZoneMgrImpl_FixInsecureSettings(IInternetZoneManagerEx2* iface)
1174 FIXME("(%p) stub\n", iface);
1178 /********************************************************************
1179 * IInternetZoneManager_Construct
1181 static const IInternetZoneManagerEx2Vtbl ZoneMgrImplVtbl = {
1182 ZoneMgrImpl_QueryInterface,
1184 ZoneMgrImpl_Release,
1185 /* IInternetZoneManager */
1186 ZoneMgrImpl_GetZoneAttributes,
1187 ZoneMgrImpl_SetZoneAttributes,
1188 ZoneMgrImpl_GetZoneCustomPolicy,
1189 ZoneMgrImpl_SetZoneCustomPolicy,
1190 ZoneMgrImpl_GetZoneActionPolicy,
1191 ZoneMgrImpl_SetZoneActionPolicy,
1192 ZoneMgrImpl_PromptAction,
1193 ZoneMgrImpl_LogAction,
1194 ZoneMgrImpl_CreateZoneEnumerator,
1195 ZoneMgrImpl_GetZoneAt,
1196 ZoneMgrImpl_DestroyZoneEnumerator,
1197 ZoneMgrImpl_CopyTemplatePoliciesToZone,
1198 /* IInternetZoneManagerEx */
1199 ZoneMgrImpl_GetZoneActionPolicyEx,
1200 ZoneMgrImpl_SetZoneActionPolicyEx,
1201 /* IInternetZoneManagerEx2 */
1202 ZoneMgrImpl_GetZoneAttributesEx,
1203 ZoneMgrImpl_GetZoneSecurityState,
1204 ZoneMgrImpl_GetIESecurityState,
1205 ZoneMgrImpl_FixInsecureSettings,
1208 HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
1210 ZoneMgrImpl* ret = heap_alloc_zero(sizeof(ZoneMgrImpl));
1212 TRACE("(%p %p)\n", pUnkOuter, ppobj);
1213 ret->IInternetZoneManagerEx2_iface.lpVtbl = &ZoneMgrImplVtbl;
1215 *ppobj = (IInternetZoneManagerEx*)ret;
1217 URLMON_LockModule();
1222 /***********************************************************************
1223 * CoInternetCreateSecurityManager (URLMON.@)
1226 HRESULT WINAPI CoInternetCreateSecurityManager( IServiceProvider *pSP,
1227 IInternetSecurityManager **ppSM, DWORD dwReserved )
1229 TRACE("%p %p %d\n", pSP, ppSM, dwReserved );
1232 FIXME("pSP not supported\n");
1234 return SecManagerImpl_Construct(NULL, (void**) ppSM);
1237 /********************************************************************
1238 * CoInternetCreateZoneManager (URLMON.@)
1240 HRESULT WINAPI CoInternetCreateZoneManager(IServiceProvider* pSP, IInternetZoneManager** ppZM, DWORD dwReserved)
1242 TRACE("(%p %p %x)\n", pSP, ppZM, dwReserved);
1243 return ZoneMgrImpl_Construct(NULL, (void**)ppZM);
1246 /********************************************************************
1247 * CoInternetGetSecurityUrl (URLMON.@)
1249 HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR pwzUrl, LPWSTR *ppwzSecUrl, PSUACTION psuAction, DWORD dwReserved)
1251 WCHAR buf1[INTERNET_MAX_URL_LENGTH], buf2[INTERNET_MAX_URL_LENGTH];
1256 TRACE("(%p,%p,%u,%u)\n", pwzUrl, ppwzSecUrl, psuAction, dwReserved);
1260 strcpyW(url, pwzUrl);
1263 hres = CoInternetParseUrl(url, PARSE_SECURITY_URL, 0, domain, INTERNET_MAX_URL_LENGTH, &len, 0);
1264 if(hres!=S_OK || !strcmpW(url, domain))
1276 if(psuAction==PSU_SECURITY_URL_ONLY) {
1277 len = lstrlenW(url)+1;
1278 *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));
1280 return E_OUTOFMEMORY;
1282 memcpy(*ppwzSecUrl, url, len*sizeof(WCHAR));
1286 hres = CoInternetParseUrl(url, PARSE_SECURITY_DOMAIN, 0, domain,
1287 INTERNET_MAX_URL_LENGTH, &len, 0);
1288 if(SUCCEEDED(hres)) {
1290 *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));
1292 return E_OUTOFMEMORY;
1294 memcpy(*ppwzSecUrl, domain, len*sizeof(WCHAR));
1298 hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, domain,
1299 INTERNET_MAX_URL_LENGTH, &len, 0);
1301 const WCHAR fileW[] = {'f','i','l','e',0};
1302 if(!strcmpW(domain, fileW)){
1303 hres = CoInternetParseUrl(url, PARSE_ROOTDOCUMENT, 0, domain, INTERNET_MAX_URL_LENGTH, &len, 0);
1306 hres = CoInternetParseUrl(url, PARSE_DOMAIN, 0, domain+len+1,
1307 INTERNET_MAX_URL_LENGTH-len-1, &len, 0);
1309 len = lstrlenW(domain)+1;
1310 *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));
1312 return E_OUTOFMEMORY;
1314 memcpy(*ppwzSecUrl, domain, len*sizeof(WCHAR));
1321 len = lstrlenW(url)+1;
1322 *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));
1324 return E_OUTOFMEMORY;
1326 memcpy(*ppwzSecUrl, url, len*sizeof(WCHAR));