2 * XML Document implementation
4 * Copyright 2007 James Hawkins
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
36 #include "wine/debug.h"
38 #include "msxml_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
44 /* FIXME: IXMLDocument needs to implement
49 typedef struct _xmldoc
51 const IXMLDocumentVtbl
*lpVtbl
;
52 const IPersistStreamInitVtbl
*lpvtblIPersistStreamInit
;
64 static inline xmldoc
*impl_from_IXMLDocument(IXMLDocument
*iface
)
66 return (xmldoc
*)((char*)iface
- FIELD_OFFSET(xmldoc
, lpVtbl
));
69 static inline xmldoc
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
71 return (xmldoc
*)((char*)iface
- FIELD_OFFSET(xmldoc
, lpvtblIPersistStreamInit
));
74 static HRESULT WINAPI
xmldoc_QueryInterface(IXMLDocument
*iface
, REFIID riid
, void** ppvObject
)
76 xmldoc
*This
= impl_from_IXMLDocument(iface
);
78 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
80 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
81 IsEqualGUID(riid
, &IID_IXMLDocument
) ||
82 IsEqualGUID(riid
, &IID_IXMLDOMDocument
))
86 else if (IsEqualGUID(&IID_IPersistStreamInit
, riid
) ||
87 IsEqualGUID(&IID_IPersistStream
, riid
))
89 *ppvObject
= (IPersistStreamInit
*)&(This
->lpvtblIPersistStreamInit
);
93 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
97 IXMLDocument_AddRef(iface
);
102 static ULONG WINAPI
xmldoc_AddRef(IXMLDocument
*iface
)
104 xmldoc
*This
= impl_from_IXMLDocument(iface
);
106 return InterlockedIncrement(&This
->ref
);
109 static ULONG WINAPI
xmldoc_Release(IXMLDocument
*iface
)
111 xmldoc
*This
= impl_from_IXMLDocument(iface
);
116 ref
= InterlockedDecrement(&This
->ref
);
119 xmlFreeDoc(This
->xmldoc
);
120 if (This
->stream
) IStream_Release(This
->stream
);
121 HeapFree(GetProcessHeap(), 0, This
);
127 static HRESULT WINAPI
xmldoc_GetTypeInfoCount(IXMLDocument
*iface
, UINT
* pctinfo
)
133 static HRESULT WINAPI
xmldoc_GetTypeInfo(IXMLDocument
*iface
, UINT iTInfo
,
134 LCID lcid
, ITypeInfo
** ppTInfo
)
140 static HRESULT WINAPI
xmldoc_GetIDsOfNames(IXMLDocument
*iface
, REFIID riid
,
141 LPOLESTR
* rgszNames
, UINT cNames
,
142 LCID lcid
, DISPID
* rgDispId
)
148 static HRESULT WINAPI
xmldoc_Invoke(IXMLDocument
*iface
, DISPID dispIdMember
,
149 REFIID riid
, LCID lcid
, WORD wFlags
,
150 DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
,
151 EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
157 static HRESULT WINAPI
xmldoc_get_root(IXMLDocument
*iface
, IXMLElement
**p
)
159 xmldoc
*This
= impl_from_IXMLDocument(iface
);
161 TRACE("(%p, %p)\n", iface
, p
);
173 static HRESULT WINAPI
xmldoc_get_fileSize(IXMLDocument
*iface
, BSTR
*p
)
175 FIXME("(%p, %p): stub\n", iface
, p
);
179 static HRESULT WINAPI
xmldoc_put_fileModifiedDate(IXMLDocument
*iface
, BSTR
*p
)
181 FIXME("(%p, %p): stub\n", iface
, p
);
185 static HRESULT WINAPI
xmldoc_get_fileUpdatedDate(IXMLDocument
*iface
, BSTR
*p
)
187 FIXME("(%p, %p): stub\n", iface
, p
);
191 static HRESULT WINAPI
xmldoc_get_URL(IXMLDocument
*iface
, BSTR
*p
)
193 FIXME("(%p, %p): stub\n", iface
, p
);
198 const struct IBindStatusCallbackVtbl
*lpVtbl
;
201 static HRESULT WINAPI
bsc_QueryInterface(
202 IBindStatusCallback
*iface
,
206 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
207 IsEqualGUID(riid
, &IID_IBindStatusCallback
))
209 IBindStatusCallback_AddRef( iface
);
214 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
215 return E_NOINTERFACE
;
218 static ULONG WINAPI
bsc_AddRef(
219 IBindStatusCallback
*iface
)
224 static ULONG WINAPI
bsc_Release(
225 IBindStatusCallback
*iface
)
230 static HRESULT WINAPI
bsc_OnStartBinding(
231 IBindStatusCallback
* iface
,
238 static HRESULT WINAPI
bsc_GetPriority(
239 IBindStatusCallback
* iface
,
245 static HRESULT WINAPI
bsc_OnLowResource(
246 IBindStatusCallback
* iface
,
252 static HRESULT WINAPI
bsc_OnProgress(
253 IBindStatusCallback
* iface
,
257 LPCWSTR szStatusText
)
262 static HRESULT WINAPI
bsc_OnStopBinding(
263 IBindStatusCallback
* iface
,
270 static HRESULT WINAPI
bsc_GetBindInfo(
271 IBindStatusCallback
* iface
,
275 *grfBINDF
= BINDF_RESYNCHRONIZE
;
280 static HRESULT WINAPI
bsc_OnDataAvailable(
281 IBindStatusCallback
* iface
,
284 FORMATETC
* pformatetc
,
290 static HRESULT WINAPI
bsc_OnObjectAvailable(
291 IBindStatusCallback
* iface
,
298 static const struct IBindStatusCallbackVtbl bsc_vtbl
=
310 bsc_OnObjectAvailable
313 static bsc xmldoc_bsc
= { &bsc_vtbl
};
315 static HRESULT WINAPI
xmldoc_put_URL(IXMLDocument
*iface
, BSTR p
)
317 WCHAR url
[INTERNET_MAX_URL_LENGTH
];
321 IPersistStreamInit
*persist
;
324 TRACE("(%p, %s)\n", iface
, debugstr_w(p
));
331 WCHAR fullpath
[MAX_PATH
];
332 DWORD needed
= sizeof(url
) / sizeof(WCHAR
);
334 if (!PathSearchAndQualifyW(p
, fullpath
, sizeof(fullpath
) / sizeof(WCHAR
)))
336 ERR("can't find path\n");
340 if (FAILED(UrlCreateFromPathW(fullpath
, url
, &needed
, 0)))
342 ERR("can't create url from path\n");
349 hr
= CreateURLMoniker(NULL
, p
, &moniker
);
353 CreateAsyncBindCtx(0, (IBindStatusCallback
*)&xmldoc_bsc
, 0, &bctx
);
355 hr
= IMoniker_BindToStorage(moniker
, bctx
, NULL
, &IID_IStream
, (LPVOID
*)&stream
);
356 IBindCtx_Release(bctx
);
357 IMoniker_Release(moniker
);
361 hr
= IXMLDocument_QueryInterface(iface
, &IID_IPersistStreamInit
, (LPVOID
*)&persist
);
364 IStream_Release(stream
);
368 hr
= IPersistStreamInit_Load(persist
, stream
);
369 IPersistStreamInit_Release(persist
);
370 IStream_Release(stream
);
375 static HRESULT WINAPI
xmldoc_get_mimeType(IXMLDocument
*iface
, BSTR
*p
)
377 FIXME("(%p, %p): stub\n", iface
, p
);
381 static HRESULT WINAPI
xmldoc_get_readyState(IXMLDocument
*iface
, long *p
)
383 FIXME("(%p, %p): stub\n", iface
, p
);
387 static HRESULT WINAPI
xmldoc_get_charset(IXMLDocument
*iface
, BSTR
*p
)
389 FIXME("(%p, %p): stub\n", iface
, p
);
393 static HRESULT WINAPI
xmldoc_put_charset(IXMLDocument
*iface
, BSTR p
)
395 FIXME("(%p, %p): stub\n", iface
, p
);
399 static HRESULT WINAPI
xmldoc_get_version(IXMLDocument
*iface
, BSTR
*p
)
401 FIXME("(%p, %p): stub\n", iface
, p
);
405 static HRESULT WINAPI
xmldoc_get_doctype(IXMLDocument
*iface
, BSTR
*p
)
407 FIXME("(%p, %p): stub\n", iface
, p
);
411 static HRESULT WINAPI
xmldoc_get_dtdURl(IXMLDocument
*iface
, BSTR
*p
)
413 FIXME("(%p, %p): stub\n", iface
, p
);
417 static xmlElementType
type_msxml_to_libxml(long type
)
421 case XMLELEMTYPE_ELEMENT
:
422 return XML_ELEMENT_NODE
;
423 case XMLELEMTYPE_TEXT
:
424 return XML_TEXT_NODE
;
425 case XMLELEMTYPE_COMMENT
:
426 return XML_COMMENT_NODE
;
427 case XMLELEMTYPE_DOCUMENT
:
428 return XML_DOCUMENT_NODE
;
429 case XMLELEMTYPE_DTD
:
437 return -1; /* FIXME: what is OTHER in msxml? */
440 static HRESULT WINAPI
xmldoc_createElement(IXMLDocument
*iface
, VARIANT vType
,
441 VARIANT var1
, IXMLElement
**ppElem
)
444 static const xmlChar empty
[] = "\0";
446 TRACE("(%p, %p)\n", iface
, ppElem
);
453 if (V_VT(&vType
) != VT_I4
)
456 node
= xmlNewNode(NULL
, empty
);
457 node
->type
= type_msxml_to_libxml(V_I4(&vType
));
459 /* FIXME: create xmlNodePtr based on vType and var1 */
460 return XMLElement_create((IUnknown
*)iface
, node
, (LPVOID
*)ppElem
);
463 static const struct IXMLDocumentVtbl xmldoc_vtbl
=
465 xmldoc_QueryInterface
,
468 xmldoc_GetTypeInfoCount
,
470 xmldoc_GetIDsOfNames
,
474 xmldoc_put_fileModifiedDate
,
475 xmldoc_get_fileUpdatedDate
,
479 xmldoc_get_readyState
,
488 /************************************************************************
489 * xmldoc implementation of IPersistStreamInit.
491 static HRESULT WINAPI
xmldoc_IPersistStreamInit_QueryInterface(
492 IPersistStreamInit
*iface
, REFIID riid
, LPVOID
*ppvObj
)
494 xmldoc
*this = impl_from_IPersistStreamInit(iface
);
495 return IXMLDocument_QueryInterface((IXMLDocument
*)this, riid
, ppvObj
);
498 static ULONG WINAPI
xmldoc_IPersistStreamInit_AddRef(
499 IPersistStreamInit
*iface
)
501 xmldoc
*this = impl_from_IPersistStreamInit(iface
);
502 return IXMLDocument_AddRef((IXMLDocument
*)this);
505 static ULONG WINAPI
xmldoc_IPersistStreamInit_Release(
506 IPersistStreamInit
*iface
)
508 xmldoc
*this = impl_from_IPersistStreamInit(iface
);
509 return IXMLDocument_Release((IXMLDocument
*)this);
512 static HRESULT WINAPI
xmldoc_IPersistStreamInit_GetClassID(
513 IPersistStreamInit
*iface
, CLSID
*classid
)
515 FIXME("(%p,%p): stub!\n", iface
, classid
);
519 static HRESULT WINAPI
xmldoc_IPersistStreamInit_IsDirty(
520 IPersistStreamInit
*iface
)
522 FIXME("(%p): stub!\n", iface
);
526 xmlDocPtr
parse_xml(char *ptr
, int len
)
528 #ifdef HAVE_XMLREADMEMORY
529 return xmlReadMemory(ptr
, len
, NULL
, NULL
,
530 XML_PARSE_NOERROR
| XML_PARSE_NOWARNING
| XML_PARSE_NOBLANKS
);
532 return xmlParseMemory(ptr
, len
);
536 static HRESULT WINAPI
xmldoc_IPersistStreamInit_Load(
537 IPersistStreamInit
*iface
, LPSTREAM pStm
)
539 xmldoc
*This
= impl_from_IPersistStreamInit(iface
);
543 DWORD read
, written
, len
;
547 TRACE("(%p, %p)\n", iface
, pStm
);
552 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &This
->stream
);
558 IStream_Read(pStm
, buf
, sizeof(buf
), &read
);
559 hr
= IStream_Write(This
->stream
, buf
, read
, &written
);
560 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
564 ERR("Failed to copy stream\n");
568 hr
= GetHGlobalFromStream(This
->stream
, &hglobal
);
572 len
= GlobalSize(hglobal
);
573 ptr
= GlobalLock(hglobal
);
575 This
->xmldoc
= parse_xml(ptr
, len
);
576 GlobalUnlock(hglobal
);
580 ERR("Failed to parse xml\n");
584 xmlnode
= xmlDocGetRootElement(This
->xmldoc
);
585 return XMLElement_create((IUnknown
*)This
, xmlnode
, (LPVOID
*)&This
->root
);
588 static HRESULT WINAPI
xmldoc_IPersistStreamInit_Save(
589 IPersistStreamInit
*iface
, LPSTREAM pStm
, BOOL fClearDirty
)
591 FIXME("(%p, %p, %d): stub!\n", iface
, pStm
, fClearDirty
);
595 static HRESULT WINAPI
xmldoc_IPersistStreamInit_GetSizeMax(
596 IPersistStreamInit
*iface
, ULARGE_INTEGER
*pcbSize
)
598 FIXME("(%p, %p): stub!\n", iface
, pcbSize
);
602 static HRESULT WINAPI
xmldoc_IPersistStreamInit_InitNew(
603 IPersistStreamInit
*iface
)
605 FIXME("(%p): stub!\n", iface
);
609 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable
=
611 xmldoc_IPersistStreamInit_QueryInterface
,
612 xmldoc_IPersistStreamInit_AddRef
,
613 xmldoc_IPersistStreamInit_Release
,
614 xmldoc_IPersistStreamInit_GetClassID
,
615 xmldoc_IPersistStreamInit_IsDirty
,
616 xmldoc_IPersistStreamInit_Load
,
617 xmldoc_IPersistStreamInit_Save
,
618 xmldoc_IPersistStreamInit_GetSizeMax
,
619 xmldoc_IPersistStreamInit_InitNew
622 HRESULT
XMLDocument_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
626 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
628 doc
= HeapAlloc(GetProcessHeap(), 0, sizeof (*doc
));
630 return E_OUTOFMEMORY
;
632 doc
->lpVtbl
= &xmldoc_vtbl
;
633 doc
->lpvtblIPersistStreamInit
= &xmldoc_IPersistStreamInit_VTable
;
640 *ppObj
= &doc
->lpVtbl
;
642 TRACE("returning iface %p\n", *ppObj
);
648 HRESULT
XMLDocument_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
650 MESSAGE("This program tried to use an XMLDocument object, but\n"
651 "libxml2 support was not present at compile time.\n");