jscript: Store concatenated strings as a rope string to avoid useless copying.
[wine] / dlls / msxml3 / xmlview.c
1 /*
2  * Copyright 2012 Piotr Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22
23 #define COBJMACROS
24 #define NONAMELESSUNION
25
26 #ifdef HAVE_LIBXML2
27 #include <libxml/parser.h>
28 #endif
29
30 #include "windef.h"
31 #include "winbase.h"
32 #include "ole2.h"
33 #include "msxml6.h"
34 #include "mshtml.h"
35 #include "mshtmhst.h"
36 #include "perhist.h"
37 #include "docobj.h"
38
39 #include "wine/debug.h"
40
41 #include "msxml_private.h"
42
43 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
44
45 #ifdef HAVE_LIBXML2
46
47 typedef struct
48 {
49     IPersistMoniker IPersistMoniker_iface;
50     IPersistHistory IPersistHistory_iface;
51     IOleCommandTarget IOleCommandTarget_iface;
52     IOleObject IOleObject_iface;
53
54     LONG ref;
55
56     IUnknown *html_doc;
57     IMoniker *mon;
58 } XMLView;
59
60 typedef struct
61 {
62     IMoniker IMoniker_iface;
63     LONG ref;
64     IMoniker *mon;
65
66     IStream *stream;
67 } Moniker;
68
69 typedef struct
70 {
71     IBindStatusCallback IBindStatusCallback_iface;
72     LONG ref;
73     IBindStatusCallback *bsc;
74
75     IMoniker *mon;
76     IStream *stream;
77 } BindStatusCallback;
78
79 typedef struct
80 {
81     IBinding IBinding_iface;
82     LONG ref;
83     IBinding *binding;
84 } Binding;
85
86 static inline Binding* impl_from_IBinding(IBinding *iface)
87 {
88     return CONTAINING_RECORD(iface, Binding, IBinding_iface);
89 }
90
91 static HRESULT WINAPI XMLView_Binding_QueryInterface(
92         IBinding *iface, REFIID riid, void **ppvObject)
93 {
94     Binding *This = impl_from_IBinding(iface);
95
96     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
97
98     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IBinding)) {
99         *ppvObject = iface;
100         IBinding_AddRef(iface);
101         return S_OK;
102     }
103
104     *ppvObject = NULL;
105     return E_NOINTERFACE;
106 }
107
108 static ULONG WINAPI XMLView_Binding_AddRef(IBinding *iface)
109 {
110     Binding *This = impl_from_IBinding(iface);
111     LONG ref = InterlockedIncrement(&This->ref);
112
113     TRACE("(%p)->(%d)\n", This, ref);
114
115     return ref;
116 }
117
118 static ULONG WINAPI XMLView_Binding_Release(IBinding *iface)
119 {
120     Binding *This = impl_from_IBinding(iface);
121     ULONG ref = InterlockedDecrement(&This->ref);
122
123     TRACE("(%p)->(%d)\n", This, ref);
124
125     if(!ref) {
126         IBinding_Release(This->binding);
127         heap_free(This);
128     }
129     return ref;
130 }
131
132 static HRESULT WINAPI XMLView_Binding_Abort(IBinding *iface)
133 {
134     Binding *This = impl_from_IBinding(iface);
135     TRACE("(%p)\n", This);
136
137     return IBinding_Abort(This->binding);
138 }
139
140 static HRESULT WINAPI XMLView_Binding_Suspend(IBinding *iface)
141 {
142     Binding *This = impl_from_IBinding(iface);
143     FIXME("(%p)\n", This);
144     return E_NOTIMPL;
145 }
146
147 static HRESULT WINAPI XMLView_Binding_Resume(IBinding *iface)
148 {
149     Binding *This = impl_from_IBinding(iface);
150     FIXME("(%p)\n", This);
151     return E_NOTIMPL;
152 }
153
154 static HRESULT WINAPI XMLView_Binding_SetPriority(
155         IBinding *iface, LONG nPriority)
156 {
157     Binding *This = impl_from_IBinding(iface);
158     TRACE("(%p)->(%d)\n", This, nPriority);
159
160     return IBinding_SetPriority(This->binding, nPriority);
161 }
162
163 static HRESULT WINAPI XMLView_Binding_GetPriority(
164         IBinding *iface, LONG *pnPriority)
165 {
166     Binding *This = impl_from_IBinding(iface);
167     TRACE("(%p)->(%p)\n", This, pnPriority);
168
169     return IBinding_GetPriority(This->binding, pnPriority);
170 }
171
172 static HRESULT WINAPI XMLView_Binding_GetBindResult(IBinding *iface,
173         CLSID *pclsidProtocol, DWORD *pdwResult, LPOLESTR *pszResult,
174         DWORD *pdwReserved)
175 {
176     Binding *This = impl_from_IBinding(iface);
177     FIXME("(%p)->(%s %p %p %p)\n", This, debugstr_guid(pclsidProtocol),
178             pdwResult, pszResult, pdwReserved);
179     return E_NOTIMPL;
180 }
181
182 static IBindingVtbl XMLView_BindingVtbl = {
183     XMLView_Binding_QueryInterface,
184     XMLView_Binding_AddRef,
185     XMLView_Binding_Release,
186     XMLView_Binding_Abort,
187     XMLView_Binding_Suspend,
188     XMLView_Binding_Resume,
189     XMLView_Binding_SetPriority,
190     XMLView_Binding_GetPriority,
191     XMLView_Binding_GetBindResult
192 };
193
194 static inline HRESULT XMLView_Binding_Create(IBinding *binding, IBinding **ret)
195 {
196     Binding *bind;
197
198     bind = heap_alloc_zero(sizeof(Binding));
199     if(!bind)
200         return E_OUTOFMEMORY;
201
202     bind->IBinding_iface.lpVtbl = &XMLView_BindingVtbl;
203     bind->ref = 1;
204
205     bind->binding = binding;
206     IBinding_AddRef(binding);
207
208     *ret = &bind->IBinding_iface;
209     return S_OK;
210 }
211
212 static inline BindStatusCallback* impl_from_IBindStatusCallback(
213         IBindStatusCallback *iface)
214 {
215     return CONTAINING_RECORD(iface, BindStatusCallback,
216             IBindStatusCallback_iface);
217 }
218
219 static HRESULT WINAPI XMLView_BindStatusCallback_QueryInterface(
220         IBindStatusCallback *iface, REFIID riid, void **ppvObject)
221 {
222     BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
223
224     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
225
226     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IBindStatusCallback)) {
227         *ppvObject = iface;
228         IBindStatusCallback_AddRef(iface);
229         return S_OK;
230     }
231
232     *ppvObject = NULL;
233     return E_NOINTERFACE;
234 }
235
236 static ULONG WINAPI XMLView_BindStatusCallback_AddRef(
237         IBindStatusCallback *iface)
238 {
239     BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
240     LONG ref = InterlockedIncrement(&This->ref);
241
242     TRACE("(%p)->(%d)\n", This, ref);
243
244     return ref;
245 }
246
247 static ULONG WINAPI XMLView_BindStatusCallback_Release(
248         IBindStatusCallback *iface)
249 {
250     BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
251     ULONG ref = InterlockedDecrement(&This->ref);
252
253     TRACE("(%p)->(%d)\n", This, ref);
254
255     if(!ref) {
256         if(This->stream)
257             IStream_Release(This->stream);
258         IBindStatusCallback_Release(This->bsc);
259         IMoniker_Release(This->mon);
260         heap_free(This);
261     }
262     return ref;
263 }
264
265 static HRESULT WINAPI XMLView_BindStatusCallback_OnStartBinding(
266         IBindStatusCallback *iface, DWORD dwReserved, IBinding *pib)
267 {
268     BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
269     IBinding *binding;
270     HRESULT hres;
271
272     TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
273
274     hres = XMLView_Binding_Create(pib, &binding);
275     if(FAILED(hres)) {
276         IBinding_Abort(pib);
277         return hres;
278     }
279
280     hres = IBindStatusCallback_OnStartBinding(This->bsc, dwReserved, binding);
281     if(FAILED(hres)) {
282         IBinding_Abort(binding);
283         return hres;
284     }
285
286     IBinding_Release(binding);
287     return hres;
288 }
289
290 static HRESULT WINAPI XMLView_BindStatusCallback_GetPriority(
291         IBindStatusCallback *iface, LONG *pnPriority)
292 {
293     BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
294     FIXME("(%p)->(%p)\n", This, pnPriority);
295     return E_NOTIMPL;
296 }
297
298 static HRESULT WINAPI XMLView_BindStatusCallback_OnLowResource(
299         IBindStatusCallback *iface, DWORD reserved)
300 {
301     BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
302     FIXME("(%p)->(%x)\n", This, reserved);
303     return E_NOTIMPL;
304 }
305
306 static HRESULT WINAPI XMLView_BindStatusCallback_OnProgress(
307         IBindStatusCallback *iface, ULONG ulProgress, ULONG ulProgressMax,
308         ULONG ulStatusCode, LPCWSTR szStatusText)
309 {
310     BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
311     TRACE("(%p)->(%d %d %x %s)\n", This, ulProgress, ulProgressMax,
312             ulStatusCode, debugstr_w(szStatusText));
313
314     switch(ulStatusCode) {
315     case BINDSTATUS_BEGINDOWNLOADDATA:
316         return IBindStatusCallback_OnProgress(This->bsc, ulProgress,
317                 ulProgressMax, ulStatusCode, szStatusText);
318     case BINDSTATUS_MIMETYPEAVAILABLE:
319         return S_OK;
320     default:
321         FIXME("ulStatusCode: %d\n", ulStatusCode);
322         return E_NOTIMPL;
323     }
324 }
325
326 static HRESULT WINAPI XMLView_BindStatusCallback_OnStopBinding(
327         IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
328 {
329     BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
330     TRACE("(%p)->(%x %s)\n", This, hresult, debugstr_w(szError));
331     return IBindStatusCallback_OnStopBinding(This->bsc, hresult, szError);
332 }
333
334 static HRESULT WINAPI XMLView_BindStatusCallback_GetBindInfo(
335         IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
336 {
337     BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
338     TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
339     return IBindStatusCallback_GetBindInfo(This->bsc, grfBINDF, pbindinfo);
340 }
341
342 static inline HRESULT report_data(BindStatusCallback *This)
343 {
344     FORMATETC formatetc = {0, NULL, 1, -1, TYMED_ISTREAM};
345     STGMEDIUM stgmedium;
346     LARGE_INTEGER off;
347     ULARGE_INTEGER size;
348     HRESULT hres;
349
350     off.QuadPart = 0;
351     hres = IStream_Seek(This->stream, off, STREAM_SEEK_CUR, &size);
352     if(FAILED(hres))
353         return hres;
354
355     hres = IStream_Seek(This->stream, off, STREAM_SEEK_SET, NULL);
356     if(FAILED(hres))
357         return hres;
358
359     stgmedium.tymed = TYMED_ISTREAM;
360     stgmedium.u.pstm = This->stream;
361     stgmedium.pUnkForRelease = NULL;
362
363     hres = IBindStatusCallback_OnDataAvailable(This->bsc,
364             BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION,
365             size.u.LowPart, &formatetc, &stgmedium);
366
367     IStream_Release(This->stream);
368     This->stream = NULL;
369     return hres;
370 }
371
372 static inline HRESULT display_error_page(BindStatusCallback *This)
373 {
374     FIXME("Error page not implemented yet.\n");
375     return report_data(This);
376 }
377
378 static inline HRESULT handle_xml_load(BindStatusCallback *This)
379 {
380     static const WCHAR selectW[] = {'p','r','o','c','e','s','s','i','n','g','-',
381         'i','n','s','t','r','u','c','t','i','o','n','(','\'','x','m','l',
382         '-','s','t','y','l','e','s','h','e','e','t','\'',')',0};
383     static const WCHAR hrefW[] = {'h','r','e','f','=',0};
384
385     IXMLDOMDocument3 *xml = NULL, *xsl = NULL;
386     IXMLDOMNode *stylesheet;
387     IBindCtx *pbc;
388     IMoniker *mon;
389     LPOLESTR xsl_url;
390     LARGE_INTEGER off;
391     VARIANT_BOOL succ;
392     VARIANT var;
393     WCHAR *href = NULL, *p;
394     BSTR bstr;
395     HRESULT hres;
396
397     off.QuadPart = 0;
398     hres = IStream_Seek(This->stream, off, STREAM_SEEK_SET, NULL);
399     if(FAILED(hres))
400         return display_error_page(This);
401
402     hres = DOMDocument_create(MSXML_DEFAULT, NULL, (void**)&xml);
403     if(FAILED(hres))
404         return display_error_page(This);
405
406     V_VT(&var) = VT_UNKNOWN;
407     V_UNKNOWN(&var) = (IUnknown*)This->stream;
408     hres = IXMLDOMDocument3_load(xml, var, &succ);
409     if(FAILED(hres) || !succ) {
410         IXMLDOMDocument3_Release(xml);
411         return display_error_page(This);
412     }
413     V_VT(&var) = VT_EMPTY;
414
415     bstr = SysAllocString(selectW);
416     hres = IXMLDOMDocument3_selectSingleNode(xml, bstr, &stylesheet);
417     SysFreeString(bstr);
418     if(hres != S_OK) {
419         IXMLDOMDocument3_Release(xml);
420         return display_error_page(This);
421     }
422
423     hres = IXMLDOMNode_get_nodeValue(stylesheet, &var);
424     IXMLDOMNode_Release(stylesheet);
425     if(SUCCEEDED(hres) && V_VT(&var)!=VT_BSTR) {
426         FIXME("Variant type %d not supported\n", V_VT(&var));
427         VariantClear(&var);
428         hres = E_FAIL;
429     }
430     if(FAILED(hres)) {
431         IXMLDOMDocument3_Release(xml);
432         return display_error_page(This);
433     }
434
435     /* TODO: fix parsing processing instruction value */
436     if((p = strstrW(V_BSTR(&var), hrefW))) {
437         p += sizeof(hrefW)/sizeof(WCHAR)-1;
438         if(*p!='\'' && *p!='\"') p = NULL;
439         else {
440             href = p+1;
441             p = strchrW(href, *p);
442         }
443     }
444     if(p) {
445         *p = 0;
446     } else {
447         VariantClear(&var);
448         IXMLDOMDocument3_Release(xml);
449         return display_error_page(This);
450     }
451
452     hres = CreateURLMonikerEx(This->mon, href, &mon, 0);
453     VariantClear(&var);
454     if(FAILED(hres)) {
455         IXMLDOMDocument3_Release(xml);
456         return display_error_page(This);
457     }
458
459     hres = CreateBindCtx(0, &pbc);
460     if(SUCCEEDED(hres)) {
461         hres = IMoniker_GetDisplayName(mon, pbc, NULL, &xsl_url);
462         IMoniker_Release(mon);
463         IBindCtx_Release(pbc);
464     }
465     if(FAILED(hres)) {
466         IXMLDOMDocument3_Release(xml);
467         return display_error_page(This);
468     }
469
470     V_VT(&var) = VT_BSTR;
471     V_BSTR(&var) = SysAllocString(xsl_url);
472     CoTaskMemFree(xsl_url);
473     if(!V_BSTR(&var)) {
474         IXMLDOMDocument3_Release(xml);
475         return display_error_page(This);
476     }
477
478     hres = DOMDocument_create(MSXML_DEFAULT, NULL, (void**)&xsl);
479     if(FAILED(hres)) {
480         VariantClear(&var);
481         IXMLDOMDocument3_Release(xml);
482         return display_error_page(This);
483     }
484
485     /* TODO: do the binding asynchronously */
486     hres = IXMLDOMDocument3_load(xsl, var, &succ);
487     VariantClear(&var);
488     if(FAILED(hres) || !succ) {
489         IXMLDOMDocument3_Release(xsl);
490         IXMLDOMDocument3_Release(xml);
491         return display_error_page(This);
492     }
493
494     hres = IXMLDOMDocument3_transformNode(xml, (IXMLDOMNode*)xsl, &bstr);
495     IXMLDOMDocument3_Release(xsl);
496     IXMLDOMDocument3_Release(xml);
497     if(FAILED(hres))
498         return display_error_page(This);
499
500     hres = IStream_Seek(This->stream, off, STREAM_SEEK_SET, NULL);
501     if(FAILED(hres)) {
502         SysFreeString(bstr);
503         return display_error_page(This);
504     }
505
506     hres = IStream_Write(This->stream, (BYTE*)bstr,
507             SysStringLen(bstr)*sizeof(WCHAR), NULL);
508     SysFreeString(bstr);
509     if(FAILED(hres))
510         return display_error_page(This);
511
512     return report_data(This);
513 }
514
515 static HRESULT WINAPI XMLView_BindStatusCallback_OnDataAvailable(
516         IBindStatusCallback *iface, DWORD grfBSCF, DWORD dwSize,
517         FORMATETC *pformatetc, STGMEDIUM *pstgmed)
518 {
519     BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
520     char buf[1024];
521     DWORD size;
522     HRESULT hres;
523
524     TRACE("(%p)->(%x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
525
526     if(!This->stream)
527         return E_FAIL;
528
529     do {
530         hres = IStream_Read(pstgmed->u.pstm, buf, sizeof(buf), &size);
531         IStream_Write(This->stream, buf, size, &size);
532     } while(hres==S_OK && size);
533
534     if(FAILED(hres) && hres!=E_PENDING)
535         return hres;
536     if(hres != S_FALSE)
537         return S_OK;
538
539     return handle_xml_load(This);
540 }
541
542 static HRESULT WINAPI XMLView_BindStatusCallback_OnObjectAvailable(
543         IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
544 {
545     BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
546     FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk);
547     return E_NOTIMPL;
548 }
549
550 static IBindStatusCallbackVtbl XMLView_BindStatusCallbackVtbl = {
551     XMLView_BindStatusCallback_QueryInterface,
552     XMLView_BindStatusCallback_AddRef,
553     XMLView_BindStatusCallback_Release,
554     XMLView_BindStatusCallback_OnStartBinding,
555     XMLView_BindStatusCallback_GetPriority,
556     XMLView_BindStatusCallback_OnLowResource,
557     XMLView_BindStatusCallback_OnProgress,
558     XMLView_BindStatusCallback_OnStopBinding,
559     XMLView_BindStatusCallback_GetBindInfo,
560     XMLView_BindStatusCallback_OnDataAvailable,
561     XMLView_BindStatusCallback_OnObjectAvailable
562 };
563
564 static inline HRESULT XMLView_BindStatusCallback_Create(IBindStatusCallback *bsc_html,
565         IMoniker *mon, IStream *stream, IBindStatusCallback **ret)
566 {
567     BindStatusCallback *bsc;
568
569     bsc = heap_alloc_zero(sizeof(BindStatusCallback));
570     if(!bsc)
571         return E_OUTOFMEMORY;
572
573     bsc->IBindStatusCallback_iface.lpVtbl = &XMLView_BindStatusCallbackVtbl;
574     bsc->ref = 1;
575
576     bsc->bsc = bsc_html;
577     IBindStatusCallback_AddRef(bsc_html);
578     bsc->stream = stream;
579     IStream_AddRef(bsc->stream);
580     bsc->mon = mon;
581     IMoniker_AddRef(mon);
582
583     *ret = &bsc->IBindStatusCallback_iface;
584     return S_OK;
585 }
586
587 static inline Moniker* impl_from_IMoniker(IMoniker *iface)
588 {
589     return CONTAINING_RECORD(iface, Moniker, IMoniker_iface);
590 }
591
592 static HRESULT WINAPI XMLView_Moniker_QueryInterface(
593         IMoniker *iface, REFIID riid, void **ppvObject)
594 {
595     Moniker *This = impl_from_IMoniker(iface);
596
597     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
598
599     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IPersist)
600             || IsEqualGUID(riid, &IID_IPersistStream) || IsEqualGUID(riid, &IID_IMoniker)) {
601         *ppvObject = iface;
602         IMoniker_AddRef(iface);
603         return S_OK;
604     }
605
606     *ppvObject = NULL;
607     return E_NOINTERFACE;
608 }
609
610 static ULONG WINAPI XMLView_Moniker_AddRef(IMoniker *iface)
611 {
612     Moniker *This = impl_from_IMoniker(iface);
613     LONG ref = InterlockedIncrement(&This->ref);
614
615     TRACE("(%p)->(%d)\n", This, ref);
616
617     return ref;
618 }
619
620 static ULONG WINAPI XMLView_Moniker_Release(IMoniker *iface)
621 {
622     Moniker *This = impl_from_IMoniker(iface);
623     ULONG ref = InterlockedDecrement(&This->ref);
624
625     TRACE("(%p)->(%d)\n", This, ref);
626
627     if(!ref) {
628         IMoniker_Release(This->mon);
629         heap_free(This);
630     }
631     return ref;
632 }
633
634 static HRESULT WINAPI XMLView_Moniker_GetClassID(IMoniker *iface, CLSID *pClassID)
635 {
636     Moniker *This = impl_from_IMoniker(iface);
637     FIXME("(%p)->(%p)\n", This, pClassID);
638     return E_NOTIMPL;
639 }
640
641 static HRESULT WINAPI XMLView_Moniker_IsDirty(IMoniker *iface)
642 {
643     Moniker *This = impl_from_IMoniker(iface);
644     FIXME("(%p)\n", This);
645     return E_NOTIMPL;
646 }
647
648 static HRESULT WINAPI XMLView_Moniker_Load(IMoniker *iface, IStream *pStm)
649 {
650     Moniker *This = impl_from_IMoniker(iface);
651     FIXME("(%p)->(%p)\n", This, pStm);
652     return E_NOTIMPL;
653 }
654
655 static HRESULT WINAPI XMLView_Moniker_Save(IMoniker *iface,
656         IStream *pStm, BOOL fClearDirty)
657 {
658     Moniker *This = impl_from_IMoniker(iface);
659     FIXME("(%p)->(%p %x)\n", This, pStm, fClearDirty);
660     return E_NOTIMPL;
661 }
662
663 static HRESULT WINAPI XMLView_Moniker_GetSizeMax(
664         IMoniker *iface, ULARGE_INTEGER *pcbSize)
665 {
666     Moniker *This = impl_from_IMoniker(iface);
667     FIXME("(%p)->(%p)\n", This, pcbSize);
668     return E_NOTIMPL;
669 }
670
671 static HRESULT WINAPI XMLView_Moniker_BindToObject(IMoniker *iface, IBindCtx *pbc,
672         IMoniker *pmkToLeft, REFIID riidResult, void **ppvResult)
673 {
674     Moniker *This = impl_from_IMoniker(iface);
675     FIXME("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft,
676             debugstr_guid(riidResult), ppvResult);
677     return E_NOTIMPL;
678 }
679
680 static HRESULT WINAPI XMLView_Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc,
681         IMoniker *pmkToLeft, REFIID riid, void **ppvObj)
682 {
683     Moniker *This = impl_from_IMoniker(iface);
684
685     TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObj);
686
687     if(IsEqualGUID(riid, &IID_IStream)) {
688         if(!This->stream)
689             return E_FAIL;
690
691         *ppvObj = This->stream;
692         This->stream = NULL;
693         return S_ASYNCHRONOUS;
694     }
695
696     return E_NOTIMPL;
697 }
698
699 static HRESULT WINAPI XMLView_Moniker_Reduce(IMoniker *iface, IBindCtx *pbc,
700         DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
701 {
702     Moniker *This = impl_from_IMoniker(iface);
703     FIXME("(%p)->(%p %d %p %p)\n", This, pbc, dwReduceHowFar, ppmkToLeft, ppmkReduced);
704     return E_NOTIMPL;
705 }
706
707 static HRESULT WINAPI XMLView_Moniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
708         BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite)
709 {
710     Moniker *This = impl_from_IMoniker(iface);
711     FIXME("(%p)->(%p %x %p)\n", This, pmkRight, fOnlyIfNotGeneric, ppmkComposite);
712     return E_NOTIMPL;
713 }
714
715 static HRESULT WINAPI XMLView_Moniker_Enum(IMoniker *iface,
716         BOOL fForward, IEnumMoniker **ppenumMoniker)
717 {
718     Moniker *This = impl_from_IMoniker(iface);
719     FIXME("(%p)->(%x %p)\n", This, fForward, ppenumMoniker);
720     return E_NOTIMPL;
721 }
722
723 static HRESULT WINAPI XMLView_Moniker_IsEqual(IMoniker *iface,
724         IMoniker *pmkOtherMoniker)
725 {
726     Moniker *This = impl_from_IMoniker(iface);
727     FIXME("(%p)->(%p)\n", This, pmkOtherMoniker);
728     return E_NOTIMPL;
729 }
730
731 static HRESULT WINAPI XMLView_Moniker_Hash(IMoniker *iface, DWORD *pdwHash)
732 {
733     Moniker *This = impl_from_IMoniker(iface);
734     FIXME("(%p)->(%p)\n", This, pdwHash);
735     return E_NOTIMPL;
736 }
737
738 static HRESULT WINAPI XMLView_Moniker_IsRunning(IMoniker *iface, IBindCtx *pbc,
739         IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning)
740 {
741     Moniker *This = impl_from_IMoniker(iface);
742     FIXME("(%p)->(%p %p %p)\n", This, pbc, pmkToLeft, pmkNewlyRunning);
743     return E_NOTIMPL;
744 }
745
746 static HRESULT WINAPI XMLView_Moniker_GetTimeOfLastChange(IMoniker *iface,
747         IBindCtx *pbc, IMoniker *pmkToLeft, FILETIME *pFileTime)
748 {
749     Moniker *This = impl_from_IMoniker(iface);
750     FIXME("(%p)->(%p %p %p)\n", This, pbc, pmkToLeft, pFileTime);
751     return E_NOTIMPL;
752 }
753
754 static HRESULT WINAPI XMLView_Moniker_Inverse(IMoniker *iface, IMoniker **ppmk)
755 {
756     Moniker *This = impl_from_IMoniker(iface);
757     FIXME("(%p)->(%p)\n", This, ppmk);
758     return E_NOTIMPL;
759 }
760
761 static HRESULT WINAPI XMLView_Moniker_CommonPrefixWith(IMoniker *iface,
762         IMoniker *pmkOther, IMoniker **ppmkPrefix)
763 {
764     Moniker *This = impl_from_IMoniker(iface);
765     FIXME("(%p)->(%p %p)\n", This, pmkOther, ppmkPrefix);
766     return E_NOTIMPL;
767 }
768
769 static HRESULT WINAPI XMLView_Moniker_RelativePathTo(IMoniker *iface,
770         IMoniker *pmkOther, IMoniker **ppmkRelPath)
771 {
772     Moniker *This = impl_from_IMoniker(iface);
773     FIXME("(%p)->(%p %p)\n", This, pmkOther, ppmkRelPath);
774     return E_NOTIMPL;
775 }
776
777 static HRESULT WINAPI XMLView_Moniker_GetDisplayName(IMoniker *iface,
778         IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
779 {
780     Moniker *This = impl_from_IMoniker(iface);
781     TRACE("(%p)->(%p %p %p)\n", This, pbc, pmkToLeft, ppszDisplayName);
782     return IMoniker_GetDisplayName(This->mon, pbc, pmkToLeft, ppszDisplayName);
783 }
784
785 static HRESULT WINAPI XMLView_Moniker_ParseDisplayName(IMoniker *iface,
786         IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR pszDisplayName,
787         ULONG *pchEaten, IMoniker **ppmkOut)
788 {
789     Moniker *This = impl_from_IMoniker(iface);
790     FIXME("(%p)->(%p %p %s %p %p)\n", This, pbc, pmkToLeft,
791             debugstr_w(pszDisplayName), pchEaten, ppmkOut);
792     return E_NOTIMPL;
793 }
794
795 static HRESULT WINAPI XMLView_Moniker_IsSystemMoniker(
796         IMoniker *iface, DWORD *pdwMksys)
797 {
798     Moniker *This = impl_from_IMoniker(iface);
799     FIXME("(%p)->(%p)\n", This, pdwMksys);
800     return E_NOTIMPL;
801 }
802
803 static IMonikerVtbl XMLView_MonikerVtbl = {
804     XMLView_Moniker_QueryInterface,
805     XMLView_Moniker_AddRef,
806     XMLView_Moniker_Release,
807     XMLView_Moniker_GetClassID,
808     XMLView_Moniker_IsDirty,
809     XMLView_Moniker_Load,
810     XMLView_Moniker_Save,
811     XMLView_Moniker_GetSizeMax,
812     XMLView_Moniker_BindToObject,
813     XMLView_Moniker_BindToStorage,
814     XMLView_Moniker_Reduce,
815     XMLView_Moniker_ComposeWith,
816     XMLView_Moniker_Enum,
817     XMLView_Moniker_IsEqual,
818     XMLView_Moniker_Hash,
819     XMLView_Moniker_IsRunning,
820     XMLView_Moniker_GetTimeOfLastChange,
821     XMLView_Moniker_Inverse,
822     XMLView_Moniker_CommonPrefixWith,
823     XMLView_Moniker_RelativePathTo,
824     XMLView_Moniker_GetDisplayName,
825     XMLView_Moniker_ParseDisplayName,
826     XMLView_Moniker_IsSystemMoniker
827 };
828
829 static inline HRESULT XMLView_Moniker_Create(IMoniker *mon,
830         IStream *stream, IMoniker **ret)
831 {
832     Moniker *wrap;
833
834     wrap = heap_alloc_zero(sizeof(Moniker));
835     if(!wrap)
836         return E_OUTOFMEMORY;
837
838     wrap->IMoniker_iface.lpVtbl = &XMLView_MonikerVtbl;
839     wrap->ref = 1;
840
841     wrap->mon = mon;
842     IMoniker_AddRef(mon);
843     wrap->stream = stream;
844     IStream_AddRef(stream);
845
846     *ret = &wrap->IMoniker_iface;
847     return S_OK;
848 }
849
850 static inline XMLView* impl_from_IPersistMoniker(IPersistMoniker *iface)
851 {
852     return CONTAINING_RECORD(iface, XMLView, IPersistMoniker_iface);
853 }
854
855 static HRESULT WINAPI XMLView_PersistMoniker_QueryInterface(
856         IPersistMoniker *iface, REFIID riid, void **ppvObject)
857 {
858     XMLView *This = impl_from_IPersistMoniker(iface);
859
860     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
861
862     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IPersistMoniker))
863         *ppvObject = &This->IPersistMoniker_iface;
864     else if(IsEqualGUID(riid, &IID_IPersistHistory) ||
865             IsEqualGUID(riid, &IID_IPersist))
866         *ppvObject = &This->IPersistHistory_iface;
867     else if(IsEqualGUID(riid, &IID_IOleCommandTarget))
868         *ppvObject = &This->IOleCommandTarget_iface;
869     else if(IsEqualGUID(riid, &IID_IOleObject))
870         *ppvObject = &This->IOleObject_iface;
871     else
872         return IUnknown_QueryInterface(This->html_doc, riid, ppvObject);
873
874     IPersistMoniker_AddRef(&This->IPersistMoniker_iface);
875     return S_OK;
876 }
877
878 static ULONG WINAPI XMLView_PersistMoniker_AddRef(IPersistMoniker *iface)
879 {
880     XMLView *This = impl_from_IPersistMoniker(iface);
881     LONG ref = InterlockedIncrement(&This->ref);
882
883     TRACE("(%p)->(%d)\n", This, ref);
884
885     return ref;
886 }
887
888 static ULONG WINAPI XMLView_PersistMoniker_Release(IPersistMoniker *iface)
889 {
890     XMLView *This = impl_from_IPersistMoniker(iface);
891     ULONG ref = InterlockedDecrement(&This->ref);
892
893     TRACE("(%p)->(%d)\n", This, ref);
894
895     if(!ref) {
896         if(This->mon)
897             IMoniker_Release(This->mon);
898         IUnknown_Release(This->html_doc);
899         heap_free(This);
900     }
901     return ref;
902 }
903
904 static HRESULT WINAPI XMLView_PersistMoniker_GetClassID(
905         IPersistMoniker *iface, CLSID *pClassID)
906 {
907     XMLView *This = impl_from_IPersistMoniker(iface);
908     FIXME("(%p)->(%p)\n", This, pClassID);
909     return E_NOTIMPL;
910 }
911
912 static HRESULT WINAPI XMLView_PersistMoniker_IsDirty(IPersistMoniker *iface)
913 {
914     XMLView *This = impl_from_IPersistMoniker(iface);
915     FIXME("(%p)\n", This);
916     return E_NOTIMPL;
917 }
918
919 static HRESULT WINAPI XMLView_PersistMoniker_Load(IPersistMoniker *iface,
920         BOOL fFullyAvailable, IMoniker *pimkName, LPBC pibc, DWORD grfMode)
921 {
922     static const WCHAR XSLParametersW[] = {'X','S','L','P','a','r','a','m','e','t','e','r','s',0};
923     static const WCHAR XMLBufferStreamW[] = {'X','M','L','B','u','f','f','e','r','S','t','r','e','a','m',0};
924     static const WCHAR DWNBINDINFOW[] = {'_','_','D','W','N','B','I','N','D','I','N','F','O',0};
925     static const WCHAR HTMLLOADOPTIONSW[] = {'_','_','H','T','M','L','L','O','A','D','O','P','T','I','O','N','S',0};
926     static const WCHAR BSCBHolderW[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
927
928     XMLView *This = impl_from_IPersistMoniker(iface);
929     IPersistMoniker *html_persist_mon;
930     IBindStatusCallback *bsc, *bsc_html;
931     IBindCtx *bindctx;
932     IStream *stream;
933     IMoniker *mon;
934     IUnknown *unk;
935     HRESULT hres;
936
937     TRACE("(%p)->(%x %p %p %x)\n", This, fFullyAvailable, pimkName, pibc, grfMode);
938
939     hres = IBindCtx_GetObjectParam(pibc, (LPOLESTR)XSLParametersW, &unk);
940     if(SUCCEEDED(hres)) {
941         FIXME("ignoring XSLParameters\n");
942         IUnknown_Release(unk);
943     }
944     hres = IBindCtx_GetObjectParam(pibc, (LPOLESTR)XMLBufferStreamW, &unk);
945     if(SUCCEEDED(hres)) {
946         FIXME("ignoring XMLBufferStream\n");
947         IUnknown_Release(unk);
948     }
949
950     hres = CreateBindCtx(0, &bindctx);
951     if(FAILED(hres))
952         return hres;
953
954     hres = IBindCtx_GetObjectParam(pibc, (LPOLESTR)DWNBINDINFOW, &unk);
955     if(SUCCEEDED(hres)) {
956         IBindCtx_RegisterObjectParam(bindctx, (LPOLESTR)DWNBINDINFOW, unk);
957         IUnknown_Release(unk);
958     }
959     hres = IBindCtx_GetObjectParam(pibc, (LPOLESTR)HTMLLOADOPTIONSW, &unk);
960     if(SUCCEEDED(hres)) {
961         IBindCtx_RegisterObjectParam(bindctx, (LPOLESTR)HTMLLOADOPTIONSW, unk);
962         IUnknown_Release(unk);
963     }
964     hres = IBindCtx_GetObjectParam(pibc, (LPOLESTR)SZ_HTML_CLIENTSITE_OBJECTPARAM, &unk);
965     if(SUCCEEDED(hres)) {
966         IBindCtx_RegisterObjectParam(bindctx, (LPOLESTR)SZ_HTML_CLIENTSITE_OBJECTPARAM, unk);
967         IUnknown_Release(unk);
968     }
969
970     hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
971     if(FAILED(hres)) {
972         IBindCtx_Release(bindctx);
973         return hres;
974     }
975
976     if(This->mon)
977         IMoniker_Release(This->mon);
978     This->mon = pimkName;
979     IMoniker_AddRef(This->mon);
980
981     hres = XMLView_Moniker_Create(This->mon, stream, &mon);
982     if(FAILED(hres)) {
983         IStream_Release(stream);
984         IBindCtx_Release(bindctx);
985         return hres;
986     }
987
988     hres = IUnknown_QueryInterface(This->html_doc,
989             &IID_IPersistMoniker, (void**)&html_persist_mon);
990     if(FAILED(hres)) {
991         IMoniker_Release(mon);
992         IStream_Release(stream);
993         IBindCtx_Release(bindctx);
994         return hres;
995     }
996
997     hres = IPersistMoniker_Load(html_persist_mon, FALSE, mon, bindctx, 0);
998     IPersistMoniker_Release(html_persist_mon);
999     IMoniker_Release(mon);
1000     if(FAILED(hres)) {
1001         IStream_Release(stream);
1002         IBindCtx_Release(bindctx);
1003         return hres;
1004     }
1005
1006     hres = IBindCtx_GetObjectParam(bindctx, (LPOLESTR)BSCBHolderW, &unk);
1007     IBindCtx_Release(bindctx);
1008     if(FAILED(hres)) {
1009         IStream_Release(stream);
1010         return hres;
1011     }
1012     hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&bsc_html);
1013     IUnknown_Release(unk);
1014     if(FAILED(hres)) {
1015         IStream_Release(stream);
1016         return hres;
1017     }
1018
1019     hres = XMLView_BindStatusCallback_Create(bsc_html, This->mon, stream, &bsc);
1020     IStream_Release(stream);
1021     if(FAILED(hres)) {
1022         IBindStatusCallback_OnStopBinding(bsc_html, hres, NULL);
1023         IBindStatusCallback_Release(bsc_html);
1024         return hres;
1025     }
1026
1027     hres = RegisterBindStatusCallback(pibc, bsc, NULL, 0);
1028     IBindStatusCallback_Release(bsc);
1029     if(FAILED(hres)) {
1030         IBindStatusCallback_OnStopBinding(bsc_html, hres, NULL);
1031         IBindStatusCallback_Release(bsc_html);
1032         return hres;
1033     }
1034
1035     hres = IMoniker_BindToStorage(pimkName, pibc, NULL,
1036             &IID_IStream, (void**)&stream);
1037     if(FAILED(hres)) {
1038         IBindStatusCallback_OnStopBinding(bsc_html, hres, NULL);
1039         IBindStatusCallback_Release(bsc_html);
1040         return hres;
1041     }
1042
1043     if(stream)
1044         IStream_Release(stream);
1045     IBindStatusCallback_Release(bsc_html);
1046     return S_OK;
1047 }
1048
1049 static HRESULT WINAPI XMLView_PersistMoniker_Save(IPersistMoniker *iface,
1050         IMoniker *pimkName, LPBC pbc, BOOL fRemember)
1051 {
1052     XMLView *This = impl_from_IPersistMoniker(iface);
1053     FIXME("(%p)->(%p %p %x)\n", This, pimkName, pbc, fRemember);
1054     return E_NOTIMPL;
1055 }
1056
1057 static HRESULT WINAPI XMLView_PersistMoniker_SaveCompleted(
1058         IPersistMoniker *iface, IMoniker *pimkName, LPBC pibc)
1059 {
1060     XMLView *This = impl_from_IPersistMoniker(iface);
1061     FIXME("(%p)->(%p %p)\n", This, pimkName, pibc);
1062     return E_NOTIMPL;
1063 }
1064
1065 static HRESULT WINAPI XMLView_PersistMoniker_GetCurMoniker(
1066         IPersistMoniker *iface, IMoniker **ppimkName)
1067 {
1068     XMLView *This = impl_from_IPersistMoniker(iface);
1069     FIXME("(%p)->(%p)\n", This, ppimkName);
1070     return E_NOTIMPL;
1071 }
1072
1073 static IPersistMonikerVtbl XMLView_PersistMonikerVtbl = {
1074     XMLView_PersistMoniker_QueryInterface,
1075     XMLView_PersistMoniker_AddRef,
1076     XMLView_PersistMoniker_Release,
1077     XMLView_PersistMoniker_GetClassID,
1078     XMLView_PersistMoniker_IsDirty,
1079     XMLView_PersistMoniker_Load,
1080     XMLView_PersistMoniker_Save,
1081     XMLView_PersistMoniker_SaveCompleted,
1082     XMLView_PersistMoniker_GetCurMoniker
1083 };
1084
1085 static inline XMLView* impl_from_IPersistHistory(IPersistHistory *iface)
1086 {
1087     return CONTAINING_RECORD(iface, XMLView, IPersistHistory_iface);
1088 }
1089
1090 static HRESULT WINAPI XMLView_PersistHistory_QueryInterface(
1091         IPersistHistory *iface, REFIID riid, void **ppvObject)
1092 {
1093     XMLView *This = impl_from_IPersistHistory(iface);
1094     return IPersistMoniker_QueryInterface(&This->IPersistMoniker_iface, riid, ppvObject);
1095 }
1096
1097 static ULONG WINAPI XMLView_PersistHistory_AddRef(IPersistHistory *iface)
1098 {
1099     XMLView *This = impl_from_IPersistHistory(iface);
1100     return IPersistMoniker_AddRef(&This->IPersistMoniker_iface);
1101 }
1102
1103 static ULONG WINAPI XMLView_PersistHistory_Release(IPersistHistory *iface)
1104 {
1105     XMLView *This = impl_from_IPersistHistory(iface);
1106     return IPersistMoniker_Release(&This->IPersistMoniker_iface);
1107 }
1108
1109 static HRESULT WINAPI XMLView_PersistHistory_GetClassID(
1110         IPersistHistory *iface, CLSID *pClassID)
1111 {
1112     XMLView *This = impl_from_IPersistHistory(iface);
1113     FIXME("(%p)->(%p)\n", This, pClassID);
1114     return E_NOTIMPL;
1115 }
1116
1117 static HRESULT WINAPI XMLView_PersistHistory_LoadHistory(
1118         IPersistHistory *iface, IStream *pStream, IBindCtx *pbc)
1119 {
1120     XMLView *This = impl_from_IPersistHistory(iface);
1121     FIXME("(%p)->(%p %p)\n", This, pStream, pbc);
1122     return E_NOTIMPL;
1123 }
1124
1125 static HRESULT WINAPI XMLView_PersistHistory_SaveHistory(
1126         IPersistHistory *iface, IStream *pStream)
1127 {
1128     XMLView *This = impl_from_IPersistHistory(iface);
1129     FIXME("(%p)->(%p)\n", This, pStream);
1130     return E_NOTIMPL;
1131 }
1132
1133 static HRESULT WINAPI XMLView_PersistHistory_SetPositionCookie(
1134         IPersistHistory *iface, DWORD dwPositioncookie)
1135 {
1136     XMLView *This = impl_from_IPersistHistory(iface);
1137     FIXME("(%p)->(%d)\n", This, dwPositioncookie);
1138     return E_NOTIMPL;
1139 }
1140
1141 static HRESULT WINAPI XMLView_PersistHistory_GetPositionCookie(
1142         IPersistHistory *iface, DWORD *pdwPositioncookie)
1143 {
1144     XMLView *This = impl_from_IPersistHistory(iface);
1145     FIXME("(%p)->(%p)\n", This, pdwPositioncookie);
1146     return E_NOTIMPL;
1147 }
1148
1149 static IPersistHistoryVtbl XMLView_PersistHistoryVtbl = {
1150     XMLView_PersistHistory_QueryInterface,
1151     XMLView_PersistHistory_AddRef,
1152     XMLView_PersistHistory_Release,
1153     XMLView_PersistHistory_GetClassID,
1154     XMLView_PersistHistory_LoadHistory,
1155     XMLView_PersistHistory_SaveHistory,
1156     XMLView_PersistHistory_SetPositionCookie,
1157     XMLView_PersistHistory_GetPositionCookie
1158 };
1159
1160 static inline XMLView* impl_from_IOleCommandTarget(IOleCommandTarget *iface)
1161 {
1162     return CONTAINING_RECORD(iface, XMLView, IOleCommandTarget_iface);
1163 }
1164
1165 static HRESULT WINAPI XMLView_OleCommandTarget_QueryInterface(
1166         IOleCommandTarget *iface, REFIID riid, void **ppvObject)
1167 {
1168     XMLView *This = impl_from_IOleCommandTarget(iface);
1169     return IPersistMoniker_QueryInterface(&This->IPersistMoniker_iface, riid, ppvObject);
1170 }
1171
1172 static ULONG WINAPI XMLView_OleCommandTarget_AddRef(IOleCommandTarget *iface)
1173 {
1174     XMLView *This = impl_from_IOleCommandTarget(iface);
1175     return IPersistMoniker_AddRef(&This->IPersistMoniker_iface);
1176 }
1177
1178 static ULONG WINAPI XMLView_OleCommandTarget_Release(IOleCommandTarget *iface)
1179 {
1180     XMLView *This = impl_from_IOleCommandTarget(iface);
1181     return IPersistMoniker_Release(&This->IPersistMoniker_iface);
1182 }
1183
1184 static HRESULT WINAPI XMLView_OleCommandTarget_QueryStatus(IOleCommandTarget *iface,
1185         const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
1186 {
1187     XMLView *This = impl_from_IOleCommandTarget(iface);
1188     FIXME("(%p)->(%p %x %p %p)\n", This, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1189     return E_NOTIMPL;
1190 }
1191
1192 static HRESULT WINAPI XMLView_OleCommandTarget_Exec(IOleCommandTarget *iface,
1193         const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt,
1194         VARIANT *pvaIn, VARIANT *pvaOut)
1195 {
1196     XMLView *This = impl_from_IOleCommandTarget(iface);
1197     FIXME("(%p)->(%p %d %x %p %p)\n", This, pguidCmdGroup,
1198             nCmdID, nCmdexecopt, pvaIn, pvaOut);
1199     return E_NOTIMPL;
1200 }
1201
1202 static IOleCommandTargetVtbl XMLView_OleCommandTargetVtbl = {
1203     XMLView_OleCommandTarget_QueryInterface,
1204     XMLView_OleCommandTarget_AddRef,
1205     XMLView_OleCommandTarget_Release,
1206     XMLView_OleCommandTarget_QueryStatus,
1207     XMLView_OleCommandTarget_Exec
1208 };
1209
1210 static inline XMLView* impl_from_IOleObject(IOleObject *iface)
1211 {
1212     return CONTAINING_RECORD(iface, XMLView, IOleObject_iface);
1213 }
1214
1215 static HRESULT WINAPI XMLView_OleObject_QueryInterface(
1216         IOleObject *iface, REFIID riid, void **ppvObject)
1217 {
1218     XMLView *This = impl_from_IOleObject(iface);
1219     return IPersistMoniker_QueryInterface(&This->IPersistMoniker_iface, riid, ppvObject);
1220 }
1221
1222 static ULONG WINAPI XMLView_OleObject_AddRef(IOleObject *iface)
1223 {
1224     XMLView *This = impl_from_IOleObject(iface);
1225     return IPersistMoniker_AddRef(&This->IPersistMoniker_iface);
1226 }
1227
1228 static ULONG WINAPI XMLView_OleObject_Release(IOleObject *iface)
1229 {
1230     XMLView *This = impl_from_IOleObject(iface);
1231     return IPersistMoniker_Release(&This->IPersistMoniker_iface);
1232 }
1233
1234 static HRESULT WINAPI XMLView_OleObject_SetClientSite(
1235         IOleObject *iface, IOleClientSite *pClientSite)
1236 {
1237     XMLView *This = impl_from_IOleObject(iface);
1238     FIXME("(%p)->(%p)\n", This, pClientSite);
1239     return E_NOTIMPL;
1240 }
1241
1242 static HRESULT WINAPI XMLView_OleObject_GetClientSite(
1243         IOleObject *iface, IOleClientSite **ppClientSite)
1244 {
1245     XMLView *This = impl_from_IOleObject(iface);
1246     FIXME("(%p)->(%p)\n", This, ppClientSite);
1247     return E_NOTIMPL;
1248 }
1249
1250 static HRESULT WINAPI XMLView_OleObject_SetHostNames(IOleObject *iface,
1251         LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
1252 {
1253     XMLView *This = impl_from_IOleObject(iface);
1254     FIXME("(%p)->(%s %s)\n", This, debugstr_w(szContainerApp), debugstr_w(szContainerObj));
1255     return E_NOTIMPL;
1256 }
1257
1258 static HRESULT WINAPI XMLView_OleObject_Close(IOleObject *iface, DWORD dwSaveOption)
1259 {
1260     XMLView *This = impl_from_IOleObject(iface);
1261     FIXME("(%p)->(%x)\n", This, dwSaveOption);
1262     return E_NOTIMPL;
1263 }
1264
1265 static HRESULT WINAPI XMLView_OleObject_SetMoniker(IOleObject *iface,
1266         DWORD dwWhichMoniker, IMoniker *pmk)
1267 {
1268     XMLView *This = impl_from_IOleObject(iface);
1269     FIXME("(%p)->(%x %p)\n", This, dwWhichMoniker, pmk);
1270     return E_NOTIMPL;
1271 }
1272
1273 static HRESULT WINAPI XMLView_OleObject_GetMoniker(IOleObject *iface,
1274         DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
1275 {
1276     XMLView *This = impl_from_IOleObject(iface);
1277     FIXME("(%p)->(%x %x %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
1278     return E_NOTIMPL;
1279 }
1280
1281 static HRESULT WINAPI XMLView_OleObject_InitFromData(IOleObject *iface,
1282         IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved)
1283 {
1284     XMLView *This = impl_from_IOleObject(iface);
1285     FIXME("(%p)->(%p %x %x)\n", This, pDataObject, fCreation, dwReserved);
1286     return E_NOTIMPL;
1287 }
1288
1289 static HRESULT WINAPI XMLView_OleObject_GetClipboardData(IOleObject *iface,
1290         DWORD dwReserved, IDataObject **ppDataObject)
1291 {
1292     XMLView *This = impl_from_IOleObject(iface);
1293     FIXME("(%p)->(%x %p)\n", This, dwReserved, ppDataObject);
1294     return E_NOTIMPL;
1295 }
1296
1297 static HRESULT WINAPI XMLView_OleObject_DoVerb(IOleObject *iface,
1298         LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite,
1299         LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
1300 {
1301     XMLView *This = impl_from_IOleObject(iface);
1302     FIXME("(%p)->(%d %p %p %d %p %p)\n", This, iVerb, lpmsg,
1303             pActiveSite, lindex, hwndParent, lprcPosRect);
1304     return E_NOTIMPL;
1305 }
1306
1307 static HRESULT WINAPI XMLView_OleObject_EnumVerbs(
1308         IOleObject *iface, IEnumOLEVERB **ppEnumOleVerb)
1309 {
1310     XMLView *This = impl_from_IOleObject(iface);
1311     FIXME("(%p)->{%p)\n", This, ppEnumOleVerb);
1312     return E_NOTIMPL;
1313 }
1314
1315 static HRESULT WINAPI XMLView_OleObject_Update(IOleObject *iface)
1316 {
1317     XMLView *This = impl_from_IOleObject(iface);
1318     FIXME("(%p)\n", This);
1319     return E_NOTIMPL;
1320 }
1321
1322 static HRESULT WINAPI XMLView_OleObject_IsUpToDate(IOleObject *iface)
1323 {
1324     XMLView *This = impl_from_IOleObject(iface);
1325     FIXME("(%p)\n", This);
1326     return E_NOTIMPL;
1327 }
1328
1329 static HRESULT WINAPI XMLView_OleObject_GetUserClassID(IOleObject *iface, CLSID *pClsid)
1330 {
1331     XMLView *This = impl_from_IOleObject(iface);
1332     FIXME("(%p)->(%p)\n", This, pClsid);
1333     return E_NOTIMPL;
1334 }
1335
1336 static HRESULT WINAPI XMLView_OleObject_GetUserType(IOleObject *iface,
1337         DWORD dwFormOfType, LPOLESTR *pszUserType)
1338 {
1339     XMLView *This = impl_from_IOleObject(iface);
1340     FIXME("(%p)->(%x %p)\n", This, dwFormOfType, pszUserType);
1341     return E_NOTIMPL;
1342 }
1343
1344 static HRESULT WINAPI XMLView_OleObject_SetExtent(IOleObject *iface,
1345         DWORD dwDrawAspect, SIZEL *psizel)
1346 {
1347     XMLView *This = impl_from_IOleObject(iface);
1348     FIXME("(%p)->(%x %p)\n", This, dwDrawAspect, psizel);
1349     return E_NOTIMPL;
1350 }
1351
1352 static HRESULT WINAPI XMLView_OleObject_GetExtent(IOleObject *iface,
1353         DWORD dwDrawAspect, SIZEL *psizel)
1354 {
1355     XMLView *This = impl_from_IOleObject(iface);
1356     FIXME("(%p)->(%x %p)\n", This, dwDrawAspect, psizel);
1357     return E_NOTIMPL;
1358 }
1359
1360 static HRESULT WINAPI XMLView_OleObject_Advise(IOleObject *iface,
1361         IAdviseSink *pAdvSink, DWORD *pdwConnection)
1362 {
1363     XMLView *This = impl_from_IOleObject(iface);
1364     FIXME("(%p)->(%p %p)\n", This, pAdvSink, pdwConnection);
1365     return E_NOTIMPL;
1366 }
1367
1368 static HRESULT WINAPI XMLView_OleObject_Unadvise(
1369         IOleObject *iface, DWORD dwConnection)
1370 {
1371     XMLView *This = impl_from_IOleObject(iface);
1372     FIXME("(%p)->(%d)\n", This, dwConnection);
1373     return E_NOTIMPL;
1374 }
1375
1376 static HRESULT WINAPI XMLView_OleObject_EnumAdvise(
1377         IOleObject *iface, IEnumSTATDATA **ppenumAdvise)
1378 {
1379     XMLView *This = impl_from_IOleObject(iface);
1380     FIXME("(%p)->(%p)\n", This, ppenumAdvise);
1381     return E_NOTIMPL;
1382 }
1383
1384 static HRESULT WINAPI XMLView_OleObject_GetMiscStatus(
1385         IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus)
1386 {
1387     XMLView *This = impl_from_IOleObject(iface);
1388     FIXME("(%p)->(%d %p)\n", This, dwAspect, pdwStatus);
1389     return E_NOTIMPL;
1390 }
1391
1392 static HRESULT WINAPI XMLView_OleObject_SetColorScheme(
1393         IOleObject *iface, LOGPALETTE *pLogpal)
1394 {
1395     XMLView *This = impl_from_IOleObject(iface);
1396     FIXME("(%p)->(%p)\n", This, pLogpal);
1397     return E_NOTIMPL;
1398 }
1399
1400 static IOleObjectVtbl XMLView_OleObjectVtbl = {
1401     XMLView_OleObject_QueryInterface,
1402     XMLView_OleObject_AddRef,
1403     XMLView_OleObject_Release,
1404     XMLView_OleObject_SetClientSite,
1405     XMLView_OleObject_GetClientSite,
1406     XMLView_OleObject_SetHostNames,
1407     XMLView_OleObject_Close,
1408     XMLView_OleObject_SetMoniker,
1409     XMLView_OleObject_GetMoniker,
1410     XMLView_OleObject_InitFromData,
1411     XMLView_OleObject_GetClipboardData,
1412     XMLView_OleObject_DoVerb,
1413     XMLView_OleObject_EnumVerbs,
1414     XMLView_OleObject_Update,
1415     XMLView_OleObject_IsUpToDate,
1416     XMLView_OleObject_GetUserClassID,
1417     XMLView_OleObject_GetUserType,
1418     XMLView_OleObject_SetExtent,
1419     XMLView_OleObject_GetExtent,
1420     XMLView_OleObject_Advise,
1421     XMLView_OleObject_Unadvise,
1422     XMLView_OleObject_EnumAdvise,
1423     XMLView_OleObject_GetMiscStatus,
1424     XMLView_OleObject_SetColorScheme
1425 };
1426
1427 HRESULT XMLView_create(IUnknown *outer, void **ppObj)
1428 {
1429     XMLView *This;
1430     HRESULT hres;
1431
1432     TRACE("(%p %p)\n", outer, ppObj);
1433
1434     if(outer)
1435         return E_FAIL;
1436
1437     This = heap_alloc_zero(sizeof(*This));
1438     if(!This)
1439         return E_OUTOFMEMORY;
1440
1441     This->IPersistMoniker_iface.lpVtbl = &XMLView_PersistMonikerVtbl;
1442     This->IPersistHistory_iface.lpVtbl = &XMLView_PersistHistoryVtbl;
1443     This->IOleCommandTarget_iface.lpVtbl = &XMLView_OleCommandTargetVtbl;
1444     This->IOleObject_iface.lpVtbl = &XMLView_OleObjectVtbl;
1445     This->ref = 1;
1446
1447     hres = CoCreateInstance(&CLSID_HTMLDocument, (IUnknown*)&This->IPersistMoniker_iface,
1448             CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&This->html_doc);
1449     if(FAILED(hres)) {
1450         heap_free(This);
1451         return hres;
1452     }
1453
1454     *ppObj = &This->IPersistMoniker_iface;
1455     return S_OK;
1456 }
1457
1458 #else
1459
1460 HRESULT XMLView_create(IUnknown *outer, void **ppObj)
1461 {
1462     MESSAGE("This program tried to use a XMLView object, but\n"
1463             "libxml2 support was not present at compile time.\n");
1464     return E_NOTIMPL;
1465 }
1466
1467 #endif /* HAVE_LIBXML2 */