comctl32: Fix read of uninitialized data in LISTVIEW_GetItemExtT when LVIF_TEXT is...
[wine] / dlls / urlmon / tests / sec_mgr.c
1 /*
2  * Copyright 2005-2006 Jacek Caban for CodeWeavers
3  * Copyright 2009-2010 Detlef Riekenberg
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #define COBJMACROS
21 #define CONST_VTABLE
22 #define NONAMELESSUNION
23
24 /* needed for IInternetZoneManagerEx2 */
25 #define _WIN32_IE 0x0700
26
27 #include <wine/test.h>
28 #include <stdarg.h>
29 #include <stddef.h>
30
31 #include "windef.h"
32 #include "winbase.h"
33 #include "ole2.h"
34 #include "urlmon.h"
35
36 #include "initguid.h"
37
38 #define DEFINE_EXPECT(func) \
39     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
40
41 #define SET_EXPECT(func) \
42     expect_ ## func = TRUE
43
44 #define CHECK_EXPECT(func) \
45     do { \
46         ok(expect_ ##func, "unexpected call " #func "\n"); \
47         expect_ ## func = FALSE; \
48         called_ ## func = TRUE; \
49     }while(0)
50
51 #define CHECK_EXPECT2(func) \
52     do { \
53         ok(expect_ ##func, "unexpected call " #func "\n"); \
54         called_ ## func = TRUE; \
55     }while(0)
56
57 #define CHECK_CALLED(func) \
58     do { \
59         ok(called_ ## func, "expected " #func "\n"); \
60         expect_ ## func = called_ ## func = FALSE; \
61     }while(0)
62
63 DEFINE_EXPECT(ParseUrl_SECURITY_URL_input);
64 DEFINE_EXPECT(ParseUrl_SECURITY_URL_input2);
65 DEFINE_EXPECT(ParseUrl_SECURITY_URL_expected);
66 DEFINE_EXPECT(ParseUrl_SECURITY_URL_http);
67 DEFINE_EXPECT(ParseUrl_SECURITY_DOMAIN_expected);
68
69 static HRESULT (WINAPI *pCoInternetCreateSecurityManager)(IServiceProvider *, IInternetSecurityManager**, DWORD);
70 static HRESULT (WINAPI *pCoInternetCreateZoneManager)(IServiceProvider *, IInternetZoneManager**, DWORD);
71 static HRESULT (WINAPI *pCoInternetGetSecurityUrl)(LPCWSTR, LPWSTR*, PSUACTION, DWORD);
72 static HRESULT (WINAPI *pCoInternetGetSecurityUrlEx)(IUri*, IUri**, PSUACTION, DWORD_PTR);
73 static HRESULT (WINAPI *pCreateUri)(LPCWSTR, DWORD, DWORD_PTR, IUri**);
74 static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession**, DWORD);
75
76 static const WCHAR url1[] = {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l',
77         '/','b','l','a','n','k','.','h','t','m',0};
78 static const WCHAR url2[] = {'i','n','d','e','x','.','h','t','m',0};
79 static const WCHAR url3[] = {'f','i','l','e',':','/','/','c',':','\\','I','n','d','e','x','.','h','t','m',0};
80 static const WCHAR url4[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e',
81         '%','2','e','j','p','g',0};
82 static const WCHAR url5[] = {'h','t','t','p',':','/','/','w','w','w','.','z','o','n','e','3',
83         '.','w','i','n','e','t','e','s','t',0};
84 static const WCHAR url6[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
85 static const WCHAR url7[] = {'f','t','p',':','/','/','z','o','n','e','3',
86         '.','w','i','n','e','t','e','s','t','/','f','i','l','e','.','t','e','s','t',0};
87 static const WCHAR url8[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
88 static const WCHAR url9[] = {'h','t','t','p',':','/','/','w','w','w','.','z','o','n','e','3',
89         '.','w','i','n','e','t','e','s','t', '/','s','i','t','e','/','a','b','o','u','t',0};
90 static const WCHAR url10[] = {'f','i','l','e',':','/','/','s','o','m','e','%','2','0','f','i','l','e',
91         '.','j','p','g',0};
92
93 static const WCHAR url4e[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e',
94         '.','j','p','g',0};
95
96 static const WCHAR winetestW[] = {'w','i','n','e','t','e','s','t',0};
97 static const WCHAR security_urlW[] = {'w','i','n','e','t','e','s','t',':','t','e','s','t','i','n','g',0};
98 static const WCHAR security_url2W[] = {'w','i','n','e','t','e','s','t',':','t','e','s','t','i','n','g','2',0};
99 static const WCHAR security_expectedW[] = {'w','i','n','e','t','e','s','t',':','z','i','p',0};
100 static const WCHAR winetest_to_httpW[] = {'w','i','n','e','t','e','s','t',':','h',0};
101
102 static const BYTE secid1[] = {'f','i','l','e',':',0,0,0,0};
103 static const BYTE secid5[] = {'h','t','t','p',':','w','w','w','.','z','o','n','e','3',
104         '.','w','i','n','e','t','e','s','t',3,0,0,0};
105 static const BYTE secid6[] = {'a','b','o','u','t',':','b','l','a','n','k',3,0,0,0};
106 static const BYTE secid7[] = {'f','t','p',':','z','o','n','e','3',
107         '.','w','i','n','e','t','e','s','t',3,0,0,0};
108 static const BYTE secid10[] =
109     {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e','.','j','p','g',3,0,0,0};
110 static const BYTE secid10_2[] =
111     {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e','.','j','p','g',3,0,0,0};
112
113 static const GUID CLSID_TestActiveX =
114     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x46}};
115
116 /* Defined as extern in urlmon.idl, but not exported by uuid.lib */
117 const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
118     {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
119
120 static int called_securl_http;
121
122 static struct secmgr_test {
123     LPCWSTR url;
124     DWORD zone;
125     HRESULT zone_hres;
126     DWORD secid_size;
127     const BYTE *secid;
128     HRESULT secid_hres;
129 } secmgr_tests[] = {
130     {url1, 0,   S_OK, sizeof(secid1), secid1, S_OK},
131     {url2, 100, 0x80041001, 0, NULL, E_INVALIDARG},
132     {url3, 0,   S_OK, sizeof(secid1), secid1, S_OK},
133     {url5, 3,   S_OK, sizeof(secid5), secid5, S_OK},
134     {url6, 3,   S_OK, sizeof(secid6), secid6, S_OK},
135     {url7, 3,   S_OK, sizeof(secid7), secid7, S_OK}
136 };
137
138 static int strcmp_w(const WCHAR *str1, const WCHAR *str2)
139 {
140     DWORD len1 = lstrlenW(str1);
141     DWORD len2 = lstrlenW(str2);
142
143     if(len1!=len2) return 1;
144     return memcmp(str1, str2, len1*sizeof(WCHAR));
145 }
146
147 static inline void heap_free(void *mem)
148 {
149     HeapFree(GetProcessHeap(), 0, mem);
150 }
151
152 static inline LPWSTR a2w(LPCSTR str)
153 {
154     LPWSTR ret = NULL;
155
156     if(str) {
157         DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
158         ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
159         MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
160     }
161
162     return ret;
163 }
164
165 static inline DWORD strcmp_aw(LPCSTR strA, LPCWSTR strB) {
166     LPWSTR strAW = a2w(strA);
167     DWORD ret = lstrcmpW(strAW, strB);
168     heap_free(strAW);
169     return ret;
170 }
171
172 static void test_SecurityManager(void)
173 {
174     int i;
175     IInternetSecurityManager *secmgr = NULL;
176     BYTE buf[512];
177     DWORD zone, size, policy;
178     HRESULT hres;
179
180     if(!pCoInternetCreateSecurityManager) {
181         return;
182     }
183
184     trace("Testing security manager...\n");
185
186     hres = pCoInternetCreateSecurityManager(NULL, &secmgr, 0);
187     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
188     if(FAILED(hres))
189         return;
190
191     for(i=0; i < sizeof(secmgr_tests)/sizeof(secmgr_tests[0]); i++) {
192         zone = 100;
193         hres = IInternetSecurityManager_MapUrlToZone(secmgr, secmgr_tests[i].url,
194                                                      &zone, 0);
195         ok(hres == secmgr_tests[i].zone_hres /* IE <=6 */
196            || (FAILED(secmgr_tests[i].zone_hres) && hres == E_INVALIDARG), /* IE7 */
197            "[%d] MapUrlToZone failed: %08x, expected %08x\n",
198                 i, hres, secmgr_tests[i].zone_hres);
199         if(SUCCEEDED(hres))
200             ok(zone == secmgr_tests[i].zone, "[%d] zone=%d, expected %d\n", i, zone,
201                secmgr_tests[i].zone);
202         else
203             ok(zone == secmgr_tests[i].zone || zone == -1, "[%d] zone=%d\n", i, zone);
204
205         size = sizeof(buf);
206         memset(buf, 0xf0, sizeof(buf));
207         hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[i].url,
208                 buf, &size, 0);
209         ok(hres == secmgr_tests[i].secid_hres,
210            "[%d] GetSecurityId failed: %08x, expected %08x\n",
211            i, hres, secmgr_tests[i].secid_hres);
212         if(secmgr_tests[i].secid) {
213             ok(size == secmgr_tests[i].secid_size, "[%d] size=%d, expected %d\n",
214                     i, size, secmgr_tests[i].secid_size);
215             ok(!memcmp(buf, secmgr_tests[i].secid, size), "[%d] wrong secid\n", i);
216         }
217     }
218
219     zone = 100;
220     hres = IInternetSecurityManager_MapUrlToZone(secmgr, url10, &zone, 0);
221     ok(hres == S_OK, "MapUrlToZone failed: %08x, expected S_OK\n", hres);
222     ok(zone == 3, "zone=%d, expected 3\n", zone);
223
224     /* win2k3 translates %20 into a space */
225     size = sizeof(buf);
226     memset(buf, 0xf0, sizeof(buf));
227     hres = IInternetSecurityManager_GetSecurityId(secmgr, url10, buf, &size, 0);
228     ok(hres == S_OK, "GetSecurityId failed: %08x, expected S_OK\n", hres);
229     ok(size == sizeof(secid10) ||
230        size == sizeof(secid10_2), /* win2k3 */
231        "size=%d\n", size);
232     ok(!memcmp(buf, secid10, size) ||
233        !memcmp(buf, secid10_2, size), /* win2k3 */
234        "wrong secid\n");
235
236     zone = 100;
237     hres = IInternetSecurityManager_MapUrlToZone(secmgr, NULL, &zone, 0);
238     ok(hres == E_INVALIDARG, "MapUrlToZone failed: %08x, expected E_INVALIDARG\n", hres);
239     ok(zone == 100 || zone == -1, "zone=%d\n", zone);
240
241     size = sizeof(buf);
242     hres = IInternetSecurityManager_GetSecurityId(secmgr, NULL, buf, &size, 0);
243     ok(hres == E_INVALIDARG,
244        "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
245     hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[1].url,
246                                                   NULL, &size, 0);
247     ok(hres == E_INVALIDARG,
248        "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
249     hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[1].url,
250                                                   buf, NULL, 0);
251     ok(hres == E_INVALIDARG,
252        "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
253
254     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, NULL, URLACTION_SCRIPT_RUN, (BYTE*)&policy,
255             sizeof(WCHAR), NULL, 0, 0, 0);
256     ok(hres == E_INVALIDARG, "ProcessUrlAction failed: %08x, expected E_INVALIDARG\n", hres);
257
258     IInternetSecurityManager_Release(secmgr);
259 }
260
261 /* Check if Internet Explorer is configured to run in "Enhanced Security Configuration" (aka hardened mode) */
262 /* Note: this code is duplicated in dlls/mshtml/tests/mshtml_test.h and dlls/urlmon/tests/sec_mgr.c */
263 static BOOL is_ie_hardened(void)
264 {
265     HKEY zone_map;
266     DWORD ie_harden, type, size;
267
268     ie_harden = 0;
269     if(RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap",
270                     0, KEY_QUERY_VALUE, &zone_map) == ERROR_SUCCESS) {
271         size = sizeof(DWORD);
272         if (RegQueryValueExA(zone_map, "IEHarden", NULL, &type, (LPBYTE) &ie_harden, &size) != ERROR_SUCCESS ||
273             type != REG_DWORD) {
274             ie_harden = 0;
275         }
276         RegCloseKey(zone_map);
277     }
278
279     return ie_harden != 0;
280 }
281
282 static void test_url_action(IInternetSecurityManager *secmgr, IInternetZoneManager *zonemgr, DWORD action)
283 {
284     DWORD res, size, policy, reg_policy;
285     char buf[10];
286     HKEY hkey;
287     HRESULT hres;
288
289     /* FIXME: HKEY_CURRENT_USER is most of the time the default but this can be changed on a system.
290      * The test should be changed to cope with that, if need be.
291      */
292     res = RegOpenKeyA(HKEY_CURRENT_USER,
293             "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3", &hkey);
294     if(res != ERROR_SUCCESS) {
295         ok(0, "Could not open zone key\n");
296         return;
297     }
298
299     wsprintf(buf, "%X", action);
300     size = sizeof(DWORD);
301     res = RegQueryValueExA(hkey, buf, NULL, NULL, (BYTE*)&reg_policy, &size);
302     RegCloseKey(hkey);
303     if(res != ERROR_SUCCESS || size != sizeof(DWORD)) {
304         policy = 0xdeadbeef;
305         hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
306                 sizeof(WCHAR), NULL, 0, 0, 0);
307         ok(hres == E_FAIL || broken(hres == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)),
308             "(0x%x) got 0x%x (expected E_FAIL)\n", action, hres);
309         ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
310
311         policy = 0xdeadbeef;
312         hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
313                 sizeof(DWORD), URLZONEREG_DEFAULT);
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         return;
318     }
319
320     policy = 0xdeadbeef;
321     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
322             sizeof(DWORD), URLZONEREG_DEFAULT);
323     ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
324     ok(policy == reg_policy, "(%x) policy=%x, expected %x\n", action, policy, reg_policy);
325
326     if(policy != URLPOLICY_QUERY) {
327         if(winetest_interactive || ! is_ie_hardened()) {
328             BOOL expect_parse_call = !called_securl_http;
329
330             policy = 0xdeadbeef;
331             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
332                     sizeof(WCHAR), NULL, 0, 0, 0);
333             if(reg_policy == URLPOLICY_DISALLOW)
334                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
335             else
336                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
337             ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
338
339             policy = 0xdeadbeef;
340             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
341                     2, NULL, 0, 0, 0);
342             if(reg_policy == URLPOLICY_DISALLOW)
343                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
344             else
345                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
346             ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
347
348             policy = 0xdeadbeef;
349             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
350                     sizeof(DWORD), NULL, 0, 0, 0);
351             if(reg_policy == URLPOLICY_DISALLOW)
352                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
353             else
354                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
355             ok(policy == reg_policy, "(%x) policy=%x\n", action, policy);
356
357             policy = 0xdeadbeef;
358             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
359                     sizeof(WCHAR), (BYTE*)0xdeadbeef, 16, 0, 0);
360             if(reg_policy == URLPOLICY_DISALLOW)
361                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
362             else
363                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
364             ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
365
366             policy = 0xdeadbeef;
367             if(expect_parse_call)
368                 SET_EXPECT(ParseUrl_SECURITY_URL_http);
369             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, winetest_to_httpW, action, (BYTE*)&policy,
370                     sizeof(DWORD), NULL, 0, 0, 0);
371             if(expect_parse_call)
372                 CHECK_CALLED(ParseUrl_SECURITY_URL_http);
373             if(reg_policy == URLPOLICY_DISALLOW)
374                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
375             else
376                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
377             ok(policy == reg_policy, "(%x) policy=%x\n", action, policy);
378         }else {
379             skip("IE running in Enhanced Security Configuration\n");
380         }
381     }
382 }
383
384 static void test_special_url_action(IInternetSecurityManager *secmgr, IInternetZoneManager *zonemgr, DWORD action)
385 {
386     DWORD policy;
387     HRESULT hres;
388
389     policy = 0xdeadbeef;
390     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
391             sizeof(DWORD), URLZONEREG_DEFAULT);
392     ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
393     ok(policy == URLPOLICY_DISALLOW, "(%x) policy=%x, expected URLPOLICY_DISALLOW\n", action, policy);
394
395     policy = 0xdeadbeef;
396     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url1, action, (BYTE*)&policy,
397             sizeof(WCHAR), NULL, 0, 0, 0);
398     ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
399
400     policy = 0xdeadbeef;
401     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url1, action, (BYTE*)&policy,
402             sizeof(DWORD), NULL, 0, 0, 0);
403     ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
404     ok(policy == URLPOLICY_DISALLOW, "policy = %x\n", policy);
405 }
406
407 static void test_activex(IInternetSecurityManager *secmgr)
408 {
409     DWORD policy, policy_size;
410     struct CONFIRMSAFETY cs;
411     BYTE *ppolicy;
412     HRESULT hres;
413
414     policy = 0xdeadbeef;
415     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url1, URLACTION_ACTIVEX_RUN, (BYTE*)&policy,
416             sizeof(DWORD), (BYTE*)&CLSID_TestActiveX, sizeof(CLSID), 0, 0);
417     ok(hres == S_OK, "ProcessUrlAction(URLACTION_ACTIVEX_RUN) failed: %08x\n", hres);
418     ok(policy == URLPOLICY_ALLOW || policy == URLPOLICY_DISALLOW, "policy = %x\n", policy);
419
420     cs.clsid = CLSID_TestActiveX;
421     cs.pUnk = (IUnknown*)0xdeadbeef;
422     cs.dwFlags = 0;
423     hres = IInternetSecurityManager_QueryCustomPolicy(secmgr, url1, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
424             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
425     ok(hres == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "QueryCusromPolicy failed: %08x\n", hres);
426 }
427
428 static void test_polices(void)
429 {
430     IInternetZoneManager *zonemgr = NULL;
431     IInternetSecurityManager *secmgr = NULL;
432     HRESULT hres;
433
434     trace("testing polices...\n");
435
436     hres = pCoInternetCreateSecurityManager(NULL, &secmgr, 0);
437     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
438     hres = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
439     ok(hres == S_OK, "CoInternetCreateZoneManager failed: %08x\n", hres);
440
441     test_url_action(secmgr, zonemgr, URLACTION_SCRIPT_RUN);
442     test_url_action(secmgr, zonemgr, URLACTION_ACTIVEX_RUN);
443     test_url_action(secmgr, zonemgr, URLACTION_ACTIVEX_OVERRIDE_OBJECT_SAFETY);
444     test_url_action(secmgr, zonemgr, URLACTION_CHANNEL_SOFTDIST_PERMISSIONS);
445     test_url_action(secmgr, zonemgr, 0xdeadbeef);
446
447     test_special_url_action(secmgr, zonemgr, URLACTION_SCRIPT_OVERRIDE_SAFETY);
448     test_special_url_action(secmgr, zonemgr, URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY);
449
450     test_activex(secmgr);
451
452     IInternetSecurityManager_Release(secmgr);
453     IInternetZoneManager_Release(zonemgr);
454 }
455
456 static void test_CoInternetCreateZoneManager(void)
457 {
458     IInternetZoneManager *zonemgr = NULL;
459     IUnknown *punk = NULL;
460     HRESULT hr;
461
462     trace("simple zone manager tests...\n");
463
464     hr = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
465     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
466     if (FAILED(hr))
467         return;
468
469     hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IUnknown, (void **) &punk);
470     ok(SUCCEEDED(hr), "got 0x%x with %p (expected Success)\n", hr, punk);
471     if (punk)
472         IUnknown_Release(punk);
473
474     hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IInternetZoneManager, (void **) &punk);
475     ok(SUCCEEDED(hr), "got 0x%x with %p (expected Success)\n", hr, punk);
476     if (punk)
477         IUnknown_Release(punk);
478
479
480     hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IInternetZoneManagerEx, (void **) &punk);
481     if (SUCCEEDED(hr)) {
482         IUnknown_Release(punk);
483
484         hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IInternetZoneManagerEx2, (void **) &punk);
485         ok(hr == S_OK || broken(hr == E_NOINTERFACE /* some W2K3 */),
486            "got 0x%x (expected S_OK)\n", hr);
487         if (punk)
488             IUnknown_Release(punk);
489         else
490             win_skip("InternetZoneManagerEx2 not supported\n");
491
492     }
493     else
494         win_skip("InternetZoneManagerEx not supported\n");
495
496     hr = IInternetZoneManager_Release(zonemgr);
497     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
498
499 }
500
501 static void test_CreateZoneEnumerator(void)
502 {
503     IInternetZoneManager *zonemgr = NULL;
504     HRESULT hr;
505     DWORD dwEnum;
506     DWORD dwEnum2;
507     DWORD dwCount;
508     DWORD dwCount2;
509
510     trace("testing zone enumerator...\n");
511
512     hr = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
513     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
514     if (FAILED(hr))
515         return;
516
517     dwEnum=0xdeadbeef;
518     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, NULL, 0);
519     ok((hr == E_INVALIDARG) && (dwEnum == 0xdeadbeef),
520         "got 0x%x with 0x%x (expected E_INVALIDARG with 0xdeadbeef)\n", hr, dwEnum);
521
522     dwCount=0xdeadbeef;
523     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, NULL, &dwCount, 0);
524     ok((hr == E_INVALIDARG) && (dwCount == 0xdeadbeef),
525         "got 0x%x and 0x%x (expected E_INVALIDARG and 0xdeadbeef)\n", hr, dwCount);
526
527     dwEnum=0xdeadbeef;
528     dwCount=0xdeadbeef;
529     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 0xffffffff);
530     ok((hr == E_INVALIDARG) && (dwEnum == 0xdeadbeef) && (dwCount == 0xdeadbeef),
531         "got 0x%x with 0x%x and 0x%x (expected E_INVALIDARG with 0xdeadbeef and 0xdeadbeef)\n",
532         hr, dwEnum, dwCount);
533
534     dwEnum=0xdeadbeef;
535     dwCount=0xdeadbeef;
536     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 1);
537     ok((hr == E_INVALIDARG) && (dwEnum == 0xdeadbeef) && (dwCount == 0xdeadbeef),
538         "got 0x%x with 0x%x and 0x%x (expected E_INVALIDARG with 0xdeadbeef and 0xdeadbeef)\n",
539         hr, dwEnum, dwCount);
540
541     dwEnum=0xdeadbeef;
542     dwCount=0xdeadbeef;
543     /* Normal use */
544     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 0);
545     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
546
547     if (SUCCEEDED(hr)) {
548         dwEnum2=0xdeadbeef;
549         dwCount2=0xdeadbeef;
550         hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum2, &dwCount2, 0);
551         ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
552         if (SUCCEEDED(hr)) {
553             /* native urlmon has an incrementing counter for dwEnum */
554             hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum2);
555             ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
556         }
557
558         hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum);
559         ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
560
561         /* Destroy the Enumerator twice is detected and handled in native urlmon */
562         hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum);
563         ok((hr == E_INVALIDARG), "got 0x%x (expected E_INVALIDARG)\n", hr);
564     }
565
566     /* ::Release succeed also, when a ::DestroyZoneEnumerator is missing */
567     hr = IInternetZoneManager_Release(zonemgr);
568     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
569 }
570
571 static void test_GetZoneActionPolicy(void)
572 {
573     IInternetZoneManager *zonemgr = NULL;
574     BYTE buf[32];
575     HRESULT hres;
576     DWORD action = URLACTION_CREDENTIALS_USE; /* Implemented on all IE versions */
577
578     trace("testing GetZoneActionPolixy...\n");
579
580     hres = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
581     ok(hres == S_OK, "CoInternetCreateZoneManager failed: %08x\n", hres);
582     if(FAILED(hres))
583         return;
584
585     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, buf,
586             sizeof(DWORD), URLZONEREG_DEFAULT);
587     ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
588     ok(*(DWORD*)buf == URLPOLICY_CREDENTIALS_SILENT_LOGON_OK ||
589             *(DWORD*)buf == URLPOLICY_CREDENTIALS_MUST_PROMPT_USER ||
590             *(DWORD*)buf == URLPOLICY_CREDENTIALS_CONDITIONAL_PROMPT ||
591             *(DWORD*)buf == URLPOLICY_CREDENTIALS_ANONYMOUS_ONLY,
592             "unexpected policy=%d\n", *(DWORD*)buf);
593
594     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, NULL,
595             sizeof(DWORD), URLZONEREG_DEFAULT);
596     ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
597
598     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, buf,
599             2, URLZONEREG_DEFAULT);
600     ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
601
602     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, 0x1fff, buf,
603             sizeof(DWORD), URLZONEREG_DEFAULT);
604     ok(hres == E_FAIL || broken(hres == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)),
605             "(0x%x) got 0x%x (expected E_FAIL)\n", action, hres);
606
607     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 13, action, buf,
608             sizeof(DWORD), URLZONEREG_DEFAULT);
609     ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
610
611     IInternetZoneManager_Release(zonemgr);
612 }
613
614 static void test_GetZoneAt(void)
615 {
616     IInternetZoneManager *zonemgr = NULL;
617     HRESULT hr;
618     DWORD dwEnum;
619     DWORD dwCount;
620     DWORD dwZone;
621     DWORD i;
622
623     trace("testing GetZoneAt...\n");
624
625     hr = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
626     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
627     if (FAILED(hr))
628         return;
629
630     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 0);
631     if (FAILED(hr))
632         goto cleanup;
633
634     if (0) {
635         /* this crashes with native urlmon */
636         IInternetZoneManager_GetZoneAt(zonemgr, dwEnum, 0, NULL);
637     }
638
639     dwZone = 0xdeadbeef;
640     hr = IInternetZoneManager_GetZoneAt(zonemgr, 0xdeadbeef, 0, &dwZone);
641     ok(hr == E_INVALIDARG,
642         "got 0x%x with 0x%x (expected E_INVALIDARG)\n", hr, dwZone);
643
644     for (i = 0; i < dwCount; i++)
645     {
646         dwZone = 0xdeadbeef;
647         hr = IInternetZoneManager_GetZoneAt(zonemgr, dwEnum, i, &dwZone);
648         ok(hr == S_OK, "#%d: got x%x with %d (expected S_OK)\n", i, hr, dwZone);
649     }
650
651     dwZone = 0xdeadbeef;
652     /* MSDN (index .. must be .. less than or equal to) is wrong */
653     hr = IInternetZoneManager_GetZoneAt(zonemgr, dwEnum, dwCount, &dwZone);
654     ok(hr == E_INVALIDARG,
655         "got 0x%x with 0x%x (expected E_INVALIDARG)\n", hr, dwZone);
656
657     hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum);
658     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
659
660 cleanup:
661     hr = IInternetZoneManager_Release(zonemgr);
662     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
663 }
664
665 static void test_GetZoneAttributes(void)
666 {
667     IInternetZoneManager *zonemgr = NULL;
668     CHAR buffer [sizeof(ZONEATTRIBUTES) + 32];
669     ZONEATTRIBUTES* pZA = (ZONEATTRIBUTES*) buffer;
670     HRESULT hr;
671     DWORD i;
672
673     trace("testing GetZoneAttributes...\n");
674
675     hr = pCoInternetCreateZoneManager(NULL, &zonemgr, 0);
676     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
677     if (FAILED(hr))
678         return;
679
680     /* native urlmon has Zone "0" up to Zone "4" since IE4 */
681     for (i = 0; i < 5; i++) {
682         memset(buffer, -1, sizeof(buffer));
683         hr = IInternetZoneManager_GetZoneAttributes(zonemgr, i, pZA);
684         ok(hr == S_OK, "#%d: got 0x%x (expected S_OK)\n", i, hr);
685     }
686
687     /* IE8 no longer set cbSize */
688     memset(buffer, -1, sizeof(buffer));
689     pZA->cbSize = 0;
690     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, pZA);
691     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
692     ok((pZA->cbSize == 0) || (pZA->cbSize == sizeof(ZONEATTRIBUTES)),
693         "got cbSize = %d (expected 0)\n", pZA->cbSize);
694
695     memset(buffer, -1, sizeof(buffer));
696     pZA->cbSize = 64;
697     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, pZA);
698     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
699     ok((pZA->cbSize == 64) || (pZA->cbSize == sizeof(ZONEATTRIBUTES)),
700         "got cbSize = %d (expected 64)\n", pZA->cbSize);
701
702     memset(buffer, -1, sizeof(buffer));
703     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, pZA);
704     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
705     ok((pZA->cbSize == 0xffffffff) || (pZA->cbSize == sizeof(ZONEATTRIBUTES)),
706         "got cbSize = 0x%x (expected 0xffffffff)\n", pZA->cbSize);
707
708     /* IE8 no longer fail on invalid zones */
709     memset(buffer, -1, sizeof(buffer));
710     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0xdeadbeef, pZA);
711     ok(hr == S_OK || (hr == E_FAIL),
712         "got 0x%x (expected S_OK or E_FAIL)\n", hr);
713
714     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, NULL);
715     ok(hr == E_INVALIDARG, "got 0x%x (expected E_INVALIDARG)\n", hr);
716
717     hr = IInternetZoneManager_Release(zonemgr);
718     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
719 }
720
721 static void test_InternetSecurityMarshalling(void)
722 {
723     IInternetSecurityManager *secmgr = NULL;
724     IUnknown *unk;
725     IStream *stream;
726     HRESULT hres;
727
728     trace("testing marshalling...\n");
729
730     hres = pCoInternetCreateSecurityManager(NULL, &secmgr, 0);
731     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
732     if(FAILED(hres))
733         return;
734
735     hres = IInternetSecurityManager_QueryInterface(secmgr, &IID_IUnknown, (void**)&unk);
736     ok(hres == S_OK, "QueryInterface returned: %08x\n", hres);
737
738     hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
739     ok(hres == S_OK, "CreateStreamOnHGlobal returned: %08x\n", hres);
740
741     hres = CoMarshalInterface(stream, &IID_IInternetSecurityManager, unk, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
742     /* Not supported in W98 */
743     ok(hres == S_OK || broken(hres == REGDB_E_IIDNOTREG),
744         "CoMarshalInterface returned: %08x\n", hres);
745
746     IStream_Release(stream);
747     IUnknown_Release(unk);
748     IInternetSecurityManager_Release(secmgr);
749 }
750
751 static void test_InternetGetSecurityUrl(void)
752 {
753     const WCHAR url5_out[] = {'h','t','t','p',':','w','w','w','.','z','o','n','e','3',
754                               '.','w','i','n','e','t','e','s','t',0};
755     const WCHAR url7_out[] = {'f','t','p',':','z','o','n','e','3','.','w','i','n','e','t','e','s','t',0};
756
757     const WCHAR *in[] = {url2, url3, url4, url5, url7, url8, url9, url10};
758     const WCHAR *out_default[] = {url2, url3, url4, url5_out, url7_out, url8, url5_out, url10};
759     const WCHAR *out_securl[] = {url2, url3, url4, url5, url7, url8, url9, url10};
760
761     WCHAR *sec;
762     DWORD i;
763     HRESULT hres;
764
765     trace("testing CoInternetGetSecurityUrl...\n");
766
767     for(i=0; i<sizeof(in)/sizeof(WCHAR*); i++) {
768         hres = pCoInternetGetSecurityUrl(in[i], &sec, PSU_DEFAULT, 0);
769         ok(hres == S_OK, "(%d) CoInternetGetSecurityUrl returned: %08x\n", i, hres);
770         if(hres == S_OK) {
771             ok(!strcmp_w(sec, out_default[i]), "(%d) Got %s, expected %s\n",
772                     i, wine_dbgstr_w(sec), wine_dbgstr_w(out_default[i]));
773             CoTaskMemFree(sec);
774         }
775
776         hres = pCoInternetGetSecurityUrl(in[i], &sec, PSU_SECURITY_URL_ONLY, 0);
777         ok(hres == S_OK, "(%d) CoInternetGetSecurityUrl returned: %08x\n", i, hres);
778         if(hres == S_OK) {
779             ok(!strcmp_w(sec, out_securl[i]), "(%d) Got %s, expected %s\n",
780                     i, wine_dbgstr_w(sec), wine_dbgstr_w(out_securl[i]));
781             CoTaskMemFree(sec);
782         }
783     }
784
785     SET_EXPECT(ParseUrl_SECURITY_URL_input2);
786     SET_EXPECT(ParseUrl_SECURITY_URL_expected);
787     SET_EXPECT(ParseUrl_SECURITY_DOMAIN_expected);
788
789     hres = pCoInternetGetSecurityUrl(security_url2W, &sec, PSU_DEFAULT, 0);
790     ok(hres == S_OK, "CoInternetGetSecurityUrl returned 0x%08x, expected S_OK\n", hres);
791
792     CHECK_CALLED(ParseUrl_SECURITY_URL_input2);
793     CHECK_CALLED(ParseUrl_SECURITY_URL_expected);
794     CHECK_CALLED(ParseUrl_SECURITY_DOMAIN_expected);
795
796     ok(!lstrcmpW(security_expectedW, sec), "Expected %s but got %s\n",
797        wine_dbgstr_w(security_expectedW), wine_dbgstr_w(sec));
798     CoTaskMemFree(sec);
799 }
800
801 static HRESULT WINAPI InternetProtocolInfo_QueryInterface(IInternetProtocolInfo *iface,
802                                                           REFIID riid, void **ppv)
803 {
804     ok(0, "unexpected call\n");
805     return E_NOINTERFACE;
806 }
807
808 static ULONG WINAPI InternetProtocolInfo_AddRef(IInternetProtocolInfo *iface)
809 {
810     return 2;
811 }
812
813 static ULONG WINAPI InternetProtocolInfo_Release(IInternetProtocolInfo *iface)
814 {
815     return 1;
816 }
817
818 static HRESULT WINAPI InternetProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
819         PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
820         DWORD *pcchResult, DWORD dwReserved)
821 {
822     const WCHAR *ret = NULL;
823
824     ok(pwzResult != NULL, "pwzResult == NULL\n");
825     ok(pcchResult != NULL, "pcchResult == NULL\n");
826     ok(!dwParseFlags, "Expected 0, but got 0x%08x\n", dwParseFlags);
827
828     switch(ParseAction) {
829     case PARSE_SECURITY_URL:
830         if(!strcmp_w(pwzUrl, security_urlW)) {
831             CHECK_EXPECT(ParseUrl_SECURITY_URL_input);
832             ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
833             ret = security_expectedW;
834         } else if(!strcmp_w(pwzUrl, security_url2W)) {
835             CHECK_EXPECT(ParseUrl_SECURITY_URL_input2);
836             ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
837             ret = security_expectedW;
838         } else if(!strcmp_w(pwzUrl, security_expectedW)) {
839             CHECK_EXPECT(ParseUrl_SECURITY_URL_expected);
840             ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
841             ret = security_expectedW;
842         } else if(!strcmp_w(pwzUrl, winetest_to_httpW)) {
843             switch(++called_securl_http) {
844             case 1:
845                 ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
846                 break;
847             case 2:
848                 CHECK_EXPECT(ParseUrl_SECURITY_URL_http);
849                 ok(cchResult == lstrlenW(url9)+1, "Got %d\n", cchResult);
850                 break;
851             default:
852                 todo_wine CHECK_EXPECT(ParseUrl_SECURITY_URL_http);
853             }
854             ret = url9;
855         } else
856             ok(0, "Unexpected call, pwzUrl=%s\n", wine_dbgstr_w(pwzUrl));
857
858         break;
859     case PARSE_SECURITY_DOMAIN:
860
861         CHECK_EXPECT(ParseUrl_SECURITY_DOMAIN_expected);
862
863         ok(!strcmp_w(pwzUrl, security_expectedW), "Expected %s but got %s\n",
864             wine_dbgstr_w(security_expectedW), wine_dbgstr_w(pwzUrl));
865         ok(cchResult == lstrlenW(pwzUrl)+1, "Got %d\n", cchResult);
866         ret = security_expectedW;
867         break;
868     default:
869         ok(0, "Unexpected call, ParseAction=%d pwzUrl=%s\n", ParseAction,
870             wine_dbgstr_w(pwzUrl));
871     }
872
873     if(!ret)
874         return E_FAIL;
875
876     *pcchResult = lstrlenW(ret)+1;
877     if(*pcchResult > cchResult)
878         return S_FALSE;
879     memcpy(pwzResult, ret, (*pcchResult)*sizeof(WCHAR));
880     return S_OK;
881 }
882
883 static HRESULT WINAPI InternetProtocolInfo_CombineUrl(IInternetProtocolInfo *iface,
884         LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags,
885         LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
886 {
887     ok(0, "unexpected call\n");
888     return E_NOTIMPL;
889 }
890
891 static HRESULT WINAPI InternetProtocolInfo_CompareUrl(IInternetProtocolInfo *iface,
892         LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
893 {
894     ok(0, "unexpected call\n");
895     return E_NOTIMPL;
896 }
897
898 static HRESULT WINAPI InternetProtocolInfo_QueryInfo(IInternetProtocolInfo *iface,
899         LPCWSTR pwzUrl, QUERYOPTION OueryOption, DWORD dwQueryFlags, LPVOID pBuffer,
900         DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved)
901 {
902     ok(0, "unexpected call\n");
903     return E_NOTIMPL;
904 }
905
906 static const IInternetProtocolInfoVtbl InternetProtocolInfoVtbl = {
907     InternetProtocolInfo_QueryInterface,
908     InternetProtocolInfo_AddRef,
909     InternetProtocolInfo_Release,
910     InternetProtocolInfo_ParseUrl,
911     InternetProtocolInfo_CombineUrl,
912     InternetProtocolInfo_CompareUrl,
913     InternetProtocolInfo_QueryInfo
914 };
915
916 static IInternetProtocolInfo protocol_info = { &InternetProtocolInfoVtbl };
917
918 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
919 {
920     if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
921         *ppv = &protocol_info;
922         return S_OK;
923     }
924
925     ok(0, "unexpected call\n");
926     return E_NOINTERFACE;
927 }
928
929 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
930 {
931     return 2;
932 }
933
934 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
935 {
936     return 1;
937 }
938
939 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
940                                         REFIID riid, void **ppv)
941 {
942     ok(0, "unexpected call\n");
943     return E_NOTIMPL;
944 }
945
946 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
947 {
948     ok(0, "unexpected call\n");
949     return S_OK;
950 }
951
952 static const IClassFactoryVtbl ClassFactoryVtbl = {
953     ClassFactory_QueryInterface,
954     ClassFactory_AddRef,
955     ClassFactory_Release,
956     ClassFactory_CreateInstance,
957     ClassFactory_LockServer
958 };
959
960 static IClassFactory protocol_cf = { &ClassFactoryVtbl };
961
962 static void register_protocols(void)
963 {
964     IInternetSession *session;
965     HRESULT hres;
966
967     hres = pCoInternetGetSession(0, &session, 0);
968     ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
969     if(FAILED(hres))
970         return;
971
972     hres = IInternetSession_RegisterNameSpace(session, &protocol_cf, &IID_NULL,
973             winetestW, 0, NULL, 0);
974     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
975
976     IInternetSession_Release(session);
977 }
978
979 static void unregister_protocols(void) {
980     IInternetSession *session;
981     HRESULT hr;
982
983     hr = pCoInternetGetSession(0, &session, 0);
984     ok(hr == S_OK, "CoInternetGetSession failed: 0x%08x\n", hr);
985     if(FAILED(hr))
986         return;
987
988     hr = IInternetSession_UnregisterNameSpace(session, &protocol_cf, winetestW);
989     ok(hr == S_OK, "UnregisterNameSpace failed: 0x%08x\n", hr);
990
991     IInternetSession_Release(session);
992 }
993
994 static const struct {
995     const char  *uri;
996     DWORD       create_flags;
997     const char  *security_uri;
998     HRESULT     security_hres;
999     const char  *default_uri;
1000     HRESULT     default_hres;
1001     BOOL        todo;
1002 } sec_url_ex_tests[] = {
1003     {"index.htm",Uri_CREATE_ALLOW_RELATIVE,"*:index.html",S_OK,"*:index.htm",S_OK},
1004     {"file://c:\\Index.htm",Uri_CREATE_FILE_USE_DOS_PATH,"file:///c:/Index.htm",S_OK,"file:///c:/Index.htm",S_OK},
1005     {"file:some%20file%2ejpg",0,NULL,E_INVALIDARG,NULL,E_INVALIDARG},
1006     {"file:some file.jpg",0,NULL,E_INVALIDARG,NULL,E_INVALIDARG},
1007     {"http://www.zone3.winetest/",0,"http://www.zone3.winetest/",S_OK,"http://www.zone3.winetest/",S_OK},
1008     {"about:blank",0,"about:blank",S_OK,"about:blank",S_OK},
1009     {"ftp://zone3.winetest/file.test",0,"ftp://zone3.winetest/file.test",S_OK,"ftp://zone3.winetest/file.test",S_OK},
1010     {"test:123abc",0,"test:123abc",S_OK,"test:123abc",S_OK},
1011     {"http:google.com/test.file",0,"http:google.com/test.file",S_OK,"http:google.com/test.file",S_OK},
1012     {"ftp://test@ftp.winehq.org/",0,"ftp://ftp.winehq.org/",S_OK,"ftp://ftp.winehq.org/",S_OK},
1013     {"test://google@ftp.winehq.org/",0,"test://google@ftp.winehq.org/",S_OK,"test://google@ftp.winehq.org/",S_OK}
1014 };
1015
1016 static void test_InternetGetSecurityUrlEx(void)
1017 {
1018     HRESULT hr;
1019     DWORD i;
1020     IUri *uri = NULL, *result = NULL;
1021
1022     trace("testing CoInternetGetSecurityUrlEx...\n");
1023
1024     hr = pCoInternetGetSecurityUrlEx(NULL, NULL, PSU_DEFAULT, 0);
1025     ok(hr == E_INVALIDARG, "CoInternetGetSecurityUrlEx returned 0x%08x, expected E_INVALIDARG\n", hr);
1026
1027     result = (void*) 0xdeadbeef;
1028     hr = pCoInternetGetSecurityUrlEx(NULL, &result, PSU_DEFAULT, 0);
1029     ok(hr == E_INVALIDARG, "CoInternetGetSecurityUrlEx returned 0x%08x, expected E_INVALIDARG\n", hr);
1030     ok(result == (void*) 0xdeadbeef, "'result' was %p\n", result);
1031
1032     for(i = 0; i < sizeof(sec_url_ex_tests)/sizeof(sec_url_ex_tests[0]); ++i) {
1033         LPWSTR uriW = a2w(sec_url_ex_tests[i].uri);
1034         uri = NULL;
1035
1036         hr = pCreateUri(uriW, sec_url_ex_tests[i].create_flags, 0, &uri);
1037         ok(hr == S_OK, "CreateUri returned 0x%08x on test %d\n", hr, i);
1038         if(hr == S_OK) {
1039             result = NULL;
1040
1041             hr = pCoInternetGetSecurityUrlEx(uri, &result, PSU_DEFAULT, 0);
1042             if(sec_url_ex_tests[i].todo) {
1043                 todo_wine
1044                     ok(hr == sec_url_ex_tests[i].default_hres,
1045                         "CoInternetGetSecurityUrlEx returned 0x%08x, expected 0x%08x on test %d\n",
1046                         hr, sec_url_ex_tests[i].default_hres, i);
1047             } else {
1048                 ok(hr == sec_url_ex_tests[i].default_hres,
1049                     "CoInternetGetSecurityUrlEx returned 0x%08x, expected 0x%08x on test %d\n",
1050                     hr, sec_url_ex_tests[i].default_hres, i);
1051             }
1052             if(SUCCEEDED(hr)) {
1053                 BSTR received;
1054
1055                 hr = IUri_GetDisplayUri(result, &received);
1056                 ok(hr == S_OK, "GetDisplayUri returned 0x%08x on test %d\n", hr, i);
1057                 if(hr == S_OK) {
1058                     if(sec_url_ex_tests[i].todo) {
1059                         todo_wine
1060                             ok(!strcmp_aw(sec_url_ex_tests[i].default_uri, received),
1061                                 "Expected %s but got %s on test %d\n", sec_url_ex_tests[i].default_uri,
1062                                 wine_dbgstr_w(received), i);
1063                     } else {
1064                         ok(!strcmp_aw(sec_url_ex_tests[i].default_uri, received),
1065                             "Expected %s but got %s on test %d\n", sec_url_ex_tests[i].default_uri,
1066                             wine_dbgstr_w(received), i);
1067                     }
1068                 }
1069                 SysFreeString(received);
1070             }
1071             if(result) IUri_Release(result);
1072
1073             result = NULL;
1074             hr = pCoInternetGetSecurityUrlEx(uri, &result, PSU_SECURITY_URL_ONLY, 0);
1075             if(sec_url_ex_tests[i].todo) {
1076                 todo_wine
1077                     ok(hr == sec_url_ex_tests[i].default_hres,
1078                         "CoInternetGetSecurityUrlEx returned 0x%08x, expected 0x%08x on test %d\n",
1079                         hr, sec_url_ex_tests[i].default_hres, i);
1080             } else {
1081                 ok(hr == sec_url_ex_tests[i].default_hres,
1082                     "CoInternetGetSecurityUrlEx returned 0x%08x, expected 0x%08x on test %d\n",
1083                     hr, sec_url_ex_tests[i].default_hres, i);
1084             }
1085             if(SUCCEEDED(hr)) {
1086                 BSTR received;
1087
1088                 hr = IUri_GetDisplayUri(result, &received);
1089                 ok(hr == S_OK, "GetDisplayUri returned 0x%08x on test %d\n", hr, i);
1090                 if(hr == S_OK) {
1091                     if(sec_url_ex_tests[i].todo) {
1092                         todo_wine
1093                             ok(!strcmp_aw(sec_url_ex_tests[i].default_uri, received),
1094                                 "Expected %s but got %s on test %d\n", sec_url_ex_tests[i].default_uri,
1095                                 wine_dbgstr_w(received), i);
1096                     } else {
1097                         ok(!strcmp_aw(sec_url_ex_tests[i].default_uri, received),
1098                             "Expected %s but got %s on test %d\n", sec_url_ex_tests[i].default_uri,
1099                             wine_dbgstr_w(received), i);
1100                     }
1101                 }
1102                 SysFreeString(received);
1103             }
1104             if(result) IUri_Release(result);
1105         }
1106
1107         if(uri) IUri_Release(uri);
1108         heap_free(uriW);
1109     }
1110 }
1111
1112 static void test_InternetGetSecurityUrlEx_Pluggable(void)
1113 {
1114     HRESULT hr;
1115     IUri *uri = NULL, *result;
1116
1117     trace("testing CoInternetGetSecurityUrlEx for plugable protocols...\n");
1118
1119     hr = pCreateUri(security_urlW, 0, 0, &uri);
1120     ok(hr == S_OK, "CreateUri returned 0x%08x\n", hr);
1121     if(hr == S_OK) {
1122         SET_EXPECT(ParseUrl_SECURITY_URL_input);
1123         SET_EXPECT(ParseUrl_SECURITY_URL_expected);
1124         SET_EXPECT(ParseUrl_SECURITY_DOMAIN_expected);
1125
1126         hr = pCoInternetGetSecurityUrlEx(uri, &result, PSU_DEFAULT, 0);
1127         ok(hr == S_OK, "CoInternetGetSecurityUrlEx returned 0x%08x, expected S_OK\n", hr);
1128
1129         CHECK_CALLED(ParseUrl_SECURITY_URL_input);
1130         CHECK_CALLED(ParseUrl_SECURITY_URL_expected);
1131         CHECK_CALLED(ParseUrl_SECURITY_DOMAIN_expected);
1132
1133         if(hr == S_OK) {
1134             BSTR received = NULL;
1135
1136             hr = IUri_GetAbsoluteUri(result, &received);
1137             ok(hr == S_OK, "GetAbsoluteUri returned 0x%08x\n", hr);
1138             if(hr == S_OK) {
1139                 ok(!strcmp_w(security_expectedW, received), "Expected %s but got %s\n",
1140                     wine_dbgstr_w(security_expectedW), wine_dbgstr_w(received));
1141             }
1142             SysFreeString(received);
1143         }
1144         if(result) IUri_Release(result);
1145
1146         result = NULL;
1147
1148         SET_EXPECT(ParseUrl_SECURITY_URL_input);
1149         SET_EXPECT(ParseUrl_SECURITY_URL_expected);
1150
1151         hr = pCoInternetGetSecurityUrlEx(uri, &result, PSU_SECURITY_URL_ONLY, 0);
1152         ok(hr == S_OK, "CoInternetGetSecurityUrlEx returned 0x%08x, expected S_OK\n", hr);
1153
1154         CHECK_CALLED(ParseUrl_SECURITY_URL_input);
1155         CHECK_CALLED(ParseUrl_SECURITY_URL_expected);
1156
1157         if(hr == S_OK) {
1158             BSTR received = NULL;
1159
1160             hr = IUri_GetAbsoluteUri(result, &received);
1161             ok(hr == S_OK, "GetAbsoluteUri returned 0x%08x\n", hr);
1162             if(hr == S_OK) {
1163                 ok(!strcmp_w(security_expectedW, received), "Expected %s but got %s\n",
1164                     wine_dbgstr_w(security_expectedW), wine_dbgstr_w(received));
1165             }
1166             SysFreeString(received);
1167         }
1168         if(result) IUri_Release(result);
1169     }
1170     if(uri) IUri_Release(uri);
1171 }
1172
1173 START_TEST(sec_mgr)
1174 {
1175     HMODULE hurlmon;
1176
1177     hurlmon = GetModuleHandle("urlmon.dll");
1178     pCoInternetCreateSecurityManager = (void*) GetProcAddress(hurlmon, "CoInternetCreateSecurityManager");
1179     pCoInternetCreateZoneManager = (void*) GetProcAddress(hurlmon, "CoInternetCreateZoneManager");
1180     pCoInternetGetSecurityUrl = (void*) GetProcAddress(hurlmon, "CoInternetGetSecurityUrl");
1181     pCoInternetGetSecurityUrlEx = (void*) GetProcAddress(hurlmon, "CoInternetGetSecurityUrlEx");
1182     pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
1183     pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
1184
1185     if (!pCoInternetCreateSecurityManager || !pCoInternetCreateZoneManager ||
1186         !pCoInternetGetSecurityUrl) {
1187         win_skip("Various CoInternet* functions not present in IE 4.0\n");
1188         return;
1189     }
1190
1191     OleInitialize(NULL);
1192     register_protocols();
1193
1194     test_InternetGetSecurityUrl();
1195
1196     if(!pCoInternetGetSecurityUrlEx || !pCreateUri)
1197         win_skip("Skipping CoInternetGetSecurityUrlEx tests, IE too old\n");
1198     else {
1199         test_InternetGetSecurityUrlEx();
1200         test_InternetGetSecurityUrlEx_Pluggable();
1201     }
1202
1203     test_SecurityManager();
1204     test_polices();
1205     test_CoInternetCreateZoneManager();
1206     test_CreateZoneEnumerator();
1207     test_GetZoneActionPolicy();
1208     test_GetZoneAt();
1209     test_GetZoneAttributes();
1210     test_InternetSecurityMarshalling();
1211
1212     unregister_protocols();
1213     OleUninitialize();
1214 }