winspool.drv: Convert string table resources to po files.
[wine.git] / dlls / urlmon / sec_mgr.c
blob6b12a9aabaa6a135ba7204655e5ae46a7a5a9229
1 /*
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
23 #include <stdio.h>
25 #include "urlmon_main.h"
26 #include "winreg.h"
27 #include "wininet.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)
57 DWORD type = REG_SZ;
58 DWORD len = maxlen * sizeof(WCHAR);
59 DWORD res;
61 res = RegQueryValueExW(hcu, name, NULL, &type, (LPBYTE) out, &len);
63 if (res && hklm) {
64 len = maxlen * sizeof(WCHAR);
65 type = REG_SZ;
66 res = RegQueryValueExW(hklm, name, NULL, &type, (LPBYTE) out, &len);
69 if (res) {
70 TRACE("%s failed: %d\n", debugstr_w(name), res);
71 *out = '\0';
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);
85 DWORD res;
87 res = RegQueryValueExW(hcu, name, NULL, &type, (LPBYTE) out, &len);
89 if (res && hklm) {
90 len = sizeof(DWORD);
91 type = REG_DWORD;
92 res = RegQueryValueExW(hklm, name, NULL, &type, (LPBYTE) out, &len);
95 if (res) {
96 TRACE("%s failed: %d\n", debugstr_w(name), res);
97 *out = 0;
101 static HRESULT get_zone_from_reg(LPCWSTR schema, DWORD *zone)
103 DWORD res, size;
104 HKEY hkey;
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));
118 return E_UNEXPECTED;
121 size = sizeof(DWORD);
122 res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size);
123 RegCloseKey(hkey);
124 if(res == ERROR_SUCCESS)
125 return S_OK;
127 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszZoneMapProtocolKey, &hkey);
128 if(res != ERROR_SUCCESS) {
129 ERR("Could not open key %s\n", debugstr_w(wszZoneMapProtocolKey));
130 return E_UNEXPECTED;
133 size = sizeof(DWORD);
134 res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size);
135 RegCloseKey(hkey);
136 if(res == ERROR_SUCCESS)
137 return S_OK;
139 *zone = 3;
140 return S_OK;
143 static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone, LPWSTR *ret_url)
145 LPWSTR secur_url;
146 WCHAR schema[64];
147 DWORD size=0;
148 HRESULT hres;
150 *zone = -1;
152 hres = CoInternetGetSecurityUrl(url, &secur_url, PSU_SECURITY_URL_ONLY, 0);
153 if(hres != S_OK) {
154 size = strlenW(url)*sizeof(WCHAR);
156 secur_url = heap_alloc(size);
157 if(!secur_url)
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);
166 return E_INVALIDARG;
169 /* file protocol is a special case */
170 if(!strcmpW(schema, fileW)) {
171 WCHAR path[MAX_PATH], root[20];
172 WCHAR *ptr;
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)) {
178 UINT type;
180 memcpy(root, path, (ptr-path)*sizeof(WCHAR));
181 root[ptr-path] = 0;
183 type = GetDriveTypeW(root);
185 switch(type) {
186 case DRIVE_UNKNOWN:
187 case DRIVE_NO_ROOT_DIR:
188 break;
189 case DRIVE_REMOVABLE:
190 case DRIVE_FIXED:
191 case DRIVE_CDROM:
192 case DRIVE_RAMDISK:
193 *zone = 0;
194 hres = S_OK;
195 break;
196 case DRIVE_REMOTE:
197 *zone = 3;
198 hres = S_OK;
199 break;
200 default:
201 FIXME("unsupported drive type %d\n", type);
206 if(*zone == -1) {
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);
213 else
214 *ret_url = secur_url;
216 return hres;
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];
224 DWORD res;
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");
232 return E_INVALIDARG;
235 return S_OK;
238 static HRESULT get_action_policy(DWORD zone, DWORD action, BYTE *policy, DWORD size, URLZONEREG zone_reg)
240 HKEY parent_key;
241 HKEY hkey;
242 LONG res;
243 HRESULT hres;
245 switch(action) {
246 case URLACTION_SCRIPT_OVERRIDE_SAFETY:
247 case URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY:
248 *(DWORD*)policy = URLPOLICY_DISALLOW;
249 return S_OK;
252 switch(zone_reg) {
253 case URLZONEREG_DEFAULT:
254 case URLZONEREG_HKCU:
255 parent_key = HKEY_CURRENT_USER;
256 break;
257 case URLZONEREG_HKLM:
258 parent_key = HKEY_LOCAL_MACHINE;
259 break;
260 default:
261 WARN("Unknown URLZONEREG: %d\n", zone_reg);
262 return E_FAIL;
265 hres = open_zone_key(parent_key, zone, &hkey);
266 if(SUCCEEDED(hres)) {
267 WCHAR action_str[16];
268 DWORD len = size;
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) {
276 hres = E_INVALIDARG;
277 }else if(res == ERROR_FILE_NOT_FOUND) {
278 hres = E_FAIL;
279 }else if(res != ERROR_SUCCESS) {
280 ERR("RegQueryValue failed: %d\n", res);
281 hres = E_UNEXPECTED;
284 RegCloseKey(hkey);
287 if(FAILED(hres) && zone_reg == URLZONEREG_DEFAULT)
288 return get_action_policy(zone, action, policy, size, URLZONEREG_HKLM);
290 return hres;
293 /***********************************************************************
294 * InternetSecurityManager implementation
297 typedef struct {
298 IInternetSecurityManager IInternetSecurityManager_iface;
300 LONG ref;
302 IInternetSecurityMgrSite *mgrsite;
303 IInternetSecurityManager *custom_manager;
304 } SecManagerImpl;
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) )
319 return E_INVALIDARG;
321 /* Initialize the return parameter */
322 *ppvObject = 0;
324 /* Compare the riid with the interface IDs implemented by this object.*/
325 if (IsEqualIID(&IID_IUnknown, riid) ||
326 IsEqualIID(&IID_IInternetSecurityManager, riid))
327 *ppvObject = iface;
329 /* Check that we obtained an interface.*/
330 if (!*ppvObject) {
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);
338 return S_OK;
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);
348 return 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 */
359 if (!refCount){
360 if(This->mgrsite)
361 IInternetSecurityMgrSite_Release(This->mgrsite);
362 if(This->custom_manager)
363 IInternetSecurityManager_Release(This->custom_manager);
365 heap_free(This);
367 URLMON_UnlockModule();
370 return refCount;
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);
380 if(This->mgrsite)
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;
390 if(pSite) {
391 IServiceProvider *servprov;
392 HRESULT hres;
394 IInternetSecurityMgrSite_AddRef(pSite);
396 hres = IInternetSecurityMgrSite_QueryInterface(pSite, &IID_IServiceProvider,
397 (void**)&servprov);
398 if(SUCCEEDED(hres)) {
399 IServiceProvider_QueryService(servprov, &SID_SInternetSecurityManager,
400 &IID_IInternetSecurityManager, (void**)&This->custom_manager);
401 IServiceProvider_Release(servprov);
405 return S_OK;
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);
415 if(!ppSite)
416 return E_INVALIDARG;
418 if(This->mgrsite)
419 IInternetSecurityMgrSite_AddRef(This->mgrsite);
421 *ppSite = This->mgrsite;
422 return S_OK;
425 static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManager *iface,
426 LPCWSTR pwszUrl, DWORD *pdwZone,
427 DWORD dwFlags)
429 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
430 HRESULT hres;
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)
438 return hres;
441 if(!pwszUrl) {
442 *pdwZone = -1;
443 return E_INVALIDARG;
446 if(dwFlags)
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;
457 DWORD zone, len;
458 HRESULT hres;
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)
469 return hres;
472 if(!pwszUrl || !pbSecurityId || !pcbSecurityId)
473 return E_INVALIDARG;
475 if(dwReserved)
476 FIXME("dwReserved is not supported\n");
478 hres = map_url_to_zone(pwszUrl, &zone, &url);
479 if(FAILED(hres))
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',':'};
488 heap_free(url);
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);
497 return S_OK;
500 ptr = strchrW(url, ':');
501 ptr2 = ++ptr;
502 while(*ptr2 == '/')
503 ptr2++;
504 if(ptr2 != ptr)
505 memmove(ptr, ptr2, (strlenW(ptr2)+1)*sizeof(WCHAR));
507 ptr = strchrW(ptr, '/');
508 if(ptr)
509 *ptr = 0;
511 len = WideCharToMultiByte(CP_ACP, 0, url, -1, NULL, 0, NULL, NULL)-1;
513 if(len+sizeof(DWORD) > *pcbSecurityId) {
514 heap_free(url);
515 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
518 WideCharToMultiByte(CP_ACP, 0, url, -1, (LPSTR)pbSecurityId, len, NULL, NULL);
519 heap_free(url);
521 *(DWORD*)(pbSecurityId+len) = zone;
523 *pcbSecurityId = len+sizeof(DWORD);
525 return S_OK;
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);
536 DWORD zone, policy;
537 HRESULT hres;
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)
546 return hres;
549 if(dwFlags || dwReserved)
550 FIXME("Unsupported arguments\n");
552 if(!pwszUrl)
553 return E_INVALIDARG;
555 hres = map_url_to_zone(pwszUrl, &zone, NULL);
556 if(FAILED(hres))
557 return hres;
559 hres = get_action_policy(zone, dwAction, (BYTE*)&policy, sizeof(policy), URLZONEREG_DEFAULT);
560 if(FAILED(hres))
561 return hres;
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:
570 return S_OK;
571 case URLPOLICY_DISALLOW:
572 return S_FALSE;
573 case URLPOLICY_QUERY:
574 FIXME("URLPOLICY_QUERY not implemented\n");
575 return E_FAIL;
576 default:
577 FIXME("Not implemented policy %x\n", policy);
580 return E_FAIL;
584 static HRESULT WINAPI SecManagerImpl_QueryCustomPolicy(IInternetSecurityManager *iface,
585 LPCWSTR pwszUrl, REFGUID guidKey,
586 BYTE **ppPolicy, DWORD *pcbPolicy,
587 BYTE *pContext, DWORD cbContext,
588 DWORD dwReserved)
590 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
591 HRESULT hres;
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)
600 return hres;
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);
611 HRESULT hres;
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)
619 return hres;
622 FIXME("Default action is not implemented\n");
623 return E_NOTIMPL;
626 static HRESULT WINAPI SecManagerImpl_GetZoneMappings(IInternetSecurityManager *iface,
627 DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags)
629 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
630 HRESULT hres;
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)
638 return hres;
641 FIXME("Default action is not implemented\n");
642 return E_NOTIMPL;
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;
670 This->ref = 1;
671 This->mgrsite = NULL;
672 This->custom_manager = NULL;
674 *ppobj = This;
676 URLMON_LockModule();
678 return S_OK;
681 /***********************************************************************
682 * InternetZoneManager implementation
685 typedef struct {
686 IInternetZoneManagerEx2 IInternetZoneManagerEx2_iface;
687 LONG ref;
688 LPDWORD *zonemaps;
689 DWORD zonemap_count;
690 } ZoneMgrImpl;
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)
706 WCHAR name[32];
707 HKEY hkey;
708 LPDWORD data = NULL;
709 DWORD allocated = 6; /* space for the zonecount and Zone "0" up to Zone "4" */
710 DWORD used = 0;
711 DWORD res;
712 DWORD len;
715 res = RegOpenKeyW(HKEY_CURRENT_USER, wszZonesKey, &hkey);
716 if (res)
717 return NULL;
719 data = heap_alloc(allocated * sizeof(DWORD));
720 if (!data)
721 goto cleanup;
723 while (!res) {
724 name[0] = '\0';
725 len = sizeof(name) / sizeof(name[0]);
726 res = RegEnumKeyExW(hkey, used, name, &len, NULL, NULL, NULL, NULL);
728 if (!res) {
729 used++;
730 if (used == allocated) {
731 LPDWORD new_data;
733 allocated *= 2;
734 new_data = heap_realloc_zero(data, allocated * sizeof(DWORD));
735 if (!new_data)
736 goto cleanup;
738 data = new_data;
740 data[used] = atoiW(name);
743 if (used) {
744 RegCloseKey(hkey);
745 data[0] = used;
746 return data;
749 cleanup:
750 /* something failed */
751 RegCloseKey(hkey);
752 heap_free(data);
753 return NULL;
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)
766 return E_INVALIDARG;
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);
777 else
779 FIXME("Unknown interface: %s\n", debugstr_guid(riid));
780 *ppvObject = NULL;
781 return E_NOINTERFACE;
784 *ppvObject = iface;
785 IInternetZoneManager_AddRef(iface);
786 return S_OK;
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);
799 return refCount;
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);
812 if(!refCount) {
813 while (This->zonemap_count) heap_free(This->zonemaps[--This->zonemap_count]);
814 heap_free(This->zonemaps);
815 heap_free(This);
816 URLMON_UnlockModule();
819 return refCount;
822 /********************************************************************
823 * IInternetZoneManager_GetZoneAttributes
825 static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributes(IInternetZoneManagerEx2* iface,
826 DWORD dwZone,
827 ZONEATTRIBUTES* pZoneAttributes)
829 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
830 HRESULT hr;
831 HKEY hcu;
832 HKEY hklm = NULL;
834 TRACE("(%p)->(%d %p)\n", This, dwZone, pZoneAttributes);
836 if (!pZoneAttributes)
837 return E_INVALIDARG;
839 hr = open_zone_key(HKEY_CURRENT_USER, dwZone, &hcu);
840 if (FAILED(hr))
841 return S_OK; /* IE6 and older returned E_FAIL here */
843 hr = open_zone_key(HKEY_LOCAL_MACHINE, dwZone, &hklm);
844 if (FAILED(hr))
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);
855 RegCloseKey(hklm);
856 RegCloseKey(hcu);
857 return S_OK;
860 /********************************************************************
861 * IInternetZoneManager_SetZoneAttributes
863 static HRESULT WINAPI ZoneMgrImpl_SetZoneAttributes(IInternetZoneManagerEx2* iface,
864 DWORD dwZone,
865 ZONEATTRIBUTES* pZoneAttributes)
867 FIXME("(%p)->(%08x %p) stub\n", iface, dwZone, pZoneAttributes);
868 return E_NOTIMPL;
871 /********************************************************************
872 * IInternetZoneManager_GetZoneCustomPolicy
874 static HRESULT WINAPI ZoneMgrImpl_GetZoneCustomPolicy(IInternetZoneManagerEx2* iface,
875 DWORD dwZone,
876 REFGUID guidKey,
877 BYTE** ppPolicy,
878 DWORD* pcbPolicy,
879 URLZONEREG ulrZoneReg)
881 FIXME("(%p)->(%08x %s %p %p %08x) stub\n", iface, dwZone, debugstr_guid(guidKey),
882 ppPolicy, pcbPolicy, ulrZoneReg);
883 return E_NOTIMPL;
886 /********************************************************************
887 * IInternetZoneManager_SetZoneCustomPolicy
889 static HRESULT WINAPI ZoneMgrImpl_SetZoneCustomPolicy(IInternetZoneManagerEx2* iface,
890 DWORD dwZone,
891 REFGUID guidKey,
892 BYTE* ppPolicy,
893 DWORD cbPolicy,
894 URLZONEREG ulrZoneReg)
896 FIXME("(%p)->(%08x %s %p %08x %08x) stub\n", iface, dwZone, debugstr_guid(guidKey),
897 ppPolicy, cbPolicy, ulrZoneReg);
898 return E_NOTIMPL;
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);
910 if(!pPolicy)
911 return E_INVALIDARG;
913 return get_action_policy(dwZone, dwAction, pPolicy, cbPolicy, urlZoneReg);
916 /********************************************************************
917 * IInternetZoneManager_SetZoneActionPolicy
919 static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicy(IInternetZoneManagerEx2* iface,
920 DWORD dwZone,
921 DWORD dwAction,
922 BYTE* pPolicy,
923 DWORD cbPolicy,
924 URLZONEREG urlZoneReg)
926 FIXME("(%p)->(%08x %08x %p %08x %08x) stub\n", iface, dwZone, dwAction, pPolicy,
927 cbPolicy, urlZoneReg);
928 return E_NOTIMPL;
931 /********************************************************************
932 * IInternetZoneManager_PromptAction
934 static HRESULT WINAPI ZoneMgrImpl_PromptAction(IInternetZoneManagerEx2* iface,
935 DWORD dwAction,
936 HWND hwndParent,
937 LPCWSTR pwszUrl,
938 LPCWSTR pwszText,
939 DWORD dwPromptFlags)
941 FIXME("%p %08x %p %s %s %08x\n", iface, dwAction, hwndParent,
942 debugstr_w(pwszUrl), debugstr_w(pwszText), dwPromptFlags );
943 return E_NOTIMPL;
946 /********************************************************************
947 * IInternetZoneManager_LogAction
949 static HRESULT WINAPI ZoneMgrImpl_LogAction(IInternetZoneManagerEx2* iface,
950 DWORD dwAction,
951 LPCWSTR pwszUrl,
952 LPCWSTR pwszText,
953 DWORD dwLogFlags)
955 FIXME("(%p)->(%08x %s %s %08x) stub\n", iface, dwAction, debugstr_w(pwszUrl),
956 debugstr_w(pwszText), dwLogFlags);
957 return E_NOTIMPL;
960 /********************************************************************
961 * IInternetZoneManager_CreateZoneEnumerator
963 static HRESULT WINAPI ZoneMgrImpl_CreateZoneEnumerator(IInternetZoneManagerEx2* iface,
964 DWORD* pdwEnum,
965 DWORD* pdwCount,
966 DWORD dwFlags)
968 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
969 LPDWORD * new_maps;
970 LPDWORD data;
971 DWORD i;
973 TRACE("(%p)->(%p, %p, 0x%08x)\n", This, pdwEnum, pdwCount, dwFlags);
974 if (!pdwEnum || !pdwCount || (dwFlags != 0))
975 return E_INVALIDARG;
977 data = build_zonemap_from_reg();
978 TRACE("found %d zones\n", data ? data[0] : -1);
980 if (!data)
981 return E_FAIL;
983 for (i = 0; i < This->zonemap_count; i++) {
984 if (This->zonemaps && !This->zonemaps[i]) {
985 This->zonemaps[i] = data;
986 *pdwEnum = i;
987 *pdwCount = data[0];
988 return S_OK;
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));
995 if (new_maps)
996 This->zonemap_count *= 2;
998 else
1000 This->zonemap_count = 2;
1001 new_maps = heap_alloc_zero(This->zonemap_count * sizeof(LPDWORD));
1004 if (!new_maps) {
1005 heap_free(data);
1006 return E_FAIL;
1008 This->zonemaps = new_maps;
1009 This->zonemaps[i] = data;
1010 *pdwEnum = i;
1011 *pdwCount = data[0];
1012 return S_OK;
1015 /********************************************************************
1016 * IInternetZoneManager_GetZoneAt
1018 static HRESULT WINAPI ZoneMgrImpl_GetZoneAt(IInternetZoneManagerEx2* iface,
1019 DWORD dwEnum,
1020 DWORD dwIndex,
1021 DWORD* pdwZone)
1023 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
1024 LPDWORD data;
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];
1033 return S_OK;
1037 return E_INVALIDARG;
1040 /********************************************************************
1041 * IInternetZoneManager_DestroyZoneEnumerator
1043 static HRESULT WINAPI ZoneMgrImpl_DestroyZoneEnumerator(IInternetZoneManagerEx2* iface,
1044 DWORD dwEnum)
1046 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
1047 LPDWORD data;
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;
1054 heap_free(data);
1055 return S_OK;
1058 return E_INVALIDARG;
1061 /********************************************************************
1062 * IInternetZoneManager_CopyTemplatePoliciesToZone
1064 static HRESULT WINAPI ZoneMgrImpl_CopyTemplatePoliciesToZone(IInternetZoneManagerEx2* iface,
1065 DWORD dwTemplate,
1066 DWORD dwZone,
1067 DWORD dwReserved)
1069 FIXME("(%p)->(%08x %08x %08x) stub\n", iface, dwTemplate, dwZone, dwReserved);
1070 return E_NOTIMPL;
1073 /********************************************************************
1074 * IInternetZoneManagerEx_GetZoneActionPolicyEx
1076 static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicyEx(IInternetZoneManagerEx2* iface,
1077 DWORD dwZone,
1078 DWORD dwAction,
1079 BYTE* pPolicy,
1080 DWORD cbPolicy,
1081 URLZONEREG urlZoneReg,
1082 DWORD dwFlags)
1084 TRACE("(%p)->(%d, 0x%x, %p, %d, %d, 0x%x)\n", iface, dwZone,
1085 dwAction, pPolicy, cbPolicy, urlZoneReg, dwFlags);
1087 if(!pPolicy)
1088 return E_INVALIDARG;
1090 if (dwFlags)
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,
1100 DWORD dwZone,
1101 DWORD dwAction,
1102 BYTE* pPolicy,
1103 DWORD cbPolicy,
1104 URLZONEREG urlZoneReg,
1105 DWORD dwFlags)
1107 FIXME("(%p)->(%d, 0x%x, %p, %d, %d, 0x%x) stub\n", iface, dwZone, dwAction, pPolicy,
1108 cbPolicy, urlZoneReg, dwFlags);
1109 return E_NOTIMPL;
1112 /********************************************************************
1113 * IInternetZoneManagerEx2_GetZoneAttributesEx
1115 static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributesEx(IInternetZoneManagerEx2* iface,
1116 DWORD dwZone,
1117 ZONEATTRIBUTES* pZoneAttributes,
1118 DWORD dwFlags)
1120 TRACE("(%p)->(%d, %p, 0x%x)\n", iface, dwZone, pZoneAttributes, dwFlags);
1122 if (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,
1133 DWORD dwZoneIndex,
1134 BOOL fRespectPolicy,
1135 LPDWORD pdwState,
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;
1146 return S_OK;
1149 /********************************************************************
1150 * IInternetZoneManagerEx2_GetIESecurityState
1152 static HRESULT WINAPI ZoneMgrImpl_GetIESecurityState(IInternetZoneManagerEx2* iface,
1153 BOOL fRespectPolicy,
1154 LPDWORD pdwState,
1155 BOOL *pfPolicyEncountered,
1156 BOOL fNoCache)
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;
1166 return S_OK;
1169 /********************************************************************
1170 * IInternetZoneManagerEx2_FixInsecureSettings
1172 static HRESULT WINAPI ZoneMgrImpl_FixInsecureSettings(IInternetZoneManagerEx2* iface)
1174 FIXME("(%p) stub\n", iface);
1175 return S_OK;
1178 /********************************************************************
1179 * IInternetZoneManager_Construct
1181 static const IInternetZoneManagerEx2Vtbl ZoneMgrImplVtbl = {
1182 ZoneMgrImpl_QueryInterface,
1183 ZoneMgrImpl_AddRef,
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;
1214 ret->ref = 1;
1215 *ppobj = (IInternetZoneManagerEx*)ret;
1217 URLMON_LockModule();
1219 return S_OK;
1222 /***********************************************************************
1223 * CoInternetCreateSecurityManager (URLMON.@)
1226 HRESULT WINAPI CoInternetCreateSecurityManager( IServiceProvider *pSP,
1227 IInternetSecurityManager **ppSM, DWORD dwReserved )
1229 TRACE("%p %p %d\n", pSP, ppSM, dwReserved );
1231 if(pSP)
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];
1252 LPWSTR url, domain;
1253 DWORD len;
1254 HRESULT hres;
1256 TRACE("(%p,%p,%u,%u)\n", pwzUrl, ppwzSecUrl, psuAction, dwReserved);
1258 url = buf1;
1259 domain = buf2;
1260 strcpyW(url, pwzUrl);
1262 while(1) {
1263 hres = CoInternetParseUrl(url, PARSE_SECURITY_URL, 0, domain, INTERNET_MAX_URL_LENGTH, &len, 0);
1264 if(hres!=S_OK || !strcmpW(url, domain))
1265 break;
1267 if(url == buf1) {
1268 url = buf2;
1269 domain = buf1;
1270 } else {
1271 url = buf1;
1272 domain = buf2;
1276 if(psuAction==PSU_SECURITY_URL_ONLY) {
1277 len = lstrlenW(url)+1;
1278 *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));
1279 if(!*ppwzSecUrl)
1280 return E_OUTOFMEMORY;
1282 memcpy(*ppwzSecUrl, url, len*sizeof(WCHAR));
1283 return S_OK;
1286 hres = CoInternetParseUrl(url, PARSE_SECURITY_DOMAIN, 0, domain,
1287 INTERNET_MAX_URL_LENGTH, &len, 0);
1288 if(SUCCEEDED(hres)) {
1289 len++;
1290 *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));
1291 if(!*ppwzSecUrl)
1292 return E_OUTOFMEMORY;
1294 memcpy(*ppwzSecUrl, domain, len*sizeof(WCHAR));
1295 return S_OK;
1298 hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, domain,
1299 INTERNET_MAX_URL_LENGTH, &len, 0);
1300 if(hres == S_OK){
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);
1304 }else{
1305 domain[len] = ':';
1306 hres = CoInternetParseUrl(url, PARSE_DOMAIN, 0, domain+len+1,
1307 INTERNET_MAX_URL_LENGTH-len-1, &len, 0);
1308 if(hres == S_OK) {
1309 len = lstrlenW(domain)+1;
1310 *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));
1311 if(!*ppwzSecUrl)
1312 return E_OUTOFMEMORY;
1314 memcpy(*ppwzSecUrl, domain, len*sizeof(WCHAR));
1315 return S_OK;
1318 }else
1319 return hres;
1321 len = lstrlenW(url)+1;
1322 *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));
1323 if(!*ppwzSecUrl)
1324 return E_OUTOFMEMORY;
1326 memcpy(*ppwzSecUrl, url, len*sizeof(WCHAR));
1327 return S_OK;