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