msxml3 [2/4]: Add initial implementation of IXMLDocument [try2]
James Hawkins
truiken at gmail.com
Thu May 24 13:13:06 CDT 2007
Hi,
This one also checks for libxml2.
Changelog:
* Add initial implementation of IXMLDocument.
dlls/msxml3/Makefile.in | 1
dlls/msxml3/factory.c | 10 +
dlls/msxml3/msxml_private.h | 2
dlls/msxml3/xmldoc.c | 656 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 668 insertions(+), 1 deletions(-)
--
James Hawkins
-------------- next part --------------
diff --git a/dlls/msxml3/Makefile.in b/dlls/msxml3/Makefile.in
index 870034d..ad5d9bc 100644
--- a/dlls/msxml3/Makefile.in
+++ b/dlls/msxml3/Makefile.in
@@ -25,6 +25,7 @@ C_SRCS = \
schema.c \
text.c \
uuid.c \
+ xmldoc.c \
xmlelem.c
RC_SRCS = version.rc
diff --git a/dlls/msxml3/factory.c b/dlls/msxml3/factory.c
index ebc342f..334906f 100644
--- a/dlls/msxml3/factory.c
+++ b/dlls/msxml3/factory.c
@@ -134,6 +134,7 @@ static const struct IClassFactoryVtbl xm
static xmlcf domdoccf = { &xmlcf_vtbl, DOMDocument_create };
static xmlcf schemacf = { &xmlcf_vtbl, SchemaCache_create };
+static xmlcf xmldoccf = { &xmlcf_vtbl, XMLDocument_create };
/******************************************************************
* DllGetClassObject (MSXML3.@)
@@ -147,11 +148,18 @@ HRESULT WINAPI DllGetClassObject( REFCLS
if( IsEqualCLSID( rclsid, &CLSID_DOMDocument ) || /* Version indep. v 2.x */
IsEqualCLSID( rclsid, &CLSID_DOMDocument2 ) || /* Version indep. v 3.0 */
IsEqualCLSID( rclsid, &CLSID_DOMDocument30 ) ) /* Version dep. v 3.0 */
+ {
cf = (IClassFactory*) &domdoccf.lpVtbl;
-
+ }
else if( IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache ) ||
IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache30 ) )
+ {
cf = (IClassFactory*) &schemacf.lpVtbl;
+ }
+ else if( IsEqualCLSID( rclsid, &CLSID_XMLDocument ) )
+ {
+ cf = (IClassFactory*) &xmldoccf.lpVtbl;
+ }
if ( !cf )
return CLASS_E_CLASSNOTAVAILABLE;
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index 74f061a..370141a 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -63,7 +63,9 @@ extern IXMLDOMParseError *create_parseEr
LONG line, LONG linepos, LONG filepos );
extern HRESULT DOMDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj );
extern HRESULT SchemaCache_create( IUnknown *pUnkOuter, LPVOID *ppObj );
+extern HRESULT XMLDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj );
extern HRESULT XMLElement_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj );
extern HRESULT XMLElementCollection_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj );
#endif /* __MSXML_PRIVATE__ */
+
diff --git a/dlls/msxml3/xmldoc.c b/dlls/msxml3/xmldoc.c
new file mode 100644
index 0000000..a5604a3
--- /dev/null
+++ b/dlls/msxml3/xmldoc.c
@@ -0,0 +1,656 @@
+/*
+ * XML Document implementation
+ *
+ * Copyright 2007 James Hawkins
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+
+#include "config.h"
+
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "ole2.h"
+#include "msxml2.h"
+#include "wininet.h"
+#include "winreg.h"
+#include "shlwapi.h"
+#include "ocidl.h"
+
+#include "wine/debug.h"
+
+#include "msxml_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msxml);
+
+#ifdef HAVE_LIBXML2
+
+/* FIXME: IXMLDocument needs to implement
+ * - IXMLError
+ * - IPersistMoniker
+ * - IPersistStream
+ */
+
+typedef struct _xmldoc
+{
+ const IXMLDocumentVtbl *lpVtbl;
+ const IPersistStreamInitVtbl *lpvtblIPersistStreamInit;
+ LONG ref;
+ HRESULT error;
+
+ /* IXMLDocument */
+ IXMLElement *root;
+ xmlDocPtr xmldoc;
+
+ /* IPersistStream */
+ IStream *stream;
+} xmldoc;
+
+static inline xmldoc *impl_from_IXMLDocument(IXMLDocument *iface)
+{
+ return (xmldoc *)((char*)iface - FIELD_OFFSET(xmldoc, lpVtbl));
+}
+
+static inline xmldoc *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
+{
+ return (xmldoc *)((char*)iface - FIELD_OFFSET(xmldoc, lpvtblIPersistStreamInit));
+}
+
+static HRESULT WINAPI xmldoc_QueryInterface(IXMLDocument *iface, REFIID riid, void** ppvObject)
+{
+ xmldoc *This = impl_from_IXMLDocument(iface);
+
+ TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
+
+ if (IsEqualGUID(riid, &IID_IUnknown) ||
+ IsEqualGUID(riid, &IID_IXMLDocument))
+ {
+ *ppvObject = iface;
+ }
+ else if (IsEqualGUID(&IID_IPersistStreamInit, riid))
+ {
+ *ppvObject = (IPersistStreamInit *)&(This->lpvtblIPersistStreamInit);
+ }
+ else
+ {
+ FIXME("interface %s not implemented\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+ }
+
+ IXMLDocument_AddRef(iface);
+
+ return S_OK;
+}
+
+static ULONG WINAPI xmldoc_AddRef(IXMLDocument *iface)
+{
+ xmldoc *This = impl_from_IXMLDocument(iface);
+ TRACE("%p\n", This);
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI xmldoc_Release(IXMLDocument *iface)
+{
+ xmldoc *This = impl_from_IXMLDocument(iface);
+ LONG ref;
+
+ TRACE("%p\n", This);
+
+ ref = InterlockedDecrement(&This->ref);
+ if (ref == 0)
+ {
+ xmlFreeDoc(This->xmldoc);
+ if (This->stream) IStream_Release(This->stream);
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI xmldoc_GetTypeInfoCount(IXMLDocument *iface, UINT* pctinfo)
+{
+ FIXME("\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_GetTypeInfo(IXMLDocument *iface, UINT iTInfo,
+ LCID lcid, ITypeInfo** ppTInfo)
+{
+ FIXME("\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_GetIDsOfNames(IXMLDocument *iface, REFIID riid,
+ LPOLESTR* rgszNames, UINT cNames,
+ LCID lcid, DISPID* rgDispId)
+{
+ FIXME("\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_Invoke(IXMLDocument *iface, DISPID dispIdMember,
+ REFIID riid, LCID lcid, WORD wFlags,
+ DISPPARAMS* pDispParams, VARIANT* pVarResult,
+ EXCEPINFO* pExcepInfo, UINT* puArgErr)
+{
+ FIXME("\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_get_root(IXMLDocument *iface, IXMLElement **p)
+{
+ xmldoc *This = impl_from_IXMLDocument(iface);
+
+ TRACE("(%p, %p)\n", iface, p);
+
+ if (!p)
+ return E_INVALIDARG;
+
+ *p = This->root;
+ if (!*p)
+ return E_FAIL;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI xmldoc_get_fileSize(IXMLDocument *iface, BSTR *p)
+{
+ FIXME("(%p, %p): stub\n", iface, p);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_put_fileModifiedDate(IXMLDocument *iface, BSTR *p)
+{
+ FIXME("(%p, %p): stub\n", iface, p);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_get_fileUpdatedDate(IXMLDocument *iface, BSTR *p)
+{
+ FIXME("(%p, %p): stub\n", iface, p);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_get_URL(IXMLDocument *iface, BSTR *p)
+{
+ FIXME("(%p, %p): stub\n", iface, p);
+ return E_NOTIMPL;
+}
+
+typedef struct {
+ const struct IBindStatusCallbackVtbl *lpVtbl;
+} bsc;
+
+static HRESULT WINAPI bsc_QueryInterface(
+ IBindStatusCallback *iface,
+ REFIID riid,
+ LPVOID *ppobj )
+{
+ if (IsEqualGUID(riid, &IID_IUnknown) ||
+ IsEqualGUID(riid, &IID_IBindStatusCallback))
+ {
+ IBindStatusCallback_AddRef( iface );
+ *ppobj = iface;
+ return S_OK;
+ }
+
+ FIXME("interface %s not implemented\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI bsc_AddRef(
+ IBindStatusCallback *iface )
+{
+ return 2;
+}
+
+static ULONG WINAPI bsc_Release(
+ IBindStatusCallback *iface )
+{
+ return 1;
+}
+
+static HRESULT WINAPI bsc_OnStartBinding(
+ IBindStatusCallback* iface,
+ DWORD dwReserved,
+ IBinding* pib)
+{
+ return S_OK;
+}
+
+static HRESULT WINAPI bsc_GetPriority(
+ IBindStatusCallback* iface,
+ LONG* pnPriority)
+{
+ return S_OK;
+}
+
+static HRESULT WINAPI bsc_OnLowResource(
+ IBindStatusCallback* iface,
+ DWORD reserved)
+{
+ return S_OK;
+}
+
+static HRESULT WINAPI bsc_OnProgress(
+ IBindStatusCallback* iface,
+ ULONG ulProgress,
+ ULONG ulProgressMax,
+ ULONG ulStatusCode,
+ LPCWSTR szStatusText)
+{
+ return S_OK;
+}
+
+static HRESULT WINAPI bsc_OnStopBinding(
+ IBindStatusCallback* iface,
+ HRESULT hresult,
+ LPCWSTR szError)
+{
+ return S_OK;
+}
+
+static HRESULT WINAPI bsc_GetBindInfo(
+ IBindStatusCallback* iface,
+ DWORD* grfBINDF,
+ BINDINFO* pbindinfo)
+{
+ *grfBINDF = BINDF_RESYNCHRONIZE;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI bsc_OnDataAvailable(
+ IBindStatusCallback* iface,
+ DWORD grfBSCF,
+ DWORD dwSize,
+ FORMATETC* pformatetc,
+ STGMEDIUM* pstgmed)
+{
+ return S_OK;
+}
+
+static HRESULT WINAPI bsc_OnObjectAvailable(
+ IBindStatusCallback* iface,
+ REFIID riid,
+ IUnknown* punk)
+{
+ return S_OK;
+}
+
+static const struct IBindStatusCallbackVtbl bsc_vtbl =
+{
+ bsc_QueryInterface,
+ bsc_AddRef,
+ bsc_Release,
+ bsc_OnStartBinding,
+ bsc_GetPriority,
+ bsc_OnLowResource,
+ bsc_OnProgress,
+ bsc_OnStopBinding,
+ bsc_GetBindInfo,
+ bsc_OnDataAvailable,
+ bsc_OnObjectAvailable
+};
+
+static bsc xmldoc_bsc = { &bsc_vtbl };
+
+static HRESULT WINAPI xmldoc_put_URL(IXMLDocument *iface, BSTR p)
+{
+ WCHAR url[INTERNET_MAX_URL_LENGTH];
+ IStream *stream;
+ IBindCtx *bctx;
+ IMoniker *moniker;
+ IPersistStreamInit *persist;
+ HRESULT hr;
+
+ TRACE("(%p, %s)\n", iface, debugstr_w(p));
+
+ if (!p)
+ return E_INVALIDARG;
+
+ if (!PathIsURLW(p))
+ {
+ WCHAR fullpath[MAX_PATH];
+ DWORD needed = sizeof(url) / sizeof(WCHAR);
+
+ if (!PathSearchAndQualifyW(p, fullpath, sizeof(fullpath) / sizeof(WCHAR)))
+ {
+ ERR("can't find path\n");
+ return E_FAIL;
+ }
+
+ if (FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
+ {
+ ERR("can't create url from path\n");
+ return E_FAIL;
+ }
+
+ p = url;
+ }
+
+ hr = CreateURLMoniker(NULL, p, &moniker);
+ if (FAILED(hr))
+ return hr;
+
+ CreateAsyncBindCtx(0, (IBindStatusCallback *)&xmldoc_bsc, 0, &bctx);
+
+ hr = IMoniker_BindToStorage(moniker, bctx, NULL, &IID_IStream, (LPVOID *)&stream);
+ IBindCtx_Release(bctx);
+ IMoniker_Release(moniker);
+ if (FAILED(hr))
+ return hr;
+
+ hr = IXMLDocument_QueryInterface(iface, &IID_IPersistStreamInit, (LPVOID *)&persist);
+ if (FAILED(hr))
+ {
+ IStream_Release(stream);
+ return hr;
+ }
+
+ hr = IPersistStreamInit_Load(persist, stream);
+ IPersistStreamInit_Release(persist);
+ IStream_Release(stream);
+
+ return hr;
+}
+
+static HRESULT WINAPI xmldoc_get_mimeType(IXMLDocument *iface, BSTR *p)
+{
+ FIXME("(%p, %p): stub\n", iface, p);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_get_readyState(IXMLDocument *iface, long *p)
+{
+ FIXME("(%p, %p): stub\n", iface, p);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_get_charset(IXMLDocument *iface, BSTR *p)
+{
+ FIXME("(%p, %p): stub\n", iface, p);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_put_charset(IXMLDocument *iface, BSTR p)
+{
+ FIXME("(%p, %p): stub\n", iface, p);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_get_version(IXMLDocument *iface, BSTR *p)
+{
+ FIXME("(%p, %p): stub\n", iface, p);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_get_doctype(IXMLDocument *iface, BSTR *p)
+{
+ FIXME("(%p, %p): stub\n", iface, p);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_get_dtdURl(IXMLDocument *iface, BSTR *p)
+{
+ FIXME("(%p, %p): stub\n", iface, p);
+ return E_NOTIMPL;
+}
+
+static xmlElementType type_msxml_to_libxml(long type)
+{
+ switch (type)
+ {
+ case XMLELEMTYPE_ELEMENT:
+ return XML_ELEMENT_NODE;
+ case XMLELEMTYPE_TEXT:
+ return XML_TEXT_NODE;
+ case XMLELEMTYPE_COMMENT:
+ return XML_COMMENT_NODE;
+ case XMLELEMTYPE_DOCUMENT:
+ return XML_DOCUMENT_NODE;
+ case XMLELEMTYPE_DTD:
+ return XML_DTD_NODE;
+ case XMLELEMTYPE_PI:
+ return XML_PI_NODE;
+ default:
+ break;
+ }
+
+ return -1; /* FIXME: what is OTHER in msxml? */
+}
+
+static HRESULT WINAPI xmldoc_createElement(IXMLDocument *iface, VARIANT vType,
+ VARIANT var1, IXMLElement **ppElem)
+{
+ xmlNodePtr node;
+ static const xmlChar empty[] = "\0";
+
+ TRACE("(%p, %p)\n", iface, ppElem);
+
+ if (!ppElem)
+ return E_INVALIDARG;
+
+ *ppElem = NULL;
+
+ node = xmlNewNode(NULL, empty);
+
+ if (V_VT(&vType) != VT_I4)
+ return E_INVALIDARG;
+
+ node->type = type_msxml_to_libxml(V_I4(&vType));
+
+ /* FIXME: create xmlNodePtr based on vType and var1 */
+ return XMLElement_create((IUnknown *)iface, node, (LPVOID *)ppElem);
+}
+
+static const struct IXMLDocumentVtbl xmldoc_vtbl =
+{
+ xmldoc_QueryInterface,
+ xmldoc_AddRef,
+ xmldoc_Release,
+ xmldoc_GetTypeInfoCount,
+ xmldoc_GetTypeInfo,
+ xmldoc_GetIDsOfNames,
+ xmldoc_Invoke,
+ xmldoc_get_root,
+ xmldoc_get_fileSize,
+ xmldoc_put_fileModifiedDate,
+ xmldoc_get_fileUpdatedDate,
+ xmldoc_get_URL,
+ xmldoc_put_URL,
+ xmldoc_get_mimeType,
+ xmldoc_get_readyState,
+ xmldoc_get_charset,
+ xmldoc_put_charset,
+ xmldoc_get_version,
+ xmldoc_get_doctype,
+ xmldoc_get_dtdURl,
+ xmldoc_createElement
+};
+
+/************************************************************************
+ * xmldoc implementation of IPersistStreamInit.
+ */
+static HRESULT WINAPI xmldoc_IPersistStreamInit_QueryInterface(
+ IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj)
+{
+ xmldoc *this = impl_from_IPersistStreamInit(iface);
+ return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
+}
+
+static ULONG WINAPI xmldoc_IPersistStreamInit_AddRef(
+ IPersistStreamInit *iface)
+{
+ xmldoc *this = impl_from_IPersistStreamInit(iface);
+ return IXMLDocument_AddRef((IXMLDocument *)this);
+}
+
+static ULONG WINAPI xmldoc_IPersistStreamInit_Release(
+ IPersistStreamInit *iface)
+{
+ xmldoc *this = impl_from_IPersistStreamInit(iface);
+ return IXMLDocument_Release((IXMLDocument *)this);
+}
+
+static HRESULT WINAPI xmldoc_IPersistStreamInit_GetClassID(
+ IPersistStreamInit *iface, CLSID *classid)
+{
+ FIXME("(%p,%p): stub!\n", iface, classid);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_IPersistStreamInit_IsDirty(
+ IPersistStreamInit *iface)
+{
+ FIXME("(%p): stub!\n", iface);
+ return E_NOTIMPL;
+}
+
+static xmlDocPtr parse_xml(char *ptr, int len)
+{
+#ifdef HAVE_XMLREADMEMORY
+ return xmlReadMemory(ptr, len, NULL, NULL,
+ XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS);
+#else
+ return xmlParseMemory(ptr, len);
+#endif
+}
+
+static HRESULT WINAPI xmldoc_IPersistStreamInit_Load(
+ IPersistStreamInit *iface, LPSTREAM pStm)
+{
+ xmldoc *This = impl_from_IPersistStreamInit(iface);
+ xmlNodePtr xmlnode;
+ HRESULT hr;
+ HGLOBAL hglobal;
+ DWORD read, written, len;
+ BYTE buf[4096];
+ char *ptr;
+
+ TRACE("(%p, %p)\n", iface, pStm);
+
+ if (!pStm)
+ return E_INVALIDARG;
+
+ hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
+ if (FAILED(hr))
+ return hr;
+
+ do
+ {
+ IStream_Read(pStm, buf, sizeof(buf), &read);
+ hr = IStream_Write(This->stream, buf, read, &written);
+ } while(SUCCEEDED(hr) && written != 0 && read != 0);
+
+ if (FAILED(hr))
+ {
+ ERR("Failed to copy stream\n");
+ return hr;
+ }
+
+ hr = GetHGlobalFromStream(This->stream, &hglobal);
+ if (FAILED(hr))
+ return hr;
+
+ len = GlobalSize(hglobal);
+ ptr = GlobalLock(hglobal);
+ if (len != 0)
+ This->xmldoc = parse_xml(ptr, len);
+ GlobalUnlock(hglobal);
+
+ if (!This->xmldoc)
+ {
+ ERR("Failed to parse xml\n");
+ return E_FAIL;
+ }
+
+ xmlnode = xmlDocGetRootElement(This->xmldoc);
+ return XMLElement_create((IUnknown *)This, xmlnode, (LPVOID *)&This->root);
+}
+
+static HRESULT WINAPI xmldoc_IPersistStreamInit_Save(
+ IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty)
+{
+ FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_IPersistStreamInit_GetSizeMax(
+ IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
+{
+ FIXME("(%p, %p): stub!\n", iface, pcbSize);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmldoc_IPersistStreamInit_InitNew(
+ IPersistStreamInit *iface)
+{
+ FIXME("(%p): stub!\n", iface);
+ return E_NOTIMPL;
+}
+
+static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
+{
+ xmldoc_IPersistStreamInit_QueryInterface,
+ xmldoc_IPersistStreamInit_AddRef,
+ xmldoc_IPersistStreamInit_Release,
+ xmldoc_IPersistStreamInit_GetClassID,
+ xmldoc_IPersistStreamInit_IsDirty,
+ xmldoc_IPersistStreamInit_Load,
+ xmldoc_IPersistStreamInit_Save,
+ xmldoc_IPersistStreamInit_GetSizeMax,
+ xmldoc_IPersistStreamInit_InitNew
+};
+
+HRESULT XMLDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
+{
+ xmldoc *doc;
+
+ TRACE("(%p,%p)\n", pUnkOuter, ppObj);
+
+ doc = HeapAlloc(GetProcessHeap(), 0, sizeof (*doc));
+ if(!doc)
+ return E_OUTOFMEMORY;
+
+ doc->lpVtbl = &xmldoc_vtbl;
+ doc->lpvtblIPersistStreamInit = &xmldoc_IPersistStreamInit_VTable;
+ doc->ref = 1;
+ doc->error = S_OK;
+ doc->root = NULL;
+ doc->xmldoc = NULL;
+ doc->stream = NULL;
+
+ *ppObj = &doc->lpVtbl;
+
+ TRACE("returning iface %p\n", *ppObj);
+ return S_OK;
+}
+
+#else
+
+HRESULT XMLDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
+{
+ MESSAGE("This program tried to use an XMLDocument object, but\n"
+ "libxml2 support was not present at compile time.\n");
+ return E_NOTIMPL;
+}
+
+#endif
+
--
1.4.1
More information about the wine-patches
mailing list