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 if(type_msxml_to_libxml(V_I4(&vType)) == -1)
459 node = xmlNewNode(NULL, empty);
460 node->type = type_msxml_to_libxml(V_I4(&vType));
462 /* FIXME: create xmlNodePtr based on vType and var1 */
463 return XMLElement_create((IUnknown *)iface, node, (LPVOID *)ppElem);
466 static const struct IXMLDocumentVtbl xmldoc_vtbl =
468 xmldoc_QueryInterface,
471 xmldoc_GetTypeInfoCount,
473 xmldoc_GetIDsOfNames,
477 xmldoc_put_fileModifiedDate,
478 xmldoc_get_fileUpdatedDate,
482 xmldoc_get_readyState,
491 /************************************************************************
492 * xmldoc implementation of IPersistStreamInit.
494 static HRESULT WINAPI xmldoc_IPersistStreamInit_QueryInterface(
495 IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj)
497 xmldoc *this = impl_from_IPersistStreamInit(iface);
498 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
501 static ULONG WINAPI xmldoc_IPersistStreamInit_AddRef(
502 IPersistStreamInit *iface)
504 xmldoc *this = impl_from_IPersistStreamInit(iface);
505 return IXMLDocument_AddRef((IXMLDocument *)this);
508 static ULONG WINAPI xmldoc_IPersistStreamInit_Release(
509 IPersistStreamInit *iface)
511 xmldoc *this = impl_from_IPersistStreamInit(iface);
512 return IXMLDocument_Release((IXMLDocument *)this);
515 static HRESULT WINAPI xmldoc_IPersistStreamInit_GetClassID(
516 IPersistStreamInit *iface, CLSID *classid)
518 FIXME("(%p,%p): stub!\n", iface, classid);
522 static HRESULT WINAPI xmldoc_IPersistStreamInit_IsDirty(
523 IPersistStreamInit *iface)
525 FIXME("(%p): stub!\n", iface);
529 xmlDocPtr parse_xml(char *ptr, int len)
531 #ifdef HAVE_XMLREADMEMORY
532 return xmlReadMemory(ptr, len, NULL, NULL,
533 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS);
535 return xmlParseMemory(ptr, len);
539 static HRESULT WINAPI xmldoc_IPersistStreamInit_Load(
540 IPersistStreamInit *iface, LPSTREAM pStm)
542 xmldoc *This = impl_from_IPersistStreamInit(iface);
546 DWORD read, written, len;
550 TRACE("(%p, %p)\n", iface, pStm);
555 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
561 IStream_Read(pStm, buf, sizeof(buf), &read);
562 hr = IStream_Write(This->stream, buf, read, &written);
563 } while(SUCCEEDED(hr) && written != 0 && read != 0);
567 ERR("Failed to copy stream\n");
571 hr = GetHGlobalFromStream(This->stream, &hglobal);
575 len = GlobalSize(hglobal);
576 ptr = GlobalLock(hglobal);
578 This->xmldoc = parse_xml(ptr, len);
579 GlobalUnlock(hglobal);
583 ERR("Failed to parse xml\n");
587 xmlnode = xmlDocGetRootElement(This->xmldoc);
588 return XMLElement_create((IUnknown *)This, xmlnode, (LPVOID *)&This->root);
591 static HRESULT WINAPI xmldoc_IPersistStreamInit_Save(
592 IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty)
594 FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);
598 static HRESULT WINAPI xmldoc_IPersistStreamInit_GetSizeMax(
599 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
601 FIXME("(%p, %p): stub!\n", iface, pcbSize);
605 static HRESULT WINAPI xmldoc_IPersistStreamInit_InitNew(
606 IPersistStreamInit *iface)
608 FIXME("(%p): stub!\n", iface);
612 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
614 xmldoc_IPersistStreamInit_QueryInterface,
615 xmldoc_IPersistStreamInit_AddRef,
616 xmldoc_IPersistStreamInit_Release,
617 xmldoc_IPersistStreamInit_GetClassID,
618 xmldoc_IPersistStreamInit_IsDirty,
619 xmldoc_IPersistStreamInit_Load,
620 xmldoc_IPersistStreamInit_Save,
621 xmldoc_IPersistStreamInit_GetSizeMax,
622 xmldoc_IPersistStreamInit_InitNew
625 HRESULT XMLDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
629 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
631 doc = HeapAlloc(GetProcessHeap(), 0, sizeof (*doc));
633 return E_OUTOFMEMORY;
635 doc->lpVtbl = &xmldoc_vtbl;
636 doc->lpvtblIPersistStreamInit = &xmldoc_IPersistStreamInit_VTable;
643 *ppObj = &doc->lpVtbl;
645 TRACE("returning iface %p\n", *ppObj);
651 HRESULT XMLDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
653 MESSAGE("This program tried to use an XMLDocument object, but\n"
654 "libxml2 support was not present at compile time.\n");