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