d3d10core: Fixup HRESULT in a bunch of error cases.
[wine] / dlls / urlmon / tests / sec_mgr.c
1 /*
2  * Copyright 2005-2006 Jacek Caban for CodeWeavers
3  * Copyright 2009-2011 Detlef Riekenberg
4  * Copyright 2011 Thomas Mullaly for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define COBJMACROS
22 #define CONST_VTABLE
23 #define NONAMELESSUNION
24
25 /* needed for IInternetZoneManagerEx2 */
26 #define _WIN32_IE 0x0700
27
28 #include <wine/test.h>
29 #include <stdarg.h>
30 #include <stddef.h>
31 #include <stdio.h>
32
33 #include "windef.h"
34 #include "winbase.h"
35 #include "ole2.h"
36 #include "urlmon.h"
37
38 #include "initguid.h"
39
40 #define URLZONE_CUSTOM  URLZONE_USER_MIN+1
41 #define URLZONE_CUSTOM2 URLZONE_CUSTOM+1
42
43 #define DEFINE_EXPECT(func) \
44     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
45
46 #define SET_EXPECT(func) \
47     expect_ ## func = TRUE
48
49 #define CHECK_EXPECT(func) \
50     do { \
51         ok(expect_ ##func, "unexpected call " #func "\n"); \
52         expect_ ## func = FALSE; \
53         called_ ## func = TRUE; \
54     }while(0)
55
56 #define CHECK_EXPECT2(func) \
57     do { \
58         ok(expect_ ##func, "unexpected call " #func "\n"); \
59         called_ ## func = TRUE; \
60     }while(0)
61
62 #define CHECK_CALLED(func) \
63     do { \
64         ok(called_ ## func, "expected " #func "\n"); \
65         expect_ ## func = called_ ## func = FALSE; \
66     }while(0)
67
68 DEFINE_EXPECT(ParseUrl_SECURITY_URL_input);
69 DEFINE_EXPECT(ParseUrl_SECURITY_URL_input2);
70 DEFINE_EXPECT(ParseUrl_SECURITY_URL_expected);
71 DEFINE_EXPECT(ParseUrl_SECURITY_URL_http);
72 DEFINE_EXPECT(ParseUrl_SECURITY_DOMAIN_expected);
73 DEFINE_EXPECT(ProcessUrlAction);
74
75 static HRESULT (WINAPI *pCoInternetCreateSecurityManager)(IServiceProvider *, IInternetSecurityManager**, DWORD);
76 static HRESULT (WINAPI *pCoInternetCreateZoneManager)(IServiceProvider *, IInternetZoneManager**, DWORD);
77 static HRESULT (WINAPI *pCoInternetGetSecurityUrl)(LPCWSTR, LPWSTR*, PSUACTION, DWORD);
78 static HRESULT (WINAPI *pCoInternetGetSecurityUrlEx)(IUri*, IUri**, PSUACTION, DWORD_PTR);
79 static HRESULT (WINAPI *pCreateUri)(LPCWSTR, DWORD, DWORD_PTR, IUri**);
80 static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession**, DWORD);
81 static HRESULT (WINAPI *pCoInternetIsFeatureEnabled)(INTERNETFEATURELIST, DWORD);
82 static HRESULT (WINAPI *pCoInternetIsFeatureEnabledForUrl)(INTERNETFEATURELIST, DWORD, LPCWSTR, IInternetSecurityManager*);
83 static HRESULT (WINAPI *pCoInternetIsFeatureZoneElevationEnabled)(LPCWSTR, LPCWSTR, IInternetSecurityManager*, DWORD);
84
85 static const WCHAR url1[] = {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l',
86         '/','b','l','a','n','k','.','h','t','m',0};
87 static const WCHAR url2[] = {'i','n','d','e','x','.','h','t','m',0};
88 static const WCHAR url3[] = {'f','i','l','e',':','/','/','c',':','\\','I','n','d','e','x','.','h','t','m',0};
89 static const WCHAR url4[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e',
90         '%','2','e','j','p','g',0};
91 static const WCHAR url5[] = {'h','t','t','p',':','/','/','w','w','w','.','z','o','n','e','3',
92         '.','w','i','n','e','t','e','s','t',0};
93 static const WCHAR url6[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
94 static const WCHAR url7[] = {'f','t','p',':','/','/','z','o','n','e','3',
95         '.','w','i','n','e','t','e','s','t','/','f','i','l','e','.','t','e','s','t',0};
96 static const WCHAR url8[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
97 static const WCHAR url9[] = {'h','t','t','p',':','/','/','w','w','w','.','z','o','n','e','3',
98         '.','w','i','n','e','t','e','s','t', '/','s','i','t','e','/','a','b','o','u','t',0};
99 static const WCHAR url10[] = {'f','i','l','e',':','/','/','s','o','m','e','%','2','0','f','i','l','e',
100         '.','j','p','g',0};
101 static const WCHAR url11[] = {'f','i','l','e',':','/','/','c',':','/','I','n','d','e','x','.','h','t','m',0};
102 static const WCHAR url12[] = {'f','i','l','e',':','/','/','/','c',':','/','I','n','d','e','x','.','h','t','m',0};
103
104 static const WCHAR url4e[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e',
105         '.','j','p','g',0};
106
107 static const WCHAR winetestW[] = {'w','i','n','e','t','e','s','t',0};
108 static const WCHAR security_urlW[] = {'w','i','n','e','t','e','s','t',':','t','e','s','t','i','n','g',0};
109 static const WCHAR security_url2W[] = {'w','i','n','e','t','e','s','t',':','t','e','s','t','i','n','g','2',0};
110 static const WCHAR security_expectedW[] = {'w','i','n','e','t','e','s','t',':','z','i','p',0};
111 static const WCHAR winetest_to_httpW[] = {'w','i','n','e','t','e','s','t',':','h',0};
112
113 static const char *szZoneMapDomainsKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap\\Domains";
114 static const char *szInternetSettingsKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
115
116 static const BYTE secid1[] = {'f','i','l','e',':',0,0,0,0};
117 static const BYTE secid5[] = {'h','t','t','p',':','w','w','w','.','z','o','n','e','3',
118         '.','w','i','n','e','t','e','s','t',3,0,0,0};
119 static const BYTE secid6[] = {'a','b','o','u','t',':','b','l','a','n','k',3,0,0,0};
120 static const BYTE secid7[] = {'f','t','p',':','z','o','n','e','3',
121         '.','w','i','n','e','t','e','s','t',3,0,0,0};
122 static const BYTE secid10[] =
123     {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e','.','j','p','g',3,0,0,0};
124 static const BYTE secid10_2[] =
125     {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e','.','j','p','g',3,0,0,0};
126
127 static const GUID CLSID_TestActiveX =
128     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x46}};
129
130 /* Defined as extern in urlmon.idl, but not exported by uuid.lib */
131 const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
132     {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
133
134 static int called_securl_http;
135 static DWORD ProcessUrlAction_policy;
136
137 static struct secmgr_test {
138     LPCWSTR url;
139     DWORD zone;
140     HRESULT zone_hres;
141     DWORD secid_size;
142     const BYTE *secid;
143     HRESULT secid_hres;
144 } secmgr_tests[] = {
145     {url1, 0,   S_OK, sizeof(secid1), secid1, S_OK},
146     {url2, 100, 0x80041001, 0, NULL, E_INVALIDARG},
147     {url3, 0,   S_OK, sizeof(secid1), secid1, S_OK},
148     {url5, 3,   S_OK, sizeof(secid5), secid5, S_OK},
149     {url6, 3,   S_OK, sizeof(secid6), secid6, S_OK},
150     {url7, 3,   S_OK, sizeof(secid7), secid7, S_OK},
151     {url11,0,   S_OK, sizeof(secid1), secid1, S_OK},
152     {url12,0,   S_OK, sizeof(secid1), secid1, S_OK}
153 };
154
155 static int strcmp_w(const WCHAR *str1, const WCHAR *str2)
156 {
157     DWORD len1 = lstrlenW(str1);
158     DWORD len2 = lstrlenW(str2);
159
160     if(len1!=len2) return 1;
161     return memcmp(str1, str2, len1*sizeof(WCHAR));
162 }
163
164 static inline void heap_free(void *mem)
165 {
166     HeapFree(GetProcessHeap(), 0, mem);
167 }
168
169 static inline LPWSTR a2w(LPCSTR str)
170 {
171     LPWSTR ret = NULL;
172
173     if(str) {
174         DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
175         ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
176         MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
177     }
178
179     return ret;
180 }
181
182 static inline DWORD strcmp_aw(LPCSTR strA, LPCWSTR strB) {
183     LPWSTR strAW = a2w(strA);
184     DWORD ret = lstrcmpW(strAW, strB);
185     heap_free(strAW);
186     return ret;
187 }
188
189
190 /* Based on RegDeleteTreeW from dlls/advapi32/registry.c */
191 static LONG myRegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
192 {
193     LONG ret;
194     DWORD dwMaxSubkeyLen, dwMaxValueLen;
195     DWORD dwMaxLen, dwSize;
196     CHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
197     HKEY hSubKey = hKey;
198
199     if(lpszSubKey)
200     {
201         ret = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
202         if (ret) return ret;
203     }
204
205     /* Get highest length for keys, values */
206     ret = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, NULL,
207             &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
208     if (ret) goto cleanup;
209
210     dwMaxSubkeyLen++;
211     dwMaxValueLen++;
212     dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
213     if (dwMaxLen > sizeof(szNameBuf)/sizeof(CHAR))
214     {
215         /* Name too big: alloc a buffer for it */
216         if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(CHAR))))
217         {
218             ret = ERROR_NOT_ENOUGH_MEMORY;
219             goto cleanup;
220         }
221     }
222
223     /* Recursively delete all the subkeys */
224     while (TRUE)
225     {
226         dwSize = dwMaxLen;
227         if (RegEnumKeyExA(hSubKey, 0, lpszName, &dwSize, NULL,
228                           NULL, NULL, NULL)) break;
229
230         ret = myRegDeleteTreeA(hSubKey, lpszName);
231         if (ret) goto cleanup;
232     }
233
234     if (lpszSubKey)
235         ret = RegDeleteKeyA(hKey, lpszSubKey);
236     else
237         while (TRUE)
238         {
239             dwSize = dwMaxLen;
240             if (RegEnumValueA(hKey, 0, lpszName, &dwSize,
241                   NULL, NULL, NULL, NULL)) break;
242
243             ret = RegDeleteValueA(hKey, lpszName);
244             if (ret) goto cleanup;
245         }
246
247 cleanup:
248     /* Free buffer if allocated */
249     if (lpszName != szNameBuf)
250         heap_free(lpszName);
251     if(lpszSubKey)
252         RegCloseKey(hSubKey);
253     return ret;
254 }
255
256 static HRESULT WINAPI SecurityManager_QueryInterface(IInternetSecurityManager* This,
257         REFIID riid, void **ppvObject)
258 {
259     ok(0, "unexpected call\n");
260     return E_NOTIMPL;
261 }
262
263 static ULONG WINAPI SecurityManager_AddRef(IInternetSecurityManager* This)
264 {
265     return 2;
266 }
267
268 static ULONG WINAPI SecurityManager_Release(IInternetSecurityManager* This)
269 {
270     return 1;
271 }
272
273 static HRESULT WINAPI SecurityManager_SetSecuritySite(IInternetSecurityManager* This,
274         IInternetSecurityMgrSite *pSite)
275 {
276     ok(0, "unexpected call\n");
277     return E_NOTIMPL;
278 }
279
280 static HRESULT WINAPI SecurityManager_GetSecuritySite(IInternetSecurityManager* This,
281         IInternetSecurityMgrSite **ppSite)
282 {
283     ok(0, "unexpected call\n");
284     return E_NOTIMPL;
285 }
286
287 static HRESULT WINAPI SecurityManager_MapUrlToZone(IInternetSecurityManager* This,
288         LPCWSTR pwszUrl, DWORD *pdwZone, DWORD dwFlags)
289 {
290     ok(0, "unexpected call\n");
291     return E_NOTIMPL;
292 }
293
294 static HRESULT WINAPI SecurityManager_GetSecurityId(IInternetSecurityManager* This,
295         LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
296 {
297     ok(0, "unexpected call\n");
298     return E_NOTIMPL;
299 }
300
301 static HRESULT WINAPI SecurityManager_ProcessUrlAction(IInternetSecurityManager* This,
302         LPCWSTR pwszUrl, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy,
303         BYTE *pContext, DWORD cbContext, DWORD dwFlags, DWORD dwReserved)
304 {
305     CHECK_EXPECT(ProcessUrlAction);
306     ok(dwAction == URLACTION_FEATURE_ZONE_ELEVATION, "dwAction = %x\n", dwAction);
307     ok(cbPolicy == sizeof(DWORD), "cbPolicy = %d\n", cbPolicy);
308     ok(!pContext, "pContext != NULL\n");
309     ok(dwFlags == PUAF_NOUI, "dwFlags = %x\n", dwFlags);
310     ok(dwReserved == 0, "dwReserved = %x\n", dwReserved);
311
312     *pPolicy = ProcessUrlAction_policy;
313     return ProcessUrlAction_policy==URLPOLICY_ALLOW ? S_OK : S_FALSE;
314 }
315
316 static HRESULT WINAPI SecurityManager_QueryCustomPolicy(IInternetSecurityManager* This,
317         LPCWSTR pwszUrl, REFGUID guidKey, BYTE **ppPolicy, DWORD *pcbPolicy,
318         BYTE *pContext, DWORD cbContext, DWORD dwReserved)
319 {
320     ok(0, "unexpected call\n");
321     return E_NOTIMPL;
322 }
323
324 static HRESULT WINAPI SecurityManager_SetZoneMapping(IInternetSecurityManager* This,
325         DWORD dwZone, LPCWSTR lpszPattern, DWORD dwFlags)
326 {
327     ok(0, "unexpected call\n");
328     return E_NOTIMPL;
329 }
330
331 static HRESULT WINAPI SecurityManager_GetZoneMappings(IInternetSecurityManager* This,
332         DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags)
333 {
334     ok(0, "unexpected call\n");
335     return E_NOTIMPL;
336 }
337
338 static const IInternetSecurityManagerVtbl SecurityManagerVtbl = {
339     SecurityManager_QueryInterface,
340     SecurityManager_AddRef,
341     SecurityManager_Release,
342     SecurityManager_SetSecuritySite,
343     SecurityManager_GetSecuritySite,
344     SecurityManager_MapUrlToZone,
345     SecurityManager_GetSecurityId,
346     SecurityManager_ProcessUrlAction,
347     SecurityManager_QueryCustomPolicy,
348     SecurityManager_SetZoneMapping,
349     SecurityManager_GetZoneMappings
350 };
351
352 static IInternetSecurityManager security_manager = { &SecurityManagerVtbl };
353
354 static void test_SecurityManager(void)
355 {
356     int i;
357     IInternetSecurityManager *secmgr = NULL;
358     BYTE buf[512];
359     DWORD zone, size, policy;
360     HRESULT hres;
361
362     if(!pCoInternetCreateSecurityManager) {
363         return;
364     }
365
366     trace("Testing security manager...\n");
367
368     hres = pCoInternetCreateSecurityManager(NULL, &secmgr, 0);
369     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
370     if(FAILED(hres))
371         return;
372
373     for(i=0; i < sizeof(secmgr_tests)/sizeof(secmgr_tests[0]); i++) {
374         zone = 100;
375         hres = IInternetSecurityManager_MapUrlToZone(secmgr, secmgr_tests[i].url,
376                                                      &zone, 0);
377         ok(hres == secmgr_tests[i].zone_hres /* IE <=6 */
378            || (FAILED(secmgr_tests[i].zone_hres) && hres == E_INVALIDARG), /* IE7 */
379            "[%d] MapUrlToZone failed: %08x, expected %08x\n",
380                 i, hres, secmgr_tests[i].zone_hres);
381         if(SUCCEEDED(hres))
382             ok(zone == secmgr_tests[i].zone, "[%d] zone=%d, expected %d\n", i, zone,
383                secmgr_tests[i].zone);
384         else
385             ok(zone == secmgr_tests[i].zone || zone == -1, "[%d] zone=%d\n", i, zone);
386
387         size = sizeof(buf);
388         memset(buf, 0xf0, sizeof(buf));
389         hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[i].url,
390                 buf, &size, 0);
391         ok(hres == secmgr_tests[i].secid_hres,
392            "[%d] GetSecurityId failed: %08x, expected %08x\n",
393            i, hres, secmgr_tests[i].secid_hres);
394         if(secmgr_tests[i].secid) {
395             ok(size == secmgr_tests[i].secid_size, "[%d] size=%d, expected %d\n",
396                     i, size, secmgr_tests[i].secid_size);
397             ok(!memcmp(buf, secmgr_tests[i].secid, size), "[%d] wrong secid\n", i);
398         }
399     }
400
401     zone = 100;
402     hres = IInternetSecurityManager_MapUrlToZone(secmgr, url10, &zone, 0);
403     ok(hres == S_OK, "MapUrlToZone failed: %08x, expected S_OK\n", hres);
404     ok(zone == 3, "zone=%d, expected 3\n", zone);
405
406     /* win2k3 translates %20 into a space */
407     size = sizeof(buf);
408     memset(buf, 0xf0, sizeof(buf));
409     hres = IInternetSecurityManager_GetSecurityId(secmgr, url10, buf, &size, 0);
410     ok(hres == S_OK, "GetSecurityId failed: %08x, expected S_OK\n", hres);
411     ok(size == sizeof(secid10) ||
412        size == sizeof(secid10_2), /* win2k3 */
413        "size=%d\n", size);
414     ok(!memcmp(buf, secid10, size) ||
415        !memcmp(buf, secid10_2, size), /* win2k3 */
416        "wrong secid\n");
417
418     zone = 100;
419     hres = IInternetSecurityManager_MapUrlToZone(secmgr, NULL, &zone, 0);
420     ok(hres == E_INVALIDARG, "MapUrlToZone failed: %08x, expected E_INVALIDARG\n", hres);
421     ok(zone == 100 || zone == -1, "zone=%d\n", zone);
422
423     size = sizeof(buf);
424     hres = IInternetSecurityManager_GetSecurityId(secmgr, NULL, buf, &size, 0);
425     ok(hres == E_INVALIDARG,
426        "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
427     hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[1].url,
428                                                   NULL, &size, 0);
429     ok(hres == E_INVALIDARG,
430        "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
431     hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[1].url,
432                                                   buf, NULL, 0);
433     ok(hres == E_INVALIDARG,
434        "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
435
436     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, NULL, URLACTION_SCRIPT_RUN, (BYTE*)&policy,
437             sizeof(WCHAR), NULL, 0, 0, 0);
438     ok(hres == E_INVALIDARG, "ProcessUrlAction failed: %08x, expected E_INVALIDARG\n", hres);
439
440     IInternetSecurityManager_Release(secmgr);
441 }
442
443 /* Check if Internet Explorer is configured to run in "Enhanced Security Configuration" (aka hardened mode) */
444 /* Note: this code is duplicated in dlls/mshtml/tests/mshtml_test.h and dlls/urlmon/tests/sec_mgr.c */
445 static BOOL is_ie_hardened(void)
446 {
447     HKEY zone_map;
448     DWORD ie_harden, type, size;
449
450     ie_harden = 0;
451     if(RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap",
452                     0, KEY_QUERY_VALUE, &zone_map) == ERROR_SUCCESS) {
453         size = sizeof(DWORD);
454         if (RegQueryValueExA(zone_map, "IEHarden", NULL, &type, (LPBYTE) &ie_harden, &size) != ERROR_SUCCESS ||
455             type != REG_DWORD) {
456             ie_harden = 0;
457         }
458         RegCloseKey(zone_map);
459     }
460
461     return ie_harden != 0;
462 }
463
464 static void test_url_action(IInternetSecurityManager *secmgr, IInternetZoneManager *zonemgr, DWORD action)
465 {
466     DWORD res, size, policy, reg_policy;
467     char buf[10];
468     HKEY hkey;
469     HRESULT hres;
470
471     /* FIXME: HKEY_CURRENT_USER is most of the time the default but this can be changed on a system.
472      * The test should be changed to cope with that, if need be.
473      */
474     res = RegOpenKeyA(HKEY_CURRENT_USER,
475             "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3", &hkey);
476     if(res != ERROR_SUCCESS) {
477         ok(0, "Could not open zone key\n");
478         return;
479     }
480
481     wsprintf(buf, "%X", action);
482     size = sizeof(DWORD);
483     res = RegQueryValueExA(hkey, buf, NULL, NULL, (BYTE*)&reg_policy, &size);
484     RegCloseKey(hkey);
485     if(res != ERROR_SUCCESS || size != sizeof(DWORD)) {
486         policy = 0xdeadbeef;
487         hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
488                 sizeof(WCHAR), NULL, 0, 0, 0);
489         ok(hres == E_FAIL || broken(hres == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)),
490             "(0x%x) got 0x%x (expected E_FAIL)\n", action, hres);
491         ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
492
493         policy = 0xdeadbeef;
494         hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
495                 sizeof(DWORD), URLZONEREG_DEFAULT);
496         ok(hres == E_FAIL || broken(hres == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)),
497             "(0x%x) got 0x%x (expected E_FAIL)\n", action, hres);
498         ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
499         return;
500     }
501
502     policy = 0xdeadbeef;
503     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
504             sizeof(DWORD), URLZONEREG_DEFAULT);
505     ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
506     ok(policy == reg_policy, "(%x) policy=%x, expected %x\n", action, policy, reg_policy);
507
508     if(policy != URLPOLICY_QUERY) {
509         if(winetest_interactive || ! is_ie_hardened()) {
510             BOOL expect_parse_call = !called_securl_http;
511
512             policy = 0xdeadbeef;
513             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
514                     sizeof(WCHAR), NULL, 0, 0, 0);
515             if(reg_policy == URLPOLICY_DISALLOW)
516                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
517             else
518                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
519             ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
520
521             policy = 0xdeadbeef;
522             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
523                     2, NULL, 0, 0, 0);
524             if(reg_policy == URLPOLICY_DISALLOW)
525                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
526             else
527                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
528             ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
529
530             policy = 0xdeadbeef;
531             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
532                     sizeof(DWORD), NULL, 0, 0, 0);
533             if(reg_policy == URLPOLICY_DISALLOW)
534                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
535             else
536                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
537             ok(policy == reg_policy, "(%x) policy=%x\n", action, policy);
538
539             policy = 0xdeadbeef;
540             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
541                     sizeof(WCHAR), (BYTE*)0xdeadbeef, 16, 0, 0);
542             if(reg_policy == URLPOLICY_DISALLOW)
543                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
544             else
545                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
546             ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
547
548             policy = 0xdeadbeef;
549             if(expect_parse_call)
550                 SET_EXPECT(ParseUrl_SECURITY_URL_http);
551             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, winetest_to_httpW, action, (BYTE*)&policy,
552                     sizeof(DWORD), NULL, 0, 0, 0);
553             if(expect_parse_call)
554                 CHECK_CALLED(ParseUrl_SECURITY_URL_http);
555             if(reg_policy == URLPOLICY_DISALLOW)
556                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
557             else
558                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
559             ok(policy == reg_policy, "(%x) policy=%x\n", action, policy);
560         }else {
561             skip("IE running in Enhanced Security Configuration\n");
562         }
563     }
564 }
565
566 static void test_special_url_action(IInternetSecurityManager *secmgr, IInternetZoneManager *zonemgr, DWORD action)
567 {
568     DWORD policy;
569     HRESULT hres;
570
571     policy = 0xdeadbeef;
572     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
573             sizeof(DWORD), URLZONEREG_DEFAULT);
574     ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
575     ok(policy == URLPOLICY_DISALLOW, "(%x) policy=%x, expected URLPOLICY_DISALLOW\n", action, policy);
576
577     policy = 0xdeadbeef;
578     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url1, action, (BYTE*)&policy,
579             sizeof(WCHAR), NULL, 0, 0, 0);
580     ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
581
582     policy = 0xdeadbeef;
583     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url1, action, (BYTE*)&policy,
584             sizeof(DWORD), NULL, 0, 0, 0);
585     ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
586     ok(policy == URLPOLICY_DISALLOW, "policy = %x\n", policy);
587 }
588
589 static void test_activex(IInternetSecurityManager *secmgr)
590 {
591     DWORD policy, policy_size;
592     struct CONFIRMSAFETY cs;
593     BYTE *ppolicy;
594     HRESULT hres;
595
596     policy = 0xdeadbeef;
597     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url1, URLACTION_ACTIVEX_RUN, (BYTE*)&policy,
598             sizeof(DWORD), (BYTE*)&CLSID_TestActiveX, sizeof(CLSID), 0, 0);
599     ok(hres == S_OK, "ProcessUrlAction(URLACTION_ACTIVEX_RUN) failed: %08x\n", hres);
600     ok(policy == URLPOLICY_ALLOW || policy == URLPOLICY_DISALLOW, "policy = %x\n", policy);
601
602     cs.clsid = CLSID_TestActiveX;
603     cs.pUnk = (IUnknown*)0xdeadbeef;
604     cs.dwFlags = 0;
605     hres = IInternetSecurityManager_QueryCustomPolicy(secmgr, url1, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
606             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
607     ok(hres == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "QueryCusromPolicy failed: %08x\n", hres);
608 }
609
610 static void test_polices(void)
611 {
612     IInternetZoneManager *zonemgr = NULL;
613     IInternetSecurityManager *secmgr = NULL;
614     HRESULT hres;
615
616     trace("testing polices...\n");
617
618     hres = pCoInternetCreateSecurityManager(NULL, &secmgr, 0);
619     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
620     hres = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
621     ok(hres == S_OK, "CoInternetCreateZoneManager failed: %08x\n", hres);
622
623     test_url_action(secmgr, zonemgr, URLACTION_SCRIPT_RUN);
624     test_url_action(secmgr, zonemgr, URLACTION_ACTIVEX_RUN);
625     test_url_action(secmgr, zonemgr, URLACTION_ACTIVEX_OVERRIDE_OBJECT_SAFETY);
626     test_url_action(secmgr, zonemgr, URLACTION_CHANNEL_SOFTDIST_PERMISSIONS);
627     test_url_action(secmgr, zonemgr, 0xdeadbeef);
628
629     test_special_url_action(secmgr, zonemgr, URLACTION_SCRIPT_OVERRIDE_SAFETY);
630     test_special_url_action(secmgr, zonemgr, URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY);
631
632     test_activex(secmgr);
633
634     IInternetSecurityManager_Release(secmgr);
635     IInternetZoneManager_Release(zonemgr);
636 }
637
638 /* IE (or at least newer versions of it) seem to cache the keys in ZoneMap
639  * when urlmon.dll is loaded and it doesn't seem to update its cache, unless
640  * SetZoneMapping is used.
641  */
642 static void test_zone_domain_cache(void)
643 {
644     HRESULT hres;
645     DWORD res, zone;
646     IInternetSecurityManager *secmgr = NULL;
647     HKEY domains, domain;
648
649     static const WCHAR testing_domain_urlW[] = {'h','t','t','p',':','/','/','t','e','s','t','i','n','g','.',
650             'd','o','m','a','i','n','/',0};
651
652     res = RegOpenKeyA(HKEY_CURRENT_USER, szZoneMapDomainsKey, &domains);
653     ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
654     if(res != ERROR_SUCCESS)
655         return;
656
657     res = RegCreateKeyA(domains, "testing.domain", &domain);
658     ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
659     if(res != ERROR_SUCCESS) {
660         RegCloseKey(domains);
661         return;
662     }
663
664     zone = URLZONE_CUSTOM;
665     res = RegSetValueExA(domain, "http", 0, REG_DWORD, (BYTE*)&zone, sizeof(DWORD));
666     ok(res == ERROR_SUCCESS, "RegSetValueEx failed: %d\n", res);
667
668     RegCloseKey(domain);
669
670     hres = pCoInternetCreateSecurityManager(NULL, &secmgr, 0);
671     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
672
673     zone = URLZONE_INVALID;
674     hres = IInternetSecurityManager_MapUrlToZone(secmgr, testing_domain_urlW, &zone, 0);
675     ok(hres == S_OK, "MapUrlToZone failed: %08x\n", hres);
676     todo_wine ok(zone == URLZONE_INTERNET, "Got %d, expected URLZONE_INTERNET\n", zone);
677
678     /* FIXME: Play nice with ZoneMaps that existed before the test is run. */
679     res = RegDeleteKeyA(domains, "testing.domain");
680     ok(res == ERROR_SUCCESS, "RegDeleteKey failed: %d\n", res);
681
682     RegCloseKey(domains);
683     IInternetSecurityManager_Release(secmgr);
684 }
685
686 typedef struct {
687     const char  *domain;
688     const char  *subdomain;
689     const char  *scheme;
690     DWORD       zone;
691 } zone_domain_mapping;
692
693 /* FIXME: Move these into SetZoneMapping tests when the day comes... */
694 static const zone_domain_mapping zone_domain_mappings[] = {
695     /* Implicitly means "*.yabadaba.do". */
696     {"yabadaba.do",NULL,"http",URLZONE_CUSTOM},
697     /* The '*' doesn't count as a wildcard, since its not the first component of the subdomain. */
698     {"super.cool","testing.*","ftp",URLZONE_CUSTOM2},
699     /* The '*' counts since it's the first component of the subdomain. */
700     {"super.cool","*.testing","ftp",URLZONE_CUSTOM2},
701     /* All known scheme types apply to wildcard schemes. */
702     {"tests.test",NULL,"*",URLZONE_CUSTOM},
703     /* Due to a defect with how windows checks the mappings, unknown scheme types
704      * never seem to get mapped properly. */
705     {"tests.test",NULL,"zip",URLZONE_CUSTOM},
706     {"www.testing.com",NULL,"http",URLZONE_CUSTOM},
707     {"www.testing.com","testing","http",URLZONE_CUSTOM2},
708     {"org",NULL,"http",URLZONE_CUSTOM},
709     {"org","testing","http",URLZONE_CUSTOM2},
710     {"wine.testing",NULL,"*",URLZONE_CUSTOM2}
711 };
712
713 static void register_zone_domains(void)
714 {
715     HKEY domains;
716     DWORD res, i;
717
718     /* Some Windows versions don't seem to have a "Domains" key in their HKLM. */
719     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, szZoneMapDomainsKey, &domains);
720     ok(res == ERROR_SUCCESS || broken(res == ERROR_FILE_NOT_FOUND), "RegOpenKey failed: %d\n", res);
721     if(res == ERROR_SUCCESS) {
722         HKEY domain;
723         DWORD zone = URLZONE_CUSTOM;
724
725         res = RegCreateKeyA(domains, "local.machine", &domain);
726         ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
727
728         res = RegSetValueExA(domain, "http", 0, REG_DWORD, (BYTE*)&zone, sizeof(DWORD));
729         ok(res == ERROR_SUCCESS, "RegSetValueEx failed: %d\n", res);
730
731         RegCloseKey(domain);
732         RegCloseKey(domains);
733     }
734
735     res = RegOpenKeyA(HKEY_CURRENT_USER, szZoneMapDomainsKey, &domains);
736     ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
737
738     for(i = 0; i < sizeof(zone_domain_mappings)/sizeof(zone_domain_mappings[0]); ++i) {
739         const zone_domain_mapping *test = zone_domain_mappings+i;
740         HKEY domain;
741
742         res = RegCreateKeyA(domains, test->domain, &domain);
743         ok(res == ERROR_SUCCESS, "RegCreateKey failed with %d on test %d\n", res, i);
744
745         /* Only set the value if there's no subdomain. */
746         if(!test->subdomain) {
747             res = RegSetValueExA(domain, test->scheme, 0, REG_DWORD, (BYTE*)&test->zone, sizeof(DWORD));
748             ok(res == ERROR_SUCCESS, "RegSetValueEx failed with %d on test %d\n", res, i);
749         } else {
750             HKEY subdomain;
751
752             res = RegCreateKeyA(domain, test->subdomain, &subdomain);
753             ok(res == ERROR_SUCCESS, "RegCreateKey failed with %d on test %d\n", res, i);
754
755             res = RegSetValueExA(subdomain, test->scheme, 0, REG_DWORD, (BYTE*)&test->zone, sizeof(DWORD));
756             ok(res == ERROR_SUCCESS, "RegSetValueEx failed with %d on test %d\n", res, i);
757
758             RegCloseKey(subdomain);
759         }
760
761         RegCloseKey(domain);
762     }
763
764     RegCloseKey(domains);
765 }
766
767 static void unregister_zone_domains(void)
768 {
769     HKEY domains;
770     DWORD res, i;
771
772     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, szZoneMapDomainsKey, &domains);
773     ok(res == ERROR_SUCCESS || broken(res == ERROR_FILE_NOT_FOUND), "RegOpenKey failed: %d\n", res);
774     if(res == ERROR_SUCCESS) {
775         RegDeleteKeyA(domains, "local.machine");
776         RegCloseKey(domains);
777     }
778
779     res = RegOpenKeyA(HKEY_CURRENT_USER, szZoneMapDomainsKey, &domains);
780     ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
781
782     for(i = 0; i < sizeof(zone_domain_mappings)/sizeof(zone_domain_mappings[0]); ++i) {
783         const zone_domain_mapping *test = zone_domain_mappings+i;
784
785         /* FIXME: Uses the "cludge" approach to remove the test data from the registry!
786          *        Although, if domain names are... unique, this shouldn't cause any harm
787          *        to keys (if any) that existed before the tests.
788          */
789         if(test->subdomain) {
790             HKEY domain;
791
792             res = RegOpenKeyA(domains, test->domain, &domain);
793             if(res == ERROR_SUCCESS) {
794                 RegDeleteKeyA(domain, test->subdomain);
795                 RegCloseKey(domain);
796             }
797         }
798         RegDeleteKeyA(domains, test->domain);
799     }
800
801     RegCloseKey(domains);
802 }
803
804 static void run_child_process(void)
805 {
806     char cmdline[MAX_PATH];
807     char path[MAX_PATH];
808     char **argv;
809     PROCESS_INFORMATION pi;
810     STARTUPINFO si = { 0 };
811     BOOL ret;
812
813     GetModuleFileNameA(NULL, path, MAX_PATH);
814
815     si.cb = sizeof(si);
816     winetest_get_mainargs(&argv);
817     sprintf(cmdline, "\"%s\" %s domain_tests", argv[0], argv[1]);
818     ret = CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
819     ok(ret, "Failed to spawn child process: %u\n", GetLastError());
820     winetest_wait_child_process(pi.hProcess);
821     CloseHandle(pi.hThread);
822     CloseHandle(pi.hProcess);
823 }
824
825 typedef struct {
826     const char  *url;
827     DWORD       zone;
828     BOOL        todo;
829     DWORD       broken_zone;
830 } zone_mapping_test;
831
832 static const zone_mapping_test zone_mapping_tests[] = {
833     /* Tests for "yabadaba.do" zone mappings. */
834     {"http://yabadaba.do/",URLZONE_CUSTOM},
835     {"http://google.yabadaba.do/",URLZONE_CUSTOM},
836     {"zip://yabadaba.do/",URLZONE_INTERNET},
837     /* Tests for "super.cool" zone mappings. */
838     {"ftp://testing.google.super.cool/",URLZONE_INTERNET},
839     {"ftp://testing.*.super.cool/",URLZONE_CUSTOM2},
840     {"ftp://google.testing.super.cool/",URLZONE_CUSTOM2},
841     /* Tests for "tests.test" zone mappings. */
842     {"http://tests.test/",URLZONE_CUSTOM},
843     {"http://www.tests.test/",URLZONE_CUSTOM},
844     {"ftp://tests.test/",URLZONE_CUSTOM},
845     {"ftp://www.tests.test/",URLZONE_CUSTOM},
846     {"test://www.tests.test/",URLZONE_INTERNET},
847     {"test://tests.test/",URLZONE_INTERNET},
848     {"zip://www.tests.test/",URLZONE_INTERNET},
849     {"zip://tests.test/",URLZONE_INTERNET},
850     /* Tests for "www.testing.com" zone mappings. */
851     {"http://google.www.testing.com/",URLZONE_INTERNET},
852     {"http://www.testing.com/",URLZONE_CUSTOM,FALSE,URLZONE_INTERNET},
853     {"http://testing.www.testing.com/",URLZONE_CUSTOM2,FALSE,URLZONE_INTERNET},
854     /* Tests for "org" zone mappings. */
855     {"http://google.org/",URLZONE_INTERNET,FALSE,URLZONE_CUSTOM},
856     {"http://org/",URLZONE_CUSTOM},
857     {"http://testing.org/",URLZONE_CUSTOM2},
858     /* Tests for "wine.testing" mapping */
859     {"*:wine.testing/test",URLZONE_CUSTOM2},
860     {"http://wine.testing/testing",URLZONE_CUSTOM2}
861 };
862
863 static void test_zone_domain_mappings(void)
864 {
865     HRESULT hres;
866     DWORD i, res;
867     IInternetSecurityManager *secmgr = NULL;
868     HKEY domains;
869     DWORD zone = URLZONE_INVALID;
870
871     trace("testing zone domain mappings...\n");
872
873     hres = pCoInternetCreateSecurityManager(NULL, &secmgr, 0);
874     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
875
876     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, szZoneMapDomainsKey, &domains);
877     if(res == ERROR_SUCCESS) {
878         static const WCHAR local_machineW[] = {'h','t','t','p',':','/','/','t','e','s','t','.','l','o','c','a','l',
879                 '.','m','a','c','h','i','n','e','/',0};
880
881         hres = IInternetSecurityManager_MapUrlToZone(secmgr, local_machineW, &zone, 0);
882         ok(hres == S_OK, "MapUrlToZone failed: %08x\n", hres);
883         ok(zone == URLZONE_CUSTOM, "Expected URLZONE_CUSTOM, but got %d\n", zone);
884
885         RegCloseKey(domains);
886     }
887
888     for(i = 0; i < sizeof(zone_mapping_tests)/sizeof(zone_mapping_tests[0]); ++i) {
889         const zone_mapping_test *test = zone_mapping_tests+i;
890         LPWSTR urlW = a2w(test->url);
891         zone = URLZONE_INVALID;
892
893         hres = IInternetSecurityManager_MapUrlToZone(secmgr, urlW, &zone, 0);
894         ok(hres == S_OK, "MapUrlToZone failed: %08x\n", hres);
895         if(test->todo)
896             todo_wine
897                 ok(zone == test->zone || broken(test->broken_zone == zone),
898                     "Expected %d, but got %d on test %d\n", test->zone, zone, i);
899         else
900             ok(zone == test->zone || broken(test->broken_zone == zone),
901                 "Expected %d, but got %d on test %d\n", test->zone, zone, i);
902
903         heap_free(urlW);
904     }
905
906     IInternetSecurityManager_Release(secmgr);
907 }
908
909 static void test_zone_domains(void)
910 {
911     if(is_ie_hardened()) {
912         skip("IE running in Enhanced Security Configuration\n");
913         return;
914     } else if(!pCreateUri) {
915         win_skip("Skipping zone domain tests, IE too old\n");
916         return;
917     }
918
919     trace("testing zone domains...\n");
920
921     test_zone_domain_cache();
922
923     register_zone_domains();
924     run_child_process();
925     unregister_zone_domains();
926 }
927
928 static void test_CoInternetCreateZoneManager(void)
929 {
930     IInternetZoneManager *zonemgr = NULL;
931     IUnknown *punk = NULL;
932     HRESULT hr;
933
934     trace("simple zone manager tests...\n");
935
936     hr = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
937     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
938     if (FAILED(hr))
939         return;
940
941     hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IUnknown, (void **) &punk);
942     ok(SUCCEEDED(hr), "got 0x%x with %p (expected Success)\n", hr, punk);
943     if (punk)
944         IUnknown_Release(punk);
945
946     hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IInternetZoneManager, (void **) &punk);
947     ok(SUCCEEDED(hr), "got 0x%x with %p (expected Success)\n", hr, punk);
948     if (punk)
949         IUnknown_Release(punk);
950
951
952     hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IInternetZoneManagerEx, (void **) &punk);
953     if (SUCCEEDED(hr)) {
954         IUnknown_Release(punk);
955
956         hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IInternetZoneManagerEx2, (void **) &punk);
957         ok(hr == S_OK || broken(hr == E_NOINTERFACE /* some W2K3 */),
958            "got 0x%x (expected S_OK)\n", hr);
959         if (punk)
960             IUnknown_Release(punk);
961         else
962             win_skip("InternetZoneManagerEx2 not supported\n");
963
964     }
965     else
966         win_skip("InternetZoneManagerEx not supported\n");
967
968     hr = IInternetZoneManager_Release(zonemgr);
969     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
970
971 }
972
973 static void test_CreateZoneEnumerator(void)
974 {
975     IInternetZoneManager *zonemgr = NULL;
976     HRESULT hr;
977     DWORD dwEnum;
978     DWORD dwEnum2;
979     DWORD dwCount;
980     DWORD dwCount2;
981
982     trace("testing zone enumerator...\n");
983
984     hr = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
985     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
986     if (FAILED(hr))
987         return;
988
989     dwEnum=0xdeadbeef;
990     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, NULL, 0);
991     ok((hr == E_INVALIDARG) && (dwEnum == 0xdeadbeef),
992         "got 0x%x with 0x%x (expected E_INVALIDARG with 0xdeadbeef)\n", hr, dwEnum);
993
994     dwCount=0xdeadbeef;
995     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, NULL, &dwCount, 0);
996     ok((hr == E_INVALIDARG) && (dwCount == 0xdeadbeef),
997         "got 0x%x and 0x%x (expected E_INVALIDARG and 0xdeadbeef)\n", hr, dwCount);
998
999     dwEnum=0xdeadbeef;
1000     dwCount=0xdeadbeef;
1001     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 0xffffffff);
1002     ok((hr == E_INVALIDARG) && (dwEnum == 0xdeadbeef) && (dwCount == 0xdeadbeef),
1003         "got 0x%x with 0x%x and 0x%x (expected E_INVALIDARG with 0xdeadbeef and 0xdeadbeef)\n",
1004         hr, dwEnum, dwCount);
1005
1006     dwEnum=0xdeadbeef;
1007     dwCount=0xdeadbeef;
1008     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 1);
1009     ok((hr == E_INVALIDARG) && (dwEnum == 0xdeadbeef) && (dwCount == 0xdeadbeef),
1010         "got 0x%x with 0x%x and 0x%x (expected E_INVALIDARG with 0xdeadbeef and 0xdeadbeef)\n",
1011         hr, dwEnum, dwCount);
1012
1013     dwEnum=0xdeadbeef;
1014     dwCount=0xdeadbeef;
1015     /* Normal use */
1016     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 0);
1017     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1018
1019     if (SUCCEEDED(hr)) {
1020         dwEnum2=0xdeadbeef;
1021         dwCount2=0xdeadbeef;
1022         hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum2, &dwCount2, 0);
1023         ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1024         if (SUCCEEDED(hr)) {
1025             /* native urlmon has an incrementing counter for dwEnum */
1026             hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum2);
1027             ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1028         }
1029
1030         hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum);
1031         ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1032
1033         /* Destroy the Enumerator twice is detected and handled in native urlmon */
1034         hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum);
1035         ok((hr == E_INVALIDARG), "got 0x%x (expected E_INVALIDARG)\n", hr);
1036     }
1037
1038     /* ::Release succeed also, when a ::DestroyZoneEnumerator is missing */
1039     hr = IInternetZoneManager_Release(zonemgr);
1040     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1041 }
1042
1043 static void test_GetZoneActionPolicy(void)
1044 {
1045     IInternetZoneManager *zonemgr = NULL;
1046     BYTE buf[32];
1047     HRESULT hres;
1048     DWORD action = URLACTION_CREDENTIALS_USE; /* Implemented on all IE versions */
1049
1050     trace("testing GetZoneActionPolixy...\n");
1051
1052     hres = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
1053     ok(hres == S_OK, "CoInternetCreateZoneManager failed: %08x\n", hres);
1054     if(FAILED(hres))
1055         return;
1056
1057     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, buf,
1058             sizeof(DWORD), URLZONEREG_DEFAULT);
1059     ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
1060     ok(*(DWORD*)buf == URLPOLICY_CREDENTIALS_SILENT_LOGON_OK ||
1061             *(DWORD*)buf == URLPOLICY_CREDENTIALS_MUST_PROMPT_USER ||
1062             *(DWORD*)buf == URLPOLICY_CREDENTIALS_CONDITIONAL_PROMPT ||
1063             *(DWORD*)buf == URLPOLICY_CREDENTIALS_ANONYMOUS_ONLY,
1064             "unexpected policy=%d\n", *(DWORD*)buf);
1065
1066     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, NULL,
1067             sizeof(DWORD), URLZONEREG_DEFAULT);
1068     ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
1069
1070     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, buf,
1071             2, URLZONEREG_DEFAULT);
1072     ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
1073
1074     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, 0x1fff, buf,
1075             sizeof(DWORD), URLZONEREG_DEFAULT);
1076     ok(hres == E_FAIL || broken(hres == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)),
1077             "(0x%x) got 0x%x (expected E_FAIL)\n", action, hres);
1078
1079     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 13, action, buf,
1080             sizeof(DWORD), URLZONEREG_DEFAULT);
1081     ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
1082
1083     IInternetZoneManager_Release(zonemgr);
1084 }
1085
1086 static void test_GetZoneAt(void)
1087 {
1088     IInternetZoneManager *zonemgr = NULL;
1089     HRESULT hr;
1090     DWORD dwEnum;
1091     DWORD dwCount;
1092     DWORD dwZone;
1093     DWORD i;
1094
1095     trace("testing GetZoneAt...\n");
1096
1097     hr = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
1098     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
1099     if (FAILED(hr))
1100         return;
1101
1102     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 0);
1103     if (FAILED(hr))
1104         goto cleanup;
1105
1106     if (0) {
1107         /* this crashes with native urlmon */
1108         IInternetZoneManager_GetZoneAt(zonemgr, dwEnum, 0, NULL);
1109     }
1110
1111     dwZone = 0xdeadbeef;
1112     hr = IInternetZoneManager_GetZoneAt(zonemgr, 0xdeadbeef, 0, &dwZone);
1113     ok(hr == E_INVALIDARG,
1114         "got 0x%x with 0x%x (expected E_INVALIDARG)\n", hr, dwZone);
1115
1116     for (i = 0; i < dwCount; i++)
1117     {
1118         dwZone = 0xdeadbeef;
1119         hr = IInternetZoneManager_GetZoneAt(zonemgr, dwEnum, i, &dwZone);
1120         ok(hr == S_OK, "#%d: got x%x with %d (expected S_OK)\n", i, hr, dwZone);
1121     }
1122
1123     dwZone = 0xdeadbeef;
1124     /* MSDN (index .. must be .. less than or equal to) is wrong */
1125     hr = IInternetZoneManager_GetZoneAt(zonemgr, dwEnum, dwCount, &dwZone);
1126     ok(hr == E_INVALIDARG,
1127         "got 0x%x with 0x%x (expected E_INVALIDARG)\n", hr, dwZone);
1128
1129     hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum);
1130     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1131
1132 cleanup:
1133     hr = IInternetZoneManager_Release(zonemgr);
1134     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1135 }
1136
1137 static void test_GetZoneAttributes(void)
1138 {
1139     IInternetZoneManager *zonemgr = NULL;
1140     CHAR buffer [sizeof(ZONEATTRIBUTES) + 32];
1141     ZONEATTRIBUTES* pZA = (ZONEATTRIBUTES*) buffer;
1142     HRESULT hr;
1143     DWORD i;
1144
1145     trace("testing GetZoneAttributes...\n");
1146
1147     hr = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
1148     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
1149     if (FAILED(hr))
1150         return;
1151
1152     /* native urlmon has Zone "0" up to Zone "4" since IE4 */
1153     for (i = 0; i < 5; i++) {
1154         memset(buffer, -1, sizeof(buffer));
1155         hr = IInternetZoneManager_GetZoneAttributes(zonemgr, i, pZA);
1156         ok(hr == S_OK, "#%d: got 0x%x (expected S_OK)\n", i, hr);
1157     }
1158
1159     /* IE8 no longer set cbSize */
1160     memset(buffer, -1, sizeof(buffer));
1161     pZA->cbSize = 0;
1162     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, pZA);
1163     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1164     ok((pZA->cbSize == 0) || (pZA->cbSize == sizeof(ZONEATTRIBUTES)),
1165         "got cbSize = %d (expected 0)\n", pZA->cbSize);
1166
1167     memset(buffer, -1, sizeof(buffer));
1168     pZA->cbSize = 64;
1169     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, pZA);
1170     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1171     ok((pZA->cbSize == 64) || (pZA->cbSize == sizeof(ZONEATTRIBUTES)),
1172         "got cbSize = %d (expected 64)\n", pZA->cbSize);
1173
1174     memset(buffer, -1, sizeof(buffer));
1175     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, pZA);
1176     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1177     ok((pZA->cbSize == 0xffffffff) || (pZA->cbSize == sizeof(ZONEATTRIBUTES)),
1178         "got cbSize = 0x%x (expected 0xffffffff)\n", pZA->cbSize);
1179
1180     /* IE8 no longer fail on invalid zones */
1181     memset(buffer, -1, sizeof(buffer));
1182     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0xdeadbeef, pZA);
1183     ok(hr == S_OK || (hr == E_FAIL),
1184         "got 0x%x (expected S_OK or E_FAIL)\n", hr);
1185
1186     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, NULL);
1187     ok(hr == E_INVALIDARG, "got 0x%x (expected E_INVALIDARG)\n", hr);
1188
1189     hr = IInternetZoneManager_Release(zonemgr);
1190     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1191 }
1192
1193 static void test_SetZoneAttributes(void)
1194 {
1195     IInternetZoneManager *zonemgr = NULL;
1196     CHAR buffer [sizeof(ZONEATTRIBUTES) + 16];
1197     ZONEATTRIBUTES* pZA = (ZONEATTRIBUTES*) buffer;
1198     CHAR regpath[MAX_PATH];
1199     HKEY hkey;
1200     HRESULT hr;
1201     DWORD res;
1202
1203     trace("testing SetZoneAttributes...\n");
1204     hr = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
1205     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
1206     if (FAILED(hr))
1207         return;
1208
1209     memset(buffer, -1, sizeof(buffer));
1210     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, URLZONE_LOCAL_MACHINE, pZA);
1211     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1212
1213     sprintf(regpath, "%s\\Zones\\%d", szInternetSettingsKey, URLZONE_CUSTOM);
1214     res = RegCreateKeyA(HKEY_CURRENT_USER, regpath, &hkey);
1215     RegCloseKey(hkey);
1216
1217     ok(res == ERROR_SUCCESS, "got %d (expected ERROR_SUCCESS)\n", res);
1218     if (res != ERROR_SUCCESS)
1219         goto cleanup;
1220
1221     pZA->cbSize = sizeof(ZONEATTRIBUTES);
1222     hr = IInternetZoneManager_SetZoneAttributes(zonemgr, URLZONE_CUSTOM, NULL);
1223     ok(hr == E_INVALIDARG, "got 0x%x (expected E_INVALIDARG)\n", hr);
1224
1225     /* normal use */
1226     hr = IInternetZoneManager_SetZoneAttributes(zonemgr, URLZONE_CUSTOM, pZA);
1227     if (hr == E_FAIL) {
1228         win_skip("SetZoneAttributes not supported: IE too old\n");
1229         goto cleanup;
1230     }
1231     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1232
1233     /* native urlmon ignores cbSize */
1234     pZA->cbSize = sizeof(ZONEATTRIBUTES) + sizeof(DWORD);
1235     hr = IInternetZoneManager_SetZoneAttributes(zonemgr, URLZONE_CUSTOM, pZA);
1236     ok(hr == S_OK, "got 0x%x for sizeof(ZONEATTRIBUTES) + sizeof(DWORD) (expected S_OK)\n", hr);
1237
1238     pZA->cbSize = sizeof(ZONEATTRIBUTES) - sizeof(DWORD);
1239     hr = IInternetZoneManager_SetZoneAttributes(zonemgr, URLZONE_CUSTOM, pZA);
1240     ok(hr == S_OK, "got 0x%x for sizeof(ZONEATTRIBUTES) - sizeof(DWORD) (expected S_OK)\n", hr);
1241
1242     pZA->cbSize = 0;
1243     hr = IInternetZoneManager_SetZoneAttributes(zonemgr, URLZONE_CUSTOM, pZA);
1244     ok(hr == S_OK, "got 0x%x for size 0 (expected S_OK)\n", hr);
1245
1246     /* The key for the zone must be present, when calling SetZoneAttributes */
1247     myRegDeleteTreeA(HKEY_CURRENT_USER, regpath);
1248     /* E_FAIL is returned from IE6 here, which is reasonable.
1249        All newer IE return S_OK without saving the zone attributes to the registry.
1250        This is a Windows bug, but we have to accept that as standard */
1251     hr = IInternetZoneManager_SetZoneAttributes(zonemgr, URLZONE_CUSTOM, pZA);
1252     ok((hr == S_OK) || broken(hr == E_FAIL), "got 0x%x (expected S_OK)\n", hr);
1253
1254     /* SetZoneAttributes did not create the directory */
1255     res = RegOpenKeyA(HKEY_CURRENT_USER, regpath, &hkey);
1256     ok((res == ERROR_FILE_NOT_FOUND) && (hkey == NULL),
1257         "got %u with %p (expected ERROR_FILE_NOT_FOUND with NULL)\n", res, hkey);
1258
1259     if (hkey) RegCloseKey(hkey);
1260
1261 cleanup:
1262     /* delete zone settings in the registry */
1263     myRegDeleteTreeA(HKEY_CURRENT_USER, regpath);
1264
1265     hr = IInternetZoneManager_Release(zonemgr);
1266     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1267 }
1268
1269
1270 static void test_InternetSecurityMarshalling(void)
1271 {
1272     IInternetSecurityManager *secmgr = NULL;
1273     IUnknown *unk;
1274     IStream *stream;
1275     HRESULT hres;
1276
1277     trace("testing marshalling...\n");
1278
1279     hres = pCoInternetCreateSecurityManager(NULL, &secmgr, 0);
1280     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
1281     if(FAILED(hres))
1282         return;
1283
1284     hres = IInternetSecurityManager_QueryInterface(secmgr, &IID_IUnknown, (void**)&unk);
1285     ok(hres == S_OK, "QueryInterface returned: %08x\n", hres);
1286
1287     hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1288     ok(hres == S_OK, "CreateStreamOnHGlobal returned: %08x\n", hres);
1289
1290     hres = CoMarshalInterface(stream, &IID_IInternetSecurityManager, unk, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1291     /* Not supported in W98 */
1292     ok(hres == S_OK || broken(hres == REGDB_E_IIDNOTREG),
1293         "CoMarshalInterface returned: %08x\n", hres);
1294
1295     IStream_Release(stream);
1296     IUnknown_Release(unk);
1297     IInternetSecurityManager_Release(secmgr);
1298 }
1299
1300 static void test_InternetGetSecurityUrl(void)
1301 {
1302     const WCHAR url5_out[] = {'h','t','t','p',':','w','w','w','.','z','o','n','e','3',
1303                               '.','w','i','n','e','t','e','s','t',0};
1304     const WCHAR url7_out[] = {'f','t','p',':','z','o','n','e','3','.','w','i','n','e','t','e','s','t',0};
1305
1306     const WCHAR *in[] = {url2, url3, url4, url5, url7, url8, url9, url10};
1307     const WCHAR *out_default[] = {url2, url3, url4, url5_out, url7_out, url8, url5_out, url10};
1308     const WCHAR *out_securl[] = {url2, url3, url4, url5, url7, url8, url9, url10};
1309
1310     WCHAR *sec;
1311     DWORD i;
1312     HRESULT hres;
1313
1314     trace("testing CoInternetGetSecurityUrl...\n");
1315
1316     for(i=0; i<sizeof(in)/sizeof(WCHAR*); i++) {
1317         hres = pCoInternetGetSecurityUrl(in[i], &sec, PSU_DEFAULT, 0);
1318         ok(hres == S_OK, "(%d) CoInternetGetSecurityUrl returned: %08x\n", i, hres);
1319         if(hres == S_OK) {
1320             ok(!strcmp_w(sec, out_default[i]), "(%d) Got %s, expected %s\n",
1321                     i, wine_dbgstr_w(sec), wine_dbgstr_w(out_default[i]));
1322             CoTaskMemFree(sec);
1323         }
1324
1325         hres = pCoInternetGetSecurityUrl(in[i], &sec, PSU_SECURITY_URL_ONLY, 0);
1326         ok(hres == S_OK, "(%d) CoInternetGetSecurityUrl returned: %08x\n", i, hres);
1327         if(hres == S_OK) {
1328             ok(!strcmp_w(sec, out_securl[i]), "(%d) Got %s, expected %s\n",
1329                     i, wine_dbgstr_w(sec), wine_dbgstr_w(out_securl[i]));
1330             CoTaskMemFree(sec);
1331         }
1332     }
1333
1334     SET_EXPECT(ParseUrl_SECURITY_URL_input2);
1335     SET_EXPECT(ParseUrl_SECURITY_URL_expected);
1336     SET_EXPECT(ParseUrl_SECURITY_DOMAIN_expected);
1337
1338     hres = pCoInternetGetSecurityUrl(security_url2W, &sec, PSU_DEFAULT, 0);
1339     ok(hres == S_OK, "CoInternetGetSecurityUrl returned 0x%08x, expected S_OK\n", hres);
1340
1341     CHECK_CALLED(ParseUrl_SECURITY_URL_input2);
1342     CHECK_CALLED(ParseUrl_SECURITY_URL_expected);
1343     CHECK_CALLED(ParseUrl_SECURITY_DOMAIN_expected);
1344
1345     ok(!lstrcmpW(security_expectedW, sec), "Expected %s but got %s\n",
1346        wine_dbgstr_w(security_expectedW), wine_dbgstr_w(sec));
1347     CoTaskMemFree(sec);
1348 }
1349
1350 static HRESULT WINAPI InternetProtocolInfo_QueryInterface(IInternetProtocolInfo *iface,
1351                                                           REFIID riid, void **ppv)
1352 {
1353     ok(0, "unexpected call\n");
1354     return E_NOINTERFACE;
1355 }
1356
1357 static ULONG WINAPI InternetProtocolInfo_AddRef(IInternetProtocolInfo *iface)
1358 {
1359     return 2;
1360 }
1361
1362 static ULONG WINAPI InternetProtocolInfo_Release(IInternetProtocolInfo *iface)
1363 {
1364     return 1;
1365 }
1366
1367 static HRESULT WINAPI InternetProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
1368         PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
1369         DWORD *pcchResult, DWORD dwReserved)
1370 {
1371     const WCHAR *ret = NULL;
1372
1373     ok(pwzResult != NULL, "pwzResult == NULL\n");
1374     ok(pcchResult != NULL, "pcchResult == NULL\n");
1375     ok(!dwParseFlags, "Expected 0, but got 0x%08x\n", dwParseFlags);
1376
1377     switch(ParseAction) {
1378     case PARSE_SECURITY_URL:
1379         if(!strcmp_w(pwzUrl, security_urlW)) {
1380             CHECK_EXPECT(ParseUrl_SECURITY_URL_input);
1381             ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
1382             ret = security_expectedW;
1383         } else if(!strcmp_w(pwzUrl, security_url2W)) {
1384             CHECK_EXPECT(ParseUrl_SECURITY_URL_input2);
1385             ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
1386             ret = security_expectedW;
1387         } else if(!strcmp_w(pwzUrl, security_expectedW)) {
1388             CHECK_EXPECT(ParseUrl_SECURITY_URL_expected);
1389             ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
1390             ret = security_expectedW;
1391         } else if(!strcmp_w(pwzUrl, winetest_to_httpW)) {
1392             switch(++called_securl_http) {
1393             case 1:
1394                 ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
1395                 break;
1396             case 2:
1397                 CHECK_EXPECT(ParseUrl_SECURITY_URL_http);
1398                 ok(cchResult == lstrlenW(url9)+1, "Got %d\n", cchResult);
1399                 break;
1400             default:
1401                 todo_wine CHECK_EXPECT(ParseUrl_SECURITY_URL_http);
1402             }
1403             ret = url9;
1404         } else
1405             ok(0, "Unexpected call, pwzUrl=%s\n", wine_dbgstr_w(pwzUrl));
1406
1407         break;
1408     case PARSE_SECURITY_DOMAIN:
1409
1410         CHECK_EXPECT(ParseUrl_SECURITY_DOMAIN_expected);
1411
1412         ok(!strcmp_w(pwzUrl, security_expectedW), "Expected %s but got %s\n",
1413             wine_dbgstr_w(security_expectedW), wine_dbgstr_w(pwzUrl));
1414         ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
1415         ret = security_expectedW;
1416         break;
1417     default:
1418         ok(0, "Unexpected call, ParseAction=%d pwzUrl=%s\n", ParseAction,
1419             wine_dbgstr_w(pwzUrl));
1420     }
1421
1422     if(!ret)
1423         return E_FAIL;
1424
1425     *pcchResult = lstrlenW(ret)+1;
1426     if(*pcchResult > cchResult)
1427         return S_FALSE;
1428     memcpy(pwzResult, ret, (*pcchResult)*sizeof(WCHAR));
1429     return S_OK;
1430 }
1431
1432 static HRESULT WINAPI InternetProtocolInfo_CombineUrl(IInternetProtocolInfo *iface,
1433         LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags,
1434         LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
1435 {
1436     ok(0, "unexpected call\n");
1437     return E_NOTIMPL;
1438 }
1439
1440 static HRESULT WINAPI InternetProtocolInfo_CompareUrl(IInternetProtocolInfo *iface,
1441         LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
1442 {
1443     ok(0, "unexpected call\n");
1444     return E_NOTIMPL;
1445 }
1446
1447 static HRESULT WINAPI InternetProtocolInfo_QueryInfo(IInternetProtocolInfo *iface,
1448         LPCWSTR pwzUrl, QUERYOPTION OueryOption, DWORD dwQueryFlags, LPVOID pBuffer,
1449         DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved)
1450 {
1451     ok(0, "unexpected call\n");
1452     return E_NOTIMPL;
1453 }
1454
1455 static const IInternetProtocolInfoVtbl InternetProtocolInfoVtbl = {
1456     InternetProtocolInfo_QueryInterface,
1457     InternetProtocolInfo_AddRef,
1458     InternetProtocolInfo_Release,
1459     InternetProtocolInfo_ParseUrl,
1460     InternetProtocolInfo_CombineUrl,
1461     InternetProtocolInfo_CompareUrl,
1462     InternetProtocolInfo_QueryInfo
1463 };
1464
1465 static IInternetProtocolInfo protocol_info = { &InternetProtocolInfoVtbl };
1466
1467 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
1468 {
1469     if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
1470         *ppv = &protocol_info;
1471         return S_OK;
1472     }
1473
1474     ok(0, "unexpected call\n");
1475     return E_NOINTERFACE;
1476 }
1477
1478 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
1479 {
1480     return 2;
1481 }
1482
1483 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
1484 {
1485     return 1;
1486 }
1487
1488 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
1489                                         REFIID riid, void **ppv)
1490 {
1491     ok(0, "unexpected call\n");
1492     return E_NOTIMPL;
1493 }
1494
1495 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
1496 {
1497     ok(0, "unexpected call\n");
1498     return S_OK;
1499 }
1500
1501 static const IClassFactoryVtbl ClassFactoryVtbl = {
1502     ClassFactory_QueryInterface,
1503     ClassFactory_AddRef,
1504     ClassFactory_Release,
1505     ClassFactory_CreateInstance,
1506     ClassFactory_LockServer
1507 };
1508
1509 static IClassFactory protocol_cf = { &ClassFactoryVtbl };
1510
1511 static void register_protocols(void)
1512 {
1513     IInternetSession *session;
1514     HRESULT hres;
1515
1516     hres = pCoInternetGetSession(0, &session, 0);
1517     ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
1518     if(FAILED(hres))
1519         return;
1520
1521     hres = IInternetSession_RegisterNameSpace(session, &protocol_cf, &IID_NULL,
1522             winetestW, 0, NULL, 0);
1523     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1524
1525     IInternetSession_Release(session);
1526 }
1527
1528 static void unregister_protocols(void) {
1529     IInternetSession *session;
1530     HRESULT hr;
1531
1532     hr = pCoInternetGetSession(0, &session, 0);
1533     ok(hr == S_OK, "CoInternetGetSession failed: 0x%08x\n", hr);
1534     if(FAILED(hr))
1535         return;
1536
1537     hr = IInternetSession_UnregisterNameSpace(session, &protocol_cf, winetestW);
1538     ok(hr == S_OK, "UnregisterNameSpace failed: 0x%08x\n", hr);
1539
1540     IInternetSession_Release(session);
1541 }
1542
1543 static const struct {
1544     const char  *uri;
1545     DWORD       create_flags;
1546     const char  *security_uri;
1547     HRESULT     security_hres;
1548     const char  *default_uri;
1549     HRESULT     default_hres;
1550     BOOL        todo;
1551 } sec_url_ex_tests[] = {
1552     {"index.htm",Uri_CREATE_ALLOW_RELATIVE,"*:index.html",S_OK,"*:index.htm",S_OK},
1553     {"file://c:\\Index.htm",Uri_CREATE_FILE_USE_DOS_PATH,"file:///c:/Index.htm",S_OK,"file:///c:/Index.htm",S_OK},
1554     {"file:some%20file%2ejpg",0,NULL,E_INVALIDARG,NULL,E_INVALIDARG},
1555     {"file:some file.jpg",0,NULL,E_INVALIDARG,NULL,E_INVALIDARG},
1556     {"http://www.zone3.winetest/",0,"http://www.zone3.winetest/",S_OK,"http://www.zone3.winetest/",S_OK},
1557     {"about:blank",0,"about:blank",S_OK,"about:blank",S_OK},
1558     {"ftp://zone3.winetest/file.test",0,"ftp://zone3.winetest/file.test",S_OK,"ftp://zone3.winetest/file.test",S_OK},
1559     {"test:123abc",0,"test:123abc",S_OK,"test:123abc",S_OK},
1560     {"http:google.com/test.file",0,"http:google.com/test.file",S_OK,"http:google.com/test.file",S_OK},
1561     {"ftp://test@ftp.winehq.org/",0,"ftp://ftp.winehq.org/",S_OK,"ftp://ftp.winehq.org/",S_OK},
1562     {"test://google@ftp.winehq.org/",0,"test://google@ftp.winehq.org/",S_OK,"test://google@ftp.winehq.org/",S_OK}
1563 };
1564
1565 static void test_InternetGetSecurityUrlEx(void)
1566 {
1567     HRESULT hr;
1568     DWORD i;
1569     IUri *uri = NULL, *result = NULL;
1570
1571     trace("testing CoInternetGetSecurityUrlEx...\n");
1572
1573     hr = pCoInternetGetSecurityUrlEx(NULL, NULL, PSU_DEFAULT, 0);
1574     ok(hr == E_INVALIDARG, "CoInternetGetSecurityUrlEx returned 0x%08x, expected E_INVALIDARG\n", hr);
1575
1576     result = (void*) 0xdeadbeef;
1577     hr = pCoInternetGetSecurityUrlEx(NULL, &result, PSU_DEFAULT, 0);
1578     ok(hr == E_INVALIDARG, "CoInternetGetSecurityUrlEx returned 0x%08x, expected E_INVALIDARG\n", hr);
1579     ok(result == (void*) 0xdeadbeef, "'result' was %p\n", result);
1580
1581     for(i = 0; i < sizeof(sec_url_ex_tests)/sizeof(sec_url_ex_tests[0]); ++i) {
1582         LPWSTR uriW = a2w(sec_url_ex_tests[i].uri);
1583         uri = NULL;
1584
1585         hr = pCreateUri(uriW, sec_url_ex_tests[i].create_flags, 0, &uri);
1586         ok(hr == S_OK, "CreateUri returned 0x%08x on test %d\n", hr, i);
1587         if(hr == S_OK) {
1588             result = NULL;
1589
1590             hr = pCoInternetGetSecurityUrlEx(uri, &result, PSU_DEFAULT, 0);
1591             if(sec_url_ex_tests[i].todo) {
1592                 todo_wine
1593                     ok(hr == sec_url_ex_tests[i].default_hres,
1594                         "CoInternetGetSecurityUrlEx returned 0x%08x, expected 0x%08x on test %d\n",
1595                         hr, sec_url_ex_tests[i].default_hres, i);
1596             } else {
1597                 ok(hr == sec_url_ex_tests[i].default_hres,
1598                     "CoInternetGetSecurityUrlEx returned 0x%08x, expected 0x%08x on test %d\n",
1599                     hr, sec_url_ex_tests[i].default_hres, i);
1600             }
1601             if(SUCCEEDED(hr)) {
1602                 BSTR received;
1603
1604                 hr = IUri_GetDisplayUri(result, &received);
1605                 ok(hr == S_OK, "GetDisplayUri returned 0x%08x on test %d\n", hr, i);
1606                 if(hr == S_OK) {
1607                     if(sec_url_ex_tests[i].todo) {
1608                         todo_wine
1609                             ok(!strcmp_aw(sec_url_ex_tests[i].default_uri, received),
1610                                 "Expected %s but got %s on test %d\n", sec_url_ex_tests[i].default_uri,
1611                                 wine_dbgstr_w(received), i);
1612                     } else {
1613                         ok(!strcmp_aw(sec_url_ex_tests[i].default_uri, received),
1614                             "Expected %s but got %s on test %d\n", sec_url_ex_tests[i].default_uri,
1615                             wine_dbgstr_w(received), i);
1616                     }
1617                 }
1618                 SysFreeString(received);
1619             }
1620             if(result) IUri_Release(result);
1621
1622             result = NULL;
1623             hr = pCoInternetGetSecurityUrlEx(uri, &result, PSU_SECURITY_URL_ONLY, 0);
1624             if(sec_url_ex_tests[i].todo) {
1625                 todo_wine
1626                     ok(hr == sec_url_ex_tests[i].default_hres,
1627                         "CoInternetGetSecurityUrlEx returned 0x%08x, expected 0x%08x on test %d\n",
1628                         hr, sec_url_ex_tests[i].default_hres, i);
1629             } else {
1630                 ok(hr == sec_url_ex_tests[i].default_hres,
1631                     "CoInternetGetSecurityUrlEx returned 0x%08x, expected 0x%08x on test %d\n",
1632                     hr, sec_url_ex_tests[i].default_hres, i);
1633             }
1634             if(SUCCEEDED(hr)) {
1635                 BSTR received;
1636
1637                 hr = IUri_GetDisplayUri(result, &received);
1638                 ok(hr == S_OK, "GetDisplayUri returned 0x%08x on test %d\n", hr, i);
1639                 if(hr == S_OK) {
1640                     if(sec_url_ex_tests[i].todo) {
1641                         todo_wine
1642                             ok(!strcmp_aw(sec_url_ex_tests[i].default_uri, received),
1643                                 "Expected %s but got %s on test %d\n", sec_url_ex_tests[i].default_uri,
1644                                 wine_dbgstr_w(received), i);
1645                     } else {
1646                         ok(!strcmp_aw(sec_url_ex_tests[i].default_uri, received),
1647                             "Expected %s but got %s on test %d\n", sec_url_ex_tests[i].default_uri,
1648                             wine_dbgstr_w(received), i);
1649                     }
1650                 }
1651                 SysFreeString(received);
1652             }
1653             if(result) IUri_Release(result);
1654         }
1655
1656         if(uri) IUri_Release(uri);
1657         heap_free(uriW);
1658     }
1659 }
1660
1661 static void test_InternetGetSecurityUrlEx_Pluggable(void)
1662 {
1663     HRESULT hr;
1664     IUri *uri = NULL, *result;
1665
1666     trace("testing CoInternetGetSecurityUrlEx for pluggable protocols...\n");
1667
1668     hr = pCreateUri(security_urlW, 0, 0, &uri);
1669     ok(hr == S_OK, "CreateUri returned 0x%08x\n", hr);
1670     if(hr == S_OK) {
1671         SET_EXPECT(ParseUrl_SECURITY_URL_input);
1672         SET_EXPECT(ParseUrl_SECURITY_URL_expected);
1673         SET_EXPECT(ParseUrl_SECURITY_DOMAIN_expected);
1674
1675         hr = pCoInternetGetSecurityUrlEx(uri, &result, PSU_DEFAULT, 0);
1676         ok(hr == S_OK, "CoInternetGetSecurityUrlEx returned 0x%08x, expected S_OK\n", hr);
1677
1678         CHECK_CALLED(ParseUrl_SECURITY_URL_input);
1679         CHECK_CALLED(ParseUrl_SECURITY_URL_expected);
1680         CHECK_CALLED(ParseUrl_SECURITY_DOMAIN_expected);
1681
1682         if(hr == S_OK) {
1683             BSTR received = NULL;
1684
1685             hr = IUri_GetAbsoluteUri(result, &received);
1686             ok(hr == S_OK, "GetAbsoluteUri returned 0x%08x\n", hr);
1687             if(hr == S_OK) {
1688                 ok(!strcmp_w(security_expectedW, received), "Expected %s but got %s\n",
1689                     wine_dbgstr_w(security_expectedW), wine_dbgstr_w(received));
1690             }
1691             SysFreeString(received);
1692         }
1693         if(result) IUri_Release(result);
1694
1695         result = NULL;
1696
1697         SET_EXPECT(ParseUrl_SECURITY_URL_input);
1698         SET_EXPECT(ParseUrl_SECURITY_URL_expected);
1699
1700         hr = pCoInternetGetSecurityUrlEx(uri, &result, PSU_SECURITY_URL_ONLY, 0);
1701         ok(hr == S_OK, "CoInternetGetSecurityUrlEx returned 0x%08x, expected S_OK\n", hr);
1702
1703         CHECK_CALLED(ParseUrl_SECURITY_URL_input);
1704         CHECK_CALLED(ParseUrl_SECURITY_URL_expected);
1705
1706         if(hr == S_OK) {
1707             BSTR received = NULL;
1708
1709             hr = IUri_GetAbsoluteUri(result, &received);
1710             ok(hr == S_OK, "GetAbsoluteUri returned 0x%08x\n", hr);
1711             if(hr == S_OK) {
1712                 ok(!strcmp_w(security_expectedW, received), "Expected %s but got %s\n",
1713                     wine_dbgstr_w(security_expectedW), wine_dbgstr_w(received));
1714             }
1715             SysFreeString(received);
1716         }
1717         if(result) IUri_Release(result);
1718     }
1719     if(uri) IUri_Release(uri);
1720 }
1721
1722 static const struct {
1723     const char  *uri;
1724     DWORD       create_flags;
1725     HRESULT     map_hres;
1726     DWORD       zone;
1727     BOOL        map_todo;
1728 } sec_mgr_ex2_tests[] = {
1729     {"res://mshtml.dll/blank.htm",0,S_OK,URLZONE_LOCAL_MACHINE},
1730     {"index.htm",Uri_CREATE_ALLOW_RELATIVE,0,URLZONE_INTERNET},
1731     {"file://c:\\Index.html",0,0,URLZONE_LOCAL_MACHINE},
1732     {"http://www.zone3.winetest/",0,0,URLZONE_INTERNET},
1733     {"about:blank",0,0,URLZONE_INTERNET},
1734     {"ftp://zone3.winetest/file.test",0,0,URLZONE_INTERNET},
1735     {"/file/testing/test.test",Uri_CREATE_ALLOW_RELATIVE,0,URLZONE_INTERNET},
1736     {"zip://testing.com/",0,0,URLZONE_INTERNET},
1737     {"zip:testing.com",0,0,URLZONE_INTERNET}
1738 };
1739
1740 static void test_SecurityManagerEx2(void)
1741 {
1742     HRESULT hres;
1743     DWORD i, zone;
1744     IInternetSecurityManager *sec_mgr;
1745     IInternetSecurityManagerEx2 *sec_mgr2;
1746     IUri *uri = NULL;
1747
1748     if(!pCreateUri) {
1749         win_skip("Skipping SecurityManagerEx2, IE is too old\n");
1750         return;
1751     }
1752
1753     trace("Testing SecurityManagerEx2...\n");
1754
1755     hres = pCoInternetCreateSecurityManager(NULL, &sec_mgr, 0);
1756     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
1757
1758     hres = IInternetSecurityManager_QueryInterface(sec_mgr, &IID_IInternetSecurityManagerEx2, (void**)&sec_mgr2);
1759     ok(hres == S_OK, "QueryInterface(IID_IInternetSecurityManagerEx2) failed: %08x\n", hres);
1760
1761     zone = 0xdeadbeef;
1762
1763     hres = IInternetSecurityManagerEx2_MapUrlToZoneEx2(sec_mgr2, NULL, &zone, 0, NULL, NULL);
1764     ok(hres == E_INVALIDARG, "MapUrlToZoneEx2 returned %08x, expected E_INVALIDARG\n", hres);
1765     ok(zone == URLZONE_INVALID, "zone was %d\n", zone);
1766
1767     hres = pCreateUri(url5, 0, 0, &uri);
1768     ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
1769
1770     hres = IInternetSecurityManagerEx2_MapUrlToZoneEx2(sec_mgr2, uri, NULL, 0, NULL, NULL);
1771     ok(hres == E_INVALIDARG, "MapToUrlZoneEx2 returned %08x, expected E_INVALIDARG\n", hres);
1772
1773     IUri_Release(uri);
1774
1775     for(i = 0; i < sizeof(sec_mgr_ex2_tests)/sizeof(sec_mgr_ex2_tests[0]); ++i) {
1776         LPWSTR uriW = a2w(sec_mgr_ex2_tests[i].uri);
1777
1778         uri = NULL;
1779         zone = URLZONE_INVALID;
1780
1781         hres = pCreateUri(uriW, sec_mgr_ex2_tests[i].create_flags, 0, &uri);
1782         ok(hres == S_OK, "CreateUri returned %08x for '%s'\n", hres, sec_mgr_ex2_tests[i].uri);
1783
1784         hres = IInternetSecurityManagerEx2_MapUrlToZoneEx2(sec_mgr2, uri, &zone, 0, NULL, NULL);
1785         if(sec_mgr_ex2_tests[i].map_todo) {
1786             todo_wine
1787                 ok(hres == sec_mgr_ex2_tests[i].map_hres, "MapUrlZoneToEx2 returned %08x, expected %08x for '%s'\n",
1788                     hres, sec_mgr_ex2_tests[i].map_hres, sec_mgr_ex2_tests[i].uri);
1789             todo_wine
1790                 ok(zone == sec_mgr_ex2_tests[i].zone, "Expected zone %d, but got %d for '%s'\n", sec_mgr_ex2_tests[i].zone,
1791                     zone, sec_mgr_ex2_tests[i].uri);
1792         } else {
1793             ok(hres == sec_mgr_ex2_tests[i].map_hres, "MapUrlToZoneEx2 returned %08x, expected %08x for '%s'\n",
1794                 hres, sec_mgr_ex2_tests[i].map_hres, sec_mgr_ex2_tests[i].uri);
1795             ok(zone == sec_mgr_ex2_tests[i].zone, "Expected zone %d, but got %d for '%s'\n", sec_mgr_ex2_tests[i].zone,
1796                 zone, sec_mgr_ex2_tests[i].uri);
1797         }
1798
1799         heap_free(uriW);
1800         IUri_Release(uri);
1801     }
1802
1803     IInternetSecurityManagerEx2_Release(sec_mgr2);
1804     IInternetSecurityManager_Release(sec_mgr);
1805 }
1806
1807 static void test_CoInternetIsFeatureZoneElevationEnabled(void)
1808 {
1809     struct {
1810         const char *url_from;
1811         const char *url_to;
1812         DWORD flags;
1813         HRESULT hres;
1814         DWORD policy_flags;
1815     } testcases[] = {
1816         /*  0 */ { "http://www.winehq.org", "http://www.winehq.org", 0, S_FALSE, URLPOLICY_ALLOW },
1817         /*  1 */ { "http://www.winehq.org", "http://www.winehq.org", 0, S_OK, URLPOLICY_DISALLOW },
1818         /*  2 */ { "http://www.winehq.org", "http://www.codeweavers.com", 0, S_FALSE, URLPOLICY_ALLOW },
1819         /*  3 */ { "http://www.winehq.org", "http://www.codeweavers.com", 0, S_OK, URLPOLICY_DISALLOW },
1820         /*  4 */ { "http://www.winehq.org", "http://www.winehq.org", GET_FEATURE_FROM_PROCESS, S_FALSE, -1 },
1821         /*  5 */ { "http://www.winehq.org", "http://www.winehq.org/dir", GET_FEATURE_FROM_PROCESS, S_FALSE, -1 },
1822         /*  6 */ { "http://www.winehq.org", "http://www.codeweavers.com", GET_FEATURE_FROM_PROCESS, S_FALSE, -1 },
1823         /*  7 */ { "http://www.winehq.org", "ftp://winehq.org", GET_FEATURE_FROM_PROCESS, S_FALSE, -1 },
1824         /*  8 */ { "http://www.winehq.org", "ftp://winehq.org", GET_FEATURE_FROM_PROCESS|0x100, S_FALSE, URLPOLICY_ALLOW },
1825         /*  9 */ { "http://www.winehq.org", "ftp://winehq.org", GET_FEATURE_FROM_REGISTRY, S_FALSE, URLPOLICY_ALLOW },
1826     };
1827
1828     WCHAR *url_from, *url_to;
1829     int i;
1830     HRESULT hres;
1831
1832     if(!pCoInternetIsFeatureZoneElevationEnabled || !pCoInternetIsFeatureEnabled
1833             || !pCoInternetIsFeatureEnabledForUrl) {
1834         win_skip("Skipping CoInternetIsFeatureZoneElevationEnabled tests\n");
1835         return;
1836     }
1837
1838
1839     hres = pCoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, GET_FEATURE_FROM_PROCESS);
1840     ok(SUCCEEDED(hres), "CoInternetIsFeatureEnabled returned %x\n", hres);
1841
1842     trace("Testing CoInternetIsFeatureZoneElevationEnabled... (%x)\n", hres);
1843
1844     for(i=0; i<sizeof(testcases)/sizeof(testcases[0]); i++) {
1845         if(hres==S_OK && testcases[i].flags == GET_FEATURE_FROM_PROCESS)
1846             testcases[i].policy_flags = URLPOLICY_ALLOW;
1847     }
1848
1849     for(i=0; i<sizeof(testcases)/sizeof(testcases[0]); i++) {
1850         url_from = a2w(testcases[i].url_from);
1851         url_to = a2w(testcases[i].url_to);
1852
1853         if(testcases[i].policy_flags != -1) {
1854             ProcessUrlAction_policy = testcases[i].policy_flags;
1855             SET_EXPECT(ProcessUrlAction);
1856         }
1857         hres = pCoInternetIsFeatureZoneElevationEnabled(url_from, url_to,
1858                 &security_manager, testcases[i].flags);
1859         ok(hres == testcases[i].hres, "%d) CoInternetIsFeatureZoneElevationEnabled returned %x\n", i, hres);
1860         if(testcases[i].policy_flags != -1)
1861             CHECK_CALLED(ProcessUrlAction);
1862
1863         if(testcases[i].policy_flags != -1)
1864             SET_EXPECT(ProcessUrlAction);
1865         hres = pCoInternetIsFeatureEnabledForUrl(FEATURE_ZONE_ELEVATION,
1866                 testcases[i].flags, url_to, &security_manager);
1867         ok(hres == testcases[i].hres, "%d) CoInternetIsFeatureEnabledForUrl returned %x\n", i, hres);
1868         if(testcases[i].policy_flags != -1)
1869             CHECK_CALLED(ProcessUrlAction);
1870
1871         heap_free(url_from);
1872         heap_free(url_to);
1873     }
1874 }
1875
1876 START_TEST(sec_mgr)
1877 {
1878     HMODULE hurlmon;
1879     int argc;
1880     char **argv;
1881
1882     hurlmon = GetModuleHandle("urlmon.dll");
1883     pCoInternetCreateSecurityManager = (void*) GetProcAddress(hurlmon, "CoInternetCreateSecurityManager");
1884     pCoInternetCreateZoneManager = (void*) GetProcAddress(hurlmon, "CoInternetCreateZoneManager");
1885     pCoInternetGetSecurityUrl = (void*) GetProcAddress(hurlmon, "CoInternetGetSecurityUrl");
1886     pCoInternetGetSecurityUrlEx = (void*) GetProcAddress(hurlmon, "CoInternetGetSecurityUrlEx");
1887     pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
1888     pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
1889     pCoInternetIsFeatureEnabled = (void*) GetProcAddress(hurlmon, "CoInternetIsFeatureEnabled");
1890     pCoInternetIsFeatureEnabledForUrl = (void*) GetProcAddress(hurlmon, "CoInternetIsFeatureEnabledForUrl");
1891     pCoInternetIsFeatureZoneElevationEnabled = (void*) GetProcAddress(hurlmon, "CoInternetIsFeatureZoneElevationEnabled");
1892
1893     if (!pCoInternetCreateSecurityManager || !pCoInternetCreateZoneManager ||
1894         !pCoInternetGetSecurityUrl) {
1895         win_skip("Various CoInternet* functions not present in IE 4.0\n");
1896         return;
1897     }
1898
1899     argc = winetest_get_mainargs(&argv);
1900     if(argc > 2 && !strcmp(argv[2], "domain_tests")) {
1901         test_zone_domain_mappings();
1902         return;
1903     }
1904
1905     OleInitialize(NULL);
1906     register_protocols();
1907
1908     test_InternetGetSecurityUrl();
1909
1910     if(!pCoInternetGetSecurityUrlEx || !pCreateUri)
1911         win_skip("Skipping CoInternetGetSecurityUrlEx tests, IE too old\n");
1912     else {
1913         test_InternetGetSecurityUrlEx();
1914         test_InternetGetSecurityUrlEx_Pluggable();
1915     }
1916
1917     test_SecurityManager();
1918     test_SecurityManagerEx2();
1919     test_polices();
1920     test_zone_domains();
1921     test_CoInternetCreateZoneManager();
1922     test_CreateZoneEnumerator();
1923     test_GetZoneActionPolicy();
1924     test_GetZoneAt();
1925     test_GetZoneAttributes();
1926     test_SetZoneAttributes();
1927     test_InternetSecurityMarshalling();
1928     test_CoInternetIsFeatureZoneElevationEnabled();
1929
1930     unregister_protocols();
1931     OleUninitialize();
1932 }