ntprint: Add a stub for ntprint.dll.
[wine] / dlls / urlmon / sec_mgr.c
1 /*
2  * Internet Security and Zone Manager
3  *
4  * Copyright (c) 2004 Huw D M Davies
5  * Copyright 2004 Jacek Caban
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include <stdarg.h>
23 #include <stdio.h>
24
25 #define COBJMACROS
26
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "winreg.h"
31 #include "wine/debug.h"
32 #include "ole2.h"
33 #include "wine/unicode.h"
34 #include "urlmon.h"
35 #include "urlmon_main.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
38
39 /***********************************************************************
40  *           InternetSecurityManager implementation
41  *
42  */
43 typedef struct {
44     const IInternetSecurityManagerVtbl* lpInternetSecurityManagerVtbl;
45
46     LONG ref;
47
48     IInternetSecurityMgrSite *mgrsite;
49     IInternetSecurityManager *custom_manager;
50 } SecManagerImpl;
51
52 #define SECMGR_THIS(iface) DEFINE_THIS(SecManagerImpl, InternetSecurityManager, iface)
53
54 static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone)
55 {
56     WCHAR schema[64];
57     DWORD res, size=0;
58     HKEY hkey;
59     HRESULT hres;
60
61     static const WCHAR wszZoneMapProtocolKey[] =
62         {'S','o','f','t','w','a','r','e','\\',
63                     'M','i','c','r','o','s','o','f','t','\\',
64                     'W','i','n','d','o','w','s','\\',
65                     'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
66                     'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
67                     'Z','o','n','e','M','a','p','\\',
68                     'P','r','o','t','o','c','o','l','D','e','f','a','u','l','t','s',0};
69     static const WCHAR wszFile[] = {'f','i','l','e',0};
70
71     *zone = -1;
72
73     hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(WCHAR), &size, 0);
74     if(FAILED(hres))
75         return hres;
76     if(!*schema)
77         return 0x80041001;
78
79     /* file protocol is a special case */
80     if(!strcmpW(schema, wszFile)) {
81         WCHAR path[MAX_PATH];
82
83         hres = CoInternetParseUrl(url, PARSE_PATH_FROM_URL, 0, path,
84                 sizeof(path)/sizeof(WCHAR), &size, 0);
85
86         if(SUCCEEDED(hres) && strchrW(path, '\\')) {
87             *zone = 0;
88             return S_OK;
89         }
90     }
91
92     WARN("domains are not yet implemented\n");
93
94     res = RegOpenKeyW(HKEY_CURRENT_USER, wszZoneMapProtocolKey, &hkey);
95     if(res != ERROR_SUCCESS) {
96         ERR("Could not open key %s\n", debugstr_w(wszZoneMapProtocolKey));
97         return E_UNEXPECTED;
98     }
99
100     size = sizeof(DWORD);
101     res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size);
102     RegCloseKey(hkey);
103     if(res == ERROR_SUCCESS)
104         return S_OK;
105
106     res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszZoneMapProtocolKey, &hkey);
107     if(res != ERROR_SUCCESS) {
108         ERR("Could not open key %s\n", debugstr_w(wszZoneMapProtocolKey));
109         return E_UNEXPECTED;
110     }
111
112     size = sizeof(DWORD);
113     res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size);
114     RegCloseKey(hkey);
115     if(res == ERROR_SUCCESS)
116         return S_OK;
117
118     *zone = 3;
119     return S_OK;
120 }
121
122 static HRESULT WINAPI SecManagerImpl_QueryInterface(IInternetSecurityManager* iface,REFIID riid,void** ppvObject)
123 {
124     SecManagerImpl *This = SECMGR_THIS(iface);
125
126     TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject);
127
128     /* Perform a sanity check on the parameters.*/
129     if ( (This==0) || (ppvObject==0) )
130         return E_INVALIDARG;
131
132     /* Initialize the return parameter */
133     *ppvObject = 0;
134
135     /* Compare the riid with the interface IDs implemented by this object.*/
136     if (IsEqualIID(&IID_IUnknown, riid) ||
137         IsEqualIID(&IID_IInternetSecurityManager, riid))
138         *ppvObject = iface;
139
140     /* Check that we obtained an interface.*/
141     if (!*ppvObject) {
142         WARN("not supported interface %s\n", debugstr_guid(riid));
143         return E_NOINTERFACE;
144     }
145
146     /* Query Interface always increases the reference count by one when it is successful */
147     IInternetSecurityManager_AddRef(iface);
148
149     return S_OK;
150 }
151
152 static ULONG WINAPI SecManagerImpl_AddRef(IInternetSecurityManager* iface)
153 {
154     SecManagerImpl *This = SECMGR_THIS(iface);
155     ULONG refCount = InterlockedIncrement(&This->ref);
156
157     TRACE("(%p) ref=%u\n", This, refCount);
158
159     return refCount;
160 }
161
162 static ULONG WINAPI SecManagerImpl_Release(IInternetSecurityManager* iface)
163 {
164     SecManagerImpl *This = SECMGR_THIS(iface);
165     ULONG refCount = InterlockedDecrement(&This->ref);
166
167     TRACE("(%p) ref=%u\n", This, refCount);
168
169     /* destroy the object if there's no more reference on it */
170     if (!refCount){
171         if(This->mgrsite)
172             IInternetSecurityMgrSite_Release(This->mgrsite);
173         if(This->custom_manager)
174             IInternetSecurityManager_Release(This->custom_manager);
175
176         HeapFree(GetProcessHeap(),0,This);
177
178         URLMON_UnlockModule();
179     }
180
181     return refCount;
182 }
183
184 static HRESULT WINAPI SecManagerImpl_SetSecuritySite(IInternetSecurityManager *iface,
185                                                      IInternetSecurityMgrSite *pSite)
186 {
187     SecManagerImpl *This = SECMGR_THIS(iface);
188
189     TRACE("(%p)->(%p)\n", This, pSite);
190
191     if(This->mgrsite)
192         IInternetSecurityMgrSite_Release(This->mgrsite);
193
194     if(This->custom_manager) {
195         IInternetSecurityManager_Release(This->custom_manager);
196         This->custom_manager = NULL;
197     }
198
199     This->mgrsite = pSite;
200
201     if(pSite) {
202         IServiceProvider *servprov;
203         HRESULT hres;
204
205         IInternetSecurityMgrSite_AddRef(pSite);
206
207         hres = IInternetSecurityMgrSite_QueryInterface(pSite, &IID_IServiceProvider,
208                 (void**)&servprov);
209         if(SUCCEEDED(hres)) {
210             IServiceProvider_QueryService(servprov, &SID_SInternetSecurityManager,
211                     &IID_IInternetSecurityManager, (void**)&This->custom_manager);
212             IServiceProvider_Release(servprov);
213         }
214     }
215
216     return S_OK;
217 }
218
219 static HRESULT WINAPI SecManagerImpl_GetSecuritySite(IInternetSecurityManager *iface,
220                                                      IInternetSecurityMgrSite **ppSite)
221 {
222     SecManagerImpl *This = SECMGR_THIS(iface);
223
224     TRACE("(%p)->(%p)\n", This, ppSite);
225
226     if(!ppSite)
227         return E_INVALIDARG;
228
229     if(This->mgrsite)
230         IInternetSecurityMgrSite_AddRef(This->mgrsite);
231
232     *ppSite = This->mgrsite;
233     return S_OK;
234 }
235
236 static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManager *iface,
237                                                   LPCWSTR pwszUrl, DWORD *pdwZone,
238                                                   DWORD dwFlags)
239 {
240     SecManagerImpl *This = SECMGR_THIS(iface);
241     LPWSTR url;
242     DWORD size;
243     HRESULT hres;
244
245     TRACE("(%p)->(%s %p %08x)\n", iface, debugstr_w(pwszUrl), pdwZone, dwFlags);
246
247     if(This->custom_manager) {
248         hres = IInternetSecurityManager_MapUrlToZone(This->custom_manager,
249                 pwszUrl, pdwZone, dwFlags);
250         if(hres != INET_E_DEFAULT_ACTION)
251             return hres;
252     }
253
254     if(!pwszUrl)
255         return E_INVALIDARG;
256
257     if(dwFlags)
258         FIXME("not supported flags: %08x\n", dwFlags);
259
260     size = (strlenW(pwszUrl)+16) * sizeof(WCHAR);
261     url = HeapAlloc(GetProcessHeap(), 0, size);
262
263     hres = CoInternetParseUrl(pwszUrl, PARSE_SECURITY_URL, 0, url, size/sizeof(WCHAR), &size, 0);
264     if(FAILED(hres))
265         memcpy(url, pwszUrl, size);
266
267     hres = map_url_to_zone(url, pdwZone);
268
269     HeapFree(GetProcessHeap(), 0, url);
270
271     return hres;
272 }
273
274 static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *iface, 
275         LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
276 {
277     SecManagerImpl *This = SECMGR_THIS(iface);
278     LPWSTR buf, ptr, ptr2;
279     DWORD size, zone, len;
280     HRESULT hres;
281
282     static const WCHAR wszFile[] = {'f','i','l','e',':'};
283
284     TRACE("(%p)->(%s %p %p %08lx)\n", iface, debugstr_w(pwszUrl), pbSecurityId,
285           pcbSecurityId, dwReserved);
286
287     if(This->custom_manager) {
288         hres = IInternetSecurityManager_GetSecurityId(This->custom_manager,
289                 pwszUrl, pbSecurityId, pcbSecurityId, dwReserved);
290         if(hres != INET_E_DEFAULT_ACTION)
291             return hres;
292     }
293
294     if(!pwszUrl || !pbSecurityId || !pcbSecurityId)
295         return E_INVALIDARG;
296
297     if(dwReserved)
298         FIXME("dwReserved is not supported\n");
299
300     len = strlenW(pwszUrl)+1;
301     buf = HeapAlloc(GetProcessHeap(), 0, (len+16)*sizeof(WCHAR));
302
303     hres = CoInternetParseUrl(pwszUrl, PARSE_SECURITY_URL, 0, buf, len, &size, 0);
304     if(FAILED(hres))
305         memcpy(buf, pwszUrl, len*sizeof(WCHAR));
306
307     hres = map_url_to_zone(buf, &zone);
308     if(FAILED(hres)) {
309         HeapFree(GetProcessHeap(), 0, buf);
310         return hres == 0x80041001 ? E_INVALIDARG : hres;
311     }
312
313     /* file protocol is a special case */
314     if(strlenW(pwszUrl) >= sizeof(wszFile)/sizeof(WCHAR)
315             && !memcmp(buf, wszFile, sizeof(wszFile))) {
316
317         static const BYTE secidFile[] = {'f','i','l','e',':'};
318
319         if(*pcbSecurityId < sizeof(secidFile)+sizeof(zone))
320             return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
321
322         memcpy(pbSecurityId, secidFile, sizeof(secidFile));
323         *(DWORD*)(pbSecurityId+sizeof(secidFile)) = zone;
324
325         *pcbSecurityId = sizeof(secidFile)+sizeof(zone);
326         return S_OK;
327     }
328
329     ptr = strchrW(buf, ':');
330     ptr2 = ++ptr;
331     while(*ptr2 == '/')
332         ptr2++;
333     if(ptr2 != ptr)
334         memmove(ptr, ptr2, (strlenW(ptr2)+1)*sizeof(WCHAR));
335
336     ptr = strchrW(ptr, '/');
337     if(ptr)
338         *ptr = 0;
339
340     len = WideCharToMultiByte(CP_ACP, 0, buf, -1, NULL, 0, NULL, NULL)-1;
341
342     if(len+sizeof(DWORD) > *pcbSecurityId)
343         return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
344
345     WideCharToMultiByte(CP_ACP, 0, buf, -1, (LPSTR)pbSecurityId, -1, NULL, NULL);
346     HeapFree(GetProcessHeap(), 0, buf);
347
348     *(DWORD*)(pbSecurityId+len) = zone;
349
350     *pcbSecurityId = len+sizeof(DWORD);
351
352     return S_OK;
353 }
354
355
356 static HRESULT WINAPI SecManagerImpl_ProcessUrlAction(IInternetSecurityManager *iface,
357                                                       LPCWSTR pwszUrl, DWORD dwAction,
358                                                       BYTE *pPolicy, DWORD cbPolicy,
359                                                       BYTE *pContext, DWORD cbContext,
360                                                       DWORD dwFlags, DWORD dwReserved)
361 {
362     SecManagerImpl *This = SECMGR_THIS(iface);
363     HRESULT hres;
364
365     TRACE("(%p)->(%s %08x %p %08x %p %08x %08x %08x)\n", iface, debugstr_w(pwszUrl), dwAction,
366           pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved);
367
368     if(This->custom_manager) {
369         hres = IInternetSecurityManager_ProcessUrlAction(This->custom_manager, pwszUrl, dwAction,
370                 pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved);
371         if(hres != INET_E_DEFAULT_ACTION)
372             return hres;
373     }
374
375     FIXME("Default action is not implemented\n");
376     return E_NOTIMPL;
377 }
378                                                
379
380 static HRESULT WINAPI SecManagerImpl_QueryCustomPolicy(IInternetSecurityManager *iface,
381                                                        LPCWSTR pwszUrl, REFGUID guidKey,
382                                                        BYTE **ppPolicy, DWORD *pcbPolicy,
383                                                        BYTE *pContext, DWORD cbContext,
384                                                        DWORD dwReserved)
385 {
386     SecManagerImpl *This = SECMGR_THIS(iface);
387     HRESULT hres;
388
389     TRACE("(%p)->(%s %s %p %p %p %08x %08x )\n", iface, debugstr_w(pwszUrl), debugstr_guid(guidKey),
390           ppPolicy, pcbPolicy, pContext, cbContext, dwReserved);
391
392     if(This->custom_manager) {
393         hres = IInternetSecurityManager_QueryCustomPolicy(This->custom_manager, pwszUrl, guidKey,
394                 ppPolicy, pcbPolicy, pContext, cbContext, dwReserved);
395         if(hres != INET_E_DEFAULT_ACTION)
396             return hres;
397     }
398
399     FIXME("Default action is not implemented\n");
400     return E_NOTIMPL;
401 }
402
403 static HRESULT WINAPI SecManagerImpl_SetZoneMapping(IInternetSecurityManager *iface,
404                                                     DWORD dwZone, LPCWSTR pwszPattern, DWORD dwFlags)
405 {
406     SecManagerImpl *This = SECMGR_THIS(iface);
407     HRESULT hres;
408
409     TRACE("(%p)->(%08x %s %08x)\n", iface, dwZone, debugstr_w(pwszPattern),dwFlags);
410
411     if(This->custom_manager) {
412         hres = IInternetSecurityManager_SetZoneMapping(This->custom_manager, dwZone,
413                 pwszPattern, dwFlags);
414         if(hres != INET_E_DEFAULT_ACTION)
415             return hres;
416     }
417
418     FIXME("Default action is not implemented\n");
419     return E_NOTIMPL;
420 }
421
422 static HRESULT WINAPI SecManagerImpl_GetZoneMappings(IInternetSecurityManager *iface,
423         DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags)
424 {
425     SecManagerImpl *This = SECMGR_THIS(iface);
426     HRESULT hres;
427
428     TRACE("(%p)->(%08x %p %08x)\n", iface, dwZone, ppenumString,dwFlags);
429
430     if(This->custom_manager) {
431         hres = IInternetSecurityManager_GetZoneMappings(This->custom_manager, dwZone,
432                 ppenumString, dwFlags);
433         if(hres != INET_E_DEFAULT_ACTION)
434             return hres;
435     }
436
437     FIXME("Default action is not implemented\n");
438     return E_NOTIMPL;
439 }
440
441 static const IInternetSecurityManagerVtbl VT_SecManagerImpl =
442 {
443     SecManagerImpl_QueryInterface,
444     SecManagerImpl_AddRef,
445     SecManagerImpl_Release,
446     SecManagerImpl_SetSecuritySite,
447     SecManagerImpl_GetSecuritySite,
448     SecManagerImpl_MapUrlToZone,
449     SecManagerImpl_GetSecurityId,
450     SecManagerImpl_ProcessUrlAction,
451     SecManagerImpl_QueryCustomPolicy,
452     SecManagerImpl_SetZoneMapping,
453     SecManagerImpl_GetZoneMappings
454 };
455
456 HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
457 {
458     SecManagerImpl *This;
459
460     TRACE("(%p,%p)\n",pUnkOuter,ppobj);
461     This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
462
463     /* Initialize the virtual function table. */
464     This->lpInternetSecurityManagerVtbl = &VT_SecManagerImpl;
465
466     This->ref = 1;
467     This->mgrsite = NULL;
468     This->custom_manager = NULL;
469
470     *ppobj = This;
471
472     URLMON_LockModule();
473
474     return S_OK;
475 }
476
477 /***********************************************************************
478  *           InternetZoneManager implementation
479  *
480  */
481 typedef struct {
482     const IInternetZoneManagerVtbl* lpVtbl;
483     LONG ref;
484 } ZoneMgrImpl;
485
486 static HRESULT open_zone_key(DWORD zone, HKEY *hkey, URLZONEREG zone_reg)
487 {
488     static const WCHAR wszZonesKey[] =
489         {'S','o','f','t','w','a','r','e','\\',
490             'M','i','c','r','o','s','o','f','t','\\',
491             'W','i','n','d','o','w','s','\\',
492             'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
493             'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
494             'Z','o','n','e','s','\\',0};
495     static const WCHAR wszFormat[] = {'%','s','%','l','d',0};
496
497     WCHAR key_name[sizeof(wszZonesKey)/sizeof(WCHAR)+8];
498     HKEY parent_key;
499     DWORD res;
500
501     switch(zone_reg) {
502     case URLZONEREG_DEFAULT: /* FIXME: TEST */
503     case URLZONEREG_HKCU:
504         parent_key = HKEY_CURRENT_USER;
505         break;
506     case URLZONEREG_HKLM:
507         parent_key = HKEY_LOCAL_MACHINE;
508         break;
509     default:
510         WARN("Unknown URLZONEREG: %d\n", zone_reg);
511         return E_FAIL;
512     };
513
514     wsprintfW(key_name, wszFormat, wszZonesKey, zone);
515
516     res = RegOpenKeyW(parent_key, key_name, hkey);
517
518     if(res != ERROR_SUCCESS) {
519         WARN("RegOpenKey failed\n");
520         return E_INVALIDARG;
521     }
522
523     return S_OK;
524 }
525
526 /********************************************************************
527  *      IInternetZoneManager_QueryInterface
528  */
529 static HRESULT WINAPI ZoneMgrImpl_QueryInterface(IInternetZoneManager* iface, REFIID riid, void** ppvObject)
530 {
531     ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
532
533     TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppvObject);
534
535     if(!This || !ppvObject)
536         return E_INVALIDARG;
537
538     if(!IsEqualIID(&IID_IUnknown, riid) && !IsEqualIID(&IID_IInternetZoneManager, riid)) {
539         FIXME("Unknown interface: %s\n", debugstr_guid(riid));
540         *ppvObject = NULL;
541         return E_NOINTERFACE;
542     }
543
544     *ppvObject = iface;
545     IInternetZoneManager_AddRef(iface);
546
547     return S_OK;
548 }
549
550 /********************************************************************
551  *      IInternetZoneManager_AddRef
552  */
553 static ULONG WINAPI ZoneMgrImpl_AddRef(IInternetZoneManager* iface)
554 {
555     ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
556     ULONG refCount = InterlockedIncrement(&This->ref);
557
558     TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);
559
560     return refCount;
561 }
562
563 /********************************************************************
564  *      IInternetZoneManager_Release
565  */
566 static ULONG WINAPI ZoneMgrImpl_Release(IInternetZoneManager* iface)
567 {
568     ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
569     ULONG refCount = InterlockedDecrement(&This->ref);
570
571     TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);
572
573     if(!refCount) {
574         HeapFree(GetProcessHeap(), 0, This);
575         URLMON_UnlockModule();
576     }
577     
578     return refCount;
579 }
580
581 /********************************************************************
582  *      IInternetZoneManager_GetZoneAttributes
583  */
584 static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributes(IInternetZoneManager* iface,
585                                                     DWORD dwZone,
586                                                     ZONEATTRIBUTES* pZoneAttributes)
587 {
588     FIXME("(%p)->(%d %p) stub\n", iface, dwZone, pZoneAttributes);
589     return E_NOTIMPL;
590 }
591
592 /********************************************************************
593  *      IInternetZoneManager_SetZoneAttributes
594  */
595 static HRESULT WINAPI ZoneMgrImpl_SetZoneAttributes(IInternetZoneManager* iface,
596                                                     DWORD dwZone,
597                                                     ZONEATTRIBUTES* pZoneAttributes)
598 {
599     FIXME("(%p)->(%08x %p) stub\n", iface, dwZone, pZoneAttributes);
600     return E_NOTIMPL;
601 }
602
603 /********************************************************************
604  *      IInternetZoneManager_GetZoneCustomPolicy
605  */
606 static HRESULT WINAPI ZoneMgrImpl_GetZoneCustomPolicy(IInternetZoneManager* iface,
607                                                       DWORD dwZone,
608                                                       REFGUID guidKey,
609                                                       BYTE** ppPolicy,
610                                                       DWORD* pcbPolicy,
611                                                       URLZONEREG ulrZoneReg)
612 {
613     FIXME("(%p)->(%08x %s %p %p %08x) stub\n", iface, dwZone, debugstr_guid(guidKey),
614                                                     ppPolicy, pcbPolicy, ulrZoneReg);
615     return E_NOTIMPL;
616 }
617
618 /********************************************************************
619  *      IInternetZoneManager_SetZoneCustomPolicy
620  */
621 static HRESULT WINAPI ZoneMgrImpl_SetZoneCustomPolicy(IInternetZoneManager* iface,
622                                                       DWORD dwZone,
623                                                       REFGUID guidKey,
624                                                       BYTE* ppPolicy,
625                                                       DWORD cbPolicy,
626                                                       URLZONEREG ulrZoneReg)
627 {
628     FIXME("(%p)->(%08x %s %p %08x %08x) stub\n", iface, dwZone, debugstr_guid(guidKey),
629                                                     ppPolicy, cbPolicy, ulrZoneReg);
630     return E_NOTIMPL;
631 }
632
633 /********************************************************************
634  *      IInternetZoneManager_GetZoneActionPolicy
635  */
636 static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicy(IInternetZoneManager* iface,
637         DWORD dwZone, DWORD dwAction, BYTE* pPolicy, DWORD cbPolicy, URLZONEREG urlZoneReg)
638 {
639     WCHAR action[16];
640     HKEY hkey;
641     LONG res;
642     DWORD size = cbPolicy;
643     HRESULT hres;
644
645     static const WCHAR wszFormat[] = {'%','l','X',0};
646
647     TRACE("(%p)->(%d %08x %p %d %d)\n", iface, dwZone, dwAction, pPolicy,
648             cbPolicy, urlZoneReg);
649
650     if(!pPolicy)
651         return E_INVALIDARG;
652
653     hres = open_zone_key(dwZone, &hkey, urlZoneReg);
654     if(FAILED(hres))
655         return hres;
656
657     wsprintfW(action, wszFormat, dwAction);
658
659     res = RegQueryValueExW(hkey, action, NULL, NULL, pPolicy, &size);
660     if(res == ERROR_MORE_DATA) {
661         hres = E_INVALIDARG;
662     }else if(res == ERROR_FILE_NOT_FOUND) {
663         hres = E_FAIL;
664     }else if(res != ERROR_SUCCESS) {
665         ERR("RegQueryValue failed: %d\n", res);
666         hres = E_UNEXPECTED;
667     }
668
669     RegCloseKey(hkey);
670
671     return hres;
672 }
673
674 /********************************************************************
675  *      IInternetZoneManager_SetZoneActionPolicy
676  */
677 static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicy(IInternetZoneManager* iface,
678                                                       DWORD dwZone,
679                                                       DWORD dwAction,
680                                                       BYTE* pPolicy,
681                                                       DWORD cbPolicy,
682                                                       URLZONEREG urlZoneReg)
683 {
684     FIXME("(%p)->(%08x %08x %p %08x %08x) stub\n", iface, dwZone, dwAction, pPolicy,
685                                                        cbPolicy, urlZoneReg);
686     return E_NOTIMPL;
687 }
688
689 /********************************************************************
690  *      IInternetZoneManager_PromptAction
691  */
692 static HRESULT WINAPI ZoneMgrImpl_PromptAction(IInternetZoneManager* iface,
693                                                DWORD dwAction,
694                                                HWND hwndParent,
695                                                LPCWSTR pwszUrl,
696                                                LPCWSTR pwszText,
697                                                DWORD dwPromptFlags)
698 {
699     FIXME("%p %08x %p %s %s %08x\n", iface, dwAction, hwndParent,
700           debugstr_w(pwszUrl), debugstr_w(pwszText), dwPromptFlags );
701     return E_NOTIMPL;
702 }
703
704 /********************************************************************
705  *      IInternetZoneManager_LogAction
706  */
707 static HRESULT WINAPI ZoneMgrImpl_LogAction(IInternetZoneManager* iface,
708                                             DWORD dwAction,
709                                             LPCWSTR pwszUrl,
710                                             LPCWSTR pwszText,
711                                             DWORD dwLogFlags)
712 {
713     FIXME("(%p)->(%08x %s %s %08x) stub\n", iface, dwAction, debugstr_w(pwszUrl),
714                                               debugstr_w(pwszText), dwLogFlags);
715     return E_NOTIMPL;
716 }
717
718 /********************************************************************
719  *      IInternetZoneManager_CreateZoneEnumerator
720  */
721 static HRESULT WINAPI ZoneMgrImpl_CreateZoneEnumerator(IInternetZoneManager* iface,
722                                                        DWORD* pdwEnum,
723                                                        DWORD* pdwCount,
724                                                        DWORD dwFlags)
725 {
726     FIXME("(%p)->(%p %p %08x) stub\n", iface, pdwEnum, pdwCount, dwFlags);
727     return E_NOTIMPL;
728 }
729
730 /********************************************************************
731  *      IInternetZoneManager_GetZoneAt
732  */
733 static HRESULT WINAPI ZoneMgrImpl_GetZoneAt(IInternetZoneManager* iface,
734                                             DWORD dwEnum,
735                                             DWORD dwIndex,
736                                             DWORD* pdwZone)
737 {
738     FIXME("(%p)->(%08x %08x %p) stub\n", iface, dwEnum, dwIndex, pdwZone);
739     return E_NOTIMPL;
740 }
741
742 /********************************************************************
743  *      IInternetZoneManager_DestroyZoneEnumerator
744  */
745 static HRESULT WINAPI ZoneMgrImpl_DestroyZoneEnumerator(IInternetZoneManager* iface,
746                                                         DWORD dwEnum)
747 {
748     FIXME("(%p)->(%08x) stub\n", iface, dwEnum);
749     return E_NOTIMPL;
750 }
751
752 /********************************************************************
753  *      IInternetZoneManager_CopyTemplatePoliciesToZone
754  */
755 static HRESULT WINAPI ZoneMgrImpl_CopyTemplatePoliciesToZone(IInternetZoneManager* iface,
756                                                              DWORD dwTemplate,
757                                                              DWORD dwZone,
758                                                              DWORD dwReserved)
759 {
760     FIXME("(%p)->(%08x %08x %08x) stub\n", iface, dwTemplate, dwZone, dwReserved);
761     return E_NOTIMPL;
762 }
763
764 /********************************************************************
765  *      IInternetZoneManager_Construct
766  */
767 static const IInternetZoneManagerVtbl ZoneMgrImplVtbl = {
768     ZoneMgrImpl_QueryInterface,
769     ZoneMgrImpl_AddRef,
770     ZoneMgrImpl_Release,
771     ZoneMgrImpl_GetZoneAttributes,
772     ZoneMgrImpl_SetZoneAttributes,
773     ZoneMgrImpl_GetZoneCustomPolicy,
774     ZoneMgrImpl_SetZoneCustomPolicy,
775     ZoneMgrImpl_GetZoneActionPolicy,
776     ZoneMgrImpl_SetZoneActionPolicy,
777     ZoneMgrImpl_PromptAction,
778     ZoneMgrImpl_LogAction,
779     ZoneMgrImpl_CreateZoneEnumerator,
780     ZoneMgrImpl_GetZoneAt,
781     ZoneMgrImpl_DestroyZoneEnumerator,
782     ZoneMgrImpl_CopyTemplatePoliciesToZone,
783 };
784
785 HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
786 {
787     ZoneMgrImpl* ret = HeapAlloc(GetProcessHeap(), 0, sizeof(ZoneMgrImpl));
788
789     TRACE("(%p %p)\n", pUnkOuter, ppobj);
790     ret->lpVtbl = &ZoneMgrImplVtbl;
791     ret->ref = 1;
792     *ppobj = (IInternetZoneManager*)ret;
793
794     URLMON_LockModule();
795
796     return S_OK;
797 }
798
799 /***********************************************************************
800  *           CoInternetCreateSecurityManager (URLMON.@)
801  *
802  */
803 HRESULT WINAPI CoInternetCreateSecurityManager( IServiceProvider *pSP,
804     IInternetSecurityManager **ppSM, DWORD dwReserved )
805 {
806     TRACE("%p %p %d\n", pSP, ppSM, dwReserved );
807
808     if(pSP)
809         FIXME("pSP not supported\n");
810
811     return SecManagerImpl_Construct(NULL, (void**) ppSM);
812 }
813
814 /********************************************************************
815  *      CoInternetCreateZoneManager (URLMON.@)
816  */
817 HRESULT WINAPI CoInternetCreateZoneManager(IServiceProvider* pSP, IInternetZoneManager** ppZM, DWORD dwReserved)
818 {
819     TRACE("(%p %p %x)\n", pSP, ppZM, dwReserved);
820     return ZoneMgrImpl_Construct(NULL, (void**)ppZM);
821 }