shdocvw: Support URLs passed by reference in WebBrowser_Navigate2.
[wine] / dlls / urlmon / tests / sec_mgr.c
1 /*
2  * Copyright 2005-2006 Jacek Caban for CodeWeavers
3  * Copyright 2009 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 static const WCHAR url1[] = {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l',
39         '/','b','l','a','n','k','.','h','t','m',0};
40 static const WCHAR url2[] = {'i','n','d','e','x','.','h','t','m',0};
41 static const WCHAR url3[] = {'f','i','l','e',':','/','/','c',':','\\','I','n','d','e','x','.','h','t','m',0};
42 static const WCHAR url4[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e',
43         '%','2','e','j','p','g',0};
44 static const WCHAR url5[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q',
45         '.','o','r','g',0};
46 static const WCHAR url6[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
47 static const WCHAR url7[] = {'f','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',
48         'f','i','l','e','.','t','e','s','t',0};
49 static const WCHAR url8[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
50 static const WCHAR url9[] =
51     {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
52      '/','s','i','t','e','/','a','b','o','u','t',0};
53 static const WCHAR url10[] = {'f','i','l','e',':','/','/','s','o','m','e','%','2','0','f','i','l','e',
54         '.','j','p','g',0};
55
56 static const WCHAR url4e[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e',
57         '.','j','p','g',0};
58
59
60 static const BYTE secid1[] = {'f','i','l','e',':',0,0,0,0};
61 static const BYTE secid5[] = {'h','t','t','p',':','w','w','w','.','w','i','n','e','h','q',
62     '.','o','r','g',3,0,0,0};
63 static const BYTE secid6[] = {'a','b','o','u','t',':','b','l','a','n','k',3,0,0,0};
64 static const BYTE secid7[] = {'f','t','p',':','w','i','n','e','h','q','.','o','r','g',
65                               3,0,0,0};
66 static const BYTE secid10[] =
67     {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e','.','j','p','g',3,0,0,0};
68 static const BYTE secid10_2[] =
69     {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e','.','j','p','g',3,0,0,0};
70
71 static struct secmgr_test {
72     LPCWSTR url;
73     DWORD zone;
74     HRESULT zone_hres;
75     DWORD secid_size;
76     const BYTE *secid;
77     HRESULT secid_hres;
78 } secmgr_tests[] = {
79     {url1, 0,   S_OK, sizeof(secid1), secid1, S_OK},
80     {url2, 100, 0x80041001, 0, NULL, E_INVALIDARG},
81     {url3, 0,   S_OK, sizeof(secid1), secid1, S_OK},
82     {url5, 3,   S_OK, sizeof(secid5), secid5, S_OK},
83     {url6, 3,   S_OK, sizeof(secid6), secid6, S_OK},
84     {url7, 3,   S_OK, sizeof(secid7), secid7, S_OK}
85 };
86
87 static void test_SecurityManager(void)
88 {
89     int i;
90     IInternetSecurityManager *secmgr = NULL;
91     BYTE buf[512];
92     DWORD zone, size, policy;
93     HRESULT hres;
94
95     hres = CoInternetCreateSecurityManager(NULL, &secmgr, 0);
96     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
97     if(FAILED(hres))
98         return;
99
100     for(i=0; i < sizeof(secmgr_tests)/sizeof(secmgr_tests[0]); i++) {
101         zone = 100;
102         hres = IInternetSecurityManager_MapUrlToZone(secmgr, secmgr_tests[i].url,
103                                                      &zone, 0);
104         ok(hres == secmgr_tests[i].zone_hres /* IE <=6 */
105            || (FAILED(secmgr_tests[i].zone_hres) && hres == E_INVALIDARG), /* IE7 */
106            "[%d] MapUrlToZone failed: %08x, expected %08x\n",
107                 i, hres, secmgr_tests[i].zone_hres);
108         if(SUCCEEDED(hres))
109             ok(zone == secmgr_tests[i].zone, "[%d] zone=%d, expected %d\n", i, zone,
110                secmgr_tests[i].zone);
111         else
112             ok(zone == secmgr_tests[i].zone || zone == -1, "[%d] zone=%d\n", i, zone);
113
114         size = sizeof(buf);
115         memset(buf, 0xf0, sizeof(buf));
116         hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[i].url,
117                 buf, &size, 0);
118         ok(hres == secmgr_tests[i].secid_hres,
119            "[%d] GetSecurityId failed: %08x, expected %08x\n",
120            i, hres, secmgr_tests[i].secid_hres);
121         if(secmgr_tests[i].secid) {
122             ok(size == secmgr_tests[i].secid_size, "[%d] size=%d, expected %d\n",
123                     i, size, secmgr_tests[i].secid_size);
124             ok(!memcmp(buf, secmgr_tests[i].secid, size), "[%d] wrong secid\n", i);
125         }
126     }
127
128     zone = 100;
129     hres = IInternetSecurityManager_MapUrlToZone(secmgr, url10, &zone, 0);
130     ok(hres == S_OK, "MapUrlToZone failed: %08x, expected S_OK\n", hres);
131     ok(zone == 3, "zone=%d, expected 3\n", zone);
132
133     /* win2k3 translates %20 into a space */
134     size = sizeof(buf);
135     memset(buf, 0xf0, sizeof(buf));
136     hres = IInternetSecurityManager_GetSecurityId(secmgr, url10, buf, &size, 0);
137     ok(hres == S_OK, "GetSecurityId failed: %08x, expected S_OK\n", hres);
138     ok(size == sizeof(secid10) ||
139        size == sizeof(secid10_2), /* win2k3 */
140        "size=%d\n", size);
141     ok(!memcmp(buf, secid10, size) ||
142        !memcmp(buf, secid10_2, size), /* win2k3 */
143        "wrong secid\n");
144
145     zone = 100;
146     hres = IInternetSecurityManager_MapUrlToZone(secmgr, NULL, &zone, 0);
147     ok(hres == E_INVALIDARG, "MapUrlToZone failed: %08x, expected E_INVALIDARG\n", hres);
148     ok(zone == 100 || zone == -1, "zone=%d\n", zone);
149
150     size = sizeof(buf);
151     hres = IInternetSecurityManager_GetSecurityId(secmgr, NULL, buf, &size, 0);
152     ok(hres == E_INVALIDARG,
153        "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
154     hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[1].url,
155                                                   NULL, &size, 0);
156     ok(hres == E_INVALIDARG,
157        "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
158     hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[1].url,
159                                                   buf, NULL, 0);
160     ok(hres == E_INVALIDARG,
161        "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
162
163     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, NULL, URLACTION_SCRIPT_RUN, (BYTE*)&policy,
164             sizeof(WCHAR), NULL, 0, 0, 0);
165     ok(hres == E_INVALIDARG, "ProcessUrlAction failed: %08x, expected E_INVALIDARG\n", hres);
166
167     IInternetSecurityManager_Release(secmgr);
168 }
169
170 /* Check if Internet Explorer is configured to run in "Enhanced Security Configuration" (aka hardened mode) */
171 /* Note: this code is duplicated in dlls/mshtml/tests/dom.c, dlls/mshtml/tests/script.c and dlls/urlmon/tests/sec_mgr.c */
172 static BOOL is_ie_hardened(void)
173 {
174     HKEY zone_map;
175     DWORD ie_harden, type, size;
176
177     ie_harden = 0;
178     if(RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap",
179                     0, KEY_QUERY_VALUE, &zone_map) == ERROR_SUCCESS) {
180         size = sizeof(DWORD);
181         if (RegQueryValueExA(zone_map, "IEHarden", NULL, &type, (LPBYTE) &ie_harden, &size) != ERROR_SUCCESS ||
182             type != REG_DWORD) {
183             ie_harden = 0;
184         }
185         RegCloseKey(zone_map);
186     }
187
188     return ie_harden != 0;
189 }
190
191 static void test_url_action(IInternetSecurityManager *secmgr, IInternetZoneManager *zonemgr, DWORD action)
192 {
193     DWORD res, size, policy, reg_policy;
194     char buf[10];
195     HKEY hkey;
196     HRESULT hres;
197
198     /* FIXME: HKEY_CURRENT_USER is most of the time the default but this can be changed on a system.
199      * The test should be changed to cope with that, if need be.
200      */
201     res = RegOpenKeyA(HKEY_CURRENT_USER,
202             "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3", &hkey);
203     if(res != ERROR_SUCCESS) {
204         ok(0, "Could not open zone key\n");
205         return;
206     }
207
208     wsprintf(buf, "%X", action);
209     size = sizeof(DWORD);
210     res = RegQueryValueExA(hkey, buf, NULL, NULL, (BYTE*)&reg_policy, &size);
211     RegCloseKey(hkey);
212     if(res != ERROR_SUCCESS || size != sizeof(DWORD)) {
213         policy = 0xdeadbeef;
214         hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
215                 sizeof(WCHAR), NULL, 0, 0, 0);
216         ok(hres == E_FAIL, "ProcessUrlAction(%x) failed: %08x, expected E_FAIL\n", action, hres);
217         ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
218
219         policy = 0xdeadbeef;
220         hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
221                 sizeof(DWORD), URLZONEREG_DEFAULT);
222         ok(hres == E_FAIL, "GetZoneActionPolicy failed: %08x, expected E_FAIL\n", hres);
223         ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
224         return;
225     }
226
227     policy = 0xdeadbeef;
228     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
229             sizeof(DWORD), URLZONEREG_DEFAULT);
230     ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
231     ok(policy == reg_policy, "(%x) policy=%x, expected %x\n", action, policy, reg_policy);
232
233     if(policy != URLPOLICY_QUERY) {
234         if(winetest_interactive || ! is_ie_hardened()) {
235             policy = 0xdeadbeef;
236             hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
237                     sizeof(WCHAR), NULL, 0, 0, 0);
238             if(reg_policy == URLPOLICY_DISALLOW)
239                 ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
240             else
241                 ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
242             ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
243         }else {
244             skip("IE running in Enhanced Security Configuration\n");
245         }
246     }
247 }
248
249 static void test_special_url_action(IInternetSecurityManager *secmgr, IInternetZoneManager *zonemgr, DWORD action)
250 {
251     DWORD policy;
252     HRESULT hres;
253
254     policy = 0xdeadbeef;
255     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
256             sizeof(DWORD), URLZONEREG_DEFAULT);
257     ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
258     ok(policy == URLPOLICY_DISALLOW, "(%x) policy=%x, expected URLPOLICY_DISALLOW\n", action, policy);
259
260     policy = 0xdeadbeef;
261     hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url1, action, (BYTE*)&policy,
262             sizeof(WCHAR), NULL, 0, 0, 0);
263     ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
264 }
265
266 static void test_polices(void)
267 {
268     IInternetZoneManager *zonemgr = NULL;
269     IInternetSecurityManager *secmgr = NULL;
270     HRESULT hres;
271
272     hres = CoInternetCreateSecurityManager(NULL, &secmgr, 0);
273     ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
274     hres = CoInternetCreateZoneManager(NULL, &zonemgr, 0);
275     ok(hres == S_OK, "CoInternetCreateZoneManager failed: %08x\n", hres);
276
277     test_url_action(secmgr, zonemgr, URLACTION_SCRIPT_RUN);
278     test_url_action(secmgr, zonemgr, URLACTION_ACTIVEX_OVERRIDE_OBJECT_SAFETY);
279     test_url_action(secmgr, zonemgr, URLACTION_CHANNEL_SOFTDIST_PERMISSIONS);
280     test_url_action(secmgr, zonemgr, 0xdeadbeef);
281
282     test_special_url_action(secmgr, zonemgr, URLACTION_SCRIPT_OVERRIDE_SAFETY);
283
284     IInternetSecurityManager_Release(secmgr);
285     IInternetZoneManager_Release(zonemgr);
286 }
287
288 static void test_CoInternetCreateZoneManager(void)
289 {
290     IInternetZoneManager *zonemgr = NULL;
291     IUnknown *punk = NULL;
292     HRESULT hr;
293
294     hr = CoInternetCreateZoneManager(NULL, &zonemgr, 0);
295     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
296     if (FAILED(hr))
297         return;
298
299     hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IUnknown, (void **) &punk);
300     ok(SUCCEEDED(hr), "got 0x%x with %p (expected Success)\n", hr, punk);
301     if (punk)
302         IUnknown_Release(punk);
303
304     hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IInternetZoneManager, (void **) &punk);
305     ok(SUCCEEDED(hr), "got 0x%x with %p (expected Success)\n", hr, punk);
306     if (punk)
307         IUnknown_Release(punk);
308
309
310     hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IInternetZoneManagerEx, (void **) &punk);
311     if (SUCCEEDED(hr)) {
312         IUnknown_Release(punk);
313
314         hr = IInternetZoneManager_QueryInterface(zonemgr, &IID_IInternetZoneManagerEx2, (void **) &punk);
315         if (punk)
316             IUnknown_Release(punk);
317         else
318             win_skip("InternetZoneManagerEx2 not supported\n");
319
320     }
321     else
322         win_skip("InternetZoneManagerEx not supported\n");
323
324     hr = IInternetZoneManager_Release(zonemgr);
325     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
326
327 }
328
329 static void test_CreateZoneEnumerator(void)
330 {
331     IInternetZoneManager *zonemgr = NULL;
332     HRESULT hr;
333     DWORD dwEnum;
334     DWORD dwEnum2;
335     DWORD dwCount;
336     DWORD dwCount2;
337
338     hr = CoInternetCreateZoneManager(NULL, &zonemgr, 0);
339     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
340     if (FAILED(hr))
341         return;
342
343     dwEnum=0xdeadbeef;
344     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, NULL, 0);
345     ok((hr == E_INVALIDARG) && (dwEnum == 0xdeadbeef),
346         "got 0x%x with 0x%x (expected E_INVALIDARG with 0xdeadbeef)\n", hr, dwEnum);
347
348     dwCount=0xdeadbeef;
349     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, NULL, &dwCount, 0);
350     ok((hr == E_INVALIDARG) && (dwCount == 0xdeadbeef),
351         "got 0x%x and 0x%x (expected E_INVALIDARG and 0xdeadbeef)\n", hr, dwCount);
352
353     dwEnum=0xdeadbeef;
354     dwCount=0xdeadbeef;
355     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 0xffffffff);
356     ok((hr == E_INVALIDARG) && (dwEnum == 0xdeadbeef) && (dwCount == 0xdeadbeef),
357         "got 0x%x with 0x%x and 0x%x (expected E_INVALIDARG with 0xdeadbeef and 0xdeadbeef)\n",
358         hr, dwEnum, dwCount);
359
360     dwEnum=0xdeadbeef;
361     dwCount=0xdeadbeef;
362     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 1);
363     ok((hr == E_INVALIDARG) && (dwEnum == 0xdeadbeef) && (dwCount == 0xdeadbeef),
364         "got 0x%x with 0x%x and 0x%x (expected E_INVALIDARG with 0xdeadbeef and 0xdeadbeef)\n",
365         hr, dwEnum, dwCount);
366
367     dwEnum=0xdeadbeef;
368     dwCount=0xdeadbeef;
369     /* Normal use */
370     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 0);
371     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
372
373     if (SUCCEEDED(hr)) {
374         dwEnum2=0xdeadbeef;
375         dwCount2=0xdeadbeef;
376         hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum2, &dwCount2, 0);
377         ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
378         if (SUCCEEDED(hr)) {
379             /* native urlmon has an incrementing counter for dwEnum */
380             hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum2);
381             ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
382         }
383
384         hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum);
385         ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
386
387         /* Destroy the Enumerator twice is detected and handled in native urlmon */
388         hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum);
389         ok((hr == E_INVALIDARG), "got 0x%x (expected E_INVALIDARG)\n", hr);
390     }
391
392     /* ::Release succeed also, when a ::DestroyZoneEnumerator is missing */
393     hr = IInternetZoneManager_Release(zonemgr);
394     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
395 }
396
397 static void test_GetZoneActionPolicy(void)
398 {
399     IInternetZoneManager *zonemgr = NULL;
400     BYTE buf[32];
401     HRESULT hres;
402     DWORD action = URLACTION_CREDENTIALS_USE; /* Implemented on all IE versions */
403
404     hres = CoInternetCreateZoneManager(NULL, &zonemgr, 0);
405     ok(hres == S_OK, "CoInternetCreateZoneManager failed: %08x\n", hres);
406     if(FAILED(hres))
407         return;
408
409     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, buf,
410             sizeof(DWORD), URLZONEREG_DEFAULT);
411     ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
412     ok(*(DWORD*)buf == URLPOLICY_CREDENTIALS_SILENT_LOGON_OK ||
413             *(DWORD*)buf == URLPOLICY_CREDENTIALS_MUST_PROMPT_USER ||
414             *(DWORD*)buf == URLPOLICY_CREDENTIALS_CONDITIONAL_PROMPT ||
415             *(DWORD*)buf == URLPOLICY_CREDENTIALS_ANONYMOUS_ONLY,
416             "unexpected policy=%d\n", *(DWORD*)buf);
417
418     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, NULL,
419             sizeof(DWORD), URLZONEREG_DEFAULT);
420     ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
421
422     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, buf,
423             2, URLZONEREG_DEFAULT);
424     ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
425
426     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, 0x1fff, buf,
427             sizeof(DWORD), URLZONEREG_DEFAULT);
428     ok(hres == E_FAIL, "GetZoneActionPolicy failed: %08x, expected E_FAIL\n", hres);
429
430     hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 13, action, buf,
431             sizeof(DWORD), URLZONEREG_DEFAULT);
432     ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
433
434     IInternetZoneManager_Release(zonemgr);
435 }
436
437 static void test_GetZoneAt(void)
438 {
439     IInternetZoneManager *zonemgr = NULL;
440     HRESULT hr;
441     DWORD dwEnum;
442     DWORD dwCount;
443     DWORD dwZone;
444     DWORD i;
445
446     hr = CoInternetCreateZoneManager(NULL, &zonemgr, 0);
447     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
448     if (FAILED(hr))
449         return;
450
451     hr = IInternetZoneManager_CreateZoneEnumerator(zonemgr, &dwEnum, &dwCount, 0);
452     if (FAILED(hr))
453         goto cleanup;
454
455     if (0) {
456         /* this crashes with native urlmon */
457         hr = IInternetZoneManager_GetZoneAt(zonemgr, dwEnum, 0, NULL);
458     }
459
460     dwZone = 0xdeadbeef;
461     hr = IInternetZoneManager_GetZoneAt(zonemgr, 0xdeadbeef, 0, &dwZone);
462     ok(hr == E_INVALIDARG,
463         "got 0x%x with 0x%x (expected E_INVALIDARG)\n", hr, dwZone);
464
465     for (i = 0; i < dwCount; i++)
466     {
467         dwZone = 0xdeadbeef;
468         hr = IInternetZoneManager_GetZoneAt(zonemgr, dwEnum, i, &dwZone);
469         ok(hr == S_OK, "#%d: got x%x with %d (expected S_OK)\n", i, hr, dwZone);
470     }
471
472     dwZone = 0xdeadbeef;
473     /* MSDN (index .. must be .. less than or equal to) is wrong */
474     hr = IInternetZoneManager_GetZoneAt(zonemgr, dwEnum, dwCount, &dwZone);
475     ok(hr == E_INVALIDARG,
476         "got 0x%x with 0x%x (expected E_INVALIDARG)\n", hr, dwZone);
477
478     hr = IInternetZoneManager_DestroyZoneEnumerator(zonemgr, dwEnum);
479     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
480
481 cleanup:
482     hr = IInternetZoneManager_Release(zonemgr);
483     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
484 }
485
486 static void test_GetZoneAttributes(void)
487 {
488     IInternetZoneManager *zonemgr = NULL;
489     CHAR buffer [sizeof(ZONEATTRIBUTES) + 32];
490     ZONEATTRIBUTES* pZA = (ZONEATTRIBUTES*) buffer;
491     HRESULT hr;
492     DWORD i;
493
494     hr = CoInternetCreateZoneManager(NULL, &zonemgr, 0);
495     ok(hr == S_OK, "CoInternetCreateZoneManager result: 0x%x\n", hr);
496     if (FAILED(hr))
497         return;
498
499     /* native urlmon has Zone "0" up to Zone "4" since IE4 */
500     for (i = 0; i < 5; i++) {
501         memset(buffer, -1, sizeof(buffer));
502         hr = IInternetZoneManager_GetZoneAttributes(zonemgr, i, pZA);
503         ok(hr == S_OK, "#%d: got 0x%x (expected S_OK)\n", i, hr);
504     }
505
506     /* IE8 no longer set cbSize */
507     memset(buffer, -1, sizeof(buffer));
508     pZA->cbSize = 0;
509     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, pZA);
510     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
511     ok((pZA->cbSize == 0) || (pZA->cbSize == sizeof(ZONEATTRIBUTES)),
512         "got cbSize = %d (expected 0)\n", pZA->cbSize);
513
514     memset(buffer, -1, sizeof(buffer));
515     pZA->cbSize = 64;
516     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, pZA);
517     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
518     ok((pZA->cbSize == 64) || (pZA->cbSize == sizeof(ZONEATTRIBUTES)),
519         "got cbSize = %d (expected 64)\n", pZA->cbSize);
520
521     memset(buffer, -1, sizeof(buffer));
522     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, pZA);
523     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
524     ok((pZA->cbSize == 0xffffffff) || (pZA->cbSize == sizeof(ZONEATTRIBUTES)),
525         "got cbSize = 0x%x (expected 0xffffffff)\n", pZA->cbSize);
526
527     /* IE8 no longer fail on invalid zones */
528     memset(buffer, -1, sizeof(buffer));
529     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0xdeadbeef, pZA);
530     ok(hr == S_OK || (hr == E_FAIL),
531         "got 0x%x (expected S_OK or E_FAIL)\n", hr);
532
533     hr = IInternetZoneManager_GetZoneAttributes(zonemgr, 0, NULL);
534     ok(hr == E_INVALIDARG, "got 0x%x (expected E_INVALIDARG)\n", hr);
535
536     hr = IInternetZoneManager_Release(zonemgr);
537     ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
538 }
539
540
541 START_TEST(sec_mgr)
542 {
543     OleInitialize(NULL);
544
545     test_SecurityManager();
546     test_polices();
547     test_CoInternetCreateZoneManager();
548     test_CreateZoneEnumerator();
549     test_GetZoneActionPolicy();
550     test_GetZoneAt();
551     test_GetZoneAttributes();
552
553     OleUninitialize();
554 }