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
)
129 xmldoc
*This
= impl_from_IXMLDocument(iface
);
131 TRACE("(%p)->(%p)\n", This
, pctinfo
);
138 static HRESULT WINAPI
xmldoc_GetTypeInfo(IXMLDocument
*iface
, UINT iTInfo
,
139 LCID lcid
, ITypeInfo
** ppTInfo
)
141 xmldoc
*This
= impl_from_IXMLDocument(iface
);
144 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
146 hr
= get_typeinfo(IXMLDocument_tid
, ppTInfo
);
151 static HRESULT WINAPI
xmldoc_GetIDsOfNames(IXMLDocument
*iface
, REFIID riid
,
152 LPOLESTR
* rgszNames
, UINT cNames
,
153 LCID lcid
, DISPID
* rgDispId
)
155 xmldoc
*This
= impl_from_IXMLDocument(iface
);
159 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
162 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
165 hr
= get_typeinfo(IXMLDocument_tid
, &typeinfo
);
168 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
169 ITypeInfo_Release(typeinfo
);
175 static HRESULT WINAPI
xmldoc_Invoke(IXMLDocument
*iface
, DISPID dispIdMember
,
176 REFIID riid
, LCID lcid
, WORD wFlags
,
177 DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
,
178 EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
180 xmldoc
*This
= impl_from_IXMLDocument(iface
);
184 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
185 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
187 hr
= get_typeinfo(IXMLDocument_tid
, &typeinfo
);
190 hr
= ITypeInfo_Invoke(typeinfo
, &(This
->lpVtbl
), dispIdMember
, wFlags
, pDispParams
,
191 pVarResult
, pExcepInfo
, puArgErr
);
192 ITypeInfo_Release(typeinfo
);
198 static HRESULT WINAPI
xmldoc_get_root(IXMLDocument
*iface
, IXMLElement
**p
)
200 xmldoc
*This
= impl_from_IXMLDocument(iface
);
202 TRACE("(%p, %p)\n", iface
, p
);
214 static HRESULT WINAPI
xmldoc_get_fileSize(IXMLDocument
*iface
, BSTR
*p
)
216 FIXME("(%p, %p): stub\n", iface
, p
);
220 static HRESULT WINAPI
xmldoc_put_fileModifiedDate(IXMLDocument
*iface
, BSTR
*p
)
222 FIXME("(%p, %p): stub\n", iface
, p
);
226 static HRESULT WINAPI
xmldoc_get_fileUpdatedDate(IXMLDocument
*iface
, BSTR
*p
)
228 FIXME("(%p, %p): stub\n", iface
, p
);
232 static HRESULT WINAPI
xmldoc_get_URL(IXMLDocument
*iface
, BSTR
*p
)
234 FIXME("(%p, %p): stub\n", iface
, p
);
239 const struct IBindStatusCallbackVtbl
*lpVtbl
;
242 static HRESULT WINAPI
bsc_QueryInterface(
243 IBindStatusCallback
*iface
,
247 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
248 IsEqualGUID(riid
, &IID_IBindStatusCallback
))
250 IBindStatusCallback_AddRef( iface
);
255 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
256 return E_NOINTERFACE
;
259 static ULONG WINAPI
bsc_AddRef(
260 IBindStatusCallback
*iface
)
265 static ULONG WINAPI
bsc_Release(
266 IBindStatusCallback
*iface
)
271 static HRESULT WINAPI
bsc_OnStartBinding(
272 IBindStatusCallback
* iface
,
279 static HRESULT WINAPI
bsc_GetPriority(
280 IBindStatusCallback
* iface
,
286 static HRESULT WINAPI
bsc_OnLowResource(
287 IBindStatusCallback
* iface
,
293 static HRESULT WINAPI
bsc_OnProgress(
294 IBindStatusCallback
* iface
,
298 LPCWSTR szStatusText
)
303 static HRESULT WINAPI
bsc_OnStopBinding(
304 IBindStatusCallback
* iface
,
311 static HRESULT WINAPI
bsc_GetBindInfo(
312 IBindStatusCallback
* iface
,
316 *grfBINDF
= BINDF_RESYNCHRONIZE
;
321 static HRESULT WINAPI
bsc_OnDataAvailable(
322 IBindStatusCallback
* iface
,
325 FORMATETC
* pformatetc
,
331 static HRESULT WINAPI
bsc_OnObjectAvailable(
332 IBindStatusCallback
* iface
,
339 static const struct IBindStatusCallbackVtbl bsc_vtbl
=
351 bsc_OnObjectAvailable
354 static bsc xmldoc_bsc
= { &bsc_vtbl
};
356 static HRESULT WINAPI
xmldoc_put_URL(IXMLDocument
*iface
, BSTR p
)
358 WCHAR url
[INTERNET_MAX_URL_LENGTH
];
362 IPersistStreamInit
*persist
;
365 TRACE("(%p, %s)\n", iface
, debugstr_w(p
));
372 WCHAR fullpath
[MAX_PATH
];
373 DWORD needed
= sizeof(url
) / sizeof(WCHAR
);
375 if (!PathSearchAndQualifyW(p
, fullpath
, sizeof(fullpath
) / sizeof(WCHAR
)))
377 ERR("can't find path\n");
381 if (FAILED(UrlCreateFromPathW(fullpath
, url
, &needed
, 0)))
383 ERR("can't create url from path\n");
390 hr
= CreateURLMoniker(NULL
, p
, &moniker
);
394 CreateAsyncBindCtx(0, (IBindStatusCallback
*)&xmldoc_bsc
, 0, &bctx
);
396 hr
= IMoniker_BindToStorage(moniker
, bctx
, NULL
, &IID_IStream
, (LPVOID
*)&stream
);
397 IBindCtx_Release(bctx
);
398 IMoniker_Release(moniker
);
402 hr
= IXMLDocument_QueryInterface(iface
, &IID_IPersistStreamInit
, (LPVOID
*)&persist
);
405 IStream_Release(stream
);
409 hr
= IPersistStreamInit_Load(persist
, stream
);
410 IPersistStreamInit_Release(persist
);
411 IStream_Release(stream
);
416 static HRESULT WINAPI
xmldoc_get_mimeType(IXMLDocument
*iface
, BSTR
*p
)
418 FIXME("(%p, %p): stub\n", iface
, p
);
422 static HRESULT WINAPI
xmldoc_get_readyState(IXMLDocument
*iface
, long *p
)
424 FIXME("(%p, %p): stub\n", iface
, p
);
428 static HRESULT WINAPI
xmldoc_get_charset(IXMLDocument
*iface
, BSTR
*p
)
430 FIXME("(%p, %p): stub\n", iface
, p
);
434 static HRESULT WINAPI
xmldoc_put_charset(IXMLDocument
*iface
, BSTR p
)
436 FIXME("(%p, %p): stub\n", iface
, p
);
440 static HRESULT WINAPI
xmldoc_get_version(IXMLDocument
*iface
, BSTR
*p
)
442 FIXME("(%p, %p): stub\n", iface
, p
);
446 static HRESULT WINAPI
xmldoc_get_doctype(IXMLDocument
*iface
, BSTR
*p
)
448 FIXME("(%p, %p): stub\n", iface
, p
);
452 static HRESULT WINAPI
xmldoc_get_dtdURl(IXMLDocument
*iface
, BSTR
*p
)
454 FIXME("(%p, %p): stub\n", iface
, p
);
458 static xmlElementType
type_msxml_to_libxml(long type
)
462 case XMLELEMTYPE_ELEMENT
:
463 return XML_ELEMENT_NODE
;
464 case XMLELEMTYPE_TEXT
:
465 return XML_TEXT_NODE
;
466 case XMLELEMTYPE_COMMENT
:
467 return XML_COMMENT_NODE
;
468 case XMLELEMTYPE_DOCUMENT
:
469 return XML_DOCUMENT_NODE
;
470 case XMLELEMTYPE_DTD
:
478 return -1; /* FIXME: what is OTHER in msxml? */
481 static HRESULT WINAPI
xmldoc_createElement(IXMLDocument
*iface
, VARIANT vType
,
482 VARIANT var1
, IXMLElement
**ppElem
)
485 static const xmlChar empty
[] = "\0";
487 TRACE("(%p, %p)\n", iface
, ppElem
);
494 if (V_VT(&vType
) != VT_I4
)
497 if(type_msxml_to_libxml(V_I4(&vType
)) == -1)
500 node
= xmlNewNode(NULL
, empty
);
501 node
->type
= type_msxml_to_libxml(V_I4(&vType
));
503 /* FIXME: create xmlNodePtr based on vType and var1 */
504 return XMLElement_create((IUnknown
*)iface
, node
, (LPVOID
*)ppElem
);
507 static const struct IXMLDocumentVtbl xmldoc_vtbl
=
509 xmldoc_QueryInterface
,
512 xmldoc_GetTypeInfoCount
,
514 xmldoc_GetIDsOfNames
,
518 xmldoc_put_fileModifiedDate
,
519 xmldoc_get_fileUpdatedDate
,
523 xmldoc_get_readyState
,
532 /************************************************************************
533 * xmldoc implementation of IPersistStreamInit.
535 static HRESULT WINAPI
xmldoc_IPersistStreamInit_QueryInterface(
536 IPersistStreamInit
*iface
, REFIID riid
, LPVOID
*ppvObj
)
538 xmldoc
*this = impl_from_IPersistStreamInit(iface
);
539 return IXMLDocument_QueryInterface((IXMLDocument
*)this, riid
, ppvObj
);
542 static ULONG WINAPI
xmldoc_IPersistStreamInit_AddRef(
543 IPersistStreamInit
*iface
)
545 xmldoc
*this = impl_from_IPersistStreamInit(iface
);
546 return IXMLDocument_AddRef((IXMLDocument
*)this);
549 static ULONG WINAPI
xmldoc_IPersistStreamInit_Release(
550 IPersistStreamInit
*iface
)
552 xmldoc
*this = impl_from_IPersistStreamInit(iface
);
553 return IXMLDocument_Release((IXMLDocument
*)this);
556 static HRESULT WINAPI
xmldoc_IPersistStreamInit_GetClassID(
557 IPersistStreamInit
*iface
, CLSID
*classid
)
559 FIXME("(%p,%p): stub!\n", iface
, classid
);
563 static HRESULT WINAPI
xmldoc_IPersistStreamInit_IsDirty(
564 IPersistStreamInit
*iface
)
566 FIXME("(%p): stub!\n", iface
);
570 xmlDocPtr
parse_xml(char *ptr
, int len
)
572 #ifdef HAVE_XMLREADMEMORY
573 return xmlReadMemory(ptr
, len
, NULL
, NULL
,
574 XML_PARSE_NOERROR
| XML_PARSE_NOWARNING
| XML_PARSE_NOBLANKS
);
576 return xmlParseMemory(ptr
, len
);
580 static HRESULT WINAPI
xmldoc_IPersistStreamInit_Load(
581 IPersistStreamInit
*iface
, LPSTREAM pStm
)
583 xmldoc
*This
= impl_from_IPersistStreamInit(iface
);
587 DWORD read
, written
, len
;
591 TRACE("(%p, %p)\n", iface
, pStm
);
596 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &This
->stream
);
602 IStream_Read(pStm
, buf
, sizeof(buf
), &read
);
603 hr
= IStream_Write(This
->stream
, buf
, read
, &written
);
604 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
608 ERR("Failed to copy stream\n");
612 hr
= GetHGlobalFromStream(This
->stream
, &hglobal
);
616 len
= GlobalSize(hglobal
);
617 ptr
= GlobalLock(hglobal
);
619 This
->xmldoc
= parse_xml(ptr
, len
);
620 GlobalUnlock(hglobal
);
624 ERR("Failed to parse xml\n");
628 xmlnode
= xmlDocGetRootElement(This
->xmldoc
);
629 return XMLElement_create((IUnknown
*)This
, xmlnode
, (LPVOID
*)&This
->root
);
632 static HRESULT WINAPI
xmldoc_IPersistStreamInit_Save(
633 IPersistStreamInit
*iface
, LPSTREAM pStm
, BOOL fClearDirty
)
635 FIXME("(%p, %p, %d): stub!\n", iface
, pStm
, fClearDirty
);
639 static HRESULT WINAPI
xmldoc_IPersistStreamInit_GetSizeMax(
640 IPersistStreamInit
*iface
, ULARGE_INTEGER
*pcbSize
)
642 FIXME("(%p, %p): stub!\n", iface
, pcbSize
);
646 static HRESULT WINAPI
xmldoc_IPersistStreamInit_InitNew(
647 IPersistStreamInit
*iface
)
649 FIXME("(%p): stub!\n", iface
);
653 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable
=
655 xmldoc_IPersistStreamInit_QueryInterface
,
656 xmldoc_IPersistStreamInit_AddRef
,
657 xmldoc_IPersistStreamInit_Release
,
658 xmldoc_IPersistStreamInit_GetClassID
,
659 xmldoc_IPersistStreamInit_IsDirty
,
660 xmldoc_IPersistStreamInit_Load
,
661 xmldoc_IPersistStreamInit_Save
,
662 xmldoc_IPersistStreamInit_GetSizeMax
,
663 xmldoc_IPersistStreamInit_InitNew
666 HRESULT
XMLDocument_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
670 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
672 doc
= HeapAlloc(GetProcessHeap(), 0, sizeof (*doc
));
674 return E_OUTOFMEMORY
;
676 doc
->lpVtbl
= &xmldoc_vtbl
;
677 doc
->lpvtblIPersistStreamInit
= &xmldoc_IPersistStreamInit_VTable
;
684 *ppObj
= &doc
->lpVtbl
;
686 TRACE("returning iface %p\n", *ppObj
);
692 HRESULT
XMLDocument_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
694 MESSAGE("This program tried to use an XMLDocument object, but\n"
695 "libxml2 support was not present at compile time.\n");