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
50 typedef struct _xmldoc
52 const IXMLDocumentVtbl
*lpVtbl
;
53 const IPersistStreamInitVtbl
*lpvtblIPersistStreamInit
;
65 static inline xmldoc
*impl_from_IXMLDocument(IXMLDocument
*iface
)
67 return (xmldoc
*)((char*)iface
- FIELD_OFFSET(xmldoc
, lpVtbl
));
70 static inline xmldoc
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
72 return (xmldoc
*)((char*)iface
- FIELD_OFFSET(xmldoc
, lpvtblIPersistStreamInit
));
75 static HRESULT WINAPI
xmldoc_QueryInterface(IXMLDocument
*iface
, REFIID riid
, void** ppvObject
)
77 xmldoc
*This
= impl_from_IXMLDocument(iface
);
79 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
81 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
82 IsEqualGUID(riid
, &IID_IXMLDocument
))
86 else if (IsEqualGUID(&IID_IPersistStreamInit
, riid
))
88 *ppvObject
= (IPersistStreamInit
*)&(This
->lpvtblIPersistStreamInit
);
92 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
96 IXMLDocument_AddRef(iface
);
101 static ULONG WINAPI
xmldoc_AddRef(IXMLDocument
*iface
)
103 xmldoc
*This
= impl_from_IXMLDocument(iface
);
105 return InterlockedIncrement(&This
->ref
);
108 static ULONG WINAPI
xmldoc_Release(IXMLDocument
*iface
)
110 xmldoc
*This
= impl_from_IXMLDocument(iface
);
115 ref
= InterlockedDecrement(&This
->ref
);
118 xmlFreeDoc(This
->xmldoc
);
119 if (This
->stream
) IStream_Release(This
->stream
);
120 HeapFree(GetProcessHeap(), 0, This
);
126 static HRESULT WINAPI
xmldoc_GetTypeInfoCount(IXMLDocument
*iface
, UINT
* pctinfo
)
132 static HRESULT WINAPI
xmldoc_GetTypeInfo(IXMLDocument
*iface
, UINT iTInfo
,
133 LCID lcid
, ITypeInfo
** ppTInfo
)
139 static HRESULT WINAPI
xmldoc_GetIDsOfNames(IXMLDocument
*iface
, REFIID riid
,
140 LPOLESTR
* rgszNames
, UINT cNames
,
141 LCID lcid
, DISPID
* rgDispId
)
147 static HRESULT WINAPI
xmldoc_Invoke(IXMLDocument
*iface
, DISPID dispIdMember
,
148 REFIID riid
, LCID lcid
, WORD wFlags
,
149 DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
,
150 EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
156 static HRESULT WINAPI
xmldoc_get_root(IXMLDocument
*iface
, IXMLElement
**p
)
158 xmldoc
*This
= impl_from_IXMLDocument(iface
);
160 TRACE("(%p, %p)\n", iface
, p
);
172 static HRESULT WINAPI
xmldoc_get_fileSize(IXMLDocument
*iface
, BSTR
*p
)
174 FIXME("(%p, %p): stub\n", iface
, p
);
178 static HRESULT WINAPI
xmldoc_put_fileModifiedDate(IXMLDocument
*iface
, BSTR
*p
)
180 FIXME("(%p, %p): stub\n", iface
, p
);
184 static HRESULT WINAPI
xmldoc_get_fileUpdatedDate(IXMLDocument
*iface
, BSTR
*p
)
186 FIXME("(%p, %p): stub\n", iface
, p
);
190 static HRESULT WINAPI
xmldoc_get_URL(IXMLDocument
*iface
, BSTR
*p
)
192 FIXME("(%p, %p): stub\n", iface
, p
);
197 const struct IBindStatusCallbackVtbl
*lpVtbl
;
200 static HRESULT WINAPI
bsc_QueryInterface(
201 IBindStatusCallback
*iface
,
205 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
206 IsEqualGUID(riid
, &IID_IBindStatusCallback
))
208 IBindStatusCallback_AddRef( iface
);
213 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
214 return E_NOINTERFACE
;
217 static ULONG WINAPI
bsc_AddRef(
218 IBindStatusCallback
*iface
)
223 static ULONG WINAPI
bsc_Release(
224 IBindStatusCallback
*iface
)
229 static HRESULT WINAPI
bsc_OnStartBinding(
230 IBindStatusCallback
* iface
,
237 static HRESULT WINAPI
bsc_GetPriority(
238 IBindStatusCallback
* iface
,
244 static HRESULT WINAPI
bsc_OnLowResource(
245 IBindStatusCallback
* iface
,
251 static HRESULT WINAPI
bsc_OnProgress(
252 IBindStatusCallback
* iface
,
256 LPCWSTR szStatusText
)
261 static HRESULT WINAPI
bsc_OnStopBinding(
262 IBindStatusCallback
* iface
,
269 static HRESULT WINAPI
bsc_GetBindInfo(
270 IBindStatusCallback
* iface
,
274 *grfBINDF
= BINDF_RESYNCHRONIZE
;
279 static HRESULT WINAPI
bsc_OnDataAvailable(
280 IBindStatusCallback
* iface
,
283 FORMATETC
* pformatetc
,
289 static HRESULT WINAPI
bsc_OnObjectAvailable(
290 IBindStatusCallback
* iface
,
297 static const struct IBindStatusCallbackVtbl bsc_vtbl
=
309 bsc_OnObjectAvailable
312 static bsc xmldoc_bsc
= { &bsc_vtbl
};
314 static HRESULT WINAPI
xmldoc_put_URL(IXMLDocument
*iface
, BSTR p
)
316 WCHAR url
[INTERNET_MAX_URL_LENGTH
];
320 IPersistStreamInit
*persist
;
323 TRACE("(%p, %s)\n", iface
, debugstr_w(p
));
330 WCHAR fullpath
[MAX_PATH
];
331 DWORD needed
= sizeof(url
) / sizeof(WCHAR
);
333 if (!PathSearchAndQualifyW(p
, fullpath
, sizeof(fullpath
) / sizeof(WCHAR
)))
335 ERR("can't find path\n");
339 if (FAILED(UrlCreateFromPathW(fullpath
, url
, &needed
, 0)))
341 ERR("can't create url from path\n");
348 hr
= CreateURLMoniker(NULL
, p
, &moniker
);
352 CreateAsyncBindCtx(0, (IBindStatusCallback
*)&xmldoc_bsc
, 0, &bctx
);
354 hr
= IMoniker_BindToStorage(moniker
, bctx
, NULL
, &IID_IStream
, (LPVOID
*)&stream
);
355 IBindCtx_Release(bctx
);
356 IMoniker_Release(moniker
);
360 hr
= IXMLDocument_QueryInterface(iface
, &IID_IPersistStreamInit
, (LPVOID
*)&persist
);
363 IStream_Release(stream
);
367 hr
= IPersistStreamInit_Load(persist
, stream
);
368 IPersistStreamInit_Release(persist
);
369 IStream_Release(stream
);
374 static HRESULT WINAPI
xmldoc_get_mimeType(IXMLDocument
*iface
, BSTR
*p
)
376 FIXME("(%p, %p): stub\n", iface
, p
);
380 static HRESULT WINAPI
xmldoc_get_readyState(IXMLDocument
*iface
, long *p
)
382 FIXME("(%p, %p): stub\n", iface
, p
);
386 static HRESULT WINAPI
xmldoc_get_charset(IXMLDocument
*iface
, BSTR
*p
)
388 FIXME("(%p, %p): stub\n", iface
, p
);
392 static HRESULT WINAPI
xmldoc_put_charset(IXMLDocument
*iface
, BSTR p
)
394 FIXME("(%p, %p): stub\n", iface
, p
);
398 static HRESULT WINAPI
xmldoc_get_version(IXMLDocument
*iface
, BSTR
*p
)
400 FIXME("(%p, %p): stub\n", iface
, p
);
404 static HRESULT WINAPI
xmldoc_get_doctype(IXMLDocument
*iface
, BSTR
*p
)
406 FIXME("(%p, %p): stub\n", iface
, p
);
410 static HRESULT WINAPI
xmldoc_get_dtdURl(IXMLDocument
*iface
, BSTR
*p
)
412 FIXME("(%p, %p): stub\n", iface
, p
);
416 static xmlElementType
type_msxml_to_libxml(long type
)
420 case XMLELEMTYPE_ELEMENT
:
421 return XML_ELEMENT_NODE
;
422 case XMLELEMTYPE_TEXT
:
423 return XML_TEXT_NODE
;
424 case XMLELEMTYPE_COMMENT
:
425 return XML_COMMENT_NODE
;
426 case XMLELEMTYPE_DOCUMENT
:
427 return XML_DOCUMENT_NODE
;
428 case XMLELEMTYPE_DTD
:
436 return -1; /* FIXME: what is OTHER in msxml? */
439 static HRESULT WINAPI
xmldoc_createElement(IXMLDocument
*iface
, VARIANT vType
,
440 VARIANT var1
, IXMLElement
**ppElem
)
443 static const xmlChar empty
[] = "\0";
445 TRACE("(%p, %p)\n", iface
, ppElem
);
452 node
= xmlNewNode(NULL
, empty
);
454 if (V_VT(&vType
) != VT_I4
)
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 static 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");