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