mmdevapi/tests: Add tests for IAudioClient::GetCurrentPadding.
[wine] / dlls / urlmon / tests / sec_mgr.c
1 /*
2  * Copyright 2005-2006 Jacek Caban for CodeWeavers
3  * Copyright 2009-2010 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
74 static HRESULT (WINAPI *pCoInternetCreateSecurityManager)(IServiceProvider *, IInternetSecurityManager**, DWORD);
75 static HRESULT (WINAPI *pCoInternetCreateZoneManager)(IServiceProvider *, IInternetZoneManager**, DWORD);
76 static HRESULT (WINAPI *pCoInternetGetSecurityUrl)(LPCWSTR, LPWSTR*, PSUACTION, DWORD);
77 static HRESULT (WINAPI *pCoInternetGetSecurityUrlEx)(IUri*, IUri**, PSUACTION, DWORD_PTR);
78 static HRESULT (WINAPI *pCreateUri)(LPCWSTR, DWORD, DWORD_PTR, IUri**);
79 static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession**, DWORD);
80
81 static const WCHAR url1[] = {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l',
82         '/','b','l','a','n','k','.','h','t','m',0};
83 static const WCHAR url2[] = {'i','n','d','e','x','.','h','t','m',0};
84 static const WCHAR url3[] = {'f','i','l','e',':','/','/','c',':','\\','I','n','d','e','x','.','h','t','m',0};
85 static const WCHAR url4[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e',
86         '%','2','e','j','p','g',0};
87 static const WCHAR url5[] = {'h','t','t','p',':','/','/','w','w','w','.','z','o','n','e','3',
88         '.','w','i','n','e','t','e','s','t',0};
89 static const WCHAR url6[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
90 static const WCHAR url7[] = {'f','t','p',':','/','/','z','o','n','e','3',
91         '.','w','i','n','e','t','e','s','t','/','f','i','l','e','.','t','e','s','t',0};
92 static const WCHAR url8[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
93 static const WCHAR url9[] = {'h','t','t','p',':','/','/','w','w','w','.','z','o','n','e','3',
94         '.','w','i','n','e','t','e','s','t', '/','s','i','t','e','/','a','b','o','u','t',0};
95 static const WCHAR url10[] = {'f','i','l','e',':','/','/','s','o','m','e','%','2','0','f','i','l','e',
96         '.','j','p','g',0};
97
98 static const WCHAR url4e[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e',
99         '.','j','p','g',0};
100
101 static const WCHAR winetestW[] = {'w','i','n','e','t','e','s','t',0};
102 static const WCHAR security_urlW[] = {'w','i','n','e','t','e','s','t',':','t','e','s','t','i','n','g',0};
103 static const WCHAR security_url2W[] = {'w','i','n','e','t','e','s','t',':','t','e','s','t','i','n','g','2',0};
104 static const WCHAR security_expectedW[] = {'w','i','n','e','t','e','s','t',':','z','i','p',0};
105 static const WCHAR winetest_to_httpW[] = {'w','i','n','e','t','e','s','t',':','h',0};
106
107 static const char *szZoneMapDomainsKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap\\Domains";
108
109 static const BYTE secid1[] = {'f','i','l','e',':',0,0,0,0};
110 static const BYTE secid5[] = {'h','t','t','p',':','w','w','w','.','z','o','n','e','3',
111         '.','w','i','n','e','t','e','s','t',3,0,0,0};
112 static const BYTE secid6[] = {'a','b','o','u','t',':','b','l','a','n','k',3,0,0,0};
113 static const BYTE secid7[] = {'f','t','p',':','z','o','n','e','3',
114         '.','w','i','n','e','t','e','s','t',3,0,0,0};
115 static const BYTE secid10[] =
116     {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e','.','j','p','g',3,0,0,0};
117 static const BYTE secid10_2[] =
118     {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e','.','j','p','g',3,0,0,0};
119
120 static const GUID CLSID_TestActiveX =
121     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x46}};
122
123 /* Defined as extern in urlmon.idl, but not exported by uuid.lib */
124 const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
125     {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
126
127 static int called_securl_http;
128
129 static struct secmgr_test {
130     LPCWSTR url;
131     DWORD zone;
132     HRESULT zone_hres;
133     DWORD secid_size;
134     const BYTE *secid;
135     HRESULT secid_hres;
136 } secmgr_tests[] = {
137     {url1, 0,   S_OK, sizeof(secid1), secid1, S_OK},
138     {url2, 100, 0x80041001, 0, NULL, E_INVALIDARG},
139     {url3, 0,   S_OK, sizeof(secid1), secid1, S_OK},
140     {url5, 3,   S_OK, sizeof(secid5), secid5, S_OK},
141     {url6, 3,   S_OK, sizeof(secid6), secid6, S_OK},
142     {url7, 3,   S_OK, sizeof(secid7), secid7, S_OK}
143 };
144
145 static int strcmp_w(const WCHAR *str1, const WCHAR *str2)
146 {
147     DWORD len1 = lstrlenW(str1);
148     DWORD len2 = lstrlenW(str2);
149
150     if(len1!=len2) return 1;
151     return memcmp(str1, str2, len1*sizeof(WCHAR));
152 }
153
154 static inline void heap_free(void *mem)
155 {
156     HeapFree(GetProcessHeap(), 0, mem);
157 }
158
159 static inline LPWSTR a2w(LPCSTR str)
160 {
161     LPWSTR ret = NULL;
162
163     if(str) {
164         DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
165         ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
166         MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
167     }
168
169     return ret;
170 }
171
172 static inline DWORD strcmp_aw(LPCSTR strA, LPCWSTR strB) {
173     LPWSTR strAW = a2w(strA);
174     DWORD ret = lstrcmpW(strAW, strB);
175     heap_free(strAW);
176     return ret;
177 }
178
179 static void test_SecurityManager(void)
180 {
181     int i;
182     IInternetSecurityManager *secmgr = NULL;
183     BYTE buf[512];
184     DWORD zone, size, policy;
185     HRESULT hres;
186
187     if(!pCoInternetCreateSecurityManager) {
188         return;
189     }
190
191     trace("Testing security manager...\n");
192
193     hres = pCoInternetCreateSecurityManager(NULL, &secmgr, 0);
194     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
195     if(FAILED(hres))
196         return;
197
198     for(i=0; i < sizeof(secmgr_tests)/sizeof(secmgr_tests[0]); i++) {
199         zone = 100;
200         hres = IInternetSecurityManager_MapUrlToZone(secmgr, secmgr_tests[i].url,
201                                                      &zone, 0);
202         ok(hres == secmgr_tests[i].zone_hres /* IE <=6 */
203            || (FAILED(secmgr_tests[i].zone_hres) && hres == E_INVALIDARG), /* IE7 */
204            "[%d] MapUrlToZone failed: %08x, expected %08x\n",
205                 i, hres, secmgr_tests[i].zone_hres);
206         if(SUCCEEDED(hres))
207             ok(zone == secmgr_tests[i].zone, "[%d] zone=%d, expected %d\n", i, zone,
208                secmgr_tests[i].zone);
209         else
210             ok(zone == secmgr_tests[i].zone || zone == -1, "[%d] zone=%d\n", i, zone);
211
212         size = sizeof(buf);
213         memset(buf, 0xf0, sizeof(buf));
214         hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[i].url,
215                 buf, &size, 0);
216         ok(hres == secmgr_tests[i].secid_hres,
217            "[%d] GetSecurityId failed: %08x, expected %08x\n",
218            i, hres, secmgr_tests[i].secid_hres);
219         if(secmgr_tests[i].secid) {
220             ok(size == secmgr_tests[i].secid_size, "[%d] size=%d, expected %d\n",
221                     i, size, secmgr_tests[i].secid_size);
222             ok(!memcmp(buf, secmgr_tests[i].secid, size), "[%d] wrong secid\n", i);
223         }
224     }
225
226     zone = 100;
227     hres = IInternetSecurityManager_MapUrlToZone(secmgr, url10, &zone, 0);
228     ok(hres == S_OK, "MapUrlToZone failed: %08x, expected S_OK\n", hres);
229     ok(zone == 3, "zone=%d, expected 3\n", zone);
230
231     /* win2k3 translates %20 into a space */
232     size = sizeof(buf);
233     memset(buf, 0xf0, sizeof(buf));
234     hres = IInternetSecurityManager_GetSecurityId(secmgr, url10, buf, &size, 0);
235     ok(hres == S_OK, "GetSecurityId failed: %08x, expected S_OK\n", hres);
236     ok(size == sizeof(secid10) ||
237        size == sizeof(secid10_2), /* win2k3 */
238        "size=%d\n", size);
239     ok(!memcmp(buf, secid10, size) ||
240        !memcmp(buf, secid10_2, size), /* win2k3 */
241        "wrong secid\n");
242
243     zone = 100;
244     hres = IInternetSecurityManager_MapUrlToZone(secmgr, NULL, &zone, 0);
245     ok(hres == E_INVALIDARG, "MapUrlToZone failed: %08x, expected E_INVALIDARG\n", hres);
246     ok(zone == 100 || zone == -1, "zone=%d\n", zone);
247
248     size = sizeof(buf);
249     hres = IInternetSecurityManager_GetSecurityId(secmgr, NULL, buf, &size, 0);
250     ok(hres == E_INVALIDARG,
251        "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
252     hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[1].url,
253                                                   NULL, &size, 0);
254     ok(hres == E_INVALIDARG,
255        "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
256     hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[1].url,
257                                                   buf, NULL, 0);
258     ok(hres == E_INVALIDARG,
259        "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
260
261     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, NULL, URLACTION_SCRIPT_RUN, (BYTE*)&policy,
262             sizeof(WCHAR), NULL, 0, 0, 0);
263     ok(hres == E_INVALIDARG, "ProcessUrlAction failed: %08x, expected E_INVALIDARG\n", hres);
264
265     IInternetSecurityManager_Release(secmgr);
266 }
267
268 /* Check if Internet Explorer is configured to run in "Enhanced Security Configuration" (aka hardened mode) */
269 /* Note: this code is duplicated in dlls/mshtml/tests/mshtml_test.h and dlls/urlmon/tests/sec_mgr.c */
270 static BOOL is_ie_hardened(void)
271 {
272     HKEY zone_map;
273     DWORD ie_harden, type, size;
274
275     ie_harden = 0;
276     if(RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap",
277                     0, KEY_QUERY_VALUE, &zone_map) == ERROR_SUCCESS) {
278         size = sizeof(DWORD);
279         if (RegQueryValueExA(zone_map, "IEHarden", NULL, &type, (LPBYTE) &ie_harden, &size) != ERROR_SUCCESS ||
280             type != REG_DWORD) {
281             ie_harden = 0;
282         }
283         RegCloseKey(zone_map);
284     }
285
286     return ie_harden != 0;
287 }
288
289 static void test_url_action(IInternetSecurityManager *secmgr, IInternetZoneManager *zonemgr, DWORD action)
290 {
291     DWORD res, size, policy, reg_policy;
292     char buf[10];
293     HKEY hkey;
294     HRESULT hres;
295
296     /* FIXME: HKEY_CURRENT_USER is most of the time the default but this can be changed on a system.
297      * The test should be changed to cope with that, if need be.
298      */
299     res = RegOpenKeyA(HKEY_CURRENT_USER,
300             "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3", &hkey);
301     if(res != ERROR_SUCCESS) {
302         ok(0, "Could not open zone key\n");
303         return;
304     }
305
306     wsprintf(buf, "%X", action);
307     size = sizeof(DWORD);
308     res = RegQueryValueExA(hkey, buf, NULL, NULL, (BYTE*)&reg_policy, &size);
309     RegCloseKey(hkey);
310     if(res != ERROR_SUCCESS || size != sizeof(DWORD)) {
311         policy = 0xdeadbeef;
312         hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
313                 sizeof(WCHAR), NULL, 0, 0, 0);
314         ok(hres == E_FAIL || broken(hres == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)),
315             "(0x%x) got 0x%x (expected E_FAIL)\n", action, hres);
316         ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
317
318         policy = 0xdeadbeef;
319         hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
320                 sizeof(DWORD), URLZONEREG_DEFAULT);
321         ok(hres == E_FAIL || broken(hres == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)),
322             "(0x%x) got 0x%x (expected E_FAIL)\n", action, hres);
323         ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
324         return;
325     }
326
327     policy = 0xdeadbeef;
328     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
329             sizeof(DWORD), URLZONEREG_DEFAULT);
330     ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
331     ok(policy == reg_policy, "(%x) policy=%x, expected %x\n", action, policy, reg_policy);
332
333     if(policy != URLPOLICY_QUERY) {
334         if(winetest_interactive || ! is_ie_hardened()) {
335             BOOL expect_parse_call = !called_securl_http;
336
337             policy = 0xdeadbeef;
338             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
339                     sizeof(WCHAR), NULL, 0, 0, 0);
340             if(reg_policy == URLPOLICY_DISALLOW)
341                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
342             else
343                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
344             ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
345
346             policy = 0xdeadbeef;
347             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
348                     2, NULL, 0, 0, 0);
349             if(reg_policy == URLPOLICY_DISALLOW)
350                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
351             else
352                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
353             ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
354
355             policy = 0xdeadbeef;
356             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
357                     sizeof(DWORD), NULL, 0, 0, 0);
358             if(reg_policy == URLPOLICY_DISALLOW)
359                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
360             else
361                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
362             ok(policy == reg_policy, "(%x) policy=%x\n", action, policy);
363
364             policy = 0xdeadbeef;
365             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
366                     sizeof(WCHAR), (BYTE*)0xdeadbeef, 16, 0, 0);
367             if(reg_policy == URLPOLICY_DISALLOW)
368                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
369             else
370                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
371             ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
372
373             policy = 0xdeadbeef;
374             if(expect_parse_call)
375                 SET_EXPECT(ParseUrl_SECURITY_URL_http);
376             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, winetest_to_httpW, action, (BYTE*)&policy,
377                     sizeof(DWORD), NULL, 0, 0, 0);
378             if(expect_parse_call)
379                 CHECK_CALLED(ParseUrl_SECURITY_URL_http);
380             if(reg_policy == URLPOLICY_DISALLOW)
381                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
382             else
383                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
384             ok(policy == reg_policy, "(%x) policy=%x\n", action, policy);
385         }else {
386             skip("IE running in Enhanced Security Configuration\n");
387         }
388     }
389 }
390
391 static void test_special_url_action(IInternetSecurityManager *secmgr, IInternetZoneManager *zonemgr, DWORD action)
392 {
393     DWORD policy;
394     HRESULT hres;
395
396     policy = 0xdeadbeef;
397     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
398             sizeof(DWORD), URLZONEREG_DEFAULT);
399     ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
400     ok(policy == URLPOLICY_DISALLOW, "(%x) policy=%x, expected URLPOLICY_DISALLOW\n", action, policy);
401
402     policy = 0xdeadbeef;
403     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url1, action, (BYTE*)&policy,
404             sizeof(WCHAR), NULL, 0, 0, 0);
405     ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
406
407     policy = 0xdeadbeef;
408     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url1, action, (BYTE*)&policy,
409             sizeof(DWORD), NULL, 0, 0, 0);
410     ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
411     ok(policy == URLPOLICY_DISALLOW, "policy = %x\n", policy);
412 }
413
414 static void test_activex(IInternetSecurityManager *secmgr)
415 {
416     DWORD policy, policy_size;
417     struct CONFIRMSAFETY cs;
418     BYTE *ppolicy;
419     HRESULT hres;
420
421     policy = 0xdeadbeef;
422     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url1, URLACTION_ACTIVEX_RUN, (BYTE*)&policy,
423             sizeof(DWORD), (BYTE*)&CLSID_TestActiveX, sizeof(CLSID), 0, 0);
424     ok(hres == S_OK, "ProcessUrlAction(URLACTION_ACTIVEX_RUN) failed: %08x\n", hres);
425     ok(policy == URLPOLICY_ALLOW || policy == URLPOLICY_DISALLOW, "policy = %x\n", policy);
426
427     cs.clsid = CLSID_TestActiveX;
428     cs.pUnk = (IUnknown*)0xdeadbeef;
429     cs.dwFlags = 0;
430     hres = IInternetSecurityManager_QueryCustomPolicy(secmgr, url1, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
431             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
432     ok(hres == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "QueryCusromPolicy failed: %08x\n", hres);
433 }
434
435 static void test_polices(void)
436 {
437     IInternetZoneManager *zonemgr = NULL;
438     IInternetSecurityManager *secmgr = NULL;
439     HRESULT hres;
440
441     trace("testing polices...\n");
442
443     hres = pCoInternetCreateSecurityManager(NULL, &secmgr, 0);
444     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
445     hres = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
446     ok(hres == S_OK, "CoInternetCreateZoneManager failed: %08x\n", hres);
447
448     test_url_action(secmgr, zonemgr, URLACTION_SCRIPT_RUN);
449     test_url_action(secmgr, zonemgr, URLACTION_ACTIVEX_RUN);
450     test_url_action(secmgr, zonemgr, URLACTION_ACTIVEX_OVERRIDE_OBJECT_SAFETY);
451     test_url_action(secmgr, zonemgr, URLACTION_CHANNEL_SOFTDIST_PERMISSIONS);
452     test_url_action(secmgr, zonemgr, 0xdeadbeef);
453
454     test_special_url_action(secmgr, zonemgr, URLACTION_SCRIPT_OVERRIDE_SAFETY);
455     test_special_url_action(secmgr, zonemgr, URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY);
456
457     test_activex(secmgr);
458
459     IInternetSecurityManager_Release(secmgr);
460     IInternetZoneManager_Release(zonemgr);
461 }
462
463 /* IE (or at least newer versions of it) seem to cache the keys in ZoneMap
464  * when urlmon.dll is loaded and it doesn't seem to update its cache, unless
465  * SetZoneMapping is used.
466  */
467 static void test_zone_domain_cache(void)
468 {
469     HRESULT hres;
470     DWORD res, zone;
471     IInternetSecurityManager *secmgr = NULL;
472     HKEY domains, domain;
473
474     static const WCHAR testing_domain_urlW[] = {'h','t','t','p',':','/','/','t','e','s','t','i','n','g','.',
475             'd','o','m','a','i','n','/',0};
476
477     res = RegOpenKeyA(HKEY_CURRENT_USER, szZoneMapDomainsKey, &domains);
478     ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
479     if(res != ERROR_SUCCESS)
480         return;
481
482     res = RegCreateKeyA(domains, "testing.domain", &domain);
483     ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
484     if(res != ERROR_SUCCESS) {
485         RegCloseKey(domains);
486         return;
487     }
488
489     zone = URLZONE_CUSTOM;
490     res = RegSetValueExA(domain, "http", 0, REG_DWORD, (BYTE*)&zone, sizeof(DWORD));
491     ok(res == ERROR_SUCCESS, "RegSetValueEx failed: %d\n", res);
492
493     RegCloseKey(domain);
494
495     hres = pCoInternetCreateSecurityManager(NULL, &secmgr, 0);
496     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
497
498     zone = URLZONE_INVALID;
499     hres = IInternetSecurityManager_MapUrlToZone(secmgr, testing_domain_urlW, &zone, 0);
500     ok(hres == S_OK, "MapUrlToZone failed: %08x\n", hres);
501     todo_wine ok(zone == URLZONE_INTERNET, "Got %d, expected URLZONE_INTERNET\n", zone);
502
503     /* FIXME: Play nice with ZoneMaps that existed before the test is run. */
504     res = RegDeleteKeyA(domains, "testing.domain");
505     ok(res == ERROR_SUCCESS, "RegDeleteKey failed: %d\n", res);
506
507     RegCloseKey(domains);
508     IInternetSecurityManager_Release(secmgr);
509 }
510
511 typedef struct {
512     const char  *domain;
513     const char  *subdomain;
514     const char  *scheme;
515     DWORD       zone;
516 } zone_domain_mapping;
517
518 /* FIXME: Move these into SetZoneMapping tests when the day comes... */
519 static const zone_domain_mapping zone_domain_mappings[] = {
520     /* Implicitly means "*.yabadaba.do". */
521     {"yabadaba.do",NULL,"http",URLZONE_CUSTOM},
522     /* The '*' doesn't count as a wildcard, since its not the first component of the subdomain. */
523     {"super.cool","testing.*","ftp",URLZONE_CUSTOM2},
524     /* The '*' counts since it's the first component of the subdomain. */
525     {"super.cool","*.testing","ftp",URLZONE_CUSTOM2},
526     /* All known scheme types apply to wildcard schemes. */
527     {"tests.test",NULL,"*",URLZONE_CUSTOM},
528     /* Due to a defect with how windows checks the mappings, unknown scheme types
529      * never seem to get mapped properly. */
530     {"tests.test",NULL,"zip",URLZONE_CUSTOM},
531     {"www.testing.com",NULL,"http",URLZONE_CUSTOM},
532     {"www.testing.com","testing","http",URLZONE_CUSTOM2},
533     {"org",NULL,"http",URLZONE_CUSTOM},
534     {"org","testing","http",URLZONE_CUSTOM2}
535 };
536
537 static void register_zone_domains(void)
538 {
539     HKEY domains;
540     DWORD res, i;
541
542     /* Some Windows versions don't seem to have a "Domains" key in their HKLM. */
543     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, szZoneMapDomainsKey, &domains);
544     ok(res == ERROR_SUCCESS || broken(res == ERROR_FILE_NOT_FOUND), "RegOpenKey failed: %d\n", res);
545     if(res == ERROR_SUCCESS) {
546         HKEY domain;
547         DWORD zone = URLZONE_CUSTOM;
548
549         res = RegCreateKeyA(domains, "local.machine", &domain);
550         ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
551
552         res = RegSetValueExA(domain, "http", 0, REG_DWORD, (BYTE*)&zone, sizeof(DWORD));
553         ok(res == ERROR_SUCCESS, "RegSetValueEx failed: %d\n", res);
554
555         RegCloseKey(domain);
556         RegCloseKey(domains);
557     }
558
559     res = RegOpenKeyA(HKEY_CURRENT_USER, szZoneMapDomainsKey, &domains);
560     ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
561
562     for(i = 0; i < sizeof(zone_domain_mappings)/sizeof(zone_domain_mappings[0]); ++i) {
563         const zone_domain_mapping *test = zone_domain_mappings+i;
564         HKEY domain;
565
566         res = RegCreateKeyA(domains, test->domain, &domain);
567         ok(res == ERROR_SUCCESS, "RegCreateKey failed with %d on test %d\n", res, i);
568
569         /* Only set the value if there's no subdomain. */
570         if(!test->subdomain) {
571             res = RegSetValueExA(domain, test->scheme, 0, REG_DWORD, (BYTE*)&test->zone, sizeof(DWORD));
572             ok(res == ERROR_SUCCESS, "RegSetValueEx failed with %d on test %d\n", res, i);
573         } else {
574             HKEY subdomain;
575
576             res = RegCreateKeyA(domain, test->subdomain, &subdomain);
577             ok(res == ERROR_SUCCESS, "RegCreateKey failed with %d on test %d\n", res, i);
578
579             res = RegSetValueExA(subdomain, test->scheme, 0, REG_DWORD, (BYTE*)&test->zone, sizeof(DWORD));
580             ok(res == ERROR_SUCCESS, "RegSetValueEx failed with %d on test %d\n", res, i);
581
582             RegCloseKey(subdomain);
583         }
584
585         RegCloseKey(domain);
586     }
587
588     RegCloseKey(domains);
589 }
590
591 static void unregister_zone_domains(void)
592 {
593     HKEY domains;
594     DWORD res, i;
595
596     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, szZoneMapDomainsKey, &domains);
597     ok(res == ERROR_SUCCESS || broken(res == ERROR_FILE_NOT_FOUND), "RegOpenKey failed: %d\n", res);
598     if(res == ERROR_SUCCESS) {
599         RegDeleteKeyA(domains, "local.machine");
600         RegCloseKey(domains);
601     }
602
603     res = RegOpenKeyA(HKEY_CURRENT_USER, szZoneMapDomainsKey, &domains);
604     ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
605
606     for(i = 0; i < sizeof(zone_domain_mappings)/sizeof(zone_domain_mappings[0]); ++i) {
607         const zone_domain_mapping *test = zone_domain_mappings+i;
608
609         /* FIXME: Uses the "cludge" approach to remove the test data from the registry!
610          *        Although, if domain names are... unique, this shouldn't cause any harm
611          *        to keys (if any) that existed before the tests.
612          */
613         if(test->subdomain) {
614             HKEY domain;
615
616             res = RegOpenKeyA(domains, test->domain, &domain);
617             if(res == ERROR_SUCCESS) {
618                 RegDeleteKeyA(domain, test->subdomain);
619                 RegCloseKey(domain);
620             }
621         }
622         RegDeleteKeyA(domains, test->domain);
623     }
624
625     RegCloseKey(domains);
626 }
627
628 static void run_child_process(void)
629 {
630     char cmdline[MAX_PATH];
631     char path[MAX_PATH];
632     char **argv;
633     PROCESS_INFORMATION pi;
634     STARTUPINFO si = { 0 };
635     BOOL ret;
636
637     GetModuleFileNameA(NULL, path, MAX_PATH);
638
639     si.cb = sizeof(si);
640     winetest_get_mainargs(&argv);
641     sprintf(cmdline, "\"%s\" %s domain_tests", argv[0], argv[1]);
642     ret = CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
643     ok(ret, "Failed to spawn child process: %u\n", GetLastError());
644     winetest_wait_child_process(pi.hProcess);
645     CloseHandle(pi.hThread);
646     CloseHandle(pi.hProcess);
647 }
648
649 typedef struct {
650     const char  *url;
651     DWORD       zone;
652     BOOL        todo;
653     DWORD       broken_zone;
654 } zone_mapping_test;
655
656 static const zone_mapping_test zone_mapping_tests[] = {
657     /* Tests for "yabadaba.do" zone mappings. */
658     {"http://yabadaba.do/",URLZONE_CUSTOM},
659     {"http://google.yabadaba.do/",URLZONE_CUSTOM},
660     {"zip://yabadaba.do/",URLZONE_INTERNET},
661     /* Tests for "super.cool" zone mappings. */
662     {"ftp://testing.google.super.cool/",URLZONE_INTERNET},
663     {"ftp://testing.*.super.cool/",URLZONE_CUSTOM2},
664     {"ftp://google.testing.super.cool/",URLZONE_CUSTOM2},
665     /* Tests for "tests.test" zone mappings. */
666     {"http://tests.test/",URLZONE_CUSTOM},
667     {"http://www.tests.test/",URLZONE_CUSTOM},
668     {"ftp://tests.test/",URLZONE_CUSTOM},
669     {"ftp://www.tests.test/",URLZONE_CUSTOM},
670     {"test://www.tests.test/",URLZONE_INTERNET},
671     {"test://tests.test/",URLZONE_INTERNET},
672     {"zip://www.tests.test/",URLZONE_INTERNET},
673     {"zip://tests.test/",URLZONE_INTERNET},
674     /* Tests for "www.testing.com" zone mappings. */
675     {"http://google.www.testing.com/",URLZONE_INTERNET},
676     {"http://www.testing.com/",URLZONE_CUSTOM,FALSE,URLZONE_INTERNET},
677     {"http://testing.www.testing.com/",URLZONE_CUSTOM2,FALSE,URLZONE_INTERNET},
678     /* Tests for "org" zone mappings. */
679     {"http://google.org/",URLZONE_INTERNET,FALSE,URLZONE_CUSTOM},
680     {"http://org/",URLZONE_CUSTOM},
681     {"http://testing.org/",URLZONE_CUSTOM2}
682 };
683
684 static void test_zone_domain_mappings(void)
685 {
686     HRESULT hres;
687     DWORD i, res;
688     IInternetSecurityManager *secmgr = NULL;
689     HKEY domains;
690     DWORD zone = URLZONE_INVALID;
691
692     trace("testing zone domain mappings...\n");
693
694     hres = pCoInternetCreateSecurityManager(NULL, &secmgr, 0);
695     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
696
697     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, szZoneMapDomainsKey, &domains);
698     if(res == ERROR_SUCCESS) {
699         static const WCHAR local_machineW[] = {'h','t','t','p',':','/','/','t','e','s','t','.','l','o','c','a','l',
700                 '.','m','a','c','h','i','n','e','/',0};
701
702         hres = IInternetSecurityManager_MapUrlToZone(secmgr, local_machineW, &zone, 0);
703         ok(hres == S_OK, "MapUrlToZone failed: %08x\n", hres);
704         ok(zone == URLZONE_CUSTOM, "Expected URLZONE_CUSTOM, but got %d\n", zone);
705
706         RegCloseKey(domains);
707     }
708
709     for(i = 0; i < sizeof(zone_mapping_tests)/sizeof(zone_mapping_tests[0]); ++i) {
710         const zone_mapping_test *test = zone_mapping_tests+i;
711         LPWSTR urlW = a2w(test->url);
712         zone = URLZONE_INVALID;
713
714         hres = IInternetSecurityManager_MapUrlToZone(secmgr, urlW, &zone, 0);
715         ok(hres == S_OK, "MapUrlToZone failed: %08x\n", hres);
716         if(test->todo)
717             todo_wine
718                 ok(zone == test->zone || broken(test->broken_zone == zone),
719                     "Expected %d, but got %d on test %d\n", test->zone, zone, i);
720         else
721             ok(zone == test->zone || broken(test->broken_zone == zone),
722                 "Expected %d, but got %d on test %d\n", test->zone, zone, i);
723
724         heap_free(urlW);
725     }
726
727     IInternetSecurityManager_Release(secmgr);
728 }
729
730 static void test_zone_domains(void)
731 {
732     if(is_ie_hardened()) {
733         skip("IE running in Enhanced Security Configuration\n");
734         return;
735     } else if(!pCreateUri) {
736         win_skip("Skipping zone domain tests, IE too old\n");
737         return;
738     }
739
740     trace("testing zone domains...\n");
741
742     test_zone_domain_cache();
743
744     register_zone_domains();
745     run_child_process();
746     unregister_zone_domains();
747 }
748
749 static void test_CoInternetCreateZoneManager(void)
750 {
751     IInternetZoneManager *zonemgr = NULL;
752     IUnknown *punk = NULL;
753     HRESULT hr;
754
755     trace("simple zone manager tests...\n");
756
757     hr = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
758     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
759     if (FAILED(hr))
760         return;
761
762     hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IUnknown, (void **) &punk);
763     ok(SUCCEEDED(hr), "got 0x%x with %p (expected Success)\n", hr, punk);
764     if (punk)
765         IUnknown_Release(punk);
766
767     hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IInternetZoneManager, (void **) &punk);
768     ok(SUCCEEDED(hr), "got 0x%x with %p (expected Success)\n", hr, punk);
769     if (punk)
770         IUnknown_Release(punk);
771
772
773     hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IInternetZoneManagerEx, (void **) &punk);
774     if (SUCCEEDED(hr)) {
775         IUnknown_Release(punk);
776
777         hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IInternetZoneManagerEx2, (void **) &punk);
778         ok(hr == S_OK || broken(hr == E_NOINTERFACE /* some W2K3 */),
779            "got 0x%x (expected S_OK)\n", hr);
780         if (punk)
781             IUnknown_Release(punk);
782         else
783             win_skip("InternetZoneManagerEx2 not supported\n");
784
785     }
786     else
787         win_skip("InternetZoneManagerEx not supported\n");
788
789     hr = IInternetZoneManager_Release(zonemgr);
790     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
791
792 }
793
794 static void test_CreateZoneEnumerator(void)
795 {
796     IInternetZoneManager *zonemgr = NULL;
797     HRESULT hr;
798     DWORD dwEnum;
799     DWORD dwEnum2;
800     DWORD dwCount;
801     DWORD dwCount2;
802
803     trace("testing zone enumerator...\n");
804
805     hr = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
806     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
807     if (FAILED(hr))
808         return;
809
810     dwEnum=0xdeadbeef;
811     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, NULL, 0);
812     ok((hr == E_INVALIDARG) && (dwEnum == 0xdeadbeef),
813         "got 0x%x with 0x%x (expected E_INVALIDARG with 0xdeadbeef)\n", hr, dwEnum);
814
815     dwCount=0xdeadbeef;
816     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, NULL, &dwCount, 0);
817     ok((hr == E_INVALIDARG) && (dwCount == 0xdeadbeef),
818         "got 0x%x and 0x%x (expected E_INVALIDARG and 0xdeadbeef)\n", hr, dwCount);
819
820     dwEnum=0xdeadbeef;
821     dwCount=0xdeadbeef;
822     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 0xffffffff);
823     ok((hr == E_INVALIDARG) && (dwEnum == 0xdeadbeef) && (dwCount == 0xdeadbeef),
824         "got 0x%x with 0x%x and 0x%x (expected E_INVALIDARG with 0xdeadbeef and 0xdeadbeef)\n",
825         hr, dwEnum, dwCount);
826
827     dwEnum=0xdeadbeef;
828     dwCount=0xdeadbeef;
829     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 1);
830     ok((hr == E_INVALIDARG) && (dwEnum == 0xdeadbeef) && (dwCount == 0xdeadbeef),
831         "got 0x%x with 0x%x and 0x%x (expected E_INVALIDARG with 0xdeadbeef and 0xdeadbeef)\n",
832         hr, dwEnum, dwCount);
833
834     dwEnum=0xdeadbeef;
835     dwCount=0xdeadbeef;
836     /* Normal use */
837     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 0);
838     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
839
840     if (SUCCEEDED(hr)) {
841         dwEnum2=0xdeadbeef;
842         dwCount2=0xdeadbeef;
843         hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum2, &dwCount2, 0);
844         ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
845         if (SUCCEEDED(hr)) {
846             /* native urlmon has an incrementing counter for dwEnum */
847             hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum2);
848             ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
849         }
850
851         hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum);
852         ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
853
854         /* Destroy the Enumerator twice is detected and handled in native urlmon */
855         hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum);
856         ok((hr == E_INVALIDARG), "got 0x%x (expected E_INVALIDARG)\n", hr);
857     }
858
859     /* ::Release succeed also, when a ::DestroyZoneEnumerator is missing */
860     hr = IInternetZoneManager_Release(zonemgr);
861     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
862 }
863
864 static void test_GetZoneActionPolicy(void)
865 {
866     IInternetZoneManager *zonemgr = NULL;
867     BYTE buf[32];
868     HRESULT hres;
869     DWORD action = URLACTION_CREDENTIALS_USE; /* Implemented on all IE versions */
870
871     trace("testing GetZoneActionPolixy...\n");
872
873     hres = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
874     ok(hres == S_OK, "CoInternetCreateZoneManager failed: %08x\n", hres);
875     if(FAILED(hres))
876         return;
877
878     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, buf,
879             sizeof(DWORD), URLZONEREG_DEFAULT);
880     ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
881     ok(*(DWORD*)buf == URLPOLICY_CREDENTIALS_SILENT_LOGON_OK ||
882             *(DWORD*)buf == URLPOLICY_CREDENTIALS_MUST_PROMPT_USER ||
883             *(DWORD*)buf == URLPOLICY_CREDENTIALS_CONDITIONAL_PROMPT ||
884             *(DWORD*)buf == URLPOLICY_CREDENTIALS_ANONYMOUS_ONLY,
885             "unexpected policy=%d\n", *(DWORD*)buf);
886
887     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, NULL,
888             sizeof(DWORD), URLZONEREG_DEFAULT);
889     ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
890
891     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, buf,
892             2, URLZONEREG_DEFAULT);
893     ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
894
895     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, 0x1fff, buf,
896             sizeof(DWORD), URLZONEREG_DEFAULT);
897     ok(hres == E_FAIL || broken(hres == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)),
898             "(0x%x) got 0x%x (expected E_FAIL)\n", action, hres);
899
900     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 13, action, buf,
901             sizeof(DWORD), URLZONEREG_DEFAULT);
902     ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
903
904     IInternetZoneManager_Release(zonemgr);
905 }
906
907 static void test_GetZoneAt(void)
908 {
909     IInternetZoneManager *zonemgr = NULL;
910     HRESULT hr;
911     DWORD dwEnum;
912     DWORD dwCount;
913     DWORD dwZone;
914     DWORD i;
915
916     trace("testing GetZoneAt...\n");
917
918     hr = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
919     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
920     if (FAILED(hr))
921         return;
922
923     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 0);
924     if (FAILED(hr))
925         goto cleanup;
926
927     if (0) {
928         /* this crashes with native urlmon */
929         IInternetZoneManager_GetZoneAt(zonemgr, dwEnum, 0, NULL);
930     }
931
932     dwZone = 0xdeadbeef;
933     hr = IInternetZoneManager_GetZoneAt(zonemgr, 0xdeadbeef, 0, &dwZone);
934     ok(hr == E_INVALIDARG,
935         "got 0x%x with 0x%x (expected E_INVALIDARG)\n", hr, dwZone);
936
937     for (i = 0; i < dwCount; i++)
938     {
939         dwZone = 0xdeadbeef;
940         hr = IInternetZoneManager_GetZoneAt(zonemgr, dwEnum, i, &dwZone);
941         ok(hr == S_OK, "#%d: got x%x with %d (expected S_OK)\n", i, hr, dwZone);
942     }
943
944     dwZone = 0xdeadbeef;
945     /* MSDN (index .. must be .. less than or equal to) is wrong */
946     hr = IInternetZoneManager_GetZoneAt(zonemgr, dwEnum, dwCount, &dwZone);
947     ok(hr == E_INVALIDARG,
948         "got 0x%x with 0x%x (expected E_INVALIDARG)\n", hr, dwZone);
949
950     hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum);
951     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
952
953 cleanup:
954     hr = IInternetZoneManager_Release(zonemgr);
955     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
956 }
957
958 static void test_GetZoneAttributes(void)
959 {
960     IInternetZoneManager *zonemgr = NULL;
961     CHAR buffer [sizeof(ZONEATTRIBUTES) + 32];
962     ZONEATTRIBUTES* pZA = (ZONEATTRIBUTES*) buffer;
963     HRESULT hr;
964     DWORD i;
965
966     trace("testing GetZoneAttributes...\n");
967
968     hr = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
969     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
970     if (FAILED(hr))
971         return;
972
973     /* native urlmon has Zone "0" up to Zone "4" since IE4 */
974     for (i = 0; i < 5; i++) {
975         memset(buffer, -1, sizeof(buffer));
976         hr = IInternetZoneManager_GetZoneAttributes(zonemgr, i, pZA);
977         ok(hr == S_OK, "#%d: got 0x%x (expected S_OK)\n", i, hr);
978     }
979
980     /* IE8 no longer set cbSize */
981     memset(buffer, -1, sizeof(buffer));
982     pZA->cbSize = 0;
983     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, pZA);
984     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
985     ok((pZA->cbSize == 0) || (pZA->cbSize == sizeof(ZONEATTRIBUTES)),
986         "got cbSize = %d (expected 0)\n", pZA->cbSize);
987
988     memset(buffer, -1, sizeof(buffer));
989     pZA->cbSize = 64;
990     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, pZA);
991     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
992     ok((pZA->cbSize == 64) || (pZA->cbSize == sizeof(ZONEATTRIBUTES)),
993         "got cbSize = %d (expected 64)\n", pZA->cbSize);
994
995     memset(buffer, -1, sizeof(buffer));
996     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, pZA);
997     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
998     ok((pZA->cbSize == 0xffffffff) || (pZA->cbSize == sizeof(ZONEATTRIBUTES)),
999         "got cbSize = 0x%x (expected 0xffffffff)\n", pZA->cbSize);
1000
1001     /* IE8 no longer fail on invalid zones */
1002     memset(buffer, -1, sizeof(buffer));
1003     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0xdeadbeef, pZA);
1004     ok(hr == S_OK || (hr == E_FAIL),
1005         "got 0x%x (expected S_OK or E_FAIL)\n", hr);
1006
1007     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, NULL);
1008     ok(hr == E_INVALIDARG, "got 0x%x (expected E_INVALIDARG)\n", hr);
1009
1010     hr = IInternetZoneManager_Release(zonemgr);
1011     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
1012 }
1013
1014 static void test_InternetSecurityMarshalling(void)
1015 {
1016     IInternetSecurityManager *secmgr = NULL;
1017     IUnknown *unk;
1018     IStream *stream;
1019     HRESULT hres;
1020
1021     trace("testing marshalling...\n");
1022
1023     hres = pCoInternetCreateSecurityManager(NULL, &secmgr, 0);
1024     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
1025     if(FAILED(hres))
1026         return;
1027
1028     hres = IInternetSecurityManager_QueryInterface(secmgr, &IID_IUnknown, (void**)&unk);
1029     ok(hres == S_OK, "QueryInterface returned: %08x\n", hres);
1030
1031     hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1032     ok(hres == S_OK, "CreateStreamOnHGlobal returned: %08x\n", hres);
1033
1034     hres = CoMarshalInterface(stream, &IID_IInternetSecurityManager, unk, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1035     /* Not supported in W98 */
1036     ok(hres == S_OK || broken(hres == REGDB_E_IIDNOTREG),
1037         "CoMarshalInterface returned: %08x\n", hres);
1038
1039     IStream_Release(stream);
1040     IUnknown_Release(unk);
1041     IInternetSecurityManager_Release(secmgr);
1042 }
1043
1044 static void test_InternetGetSecurityUrl(void)
1045 {
1046     const WCHAR url5_out[] = {'h','t','t','p',':','w','w','w','.','z','o','n','e','3',
1047                               '.','w','i','n','e','t','e','s','t',0};
1048     const WCHAR url7_out[] = {'f','t','p',':','z','o','n','e','3','.','w','i','n','e','t','e','s','t',0};
1049
1050     const WCHAR *in[] = {url2, url3, url4, url5, url7, url8, url9, url10};
1051     const WCHAR *out_default[] = {url2, url3, url4, url5_out, url7_out, url8, url5_out, url10};
1052     const WCHAR *out_securl[] = {url2, url3, url4, url5, url7, url8, url9, url10};
1053
1054     WCHAR *sec;
1055     DWORD i;
1056     HRESULT hres;
1057
1058     trace("testing CoInternetGetSecurityUrl...\n");
1059
1060     for(i=0; i<sizeof(in)/sizeof(WCHAR*); i++) {
1061         hres = pCoInternetGetSecurityUrl(in[i], &sec, PSU_DEFAULT, 0);
1062         ok(hres == S_OK, "(%d) CoInternetGetSecurityUrl returned: %08x\n", i, hres);
1063         if(hres == S_OK) {
1064             ok(!strcmp_w(sec, out_default[i]), "(%d) Got %s, expected %s\n",
1065                     i, wine_dbgstr_w(sec), wine_dbgstr_w(out_default[i]));
1066             CoTaskMemFree(sec);
1067         }
1068
1069         hres = pCoInternetGetSecurityUrl(in[i], &sec, PSU_SECURITY_URL_ONLY, 0);
1070         ok(hres == S_OK, "(%d) CoInternetGetSecurityUrl returned: %08x\n", i, hres);
1071         if(hres == S_OK) {
1072             ok(!strcmp_w(sec, out_securl[i]), "(%d) Got %s, expected %s\n",
1073                     i, wine_dbgstr_w(sec), wine_dbgstr_w(out_securl[i]));
1074             CoTaskMemFree(sec);
1075         }
1076     }
1077
1078     SET_EXPECT(ParseUrl_SECURITY_URL_input2);
1079     SET_EXPECT(ParseUrl_SECURITY_URL_expected);
1080     SET_EXPECT(ParseUrl_SECURITY_DOMAIN_expected);
1081
1082     hres = pCoInternetGetSecurityUrl(security_url2W, &sec, PSU_DEFAULT, 0);
1083     ok(hres == S_OK, "CoInternetGetSecurityUrl returned 0x%08x, expected S_OK\n", hres);
1084
1085     CHECK_CALLED(ParseUrl_SECURITY_URL_input2);
1086     CHECK_CALLED(ParseUrl_SECURITY_URL_expected);
1087     CHECK_CALLED(ParseUrl_SECURITY_DOMAIN_expected);
1088
1089     ok(!lstrcmpW(security_expectedW, sec), "Expected %s but got %s\n",
1090        wine_dbgstr_w(security_expectedW), wine_dbgstr_w(sec));
1091     CoTaskMemFree(sec);
1092 }
1093
1094 static HRESULT WINAPI InternetProtocolInfo_QueryInterface(IInternetProtocolInfo *iface,
1095                                                           REFIID riid, void **ppv)
1096 {
1097     ok(0, "unexpected call\n");
1098     return E_NOINTERFACE;
1099 }
1100
1101 static ULONG WINAPI InternetProtocolInfo_AddRef(IInternetProtocolInfo *iface)
1102 {
1103     return 2;
1104 }
1105
1106 static ULONG WINAPI InternetProtocolInfo_Release(IInternetProtocolInfo *iface)
1107 {
1108     return 1;
1109 }
1110
1111 static HRESULT WINAPI InternetProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
1112         PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
1113         DWORD *pcchResult, DWORD dwReserved)
1114 {
1115     const WCHAR *ret = NULL;
1116
1117     ok(pwzResult != NULL, "pwzResult == NULL\n");
1118     ok(pcchResult != NULL, "pcchResult == NULL\n");
1119     ok(!dwParseFlags, "Expected 0, but got 0x%08x\n", dwParseFlags);
1120
1121     switch(ParseAction) {
1122     case PARSE_SECURITY_URL:
1123         if(!strcmp_w(pwzUrl, security_urlW)) {
1124             CHECK_EXPECT(ParseUrl_SECURITY_URL_input);
1125             ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
1126             ret = security_expectedW;
1127         } else if(!strcmp_w(pwzUrl, security_url2W)) {
1128             CHECK_EXPECT(ParseUrl_SECURITY_URL_input2);
1129             ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
1130             ret = security_expectedW;
1131         } else if(!strcmp_w(pwzUrl, security_expectedW)) {
1132             CHECK_EXPECT(ParseUrl_SECURITY_URL_expected);
1133             ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
1134             ret = security_expectedW;
1135         } else if(!strcmp_w(pwzUrl, winetest_to_httpW)) {
1136             switch(++called_securl_http) {
1137             case 1:
1138                 ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
1139                 break;
1140             case 2:
1141                 CHECK_EXPECT(ParseUrl_SECURITY_URL_http);
1142                 ok(cchResult == lstrlenW(url9)+1, "Got %d\n", cchResult);
1143                 break;
1144             default:
1145                 todo_wine CHECK_EXPECT(ParseUrl_SECURITY_URL_http);
1146             }
1147             ret = url9;
1148         } else
1149             ok(0, "Unexpected call, pwzUrl=%s\n", wine_dbgstr_w(pwzUrl));
1150
1151         break;
1152     case PARSE_SECURITY_DOMAIN:
1153
1154         CHECK_EXPECT(ParseUrl_SECURITY_DOMAIN_expected);
1155
1156         ok(!strcmp_w(pwzUrl, security_expectedW), "Expected %s but got %s\n",
1157             wine_dbgstr_w(security_expectedW), wine_dbgstr_w(pwzUrl));
1158         ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
1159         ret = security_expectedW;
1160         break;
1161     default:
1162         ok(0, "Unexpected call, ParseAction=%d pwzUrl=%s\n", ParseAction,
1163             wine_dbgstr_w(pwzUrl));
1164     }
1165
1166     if(!ret)
1167         return E_FAIL;
1168
1169     *pcchResult = lstrlenW(ret)+1;
1170     if(*pcchResult > cchResult)
1171         return S_FALSE;
1172     memcpy(pwzResult, ret, (*pcchResult)*sizeof(WCHAR));
1173     return S_OK;
1174 }
1175
1176 static HRESULT WINAPI InternetProtocolInfo_CombineUrl(IInternetProtocolInfo *iface,
1177         LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags,
1178         LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
1179 {
1180     ok(0, "unexpected call\n");
1181     return E_NOTIMPL;
1182 }
1183
1184 static HRESULT WINAPI InternetProtocolInfo_CompareUrl(IInternetProtocolInfo *iface,
1185         LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
1186 {
1187     ok(0, "unexpected call\n");
1188     return E_NOTIMPL;
1189 }
1190
1191 static HRESULT WINAPI InternetProtocolInfo_QueryInfo(IInternetProtocolInfo *iface,
1192         LPCWSTR pwzUrl, QUERYOPTION OueryOption, DWORD dwQueryFlags, LPVOID pBuffer,
1193         DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved)
1194 {
1195     ok(0, "unexpected call\n");
1196     return E_NOTIMPL;
1197 }
1198
1199 static const IInternetProtocolInfoVtbl InternetProtocolInfoVtbl = {
1200     InternetProtocolInfo_QueryInterface,
1201     InternetProtocolInfo_AddRef,
1202     InternetProtocolInfo_Release,
1203     InternetProtocolInfo_ParseUrl,
1204     InternetProtocolInfo_CombineUrl,
1205     InternetProtocolInfo_CompareUrl,
1206     InternetProtocolInfo_QueryInfo
1207 };
1208
1209 static IInternetProtocolInfo protocol_info = { &InternetProtocolInfoVtbl };
1210
1211 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
1212 {
1213     if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
1214         *ppv = &protocol_info;
1215         return S_OK;
1216     }
1217
1218     ok(0, "unexpected call\n");
1219     return E_NOINTERFACE;
1220 }
1221
1222 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
1223 {
1224     return 2;
1225 }
1226
1227 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
1228 {
1229     return 1;
1230 }
1231
1232 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
1233                                         REFIID riid, void **ppv)
1234 {
1235     ok(0, "unexpected call\n");
1236     return E_NOTIMPL;
1237 }
1238
1239 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
1240 {
1241     ok(0, "unexpected call\n");
1242     return S_OK;
1243 }
1244
1245 static const IClassFactoryVtbl ClassFactoryVtbl = {
1246     ClassFactory_QueryInterface,
1247     ClassFactory_AddRef,
1248     ClassFactory_Release,
1249     ClassFactory_CreateInstance,
1250     ClassFactory_LockServer
1251 };
1252
1253 static IClassFactory protocol_cf = { &ClassFactoryVtbl };
1254
1255 static void register_protocols(void)
1256 {
1257     IInternetSession *session;
1258     HRESULT hres;
1259
1260     hres = pCoInternetGetSession(0, &session, 0);
1261     ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
1262     if(FAILED(hres))
1263         return;
1264
1265     hres = IInternetSession_RegisterNameSpace(session, &protocol_cf, &IID_NULL,
1266             winetestW, 0, NULL, 0);
1267     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1268
1269     IInternetSession_Release(session);
1270 }
1271
1272 static void unregister_protocols(void) {
1273     IInternetSession *session;
1274     HRESULT hr;
1275
1276     hr = pCoInternetGetSession(0, &session, 0);
1277     ok(hr == S_OK, "CoInternetGetSession failed: 0x%08x\n", hr);
1278     if(FAILED(hr))
1279         return;
1280
1281     hr = IInternetSession_UnregisterNameSpace(session, &protocol_cf, winetestW);
1282     ok(hr == S_OK, "UnregisterNameSpace failed: 0x%08x\n", hr);
1283
1284     IInternetSession_Release(session);
1285 }
1286
1287 static const struct {
1288     const char  *uri;
1289     DWORD       create_flags;
1290     const char  *security_uri;
1291     HRESULT     security_hres;
1292     const char  *default_uri;
1293     HRESULT     default_hres;
1294     BOOL        todo;
1295 } sec_url_ex_tests[] = {
1296     {"index.htm",Uri_CREATE_ALLOW_RELATIVE,"*:index.html",S_OK,"*:index.htm",S_OK},
1297     {"file://c:\\Index.htm",Uri_CREATE_FILE_USE_DOS_PATH,"file:///c:/Index.htm",S_OK,"file:///c:/Index.htm",S_OK},
1298     {"file:some%20file%2ejpg",0,NULL,E_INVALIDARG,NULL,E_INVALIDARG},
1299     {"file:some file.jpg",0,NULL,E_INVALIDARG,NULL,E_INVALIDARG},
1300     {"http://www.zone3.winetest/",0,"http://www.zone3.winetest/",S_OK,"http://www.zone3.winetest/",S_OK},
1301     {"about:blank",0,"about:blank",S_OK,"about:blank",S_OK},
1302     {"ftp://zone3.winetest/file.test",0,"ftp://zone3.winetest/file.test",S_OK,"ftp://zone3.winetest/file.test",S_OK},
1303     {"test:123abc",0,"test:123abc",S_OK,"test:123abc",S_OK},
1304     {"http:google.com/test.file",0,"http:google.com/test.file",S_OK,"http:google.com/test.file",S_OK},
1305     {"ftp://test@ftp.winehq.org/",0,"ftp://ftp.winehq.org/",S_OK,"ftp://ftp.winehq.org/",S_OK},
1306     {"test://google@ftp.winehq.org/",0,"test://google@ftp.winehq.org/",S_OK,"test://google@ftp.winehq.org/",S_OK}
1307 };
1308
1309 static void test_InternetGetSecurityUrlEx(void)
1310 {
1311     HRESULT hr;
1312     DWORD i;
1313     IUri *uri = NULL, *result = NULL;
1314
1315     trace("testing CoInternetGetSecurityUrlEx...\n");
1316
1317     hr = pCoInternetGetSecurityUrlEx(NULL, NULL, PSU_DEFAULT, 0);
1318     ok(hr == E_INVALIDARG, "CoInternetGetSecurityUrlEx returned 0x%08x, expected E_INVALIDARG\n", hr);
1319
1320     result = (void*) 0xdeadbeef;
1321     hr = pCoInternetGetSecurityUrlEx(NULL, &result, PSU_DEFAULT, 0);
1322     ok(hr == E_INVALIDARG, "CoInternetGetSecurityUrlEx returned 0x%08x, expected E_INVALIDARG\n", hr);
1323     ok(result == (void*) 0xdeadbeef, "'result' was %p\n", result);
1324
1325     for(i = 0; i < sizeof(sec_url_ex_tests)/sizeof(sec_url_ex_tests[0]); ++i) {
1326         LPWSTR uriW = a2w(sec_url_ex_tests[i].uri);
1327         uri = NULL;
1328
1329         hr = pCreateUri(uriW, sec_url_ex_tests[i].create_flags, 0, &uri);
1330         ok(hr == S_OK, "CreateUri returned 0x%08x on test %d\n", hr, i);
1331         if(hr == S_OK) {
1332             result = NULL;
1333
1334             hr = pCoInternetGetSecurityUrlEx(uri, &result, PSU_DEFAULT, 0);
1335             if(sec_url_ex_tests[i].todo) {
1336                 todo_wine
1337                     ok(hr == sec_url_ex_tests[i].default_hres,
1338                         "CoInternetGetSecurityUrlEx returned 0x%08x, expected 0x%08x on test %d\n",
1339                         hr, sec_url_ex_tests[i].default_hres, i);
1340             } else {
1341                 ok(hr == sec_url_ex_tests[i].default_hres,
1342                     "CoInternetGetSecurityUrlEx returned 0x%08x, expected 0x%08x on test %d\n",
1343                     hr, sec_url_ex_tests[i].default_hres, i);
1344             }
1345             if(SUCCEEDED(hr)) {
1346                 BSTR received;
1347
1348                 hr = IUri_GetDisplayUri(result, &received);
1349                 ok(hr == S_OK, "GetDisplayUri returned 0x%08x on test %d\n", hr, i);
1350                 if(hr == S_OK) {
1351                     if(sec_url_ex_tests[i].todo) {
1352                         todo_wine
1353                             ok(!strcmp_aw(sec_url_ex_tests[i].default_uri, received),
1354                                 "Expected %s but got %s on test %d\n", sec_url_ex_tests[i].default_uri,
1355                                 wine_dbgstr_w(received), i);
1356                     } else {
1357                         ok(!strcmp_aw(sec_url_ex_tests[i].default_uri, received),
1358                             "Expected %s but got %s on test %d\n", sec_url_ex_tests[i].default_uri,
1359                             wine_dbgstr_w(received), i);
1360                     }
1361                 }
1362                 SysFreeString(received);
1363             }
1364             if(result) IUri_Release(result);
1365
1366             result = NULL;
1367             hr = pCoInternetGetSecurityUrlEx(uri, &result, PSU_SECURITY_URL_ONLY, 0);
1368             if(sec_url_ex_tests[i].todo) {
1369                 todo_wine
1370                     ok(hr == sec_url_ex_tests[i].default_hres,
1371                         "CoInternetGetSecurityUrlEx returned 0x%08x, expected 0x%08x on test %d\n",
1372                         hr, sec_url_ex_tests[i].default_hres, i);
1373             } else {
1374                 ok(hr == sec_url_ex_tests[i].default_hres,
1375                     "CoInternetGetSecurityUrlEx returned 0x%08x, expected 0x%08x on test %d\n",
1376                     hr, sec_url_ex_tests[i].default_hres, i);
1377             }
1378             if(SUCCEEDED(hr)) {
1379                 BSTR received;
1380
1381                 hr = IUri_GetDisplayUri(result, &received);
1382                 ok(hr == S_OK, "GetDisplayUri returned 0x%08x on test %d\n", hr, i);
1383                 if(hr == S_OK) {
1384                     if(sec_url_ex_tests[i].todo) {
1385                         todo_wine
1386                             ok(!strcmp_aw(sec_url_ex_tests[i].default_uri, received),
1387                                 "Expected %s but got %s on test %d\n", sec_url_ex_tests[i].default_uri,
1388                                 wine_dbgstr_w(received), i);
1389                     } else {
1390                         ok(!strcmp_aw(sec_url_ex_tests[i].default_uri, received),
1391                             "Expected %s but got %s on test %d\n", sec_url_ex_tests[i].default_uri,
1392                             wine_dbgstr_w(received), i);
1393                     }
1394                 }
1395                 SysFreeString(received);
1396             }
1397             if(result) IUri_Release(result);
1398         }
1399
1400         if(uri) IUri_Release(uri);
1401         heap_free(uriW);
1402     }
1403 }
1404
1405 static void test_InternetGetSecurityUrlEx_Pluggable(void)
1406 {
1407     HRESULT hr;
1408     IUri *uri = NULL, *result;
1409
1410     trace("testing CoInternetGetSecurityUrlEx for plugable protocols...\n");
1411
1412     hr = pCreateUri(security_urlW, 0, 0, &uri);
1413     ok(hr == S_OK, "CreateUri returned 0x%08x\n", hr);
1414     if(hr == S_OK) {
1415         SET_EXPECT(ParseUrl_SECURITY_URL_input);
1416         SET_EXPECT(ParseUrl_SECURITY_URL_expected);
1417         SET_EXPECT(ParseUrl_SECURITY_DOMAIN_expected);
1418
1419         hr = pCoInternetGetSecurityUrlEx(uri, &result, PSU_DEFAULT, 0);
1420         ok(hr == S_OK, "CoInternetGetSecurityUrlEx returned 0x%08x, expected S_OK\n", hr);
1421
1422         CHECK_CALLED(ParseUrl_SECURITY_URL_input);
1423         CHECK_CALLED(ParseUrl_SECURITY_URL_expected);
1424         CHECK_CALLED(ParseUrl_SECURITY_DOMAIN_expected);
1425
1426         if(hr == S_OK) {
1427             BSTR received = NULL;
1428
1429             hr = IUri_GetAbsoluteUri(result, &received);
1430             ok(hr == S_OK, "GetAbsoluteUri returned 0x%08x\n", hr);
1431             if(hr == S_OK) {
1432                 ok(!strcmp_w(security_expectedW, received), "Expected %s but got %s\n",
1433                     wine_dbgstr_w(security_expectedW), wine_dbgstr_w(received));
1434             }
1435             SysFreeString(received);
1436         }
1437         if(result) IUri_Release(result);
1438
1439         result = NULL;
1440
1441         SET_EXPECT(ParseUrl_SECURITY_URL_input);
1442         SET_EXPECT(ParseUrl_SECURITY_URL_expected);
1443
1444         hr = pCoInternetGetSecurityUrlEx(uri, &result, PSU_SECURITY_URL_ONLY, 0);
1445         ok(hr == S_OK, "CoInternetGetSecurityUrlEx returned 0x%08x, expected S_OK\n", hr);
1446
1447         CHECK_CALLED(ParseUrl_SECURITY_URL_input);
1448         CHECK_CALLED(ParseUrl_SECURITY_URL_expected);
1449
1450         if(hr == S_OK) {
1451             BSTR received = NULL;
1452
1453             hr = IUri_GetAbsoluteUri(result, &received);
1454             ok(hr == S_OK, "GetAbsoluteUri returned 0x%08x\n", hr);
1455             if(hr == S_OK) {
1456                 ok(!strcmp_w(security_expectedW, received), "Expected %s but got %s\n",
1457                     wine_dbgstr_w(security_expectedW), wine_dbgstr_w(received));
1458             }
1459             SysFreeString(received);
1460         }
1461         if(result) IUri_Release(result);
1462     }
1463     if(uri) IUri_Release(uri);
1464 }
1465
1466 START_TEST(sec_mgr)
1467 {
1468     HMODULE hurlmon;
1469     int argc;
1470     char **argv;
1471
1472     hurlmon = GetModuleHandle("urlmon.dll");
1473     pCoInternetCreateSecurityManager = (void*) GetProcAddress(hurlmon, "CoInternetCreateSecurityManager");
1474     pCoInternetCreateZoneManager = (void*) GetProcAddress(hurlmon, "CoInternetCreateZoneManager");
1475     pCoInternetGetSecurityUrl = (void*) GetProcAddress(hurlmon, "CoInternetGetSecurityUrl");
1476     pCoInternetGetSecurityUrlEx = (void*) GetProcAddress(hurlmon, "CoInternetGetSecurityUrlEx");
1477     pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
1478     pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
1479
1480     if (!pCoInternetCreateSecurityManager || !pCoInternetCreateZoneManager ||
1481         !pCoInternetGetSecurityUrl) {
1482         win_skip("Various CoInternet* functions not present in IE 4.0\n");
1483         return;
1484     }
1485
1486     argc = winetest_get_mainargs(&argv);
1487     if(argc > 2 && !strcmp(argv[2], "domain_tests")) {
1488         test_zone_domain_mappings();
1489         return;
1490     }
1491
1492     OleInitialize(NULL);
1493     register_protocols();
1494
1495     test_InternetGetSecurityUrl();
1496
1497     if(!pCoInternetGetSecurityUrlEx || !pCreateUri)
1498         win_skip("Skipping CoInternetGetSecurityUrlEx tests, IE too old\n");
1499     else {
1500         test_InternetGetSecurityUrlEx();
1501         test_InternetGetSecurityUrlEx_Pluggable();
1502     }
1503
1504     test_SecurityManager();
1505     test_polices();
1506     test_zone_domains();
1507     test_CoInternetCreateZoneManager();
1508     test_CreateZoneEnumerator();
1509     test_GetZoneActionPolicy();
1510     test_GetZoneAt();
1511     test_GetZoneAttributes();
1512     test_InternetSecurityMarshalling();
1513
1514     unregister_protocols();
1515     OleUninitialize();
1516 }