1 /*
2  * XML test
3  *
4  * Copyright 2010-2012 Nikolay Sivov for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 
22 #define COBJMACROS
23 #define CONST_VTABLE
24 
25 #include <stdio.h>
26 #include <assert.h>
27 
28 #include "windows.h"
29 
30 #include "msxml2.h"
31 #include "msxml2did.h"
32 #include "dispex.h"
33 
34 #include "initguid.h"
35 #include "objsafe.h"
36 #include "mshtml.h"
37 
38 #include "wine/heap.h"
39 #include "wine/test.h"
40 
41 #define EXPECT_HR(hr,hr_exp) \
42     ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
43 
44 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
45 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
46 {
47     ULONG rc;
48     IUnknown_AddRef(obj);
49     rc = IUnknown_Release(obj);
50     ok_(__FILE__, line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
51 }
52 
53 DEFINE_GUID(SID_SContainerDispatch, 0xb722be00, 0x4e68, 0x101b, 0xa2, 0xbc, 0x00, 0xaa, 0x00, 0x40, 0x47, 0x70);
54 DEFINE_GUID(SID_UnknownSID, 0x75dd09cb, 0x6c40, 0x11d5, 0x85, 0x43, 0x00, 0xc0, 0x4f, 0xa0, 0xfb, 0xa3);
55 
56 static BOOL g_enablecallchecks;
57 
58 #define DEFINE_EXPECT(func) \
59     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
60 
61 #define SET_EXPECT(func) \
62     expect_ ## func = TRUE
63 
64 #define CHECK_EXPECT2(func) \
65     do { \
66         if (g_enablecallchecks) \
67             ok(expect_ ##func, "unexpected call " #func "\n"); \
68         called_ ## func = TRUE; \
69     }while(0)
70 
71 #define CHECK_CALLED(func) \
72     do { \
73         ok(called_ ## func, "expected " #func "\n"); \
74         expect_ ## func = called_ ## func = FALSE; \
75     }while(0)
76 
77 /* object site */
78 DEFINE_EXPECT(site_qi_IServiceProvider);
79 DEFINE_EXPECT(site_qi_IXMLDOMDocument);
80 DEFINE_EXPECT(site_qi_IOleClientSite);
81 
82 DEFINE_EXPECT(sp_queryservice_SID_SBindHost);
83 DEFINE_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
84 DEFINE_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
85 DEFINE_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
86 DEFINE_EXPECT(sp_queryservice_SID_secmgr_secmgr);
87 
88 DEFINE_EXPECT(htmldoc2_get_all);
89 DEFINE_EXPECT(htmldoc2_get_url);
90 DEFINE_EXPECT(collection_get_length);
91 
92 static int g_unexpectedcall, g_expectedcall;
93 
94 static BSTR alloc_str_from_narrow(const char *str)
95 {
96     int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
97     BSTR ret = SysAllocStringLen(NULL, len - 1);  /* NUL character added automatically */
98     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len-1);
99     return ret;
100 }
101 
102 static BSTR alloced_bstrs[256];
103 static int alloced_bstrs_count;
104 
105 static BSTR _bstr_(const char *str)
106 {
107     if(!str)
108         return NULL;
109 
110     assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
111     alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
112     return alloced_bstrs[alloced_bstrs_count++];
113 }
114 
115 static void free_bstrs(void)
116 {
117     int i;
118     for (i = 0; i < alloced_bstrs_count; i++)
119         SysFreeString(alloced_bstrs[i]);
120     alloced_bstrs_count = 0;
121 }
122 
123 static BSTR a2bstr(const char *str)
124 {
125     BSTR ret;
126     int len;
127 
128     if(!str)
129         return NULL;
130 
131     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
132     ret = SysAllocStringLen(NULL, len);
133     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
134 
135     return ret;
136 }
137 
138 
139 /* test IHTMLElementCollection */
140 static HRESULT WINAPI htmlecoll_QueryInterface(IHTMLElementCollection *iface, REFIID riid, void **ppvObject)
141 {
142     ok(0, "unexpected call\n");
143     *ppvObject = NULL;
144     return E_NOINTERFACE;
145 }
146 
147 static ULONG WINAPI htmlecoll_AddRef(IHTMLElementCollection *iface)
148 {
149     return 2;
150 }
151 
152 static ULONG WINAPI htmlecoll_Release(IHTMLElementCollection *iface)
153 {
154     return 1;
155 }
156 
157 static HRESULT WINAPI htmlecoll_GetTypeInfoCount(IHTMLElementCollection *iface, UINT *pctinfo)
158 {
159     ok(0, "unexpected call\n");
160     return E_NOTIMPL;
161 }
162 
163 static HRESULT WINAPI htmlecoll_GetTypeInfo(IHTMLElementCollection *iface, UINT iTInfo,
164                                                 LCID lcid, ITypeInfo **ppTInfo)
165 {
166     ok(0, "unexpected call\n");
167     return E_NOTIMPL;
168 }
169 
170 static HRESULT WINAPI htmlecoll_GetIDsOfNames(IHTMLElementCollection *iface, REFIID riid,
171                                                 LPOLESTR *rgszNames, UINT cNames,
172                                                 LCID lcid, DISPID *rgDispId)
173 {
174     ok(0, "unexpected call\n");
175     return E_NOTIMPL;
176 }
177 
178 static HRESULT WINAPI htmlecoll_Invoke(IHTMLElementCollection *iface, DISPID dispIdMember,
179                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
180                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
181 {
182     ok(0, "unexpected call\n");
183     return E_NOTIMPL;
184 }
185 
186 static HRESULT WINAPI htmlecoll_toString(IHTMLElementCollection *iface, BSTR *String)
187 {
188     ok(0, "unexpected call\n");
189     return E_NOTIMPL;
190 }
191 
192 static HRESULT WINAPI htmlecoll_put_length(IHTMLElementCollection *iface, LONG v)
193 {
194     ok(0, "unexpected call\n");
195     return E_NOTIMPL;
196 }
197 
198 static HRESULT WINAPI htmlecoll_get_length(IHTMLElementCollection *iface, LONG *v)
199 {
200     CHECK_EXPECT2(collection_get_length);
201     return E_NOTIMPL;
202 }
203 
204 static HRESULT WINAPI htmlecoll_get__newEnum(IHTMLElementCollection *iface, IUnknown **p)
205 {
206     ok(0, "unexpected call\n");
207     return E_NOTIMPL;
208 }
209 
210 static HRESULT WINAPI htmlecoll_item(IHTMLElementCollection *iface, VARIANT name, VARIANT index, IDispatch **pdisp)
211 {
212     ok(0, "unexpected call\n");
213     return E_NOTIMPL;
214 }
215 
216 static HRESULT WINAPI htmlecoll_tags(IHTMLElementCollection *iface, VARIANT tagName, IDispatch **pdisp)
217 {
218     ok(0, "unexpected call\n");
219     return E_NOTIMPL;
220 }
221 
222 static const IHTMLElementCollectionVtbl TestHTMLECollectionVtbl = {
223     htmlecoll_QueryInterface,
224     htmlecoll_AddRef,
225     htmlecoll_Release,
226     htmlecoll_GetTypeInfoCount,
227     htmlecoll_GetTypeInfo,
228     htmlecoll_GetIDsOfNames,
229     htmlecoll_Invoke,
230     htmlecoll_toString,
231     htmlecoll_put_length,
232     htmlecoll_get_length,
233     htmlecoll_get__newEnum,
234     htmlecoll_item,
235     htmlecoll_tags
236 };
237 
238 static IHTMLElementCollection htmlecoll = { &TestHTMLECollectionVtbl };
239 
240 /* test IHTMLDocument2 */
241 static HRESULT WINAPI htmldoc2_QueryInterface(IHTMLDocument2 *iface, REFIID riid, void **ppvObject)
242 {
243    trace("\n");
244    *ppvObject = NULL;
245    return E_NOINTERFACE;
246 }
247 
248 static ULONG WINAPI htmldoc2_AddRef(IHTMLDocument2 *iface)
249 {
250     return 2;
251 }
252 
253 static ULONG WINAPI htmldoc2_Release(IHTMLDocument2 *iface)
254 {
255     return 1;
256 }
257 
258 static HRESULT WINAPI htmldoc2_GetTypeInfoCount(IHTMLDocument2 *iface, UINT *pctinfo)
259 {
260     ok(0, "unexpected call\n");
261     return E_NOTIMPL;
262 }
263 
264 static HRESULT WINAPI htmldoc2_GetTypeInfo(IHTMLDocument2 *iface, UINT iTInfo,
265                                                 LCID lcid, ITypeInfo **ppTInfo)
266 {
267     ok(0, "unexpected call\n");
268     return E_NOTIMPL;
269 }
270 
271 static HRESULT WINAPI htmldoc2_GetIDsOfNames(IHTMLDocument2 *iface, REFIID riid,
272                                                 LPOLESTR *rgszNames, UINT cNames,
273                                                 LCID lcid, DISPID *rgDispId)
274 {
275     ok(0, "unexpected call\n");
276     return E_NOTIMPL;
277 }
278 
279 static HRESULT WINAPI htmldoc2_Invoke(IHTMLDocument2 *iface, DISPID dispIdMember,
280                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
281                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
282 {
283     ok(0, "unexpected call\n");
284     return E_NOTIMPL;
285 }
286 
287 static HRESULT WINAPI htmldoc2_get_Script(IHTMLDocument2 *iface, IDispatch **p)
288 {
289     ok(0, "unexpected call\n");
290     return E_NOTIMPL;
291 }
292 
293 static HRESULT WINAPI htmldoc2_get_all(IHTMLDocument2 *iface, IHTMLElementCollection **p)
294 {
295     CHECK_EXPECT2(htmldoc2_get_all);
296     *p = &htmlecoll;
297     return S_OK;
298 }
299 
300 static HRESULT WINAPI htmldoc2_get_body(IHTMLDocument2 *iface, IHTMLElement **p)
301 {
302     ok(0, "unexpected call\n");
303     return E_NOTIMPL;
304 }
305 
306 static HRESULT WINAPI htmldoc2_get_activeElement(IHTMLDocument2 *iface, IHTMLElement **p)
307 {
308     ok(0, "unexpected call\n");
309     return E_NOTIMPL;
310 }
311 
312 static HRESULT WINAPI htmldoc2_get_images(IHTMLDocument2 *iface, IHTMLElementCollection **p)
313 {
314     ok(0, "unexpected call\n");
315     return E_NOTIMPL;
316 }
317 
318 static HRESULT WINAPI htmldoc2_get_applets(IHTMLDocument2 *iface, IHTMLElementCollection **p)
319 {
320     ok(0, "unexpected call\n");
321     return E_NOTIMPL;
322 }
323 
324 static HRESULT WINAPI htmldoc2_get_links(IHTMLDocument2 *iface, IHTMLElementCollection **p)
325 {
326     ok(0, "unexpected call\n");
327     return E_NOTIMPL;
328 }
329 
330 static HRESULT WINAPI htmldoc2_get_forms(IHTMLDocument2 *iface, IHTMLElementCollection **p)
331 {
332     ok(0, "unexpected call\n");
333     return E_NOTIMPL;
334 }
335 
336 static HRESULT WINAPI htmldoc2_get_anchors(IHTMLDocument2 *iface, IHTMLElementCollection **p)
337 {
338     ok(0, "unexpected call\n");
339     return E_NOTIMPL;
340 }
341 
342 static HRESULT WINAPI htmldoc2_put_title(IHTMLDocument2 *iface, BSTR v)
343 {
344     ok(0, "unexpected call\n");
345     return E_NOTIMPL;
346 }
347 
348 static HRESULT WINAPI htmldoc2_get_title(IHTMLDocument2 *iface, BSTR *p)
349 {
350     ok(0, "unexpected call\n");
351     return E_NOTIMPL;
352 }
353 
354 static HRESULT WINAPI htmldoc2_get_scripts(IHTMLDocument2 *iface, IHTMLElementCollection **p)
355 {
356     ok(0, "unexpected call\n");
357     return E_NOTIMPL;
358 }
359 
360 static HRESULT WINAPI htmldoc2_put_designMode(IHTMLDocument2 *iface, BSTR v)
361 {
362     ok(0, "unexpected call\n");
363     return E_NOTIMPL;
364 }
365 
366 static HRESULT WINAPI htmldoc2_get_designMode(IHTMLDocument2 *iface, BSTR *p)
367 {
368     ok(0, "unexpected call\n");
369     return E_NOTIMPL;
370 }
371 
372 static HRESULT WINAPI htmldoc2_get_selection(IHTMLDocument2 *iface, IHTMLSelectionObject **p)
373 {
374     ok(0, "unexpected call\n");
375     return E_NOTIMPL;
376 }
377 
378 static HRESULT WINAPI htmldoc2_get_readyState(IHTMLDocument2 *iface, BSTR *p)
379 {
380     ok(0, "unexpected call\n");
381     return E_NOTIMPL;
382 }
383 
384 static HRESULT WINAPI htmldoc2_get_frames(IHTMLDocument2 *iface, IHTMLFramesCollection2 **p)
385 {
386     ok(0, "unexpected call\n");
387     return E_NOTIMPL;
388 }
389 
390 static HRESULT WINAPI htmldoc2_get_embeds(IHTMLDocument2 *iface, IHTMLElementCollection **p)
391 {
392     ok(0, "unexpected call\n");
393     return E_NOTIMPL;
394 }
395 
396 static HRESULT WINAPI htmldoc2_get_plugins(IHTMLDocument2 *iface, IHTMLElementCollection **p)
397 {
398     ok(0, "unexpected call\n");
399     return E_NOTIMPL;
400 }
401 
402 static HRESULT WINAPI htmldoc2_put_alinkColor(IHTMLDocument2 *iface, VARIANT v)
403 {
404     ok(0, "unexpected call\n");
405     return E_NOTIMPL;
406 }
407 
408 static HRESULT WINAPI htmldoc2_get_alinkColor(IHTMLDocument2 *iface, VARIANT *p)
409 {
410     ok(0, "unexpected call\n");
411     return E_NOTIMPL;
412 }
413 
414 static HRESULT WINAPI htmldoc2_put_bgColor(IHTMLDocument2 *iface, VARIANT v)
415 {
416     ok(0, "unexpected call\n");
417     return E_NOTIMPL;
418 }
419 
420 static HRESULT WINAPI htmldoc2_get_bgColor(IHTMLDocument2 *iface, VARIANT *p)
421 {
422     ok(0, "unexpected call\n");
423     return E_NOTIMPL;
424 }
425 
426 static HRESULT WINAPI htmldoc2_put_fgColor(IHTMLDocument2 *iface, VARIANT v)
427 {
428     ok(0, "unexpected call\n");
429     return E_NOTIMPL;
430 }
431 
432 static HRESULT WINAPI htmldoc2_get_fgColor(IHTMLDocument2 *iface, VARIANT *p)
433 {
434     ok(0, "unexpected call\n");
435     return E_NOTIMPL;
436 }
437 
438 static HRESULT WINAPI htmldoc2_put_linkColor(IHTMLDocument2 *iface, VARIANT v)
439 {
440     ok(0, "unexpected call\n");
441     return E_NOTIMPL;
442 }
443 
444 static HRESULT WINAPI htmldoc2_get_linkColor(IHTMLDocument2 *iface, VARIANT *p)
445 {
446     ok(0, "unexpected call\n");
447     return E_NOTIMPL;
448 }
449 
450 static HRESULT WINAPI htmldoc2_put_vlinkColor(IHTMLDocument2 *iface, VARIANT v)
451 {
452     ok(0, "unexpected call\n");
453     return E_NOTIMPL;
454 }
455 
456 static HRESULT WINAPI htmldoc2_get_vlinkColor(IHTMLDocument2 *iface, VARIANT *p)
457 {
458     ok(0, "unexpected call\n");
459     return E_NOTIMPL;
460 }
461 
462 static HRESULT WINAPI htmldoc2_get_referrer(IHTMLDocument2 *iface, BSTR *p)
463 {
464     ok(0, "unexpected call\n");
465     return E_NOTIMPL;
466 }
467 
468 static HRESULT WINAPI htmldoc2_get_location(IHTMLDocument2 *iface, IHTMLLocation **p)
469 {
470     ok(0, "unexpected call\n");
471     return E_NOTIMPL;
472 }
473 
474 static HRESULT WINAPI htmldoc2_get_lastModified(IHTMLDocument2 *iface, BSTR *p)
475 {
476     ok(0, "unexpected call\n");
477     return E_NOTIMPL;
478 }
479 
480 static HRESULT WINAPI htmldoc2_put_URL(IHTMLDocument2 *iface, BSTR v)
481 {
482     ok(0, "unexpected call\n");
483     return E_NOTIMPL;
484 }
485 
486 static HRESULT WINAPI htmldoc2_get_URL(IHTMLDocument2 *iface, BSTR *p)
487 {
488     CHECK_EXPECT2(htmldoc2_get_url);
489     *p = a2bstr("http://test.winehq.org/");
490     return S_OK;
491 }
492 
493 static HRESULT WINAPI htmldoc2_put_domain(IHTMLDocument2 *iface, BSTR v)
494 {
495     ok(0, "unexpected call\n");
496     return E_NOTIMPL;
497 }
498 
499 static HRESULT WINAPI htmldoc2_get_domain(IHTMLDocument2 *iface, BSTR *p)
500 {
501     ok(0, "unexpected call\n");
502     return E_NOTIMPL;
503 }
504 
505 static HRESULT WINAPI htmldoc2_put_cookie(IHTMLDocument2 *iface, BSTR v)
506 {
507     ok(0, "unexpected call\n");
508     return E_NOTIMPL;
509 }
510 
511 static HRESULT WINAPI htmldoc2_get_cookie(IHTMLDocument2 *iface, BSTR *p)
512 {
513     ok(0, "unexpected call\n");
514     return E_NOTIMPL;
515 }
516 
517 static HRESULT WINAPI htmldoc2_put_expando(IHTMLDocument2 *iface, VARIANT_BOOL v)
518 {
519     ok(0, "unexpected call\n");
520     return E_NOTIMPL;
521 }
522 
523 static HRESULT WINAPI htmldoc2_get_expando(IHTMLDocument2 *iface, VARIANT_BOOL *p)
524 {
525     ok(0, "unexpected call\n");
526     return E_NOTIMPL;
527 }
528 
529 static HRESULT WINAPI htmldoc2_put_charset(IHTMLDocument2 *iface, BSTR v)
530 {
531     ok(0, "unexpected call\n");
532     return E_NOTIMPL;
533 }
534 
535 static HRESULT WINAPI htmldoc2_get_charset(IHTMLDocument2 *iface, BSTR *p)
536 {
537     ok(0, "unexpected call\n");
538     return E_NOTIMPL;
539 }
540 
541 static HRESULT WINAPI htmldoc2_put_defaultCharset(IHTMLDocument2 *iface, BSTR v)
542 {
543     ok(0, "unexpected call\n");
544     return E_NOTIMPL;
545 }
546 
547 static HRESULT WINAPI htmldoc2_get_defaultCharset(IHTMLDocument2 *iface, BSTR *p)
548 {
549     ok(0, "unexpected call\n");
550     return E_NOTIMPL;
551 }
552 
553 static HRESULT WINAPI htmldoc2_get_mimeType(IHTMLDocument2 *iface, BSTR *p)
554 {
555     ok(0, "unexpected call\n");
556     return E_NOTIMPL;
557 }
558 
559 static HRESULT WINAPI htmldoc2_get_fileSize(IHTMLDocument2 *iface, BSTR *p)
560 {
561     ok(0, "unexpected call\n");
562     return E_NOTIMPL;
563 }
564 
565 static HRESULT WINAPI htmldoc2_get_fileCreatedDate(IHTMLDocument2 *iface, BSTR *p)
566 {
567     ok(0, "unexpected call\n");
568     return E_NOTIMPL;
569 }
570 
571 static HRESULT WINAPI htmldoc2_get_fileModifiedDate(IHTMLDocument2 *iface, BSTR *p)
572 {
573     ok(0, "unexpected call\n");
574     return E_NOTIMPL;
575 }
576 
577 static HRESULT WINAPI htmldoc2_get_fileUpdatedDate(IHTMLDocument2 *iface, BSTR *p)
578 {
579     ok(0, "unexpected call\n");
580     return E_NOTIMPL;
581 }
582 
583 static HRESULT WINAPI htmldoc2_get_security(IHTMLDocument2 *iface, BSTR *p)
584 {
585     ok(0, "unexpected call\n");
586     return E_NOTIMPL;
587 }
588 
589 static HRESULT WINAPI htmldoc2_get_protocol(IHTMLDocument2 *iface, BSTR *p)
590 {
591     ok(0, "unexpected call\n");
592     return E_NOTIMPL;
593 }
594 
595 static HRESULT WINAPI htmldoc2_get_nameProp(IHTMLDocument2 *iface, BSTR *p)
596 {
597     ok(0, "unexpected call\n");
598     return E_NOTIMPL;
599 }
600 
601 static HRESULT WINAPI htmldoc2_write(IHTMLDocument2 *iface, SAFEARRAY *psarray)
602 {
603     ok(0, "unexpected call\n");
604     return E_NOTIMPL;
605 }
606 
607 static HRESULT WINAPI htmldoc2_writeln(IHTMLDocument2 *iface, SAFEARRAY *psarray)
608 {
609     ok(0, "unexpected call\n");
610     return E_NOTIMPL;
611 }
612 
613 static HRESULT WINAPI htmldoc2_open(IHTMLDocument2 *iface, BSTR url, VARIANT name,
614                         VARIANT features, VARIANT replace, IDispatch **pomWindowResult)
615 {
616     ok(0, "unexpected call\n");
617     return E_NOTIMPL;
618 }
619 
620 static HRESULT WINAPI htmldoc2_close(IHTMLDocument2 *iface)
621 {
622     ok(0, "unexpected call\n");
623     return E_NOTIMPL;
624 }
625 
626 static HRESULT WINAPI htmldoc2_clear(IHTMLDocument2 *iface)
627 {
628     ok(0, "unexpected call\n");
629     return E_NOTIMPL;
630 }
631 
632 static HRESULT WINAPI htmldoc2_queryCommandSupported(IHTMLDocument2 *iface, BSTR cmdID,
633                                                         VARIANT_BOOL *pfRet)
634 {
635     ok(0, "unexpected call\n");
636     return E_NOTIMPL;
637 }
638 
639 static HRESULT WINAPI htmldoc2_queryCommandEnabled(IHTMLDocument2 *iface, BSTR cmdID,
640                                                         VARIANT_BOOL *pfRet)
641 {
642     ok(0, "unexpected call\n");
643     return E_NOTIMPL;
644 }
645 
646 static HRESULT WINAPI htmldoc2_queryCommandState(IHTMLDocument2 *iface, BSTR cmdID,
647                                                         VARIANT_BOOL *pfRet)
648 {
649     ok(0, "unexpected call\n");
650     return E_NOTIMPL;
651 }
652 
653 static HRESULT WINAPI htmldoc2_queryCommandIndeterm(IHTMLDocument2 *iface, BSTR cmdID,
654                                                         VARIANT_BOOL *pfRet)
655 {
656     ok(0, "unexpected call\n");
657     return E_NOTIMPL;
658 }
659 
660 static HRESULT WINAPI htmldoc2_queryCommandText(IHTMLDocument2 *iface, BSTR cmdID,
661                                                         BSTR *pfRet)
662 {
663     ok(0, "unexpected call\n");
664     return E_NOTIMPL;
665 }
666 
667 static HRESULT WINAPI htmldoc2_queryCommandValue(IHTMLDocument2 *iface, BSTR cmdID,
668                                                         VARIANT *pfRet)
669 {
670     ok(0, "unexpected call\n");
671     return E_NOTIMPL;
672 }
673 
674 static HRESULT WINAPI htmldoc2_execCommand(IHTMLDocument2 *iface, BSTR cmdID,
675                                 VARIANT_BOOL showUI, VARIANT value, VARIANT_BOOL *pfRet)
676 {
677     ok(0, "unexpected call\n");
678     return E_NOTIMPL;
679 }
680 
681 static HRESULT WINAPI htmldoc2_execCommandShowHelp(IHTMLDocument2 *iface, BSTR cmdID,
682                                                         VARIANT_BOOL *pfRet)
683 {
684     ok(0, "unexpected call\n");
685     return E_NOTIMPL;
686 }
687 
688 static HRESULT WINAPI htmldoc2_createElement(IHTMLDocument2 *iface, BSTR eTag,
689                                                  IHTMLElement **newElem)
690 {
691     ok(0, "unexpected call\n");
692     return E_NOTIMPL;
693 }
694 
695 static HRESULT WINAPI htmldoc2_put_onhelp(IHTMLDocument2 *iface, VARIANT v)
696 {
697     ok(0, "unexpected call\n");
698     return E_NOTIMPL;
699 }
700 
701 static HRESULT WINAPI htmldoc2_get_onhelp(IHTMLDocument2 *iface, VARIANT *p)
702 {
703     ok(0, "unexpected call\n");
704     return E_NOTIMPL;
705 }
706 
707 static HRESULT WINAPI htmldoc2_put_onclick(IHTMLDocument2 *iface, VARIANT v)
708 {
709     ok(0, "unexpected call\n");
710     return E_NOTIMPL;
711 }
712 
713 static HRESULT WINAPI htmldoc2_get_onclick(IHTMLDocument2 *iface, VARIANT *p)
714 {
715     ok(0, "unexpected call\n");
716     return E_NOTIMPL;
717 }
718 
719 static HRESULT WINAPI htmldoc2_put_ondblclick(IHTMLDocument2 *iface, VARIANT v)
720 {
721     ok(0, "unexpected call\n");
722     return E_NOTIMPL;
723 }
724 
725 static HRESULT WINAPI htmldoc2_get_ondblclick(IHTMLDocument2 *iface, VARIANT *p)
726 {
727     ok(0, "unexpected call\n");
728     return E_NOTIMPL;
729 }
730 
731 static HRESULT WINAPI htmldoc2_put_onkeyup(IHTMLDocument2 *iface, VARIANT v)
732 {
733     ok(0, "unexpected call\n");
734     return E_NOTIMPL;
735 }
736 
737 static HRESULT WINAPI htmldoc2_get_onkeyup(IHTMLDocument2 *iface, VARIANT *p)
738 {
739     ok(0, "unexpected call\n");
740     return E_NOTIMPL;
741 }
742 
743 static HRESULT WINAPI htmldoc2_put_onkeydown(IHTMLDocument2 *iface, VARIANT v)
744 {
745     ok(0, "unexpected call\n");
746     return E_NOTIMPL;
747 }
748 
749 static HRESULT WINAPI htmldoc2_get_onkeydown(IHTMLDocument2 *iface, VARIANT *p)
750 {
751     ok(0, "unexpected call\n");
752     return E_NOTIMPL;
753 }
754 
755 static HRESULT WINAPI htmldoc2_put_onkeypress(IHTMLDocument2 *iface, VARIANT v)
756 {
757     ok(0, "unexpected call\n");
758     return E_NOTIMPL;
759 }
760 
761 static HRESULT WINAPI htmldoc2_get_onkeypress(IHTMLDocument2 *iface, VARIANT *p)
762 {
763     ok(0, "unexpected call\n");
764     return E_NOTIMPL;
765 }
766 
767 static HRESULT WINAPI htmldoc2_put_onmouseup(IHTMLDocument2 *iface, VARIANT v)
768 {
769     ok(0, "unexpected call\n");
770     return E_NOTIMPL;
771 }
772 
773 static HRESULT WINAPI htmldoc2_get_onmouseup(IHTMLDocument2 *iface, VARIANT *p)
774 {
775     ok(0, "unexpected call\n");
776     return E_NOTIMPL;
777 }
778 
779 static HRESULT WINAPI htmldoc2_put_onmousedown(IHTMLDocument2 *iface, VARIANT v)
780 {
781     ok(0, "unexpected call\n");
782     return E_NOTIMPL;
783 }
784 
785 static HRESULT WINAPI htmldoc2_get_onmousedown(IHTMLDocument2 *iface, VARIANT *p)
786 {
787     ok(0, "unexpected call\n");
788     return E_NOTIMPL;
789 }
790 
791 static HRESULT WINAPI htmldoc2_put_onmousemove(IHTMLDocument2 *iface, VARIANT v)
792 {
793     ok(0, "unexpected call\n");
794     return E_NOTIMPL;
795 }
796 
797 static HRESULT WINAPI htmldoc2_get_onmousemove(IHTMLDocument2 *iface, VARIANT *p)
798 {
799     ok(0, "unexpected call\n");
800     return E_NOTIMPL;
801 }
802 
803 static HRESULT WINAPI htmldoc2_put_onmouseout(IHTMLDocument2 *iface, VARIANT v)
804 {
805     ok(0, "unexpected call\n");
806     return E_NOTIMPL;
807 }
808 
809 static HRESULT WINAPI htmldoc2_get_onmouseout(IHTMLDocument2 *iface, VARIANT *p)
810 {
811     ok(0, "unexpected call\n");
812     return E_NOTIMPL;
813 }
814 
815 static HRESULT WINAPI htmldoc2_put_onmouseover(IHTMLDocument2 *iface, VARIANT v)
816 {
817     ok(0, "unexpected call\n");
818     return E_NOTIMPL;
819 }
820 
821 static HRESULT WINAPI htmldoc2_get_onmouseover(IHTMLDocument2 *iface, VARIANT *p)
822 {
823     ok(0, "unexpected call\n");
824     return E_NOTIMPL;
825 }
826 
827 static HRESULT WINAPI htmldoc2_put_onreadystatechange(IHTMLDocument2 *iface, VARIANT v)
828 {
829     ok(0, "unexpected call\n");
830     return E_NOTIMPL;
831 }
832 
833 static HRESULT WINAPI htmldoc2_get_onreadystatechange(IHTMLDocument2 *iface, VARIANT *p)
834 {
835     ok(0, "unexpected call\n");
836     return E_NOTIMPL;
837 }
838 
839 static HRESULT WINAPI htmldoc2_put_onafterupdate(IHTMLDocument2 *iface, VARIANT v)
840 {
841     ok(0, "unexpected call\n");
842     return E_NOTIMPL;
843 }
844 
845 static HRESULT WINAPI htmldoc2_get_onafterupdate(IHTMLDocument2 *iface, VARIANT *p)
846 {
847     ok(0, "unexpected call\n");
848     return E_NOTIMPL;
849 }
850 
851 static HRESULT WINAPI htmldoc2_put_onrowexit(IHTMLDocument2 *iface, VARIANT v)
852 {
853     ok(0, "unexpected call\n");
854     return E_NOTIMPL;
855 }
856 
857 static HRESULT WINAPI htmldoc2_get_onrowexit(IHTMLDocument2 *iface, VARIANT *p)
858 {
859     ok(0, "unexpected call\n");
860     return E_NOTIMPL;
861 }
862 
863 static HRESULT WINAPI htmldoc2_put_onrowenter(IHTMLDocument2 *iface, VARIANT v)
864 {
865     ok(0, "unexpected call\n");
866     return E_NOTIMPL;
867 }
868 
869 static HRESULT WINAPI htmldoc2_get_onrowenter(IHTMLDocument2 *iface, VARIANT *p)
870 {
871     ok(0, "unexpected call\n");
872     return E_NOTIMPL;
873 }
874 
875 static HRESULT WINAPI htmldoc2_put_ondragstart(IHTMLDocument2 *iface, VARIANT v)
876 {
877     ok(0, "unexpected call\n");
878     return E_NOTIMPL;
879 }
880 
881 static HRESULT WINAPI htmldoc2_get_ondragstart(IHTMLDocument2 *iface, VARIANT *p)
882 {
883     ok(0, "unexpected call\n");
884     return E_NOTIMPL;
885 }
886 
887 static HRESULT WINAPI htmldoc2_put_onselectstart(IHTMLDocument2 *iface, VARIANT v)
888 {
889     ok(0, "unexpected call\n");
890     return E_NOTIMPL;
891 }
892 
893 static HRESULT WINAPI htmldoc2_get_onselectstart(IHTMLDocument2 *iface, VARIANT *p)
894 {
895     ok(0, "unexpected call\n");
896     return E_NOTIMPL;
897 }
898 
899 static HRESULT WINAPI htmldoc2_elementFromPoint(IHTMLDocument2 *iface, LONG x, LONG y,
900                                                         IHTMLElement **elementHit)
901 {
902     ok(0, "unexpected call\n");
903     return E_NOTIMPL;
904 }
905 
906 static HRESULT WINAPI htmldoc2_get_parentWindow(IHTMLDocument2 *iface, IHTMLWindow2 **p)
907 {
908     ok(0, "unexpected call\n");
909     return E_NOTIMPL;
910 }
911 
912 static HRESULT WINAPI htmldoc2_get_styleSheets(IHTMLDocument2 *iface,
913                                                    IHTMLStyleSheetsCollection **p)
914 {
915     ok(0, "unexpected call\n");
916     return E_NOTIMPL;
917 }
918 
919 static HRESULT WINAPI htmldoc2_put_onbeforeupdate(IHTMLDocument2 *iface, VARIANT v)
920 {
921     ok(0, "unexpected call\n");
922     return E_NOTIMPL;
923 }
924 
925 static HRESULT WINAPI htmldoc2_get_onbeforeupdate(IHTMLDocument2 *iface, VARIANT *p)
926 {
927     ok(0, "unexpected call\n");
928     return E_NOTIMPL;
929 }
930 
931 static HRESULT WINAPI htmldoc2_put_onerrorupdate(IHTMLDocument2 *iface, VARIANT v)
932 {
933     ok(0, "unexpected call\n");
934     return E_NOTIMPL;
935 }
936 
937 static HRESULT WINAPI htmldoc2_get_onerrorupdate(IHTMLDocument2 *iface, VARIANT *p)
938 {
939     ok(0, "unexpected call\n");
940     return E_NOTIMPL;
941 }
942 
943 static HRESULT WINAPI htmldoc2_toString(IHTMLDocument2 *iface, BSTR *String)
944 {
945     ok(0, "unexpected call\n");
946     return E_NOTIMPL;
947 }
948 
949 static HRESULT WINAPI htmldoc2_createStyleSheet(IHTMLDocument2 *iface, BSTR bstrHref,
950                                             LONG lIndex, IHTMLStyleSheet **ppnewStyleSheet)
951 {
952     ok(0, "unexpected call\n");
953     return E_NOTIMPL;
954 }
955 
956 static const IHTMLDocument2Vtbl TestHTMLDocumentVtbl = {
957     htmldoc2_QueryInterface,
958     htmldoc2_AddRef,
959     htmldoc2_Release,
960     htmldoc2_GetTypeInfoCount,
961     htmldoc2_GetTypeInfo,
962     htmldoc2_GetIDsOfNames,
963     htmldoc2_Invoke,
964     htmldoc2_get_Script,
965     htmldoc2_get_all,
966     htmldoc2_get_body,
967     htmldoc2_get_activeElement,
968     htmldoc2_get_images,
969     htmldoc2_get_applets,
970     htmldoc2_get_links,
971     htmldoc2_get_forms,
972     htmldoc2_get_anchors,
973     htmldoc2_put_title,
974     htmldoc2_get_title,
975     htmldoc2_get_scripts,
976     htmldoc2_put_designMode,
977     htmldoc2_get_designMode,
978     htmldoc2_get_selection,
979     htmldoc2_get_readyState,
980     htmldoc2_get_frames,
981     htmldoc2_get_embeds,
982     htmldoc2_get_plugins,
983     htmldoc2_put_alinkColor,
984     htmldoc2_get_alinkColor,
985     htmldoc2_put_bgColor,
986     htmldoc2_get_bgColor,
987     htmldoc2_put_fgColor,
988     htmldoc2_get_fgColor,
989     htmldoc2_put_linkColor,
990     htmldoc2_get_linkColor,
991     htmldoc2_put_vlinkColor,
992     htmldoc2_get_vlinkColor,
993     htmldoc2_get_referrer,
994     htmldoc2_get_location,
995     htmldoc2_get_lastModified,
996     htmldoc2_put_URL,
997     htmldoc2_get_URL,
998     htmldoc2_put_domain,
999     htmldoc2_get_domain,
1000     htmldoc2_put_cookie,
1001     htmldoc2_get_cookie,
1002     htmldoc2_put_expando,
1003     htmldoc2_get_expando,
1004     htmldoc2_put_charset,
1005     htmldoc2_get_charset,
1006     htmldoc2_put_defaultCharset,
1007     htmldoc2_get_defaultCharset,
1008     htmldoc2_get_mimeType,
1009     htmldoc2_get_fileSize,
1010     htmldoc2_get_fileCreatedDate,
1011     htmldoc2_get_fileModifiedDate,
1012     htmldoc2_get_fileUpdatedDate,
1013     htmldoc2_get_security,
1014     htmldoc2_get_protocol,
1015     htmldoc2_get_nameProp,
1016     htmldoc2_write,
1017     htmldoc2_writeln,
1018     htmldoc2_open,
1019     htmldoc2_close,
1020     htmldoc2_clear,
1021     htmldoc2_queryCommandSupported,
1022     htmldoc2_queryCommandEnabled,
1023     htmldoc2_queryCommandState,
1024     htmldoc2_queryCommandIndeterm,
1025     htmldoc2_queryCommandText,
1026     htmldoc2_queryCommandValue,
1027     htmldoc2_execCommand,
1028     htmldoc2_execCommandShowHelp,
1029     htmldoc2_createElement,
1030     htmldoc2_put_onhelp,
1031     htmldoc2_get_onhelp,
1032     htmldoc2_put_onclick,
1033     htmldoc2_get_onclick,
1034     htmldoc2_put_ondblclick,
1035     htmldoc2_get_ondblclick,
1036     htmldoc2_put_onkeyup,
1037     htmldoc2_get_onkeyup,
1038     htmldoc2_put_onkeydown,
1039     htmldoc2_get_onkeydown,
1040     htmldoc2_put_onkeypress,
1041     htmldoc2_get_onkeypress,
1042     htmldoc2_put_onmouseup,
1043     htmldoc2_get_onmouseup,
1044     htmldoc2_put_onmousedown,
1045     htmldoc2_get_onmousedown,
1046     htmldoc2_put_onmousemove,
1047     htmldoc2_get_onmousemove,
1048     htmldoc2_put_onmouseout,
1049     htmldoc2_get_onmouseout,
1050     htmldoc2_put_onmouseover,
1051     htmldoc2_get_onmouseover,
1052     htmldoc2_put_onreadystatechange,
1053     htmldoc2_get_onreadystatechange,
1054     htmldoc2_put_onafterupdate,
1055     htmldoc2_get_onafterupdate,
1056     htmldoc2_put_onrowexit,
1057     htmldoc2_get_onrowexit,
1058     htmldoc2_put_onrowenter,
1059     htmldoc2_get_onrowenter,
1060     htmldoc2_put_ondragstart,
1061     htmldoc2_get_ondragstart,
1062     htmldoc2_put_onselectstart,
1063     htmldoc2_get_onselectstart,
1064     htmldoc2_elementFromPoint,
1065     htmldoc2_get_parentWindow,
1066     htmldoc2_get_styleSheets,
1067     htmldoc2_put_onbeforeupdate,
1068     htmldoc2_get_onbeforeupdate,
1069     htmldoc2_put_onerrorupdate,
1070     htmldoc2_get_onerrorupdate,
1071     htmldoc2_toString,
1072     htmldoc2_createStyleSheet
1073 };
1074 
1075 static IHTMLDocument2 htmldoc2 = { &TestHTMLDocumentVtbl };
1076 
1077 static HRESULT WINAPI sp_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppvObject)
1078 {
1079     *ppvObject = NULL;
1080 
1081     if (IsEqualGUID(riid, &IID_IUnknown) ||
1082         IsEqualGUID(riid, &IID_IServiceProvider))
1083     {
1084         *ppvObject = iface;
1085         IServiceProvider_AddRef(iface);
1086         return S_OK;
1087     }
1088 
1089     ok(0, "unexpected query interface: %s\n", wine_dbgstr_guid(riid));
1090 
1091     return E_NOINTERFACE;
1092 }
1093 
1094 static ULONG WINAPI sp_AddRef(IServiceProvider *iface)
1095 {
1096     return 2;
1097 }
1098 
1099 static ULONG WINAPI sp_Release(IServiceProvider *iface)
1100 {
1101     return 1;
1102 }
1103 
1104 static HRESULT WINAPI sp_QueryService(IServiceProvider *iface, REFGUID service, REFIID riid, void **obj)
1105 {
1106     *obj = NULL;
1107 
1108     if (IsEqualGUID(service, &SID_SBindHost) &&
1109         IsEqualGUID(riid, &IID_IBindHost))
1110     {
1111         CHECK_EXPECT2(sp_queryservice_SID_SBindHost);
1112     }
1113     else if (IsEqualGUID(service, &SID_SContainerDispatch) &&
1114              IsEqualGUID(riid, &IID_IHTMLDocument2))
1115     {
1116         CHECK_EXPECT2(sp_queryservice_SID_SContainerDispatch_htmldoc2);
1117     }
1118     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1119              IsEqualGUID(riid, &IID_IHTMLDocument2))
1120     {
1121         CHECK_EXPECT2(sp_queryservice_SID_secmgr_htmldoc2);
1122         *obj = &htmldoc2;
1123         return S_OK;
1124     }
1125     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1126              IsEqualGUID(riid, &IID_IXMLDOMDocument))
1127     {
1128         CHECK_EXPECT2(sp_queryservice_SID_secmgr_xmldomdoc);
1129     }
1130     else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
1131              IsEqualGUID(riid, &IID_IInternetHostSecurityManager))
1132     {
1133         CHECK_EXPECT2(sp_queryservice_SID_secmgr_secmgr);
1134     }
1135     else if (IsEqualGUID(service, &SID_UnknownSID) &&
1136              IsEqualGUID(riid, &IID_IStream))
1137     {
1138         /* FIXME: unidentified service id */
1139     }
1140     else if ((IsEqualGUID(service, &IID_IInternetProtocol) && IsEqualGUID(riid, &IID_IInternetProtocol)) ||
1141              (IsEqualGUID(service, &IID_IHttpNegotiate2) && IsEqualGUID(riid, &IID_IHttpNegotiate2)) ||
1142              (IsEqualGUID(service, &IID_IGetBindHandle) && IsEqualGUID(riid, &IID_IGetBindHandle)) ||
1143              (IsEqualGUID(service, &IID_IBindStatusCallback) && IsEqualGUID(riid, &IID_IBindStatusCallback)) ||
1144              (IsEqualGUID(service, &IID_IWindowForBindingUI) && IsEqualGUID(riid, &IID_IWindowForBindingUI)))
1145     {
1146     }
1147     else
1148         ok(0, "unexpected request: sid %s, riid %s\n", wine_dbgstr_guid(service), wine_dbgstr_guid(riid));
1149 
1150     return E_NOTIMPL;
1151 }
1152 
1153 static const IServiceProviderVtbl testprovVtbl =
1154 {
1155     sp_QueryInterface,
1156     sp_AddRef,
1157     sp_Release,
1158     sp_QueryService
1159 };
1160 
1161 static IServiceProvider testprov = { &testprovVtbl };
1162 
1163 static HRESULT WINAPI site_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject)
1164 {
1165     *ppvObject = NULL;
1166 
1167     if (IsEqualGUID(riid, &IID_IServiceProvider))
1168         CHECK_EXPECT2(site_qi_IServiceProvider);
1169 
1170     if (IsEqualGUID(riid, &IID_IXMLDOMDocument))
1171         CHECK_EXPECT2(site_qi_IXMLDOMDocument);
1172 
1173     if (IsEqualGUID(riid, &IID_IOleClientSite))
1174         CHECK_EXPECT2(site_qi_IOleClientSite);
1175 
1176     if (IsEqualGUID(riid, &IID_IUnknown))
1177          *ppvObject = iface;
1178     else if (IsEqualGUID(riid, &IID_IServiceProvider))
1179          *ppvObject = &testprov;
1180 
1181     if (*ppvObject) IUnknown_AddRef(iface);
1182 
1183     return *ppvObject ? S_OK : E_NOINTERFACE;
1184 }
1185 
1186 static ULONG WINAPI site_AddRef(IUnknown *iface)
1187 {
1188     return 2;
1189 }
1190 
1191 static ULONG WINAPI site_Release(IUnknown *iface)
1192 {
1193     return 1;
1194 }
1195 
1196 static const IUnknownVtbl testsiteVtbl =
1197 {
1198     site_QueryInterface,
1199     site_AddRef,
1200     site_Release
1201 };
1202 
1203 static IUnknown testsite = { &testsiteVtbl };
1204 
1205 typedef struct
1206 {
1207     IDispatch IDispatch_iface;
1208     LONG ref;
1209 } dispevent;
1210 
1211 static IXMLHttpRequest *httpreq;
1212 
1213 static inline dispevent *impl_from_IDispatch( IDispatch *iface )
1214 {
1215     return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
1216 }
1217 
1218 static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
1219 {
1220     *ppvObject = NULL;
1221 
1222     if ( IsEqualGUID( riid, &IID_IDispatch) ||
1223          IsEqualGUID( riid, &IID_IUnknown) )
1224     {
1225         *ppvObject = iface;
1226     }
1227     else
1228         return E_NOINTERFACE;
1229 
1230     IDispatch_AddRef( iface );
1231 
1232     return S_OK;
1233 }
1234 
1235 static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
1236 {
1237     dispevent *This = impl_from_IDispatch( iface );
1238     return InterlockedIncrement( &This->ref );
1239 }
1240 
1241 static ULONG WINAPI dispevent_Release(IDispatch *iface)
1242 {
1243     dispevent *This = impl_from_IDispatch( iface );
1244     ULONG ref = InterlockedDecrement( &This->ref );
1245 
1246     if (ref == 0)
1247         heap_free(This);
1248 
1249     return ref;
1250 }
1251 
1252 static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
1253 {
1254     g_unexpectedcall++;
1255     *pctinfo = 0;
1256     return S_OK;
1257 }
1258 
1259 static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
1260         LCID lcid, ITypeInfo **ppTInfo)
1261 {
1262     g_unexpectedcall++;
1263     return S_OK;
1264 }
1265 
1266 static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
1267         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1268 {
1269     g_unexpectedcall++;
1270     return S_OK;
1271 }
1272 
1273 static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
1274         LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
1275         EXCEPINFO *excepInfo, UINT *argErr)
1276 {
1277     LONG state;
1278     HRESULT hr;
1279 
1280     ok(member == 0, "expected 0 member, got %d\n", member);
1281     ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
1282     ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
1283 
1284     ok(params->cArgs == 0, "got %d\n", params->cArgs);
1285     ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
1286     ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
1287     ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
1288 
1289     ok(result == NULL, "got %p\n", result);
1290     ok(excepInfo == NULL, "got %p\n", excepInfo);
1291     ok(argErr == NULL, "got %p\n", argErr);
1292 
1293     g_expectedcall++;
1294 
1295     state = READYSTATE_UNINITIALIZED;
1296     hr = IXMLHttpRequest_get_readyState(httpreq, &state);
1297     ok(hr == S_OK, "got 0x%08x\n", hr);
1298     if (state == READYSTATE_COMPLETE)
1299     {
1300         BSTR text = NULL;
1301 
1302         hr = IXMLHttpRequest_get_responseText(httpreq, &text);
1303         ok(hr == S_OK, "got 0x%08x\n", hr);
1304         ok(*text != 0, "got %s\n", wine_dbgstr_w(text));
1305         SysFreeString(text);
1306     }
1307 
1308     return E_FAIL;
1309 }
1310 
1311 static const IDispatchVtbl dispeventVtbl =
1312 {
1313     dispevent_QueryInterface,
1314     dispevent_AddRef,
1315     dispevent_Release,
1316     dispevent_GetTypeInfoCount,
1317     dispevent_GetTypeInfo,
1318     dispevent_GetIDsOfNames,
1319     dispevent_Invoke
1320 };
1321 
1322 static IDispatch* create_dispevent(void)
1323 {
1324     dispevent *event = heap_alloc(sizeof(*event));
1325 
1326     event->IDispatch_iface.lpVtbl = &dispeventVtbl;
1327     event->ref = 1;
1328 
1329     return &event->IDispatch_iface;
1330 }
1331 
1332 static IXMLHttpRequest *create_xhr(void)
1333 {
1334     IXMLHttpRequest *ret;
1335     HRESULT hr;
1336 
1337     hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
1338         &IID_IXMLHttpRequest, (void**)&ret);
1339 
1340     return SUCCEEDED(hr) ? ret : NULL;
1341 }
1342 
1343 static IServerXMLHTTPRequest *create_server_xhr(void)
1344 {
1345     IServerXMLHTTPRequest *ret;
1346     HRESULT hr;
1347 
1348     hr = CoCreateInstance(&CLSID_ServerXMLHTTP30, NULL, CLSCTX_INPROC_SERVER, &IID_IServerXMLHTTPRequest, (void **)&ret);
1349 
1350     return SUCCEEDED(hr) ? ret : NULL;
1351 }
1352 
1353 static void set_safety_opt(IUnknown *unk, DWORD mask, DWORD opts)
1354 {
1355     IObjectSafety *obj_safety;
1356     HRESULT hr;
1357 
1358     hr = IUnknown_QueryInterface(unk, &IID_IObjectSafety, (void**)&obj_safety);
1359     ok(hr == S_OK, "Could not get IObjectSafety iface: %08x\n", hr);
1360 
1361     hr = IObjectSafety_SetInterfaceSafetyOptions(obj_safety, &IID_IDispatch, mask, mask&opts);
1362     ok(hr == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hr);
1363 
1364     IObjectSafety_Release(obj_safety);
1365 }
1366 
1367 static void set_xhr_site(IXMLHttpRequest *xhr)
1368 {
1369     IObjectWithSite *obj_site;
1370     HRESULT hr;
1371 
1372     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site);
1373     ok(hr == S_OK, "Could not get IObjectWithSite iface: %08x\n", hr);
1374 
1375     g_enablecallchecks = TRUE;
1376 
1377     SET_EXPECT(site_qi_IServiceProvider);
1378     SET_EXPECT(sp_queryservice_SID_SBindHost);
1379     SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
1380     SET_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
1381     SET_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
1382     SET_EXPECT(sp_queryservice_SID_secmgr_secmgr);
1383 
1384     /* calls to IHTMLDocument2 */
1385     SET_EXPECT(htmldoc2_get_all);
1386     SET_EXPECT(collection_get_length);
1387     SET_EXPECT(htmldoc2_get_url);
1388 
1389     SET_EXPECT(site_qi_IXMLDOMDocument);
1390     SET_EXPECT(site_qi_IOleClientSite);
1391 
1392     hr = IObjectWithSite_SetSite(obj_site, &testsite);
1393     EXPECT_HR(hr, S_OK);
1394 
1395     CHECK_CALLED(site_qi_IServiceProvider);
1396 todo_wine
1397     CHECK_CALLED(sp_queryservice_SID_SBindHost);
1398     CHECK_CALLED(sp_queryservice_SID_SContainerDispatch_htmldoc2);
1399     CHECK_CALLED(sp_queryservice_SID_secmgr_htmldoc2);
1400 todo_wine
1401     CHECK_CALLED(sp_queryservice_SID_secmgr_xmldomdoc);
1402     /* this one isn't very reliable
1403     CHECK_CALLED(sp_queryservice_SID_secmgr_secmgr); */
1404 todo_wine {
1405     CHECK_CALLED(htmldoc2_get_all);
1406     CHECK_CALLED(collection_get_length);
1407 }
1408     CHECK_CALLED(htmldoc2_get_url);
1409 
1410 todo_wine {
1411     CHECK_CALLED(site_qi_IXMLDOMDocument);
1412     CHECK_CALLED(site_qi_IOleClientSite);
1413 }
1414 
1415     g_enablecallchecks = FALSE;
1416 
1417     IObjectWithSite_Release(obj_site);
1418 }
1419 
1420 #define test_open(a,b,c,d) _test_open(__LINE__,a,b,c,d)
1421 static void _test_open(unsigned line, IXMLHttpRequest *xhr, const char *method, const char *url, HRESULT exhres)
1422 {
1423     VARIANT empty, vfalse;
1424     HRESULT hr;
1425 
1426     V_VT(&empty) = VT_EMPTY;
1427     V_VT(&vfalse) = VT_BOOL;
1428     V_BOOL(&vfalse) = VARIANT_FALSE;
1429 
1430     hr = IXMLHttpRequest_open(xhr, _bstr_(method), _bstr_(url), vfalse, empty, empty);
1431     ok_(__FILE__,line)(hr == exhres, "open(%s %s) failed: %08x, expected %08x\n", method, url, hr, exhres);
1432 }
1433 
1434 static void test_XMLHTTP(void)
1435 {
1436     static const char bodyA[] = "mode=Test";
1437     static const char urlA[] = "http://test.winehq.org/tests/post.php";
1438     static const char xmltestA[] = "http://test.winehq.org/tests/xmltest.xml";
1439     static const char referertesturl[] = "http://test.winehq.org/tests/referer.php";
1440     static const WCHAR wszExpectedResponse[] = {'F','A','I','L','E','D',0};
1441     static const CHAR xmltestbodyA[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n";
1442     static const WCHAR norefererW[] = {'n','o',' ','r','e','f','e','r','e','r',' ','s','e','t',0};
1443 
1444     IXMLHttpRequest *xhr;
1445     IObjectWithSite *obj_site, *obj_site2;
1446     BSTR bstrResponse, str, str1;
1447     VARIANT varbody;
1448     VARIANT dummy;
1449     LONG state, status, bound;
1450     IDispatch *event;
1451     void *ptr;
1452     HRESULT hr;
1453     HGLOBAL g;
1454 
1455     xhr = create_xhr();
1456 
1457     VariantInit(&dummy);
1458     V_VT(&dummy) = VT_ERROR;
1459     V_ERROR(&dummy) = DISP_E_MEMBERNOTFOUND;
1460 
1461     hr = IXMLHttpRequest_put_onreadystatechange(xhr, NULL);
1462     EXPECT_HR(hr, S_OK);
1463 
1464     hr = IXMLHttpRequest_abort(xhr);
1465     EXPECT_HR(hr, S_OK);
1466 
1467     V_VT(&varbody) = VT_I2;
1468     V_I2(&varbody) = 1;
1469     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
1470     EXPECT_HR(hr, E_PENDING);
1471     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
1472 
1473     V_VT(&varbody) = VT_I2;
1474     V_I2(&varbody) = 1;
1475     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
1476     EXPECT_HR(hr, E_PENDING);
1477     ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
1478 
1479     /* send before open */
1480     hr = IXMLHttpRequest_send(xhr, dummy);
1481     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
1482 
1483     /* initial status code */
1484     hr = IXMLHttpRequest_get_status(xhr, NULL);
1485     ok(hr == E_POINTER || broken(hr == E_INVALIDARG) /* <win8 */, "got 0x%08x\n", hr);
1486 
1487     status = 0xdeadbeef;
1488     hr = IXMLHttpRequest_get_status(xhr, &status);
1489     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
1490     ok(status == READYSTATE_UNINITIALIZED || broken(status == 0xdeadbeef) /* <win8 */, "got %d\n", status);
1491 
1492     hr = IXMLHttpRequest_get_statusText(xhr, &str);
1493     ok(hr == E_FAIL, "got 0x%08x\n", hr);
1494 
1495     /* invalid parameters */
1496     test_open(xhr, NULL, NULL, E_INVALIDARG);
1497     test_open(xhr, "POST", NULL, E_INVALIDARG);
1498     test_open(xhr, NULL, urlA, E_INVALIDARG);
1499 
1500     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, NULL);
1501     EXPECT_HR(hr, E_INVALIDARG);
1502 
1503     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), NULL);
1504     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
1505 
1506     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
1507     EXPECT_HR(hr, E_INVALIDARG);
1508 
1509     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
1510     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
1511 
1512     hr = IXMLHttpRequest_get_readyState(xhr, NULL);
1513     ok(hr == E_POINTER || broken(hr == E_INVALIDARG) /* <win8 */, "got 0x%08x\n", hr);
1514 
1515     state = -1;
1516     hr = IXMLHttpRequest_get_readyState(xhr, &state);
1517     EXPECT_HR(hr, S_OK);
1518     ok(state == READYSTATE_UNINITIALIZED, "got %d, expected READYSTATE_UNINITIALIZED\n", state);
1519 
1520     httpreq = xhr;
1521     event = create_dispevent();
1522 
1523     EXPECT_REF(event, 1);
1524     hr = IXMLHttpRequest_put_onreadystatechange(xhr, event);
1525     EXPECT_HR(hr, S_OK);
1526     EXPECT_REF(event, 2);
1527 
1528     g_unexpectedcall = g_expectedcall = 0;
1529 
1530     test_open(xhr, "POST", urlA, S_OK);
1531 
1532     ok(g_unexpectedcall == 0, "unexpected disp event call\n");
1533     ok(g_expectedcall == 1 || broken(g_expectedcall == 0) /* win2k */, "no expected disp event call\n");
1534 
1535     /* status code after ::open() */
1536     status = 0xdeadbeef;
1537     hr = IXMLHttpRequest_get_status(xhr, &status);
1538     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
1539     ok(status == READYSTATE_UNINITIALIZED || broken(status == 0xdeadbeef) /* <win8 */, "got %d\n", status);
1540 
1541     state = -1;
1542     hr = IXMLHttpRequest_get_readyState(xhr, &state);
1543     EXPECT_HR(hr, S_OK);
1544     ok(state == READYSTATE_LOADING, "got %d, expected READYSTATE_LOADING\n", state);
1545 
1546     hr = IXMLHttpRequest_abort(xhr);
1547     EXPECT_HR(hr, S_OK);
1548 
1549     state = -1;
1550     hr = IXMLHttpRequest_get_readyState(xhr, &state);
1551     EXPECT_HR(hr, S_OK);
1552     ok(state == READYSTATE_UNINITIALIZED || broken(state == READYSTATE_LOADING) /* win2k */,
1553         "got %d, expected READYSTATE_UNINITIALIZED\n", state);
1554 
1555     test_open(xhr, "POST", urlA, S_OK);
1556 
1557     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
1558     EXPECT_HR(hr, S_OK);
1559 
1560     hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
1561     EXPECT_HR(hr, E_INVALIDARG);
1562 
1563     hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_(""), _bstr_("value1"));
1564     EXPECT_HR(hr, E_INVALIDARG);
1565 
1566     V_VT(&varbody) = VT_BSTR;
1567     V_BSTR(&varbody) = _bstr_(bodyA);
1568 
1569     hr = IXMLHttpRequest_send(xhr, varbody);
1570     if (hr == INET_E_RESOURCE_NOT_FOUND)
1571     {
1572         skip("No connection could be made with test.winehq.org\n");
1573         IXMLHttpRequest_Release(xhr);
1574         return;
1575     }
1576     EXPECT_HR(hr, S_OK);
1577 
1578     /* response headers */
1579     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, NULL);
1580     ok(hr == E_POINTER || broken(hr == E_INVALIDARG) /* <win8 */, "got 0x%08x\n", hr);
1581     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str);
1582     EXPECT_HR(hr, S_OK);
1583     /* status line is stripped already */
1584     ok(memcmp(str, _bstr_("HTTP"), 4*sizeof(WCHAR)), "got response headers %s\n", wine_dbgstr_w(str));
1585     ok(*str, "got empty headers\n");
1586     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str1);
1587     EXPECT_HR(hr, S_OK);
1588     ok(str1 != str, "got %p\n", str1);
1589     SysFreeString(str1);
1590     SysFreeString(str);
1591 
1592     hr = IXMLHttpRequest_getResponseHeader(xhr, NULL, NULL);
1593     EXPECT_HR(hr, E_INVALIDARG);
1594     hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), NULL);
1595     ok(hr == E_POINTER || broken(hr == E_INVALIDARG) /* <win8 */, "got 0x%08x\n", hr);
1596     hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), &str);
1597     EXPECT_HR(hr, S_OK);
1598     ok(*str != ' ', "got leading space in header %s\n", wine_dbgstr_w(str));
1599     SysFreeString(str);
1600 
1601     /* status code after ::send() */
1602     status = 0xdeadbeef;
1603     hr = IXMLHttpRequest_get_status(xhr, &status);
1604     EXPECT_HR(hr, S_OK);
1605     ok(status == 200, "got %d\n", status);
1606 
1607     hr = IXMLHttpRequest_get_statusText(xhr, NULL);
1608     ok(hr == E_POINTER || broken(hr == E_INVALIDARG) /* <win8 */, "got 0x%08x\n", hr);
1609 
1610     hr = IXMLHttpRequest_get_statusText(xhr, &str);
1611     EXPECT_HR(hr, S_OK);
1612     ok(!lstrcmpW(str, _bstr_("OK")), "got status %s\n", wine_dbgstr_w(str));
1613     SysFreeString(str);
1614 
1615     /* another ::send() after completed request */
1616     V_VT(&varbody) = VT_BSTR;
1617     V_BSTR(&varbody) = _bstr_(bodyA);
1618 
1619     hr = IXMLHttpRequest_send(xhr, varbody);
1620     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
1621 
1622     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
1623     EXPECT_HR(hr, S_OK);
1624     /* the server currently returns "FAILED" because the Content-Type header is
1625      * not what the server expects */
1626     if(hr == S_OK)
1627     {
1628         ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)),
1629             "expected %s, got %s\n", wine_dbgstr_w(wszExpectedResponse), wine_dbgstr_w(bstrResponse));
1630         SysFreeString(bstrResponse);
1631     }
1632 
1633     /* POST: VT_VARIANT body */
1634     /* VT_VARIANT|VT_BYREF fails on Windows 10 */
1635     test_open(xhr, "POST", urlA, S_OK);
1636 
1637     hr = IXMLHttpRequest_send(xhr, varbody);
1638     EXPECT_HR(hr, S_OK);
1639 
1640     /* GET request */
1641     test_open(xhr, "GET", xmltestA, S_OK);
1642 
1643     V_VT(&varbody) = VT_EMPTY;
1644 
1645     hr = IXMLHttpRequest_send(xhr, varbody);
1646     if (hr == INET_E_RESOURCE_NOT_FOUND)
1647     {
1648         skip("No connection could be made with test.winehq.org\n");
1649         IXMLHttpRequest_Release(xhr);
1650         return;
1651     }
1652     EXPECT_HR(hr, S_OK);
1653 
1654     hr = IXMLHttpRequest_get_responseText(xhr, NULL);
1655     ok(hr == E_POINTER || broken(hr == E_INVALIDARG) /* <win8 */, "got 0x%08x\n", hr);
1656 
1657     hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
1658     EXPECT_HR(hr, S_OK);
1659     ok(!memcmp(bstrResponse, _bstr_(xmltestbodyA), sizeof(xmltestbodyA)*sizeof(WCHAR)),
1660         "expected %s, got %s\n", xmltestbodyA, wine_dbgstr_w(bstrResponse));
1661     SysFreeString(bstrResponse);
1662 
1663     hr = IXMLHttpRequest_get_responseBody(xhr, NULL);
1664     EXPECT_HR(hr, E_INVALIDARG);
1665 
1666     V_VT(&varbody) = VT_EMPTY;
1667     hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
1668     EXPECT_HR(hr, S_OK);
1669     ok(V_VT(&varbody) == (VT_ARRAY|VT_UI1), "got type %d, expected %d\n", V_VT(&varbody), VT_ARRAY|VT_UI1);
1670     ok(SafeArrayGetDim(V_ARRAY(&varbody)) == 1, "got %d, expected one dimension\n", SafeArrayGetDim(V_ARRAY(&varbody)));
1671 
1672     bound = -1;
1673     hr = SafeArrayGetLBound(V_ARRAY(&varbody), 1, &bound);
1674     EXPECT_HR(hr, S_OK);
1675     ok(bound == 0, "got %d, expected zero bound\n", bound);
1676 
1677     hr = SafeArrayAccessData(V_ARRAY(&varbody), &ptr);
1678     EXPECT_HR(hr, S_OK);
1679     ok(memcmp(ptr, xmltestbodyA, sizeof(xmltestbodyA)-1) == 0, "got wrong body data\n");
1680     SafeArrayUnaccessData(V_ARRAY(&varbody));
1681 
1682     VariantClear(&varbody);
1683 
1684     /* get_responseStream */
1685     hr = IXMLHttpRequest_get_responseStream(xhr, NULL);
1686     EXPECT_HR(hr, E_INVALIDARG);
1687 
1688     V_VT(&varbody) = VT_EMPTY;
1689     hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
1690     ok(V_VT(&varbody) == VT_UNKNOWN, "got type %d\n", V_VT(&varbody));
1691     EXPECT_HR(hr, S_OK);
1692     EXPECT_REF(V_UNKNOWN(&varbody), 1);
1693 
1694     g = NULL;
1695     hr = GetHGlobalFromStream((IStream*)V_UNKNOWN(&varbody), &g);
1696     EXPECT_HR(hr, S_OK);
1697     ok(g != NULL, "got %p\n", g);
1698     VariantClear(&varbody);
1699 
1700     IDispatch_Release(event);
1701 
1702     /* test if referrer header is sent */
1703     test_open(xhr, "GET", referertesturl, S_OK);
1704 
1705     V_VT(&varbody) = VT_EMPTY;
1706     hr = IXMLHttpRequest_send(xhr, varbody);
1707     ok(hr == S_OK, "got 0x%08x\n", hr);
1708     hr = IXMLHttpRequest_get_responseText(xhr, &str);
1709     ok(hr == S_OK, "got 0x%08x\n", hr);
1710     ok(!lstrcmpW(str, norefererW), "got response text %s\n", wine_dbgstr_w(str));
1711     SysFreeString(str);
1712 
1713     /* interaction with object site */
1714     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site);
1715     EXPECT_HR(hr, S_OK);
1716 
1717     hr = IObjectWithSite_SetSite(obj_site, NULL);
1718     ok(hr == S_OK, "got 0x%08x\n", hr);
1719 
1720     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site2);
1721     EXPECT_HR(hr, S_OK);
1722     ok(obj_site == obj_site2 || broken(obj_site != obj_site2), "got new instance\n");
1723     IObjectWithSite_Release(obj_site2);
1724 
1725     set_xhr_site(xhr);
1726 
1727     test_open(xhr, "GET", "tests/referer.php", S_OK);
1728     str1 = a2bstr("http://test.winehq.org/");
1729 
1730     V_VT(&varbody) = VT_EMPTY;
1731     hr = IXMLHttpRequest_send(xhr, varbody);
1732     ok(hr == S_OK, "got 0x%08x\n", hr);
1733 
1734     hr = IXMLHttpRequest_get_responseText(xhr, &str);
1735     ok(hr == S_OK, "got 0x%08x\n", hr);
1736     ok(!lstrcmpW(str, str1), "got response text %s, expected %s\n", wine_dbgstr_w(str), wine_dbgstr_w(str1));
1737     SysFreeString(str);
1738     SysFreeString(str1);
1739 
1740     /* try to set site another time */
1741     hr = IObjectWithSite_SetSite(obj_site, &testsite);
1742     EXPECT_HR(hr, S_OK);
1743 
1744     IObjectWithSite_Release(obj_site);
1745 
1746     /* HEAD request */
1747     hr = IXMLHttpRequest_put_onreadystatechange(xhr, NULL);
1748     ok(hr == S_OK, "Failed to reset state change handler, hr %#x.\n", hr);
1749 
1750     test_open(xhr, "HEAD", xmltestA, S_OK);
1751 
1752     V_VT(&varbody) = VT_EMPTY;
1753     hr = IXMLHttpRequest_send(xhr, varbody);
1754     ok(hr == S_OK, "Failed to send HEAD request, hr %#x.\n", hr);
1755 
1756     str = NULL;
1757     hr = IXMLHttpRequest_get_responseText(xhr, &str);
1758     ok(hr == S_OK, "Failed to get response text, hr %#x.\n", hr);
1759     ok(!*str, "Unexpected text %s.\n", wine_dbgstr_w(str));
1760     SysFreeString(str);
1761 
1762     hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str);
1763     ok(hr == S_OK, "Failed to get response headers, hr %#x.\n", hr);
1764     ok(str && *str, "Expected response headers.\n");
1765     SysFreeString(str);
1766 
1767     IXMLHttpRequest_Release(xhr);
1768     free_bstrs();
1769 }
1770 
1771 static void test_safe_httpreq(void)
1772 {
1773     IXMLHttpRequest *xhr;
1774 
1775     xhr = create_xhr();
1776 
1777     set_safety_opt((IUnknown*)xhr, INTERFACESAFE_FOR_UNTRUSTED_DATA, -1);
1778     set_xhr_site(xhr);
1779 
1780     /* different scheme */
1781     test_open(xhr, "GET", "https://test.winehq.org/tests/hello.html", E_ACCESSDENIED);
1782 
1783     /* different host */
1784     test_open(xhr, "GET", "http://tests.winehq.org/tests/hello.html", E_ACCESSDENIED);
1785     test_open(xhr, "GET", "http://www.test.winehq.org/tests/hello.html", E_ACCESSDENIED);
1786 
1787     IXMLHttpRequest_Release(xhr);
1788     free_bstrs();
1789 }
1790 
1791 static void test_supporterrorinfo(void)
1792 {
1793     HRESULT hr;
1794     IXMLHttpRequest *xhr;
1795     IServerXMLHTTPRequest *server_xhr;
1796     ISupportErrorInfo *errorinfo, *errorinfo2;
1797 
1798     xhr = create_xhr();
1799 
1800     EXPECT_REF(xhr, 1);
1801     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_ISupportErrorInfo, (void **)&errorinfo);
1802     ok(hr == S_OK, "Failed to get ISupportErrorInfo, hr %#x.\n", hr);
1803     EXPECT_REF(xhr, 2);
1804 
1805     hr = IXMLHttpRequest_QueryInterface(xhr, &IID_ISupportErrorInfo, (void **)&errorinfo2);
1806     ok(hr == S_OK, "Failed to get ISupportErrorInfo, hr %#x.\n", hr);
1807     ok(errorinfo == errorinfo2, "Unexpected error info instance.\n");
1808     EXPECT_REF(xhr, 3);
1809 
1810     ISupportErrorInfo_Release(errorinfo2);
1811     ISupportErrorInfo_Release(errorinfo);
1812 
1813     IXMLHttpRequest_Release(xhr);
1814 
1815     /* ServerXMLHTTP */
1816     server_xhr = create_server_xhr();
1817 
1818     EXPECT_REF(server_xhr, 1);
1819     hr = IServerXMLHTTPRequest_QueryInterface(server_xhr, &IID_ISupportErrorInfo, (void **)&errorinfo);
1820     ok(hr == S_OK, "Failed to get ISupportErrorInfo, hr %#x.\n", hr);
1821     EXPECT_REF(server_xhr, 2);
1822 
1823     hr = IServerXMLHTTPRequest_QueryInterface(server_xhr, &IID_ISupportErrorInfo, (void **)&errorinfo2);
1824     ok(hr == S_OK, "Failed to get ISupportErrorInfo, hr %#x.\n", hr);
1825     ok(errorinfo == errorinfo2, "Unexpected error info instance.\n");
1826     EXPECT_REF(server_xhr, 3);
1827 
1828     ISupportErrorInfo_Release(errorinfo2);
1829     ISupportErrorInfo_Release(errorinfo);
1830 
1831     IServerXMLHTTPRequest_Release(server_xhr);
1832 }
1833 
1834 START_TEST(httpreq)
1835 {
1836     IXMLHttpRequest *xhr;
1837 
1838     CoInitialize(NULL);
1839 
1840     if (!(xhr = create_xhr()))
1841     {
1842         win_skip("IXMLHTTPRequest is not available\n");
1843         CoUninitialize();
1844         return;
1845     }
1846 
1847     IXMLHttpRequest_Release(xhr);
1848 
1849     test_XMLHTTP();
1850     test_safe_httpreq();
1851     test_supporterrorinfo();
1852 
1853     CoUninitialize();
1854 }
1855