ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

domdoc.c
Go to the documentation of this file.
00001 /*
00002  *    DOM Document implementation
00003  *
00004  * Copyright 2005 Mike McCormack
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #define COBJMACROS
00022 #define NONAMELESSUNION
00023 
00024 #include "config.h"
00025 
00026 #include <stdarg.h>
00027 #include <assert.h>
00028 #include "windef.h"
00029 #include "winbase.h"
00030 #include "winuser.h"
00031 #include "winnls.h"
00032 #include "ole2.h"
00033 #include "msxml2.h"
00034 #include "wininet.h"
00035 #include "winreg.h"
00036 #include "shlwapi.h"
00037 #include "ocidl.h"
00038 #include "objsafe.h"
00039 #include "dispex.h"
00040 
00041 #include "wine/debug.h"
00042 #include "wine/list.h"
00043 
00044 #include "msxml_private.h"
00045 
00046 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
00047 
00048 #ifdef HAVE_LIBXML2
00049 
00050 #include <libxml/xmlsave.h>
00051 
00052 /* not defined in older versions */
00053 #define XML_SAVE_FORMAT     1
00054 #define XML_SAVE_NO_DECL    2
00055 #define XML_SAVE_NO_EMPTY   4
00056 #define XML_SAVE_NO_XHTML   8
00057 #define XML_SAVE_XHTML     16
00058 #define XML_SAVE_AS_XML    32
00059 #define XML_SAVE_AS_HTML   64
00060 
00061 static const WCHAR SZ_PROPERTY_SELECTION_LANGUAGE[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
00062 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
00063 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
00064 
00065 typedef struct _domdoc
00066 {
00067     xmlnode node;
00068     const struct IXMLDOMDocument2Vtbl *lpVtbl;
00069     const struct IPersistStreamInitVtbl   *lpvtblIPersistStreamInit;
00070     const struct IObjectWithSiteVtbl  *lpvtblIObjectWithSite;
00071     const struct IObjectSafetyVtbl    *lpvtblIObjectSafety;
00072     const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
00073     LONG ref;
00074     VARIANT_BOOL async;
00075     VARIANT_BOOL validating;
00076     VARIANT_BOOL resolving;
00077     VARIANT_BOOL preserving;
00078     BOOL bUseXPath;
00079     IXMLDOMSchemaCollection *schema;
00080     bsc_t *bsc;
00081     HRESULT error;
00082 
00083     /* IPersistStream */
00084     IStream *stream;
00085 
00086     /* IObjectWithSite*/
00087     IUnknown *site;
00088 
00089     /* IObjectSafety */
00090     DWORD safeopt;
00091 } domdoc;
00092 
00093 /*
00094   In native windows, the whole lifetime management of XMLDOMNodes is
00095   managed automatically using reference counts. Wine emulates that by
00096   maintaining a reference count to the document that is increased for
00097   each IXMLDOMNode pointer passed out for this document. If all these
00098   pointers are gone, the document is unreachable and gets freed, that
00099   is, all nodes in the tree of the document get freed.
00100 
00101   You are able to create nodes that are associated to a document (in
00102   fact, in msxml's XMLDOM model, all nodes are associated to a document),
00103   but not in the tree of that document, for example using the createFoo
00104   functions from IXMLDOMDocument. These nodes do not get cleaned up
00105   by libxml, so we have to do it ourselves.
00106 
00107   To catch these nodes, a list of "orphan nodes" is introduced.
00108   It contains pointers to all roots of node trees that are
00109   associated with the document without being part of the document
00110   tree. All nodes with parent==NULL (except for the document root nodes)
00111   should be in the orphan node list of their document. All orphan nodes
00112   get freed together with the document itself.
00113  */
00114 
00115 typedef struct _xmldoc_priv {
00116     LONG refs;
00117     struct list orphans;
00118 } xmldoc_priv;
00119 
00120 typedef struct _orphan_entry {
00121     struct list entry;
00122     xmlNode * node;
00123 } orphan_entry;
00124 
00125 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
00126 {
00127     return doc->_private;
00128 }
00129 
00130 static xmldoc_priv * create_priv(void)
00131 {
00132     xmldoc_priv *priv;
00133     priv = heap_alloc( sizeof (*priv) );
00134 
00135     if(priv)
00136     {
00137         priv->refs = 0;
00138         list_init( &priv->orphans );
00139     }
00140 
00141     return priv;
00142 }
00143 
00144 /* links a "<?xml" node as a first child */
00145 void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node)
00146 {
00147     assert(doc != NULL);
00148     if (doc->standalone != -1) xmlAddPrevSibling( doc->children, node );
00149 }
00150 
00151 /* unlinks a first "<?xml" child if it was created */
00152 xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc)
00153 {
00154     xmlNodePtr node;
00155 
00156     assert(doc != NULL);
00157 
00158     if (doc->standalone != -1)
00159     {
00160         node = doc->children;
00161         xmlUnlinkNode( node );
00162     }
00163     else
00164         node = NULL;
00165 
00166     return node;
00167 }
00168 
00169 static xmlDocPtr doparse( char *ptr, int len, const char *encoding )
00170 {
00171     xmlDocPtr doc;
00172 
00173 #ifdef HAVE_XMLREADMEMORY
00174     /*
00175      * use xmlReadMemory if possible so we can suppress
00176      * writing errors to stderr
00177      */
00178     doc = xmlReadMemory( ptr, len, NULL, encoding,
00179                            XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
00180 #else
00181     doc = xmlParseMemory( ptr, len );
00182 #endif
00183 
00184     /* create first child as a <?xml...?> */
00185     if (doc && doc->standalone != -1)
00186     {
00187         xmlNodePtr node;
00188         char buff[30];
00189         xmlChar *xmlbuff = (xmlChar*)buff;
00190 
00191         node = xmlNewDocPI( doc, (xmlChar*)"xml", NULL );
00192 
00193         /* version attribute can't be omitted */
00194         sprintf(buff, "version=\"%s\"", doc->version ? (char*)doc->version : "1.0");
00195         xmlNodeAddContent( node, xmlbuff );
00196 
00197         if (doc->encoding)
00198         {
00199             sprintf(buff, " encoding=\"%s\"", doc->encoding);
00200             xmlNodeAddContent( node, xmlbuff );
00201         }
00202 
00203         if (doc->standalone != -2)
00204         {
00205             sprintf(buff, " standalone=\"%s\"", doc->standalone == 0 ? "no" : "yes");
00206             xmlNodeAddContent( node, xmlbuff );
00207         }
00208 
00209         xmldoc_link_xmldecl( doc, node );
00210     }
00211 
00212     return doc;
00213 }
00214 
00215 LONG xmldoc_add_ref(xmlDocPtr doc)
00216 {
00217     LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
00218     TRACE("(%p)->(%d)\n", doc, ref);
00219     return ref;
00220 }
00221 
00222 LONG xmldoc_release(xmlDocPtr doc)
00223 {
00224     xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
00225     LONG ref = InterlockedDecrement(&priv->refs);
00226     TRACE("(%p)->(%d)\n", doc, ref);
00227     if(ref == 0)
00228     {
00229         orphan_entry *orphan, *orphan2;
00230         TRACE("freeing docptr %p\n", doc);
00231 
00232         LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
00233         {
00234             xmlFreeNode( orphan->node );
00235             heap_free( orphan );
00236         }
00237         heap_free(doc->_private);
00238 
00239         xmlFreeDoc(doc);
00240     }
00241 
00242     return ref;
00243 }
00244 
00245 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
00246 {
00247     xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
00248     orphan_entry *entry;
00249 
00250     entry = heap_alloc( sizeof (*entry) );
00251     if(!entry)
00252         return E_OUTOFMEMORY;
00253 
00254     entry->node = node;
00255     list_add_head( &priv->orphans, &entry->entry );
00256     return S_OK;
00257 }
00258 
00259 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
00260 {
00261     xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
00262     orphan_entry *entry, *entry2;
00263 
00264     LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
00265     {
00266         if( entry->node == node )
00267         {
00268             list_remove( &entry->entry );
00269             heap_free( entry );
00270             return S_OK;
00271         }
00272     }
00273 
00274     return S_FALSE;
00275 }
00276 
00277 static HRESULT attach_xmldoc( xmlnode *node, xmlDocPtr xml )
00278 {
00279     if(node->node)
00280         xmldoc_release(node->node->doc);
00281 
00282     node->node = (xmlNodePtr) xml;
00283     if(node->node)
00284         xmldoc_add_ref(node->node->doc);
00285 
00286     return S_OK;
00287 }
00288 
00289 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
00290 {
00291     return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
00292 }
00293 
00294 static inline xmlDocPtr get_doc( domdoc *This )
00295 {
00296     return (xmlDocPtr)This->node.node;
00297 }
00298 
00299 static inline domdoc *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
00300 {
00301     return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStreamInit));
00302 }
00303 
00304 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
00305 {
00306     return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
00307 }
00308 
00309 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
00310 {
00311     return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
00312 }
00313 
00314 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
00315 {
00316     return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
00317 }
00318 
00319 /************************************************************************
00320  * domdoc implementation of IPersistStream.
00321  */
00322 static HRESULT WINAPI domdoc_IPersistStreamInit_QueryInterface(
00323     IPersistStreamInit *iface, REFIID riid, void **ppvObj)
00324 {
00325     domdoc *this = impl_from_IPersistStreamInit(iface);
00326     return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)this, riid, ppvObj);
00327 }
00328 
00329 static ULONG WINAPI domdoc_IPersistStreamInit_AddRef(
00330     IPersistStreamInit *iface)
00331 {
00332     domdoc *this = impl_from_IPersistStreamInit(iface);
00333     return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)this);
00334 }
00335 
00336 static ULONG WINAPI domdoc_IPersistStreamInit_Release(
00337     IPersistStreamInit *iface)
00338 {
00339     domdoc *this = impl_from_IPersistStreamInit(iface);
00340     return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)this);
00341 }
00342 
00343 static HRESULT WINAPI domdoc_IPersistStreamInit_GetClassID(
00344     IPersistStreamInit *iface, CLSID *classid)
00345 {
00346     TRACE("(%p,%p): stub!\n", iface, classid);
00347 
00348     if(!classid)
00349         return E_POINTER;
00350 
00351     *classid = CLSID_DOMDocument2;
00352 
00353     return S_OK;
00354 }
00355 
00356 static HRESULT WINAPI domdoc_IPersistStreamInit_IsDirty(
00357     IPersistStreamInit *iface)
00358 {
00359     domdoc *This = impl_from_IPersistStreamInit(iface);
00360     FIXME("(%p): stub!\n", This);
00361     return S_FALSE;
00362 }
00363 
00364 static HRESULT WINAPI domdoc_IPersistStreamInit_Load(
00365     IPersistStreamInit *iface, LPSTREAM pStm)
00366 {
00367     domdoc *This = impl_from_IPersistStreamInit(iface);
00368     HRESULT hr;
00369     HGLOBAL hglobal;
00370     DWORD read, written, len;
00371     BYTE buf[4096];
00372     char *ptr;
00373     xmlDocPtr xmldoc = NULL;
00374 
00375     TRACE("(%p)->(%p)\n", This, pStm);
00376 
00377     if (!pStm)
00378         return E_INVALIDARG;
00379 
00380     hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
00381     if (FAILED(hr))
00382         return hr;
00383 
00384     do
00385     {
00386         IStream_Read(pStm, buf, sizeof(buf), &read);
00387         hr = IStream_Write(This->stream, buf, read, &written);
00388     } while(SUCCEEDED(hr) && written != 0 && read != 0);
00389 
00390     if (FAILED(hr))
00391     {
00392         ERR("Failed to copy stream\n");
00393         return hr;
00394     }
00395 
00396     hr = GetHGlobalFromStream(This->stream, &hglobal);
00397     if (FAILED(hr))
00398         return hr;
00399 
00400     len = GlobalSize(hglobal);
00401     ptr = GlobalLock(hglobal);
00402     if (len != 0)
00403         xmldoc = doparse(ptr, len, NULL);
00404     GlobalUnlock(hglobal);
00405 
00406     if (!xmldoc)
00407     {
00408         ERR("Failed to parse xml\n");
00409         return E_FAIL;
00410     }
00411 
00412     xmldoc->_private = create_priv();
00413 
00414     return attach_xmldoc( &This->node, xmldoc );
00415 }
00416 
00417 static HRESULT WINAPI domdoc_IPersistStreamInit_Save(
00418     IPersistStreamInit *iface, IStream *stream, BOOL clr_dirty)
00419 {
00420     domdoc *This = impl_from_IPersistStreamInit(iface);
00421     BSTR xmlString;
00422     HRESULT hr;
00423 
00424     TRACE("(%p)->(%p %d)\n", This, stream, clr_dirty);
00425 
00426     hr = IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), &xmlString );
00427     if(hr == S_OK)
00428     {
00429         DWORD len = SysStringLen(xmlString) * sizeof(WCHAR);
00430 
00431         hr = IStream_Write( stream, xmlString, len, NULL );
00432         SysFreeString(xmlString);
00433     }
00434 
00435     TRACE("ret 0x%08x\n", hr);
00436 
00437     return hr;
00438 }
00439 
00440 static HRESULT WINAPI domdoc_IPersistStreamInit_GetSizeMax(
00441     IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
00442 {
00443     domdoc *This = impl_from_IPersistStreamInit(iface);
00444     TRACE("(%p)->(%p): stub!\n", This, pcbSize);
00445     return E_NOTIMPL;
00446 }
00447 
00448 static HRESULT WINAPI domdoc_IPersistStreamInit_InitNew(
00449     IPersistStreamInit *iface)
00450 {
00451     domdoc *This = impl_from_IPersistStreamInit(iface);
00452     TRACE("(%p)\n", This);
00453     return S_OK;
00454 }
00455 
00456 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
00457 {
00458     domdoc_IPersistStreamInit_QueryInterface,
00459     domdoc_IPersistStreamInit_AddRef,
00460     domdoc_IPersistStreamInit_Release,
00461     domdoc_IPersistStreamInit_GetClassID,
00462     domdoc_IPersistStreamInit_IsDirty,
00463     domdoc_IPersistStreamInit_Load,
00464     domdoc_IPersistStreamInit_Save,
00465     domdoc_IPersistStreamInit_GetSizeMax,
00466     domdoc_IPersistStreamInit_InitNew
00467 };
00468 
00469 /* ISupportErrorInfo interface */
00470 static HRESULT WINAPI support_error_QueryInterface(
00471     ISupportErrorInfo *iface,
00472     REFIID riid, void** ppvObj )
00473 {
00474     domdoc *This = impl_from_ISupportErrorInfo(iface);
00475     return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)This, riid, ppvObj);
00476 }
00477 
00478 static ULONG WINAPI support_error_AddRef(
00479     ISupportErrorInfo *iface )
00480 {
00481     domdoc *This = impl_from_ISupportErrorInfo(iface);
00482     return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)This);
00483 }
00484 
00485 static ULONG WINAPI support_error_Release(
00486     ISupportErrorInfo *iface )
00487 {
00488     domdoc *This = impl_from_ISupportErrorInfo(iface);
00489     return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)This);
00490 }
00491 
00492 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
00493     ISupportErrorInfo *iface,
00494     REFIID riid )
00495 {
00496     FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
00497     return S_FALSE;
00498 }
00499 
00500 static const struct ISupportErrorInfoVtbl support_error_vtbl =
00501 {
00502     support_error_QueryInterface,
00503     support_error_AddRef,
00504     support_error_Release,
00505     support_error_InterfaceSupportsErrorInfo
00506 };
00507 
00508 /* IXMLDOMDocument2 interface */
00509 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
00510 {
00511     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00512 
00513     TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppvObject );
00514 
00515     *ppvObject = NULL;
00516 
00517     if ( IsEqualGUID( riid, &IID_IUnknown ) ||
00518          IsEqualGUID( riid, &IID_IDispatch ) ||
00519          IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
00520          IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
00521     {
00522         *ppvObject = iface;
00523     }
00524     else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
00525     {
00526         *ppvObject = IXMLDOMNode_from_impl(&This->node);
00527     }
00528     else if (IsEqualGUID(&IID_IPersistStream, riid) ||
00529              IsEqualGUID(&IID_IPersistStreamInit, riid))
00530     {
00531         *ppvObject = &(This->lpvtblIPersistStreamInit);
00532     }
00533     else if (IsEqualGUID(&IID_IObjectWithSite, riid))
00534     {
00535         *ppvObject = &(This->lpvtblIObjectWithSite);
00536     }
00537     else if (IsEqualGUID(&IID_IObjectSafety, riid))
00538     {
00539         *ppvObject = &(This->lpvtblIObjectSafety);
00540     }
00541     else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
00542     {
00543         *ppvObject = &This->lpvtblISupportErrorInfo;
00544     }
00545     else if(dispex_query_interface(&This->node.dispex, riid, ppvObject))
00546     {
00547         return *ppvObject ? S_OK : E_NOINTERFACE;
00548     }
00549     else if(IsEqualGUID(&IID_IRunnableObject, riid))
00550     {
00551         TRACE("IID_IRunnableObject not supported returning NULL\n");
00552         return E_NOINTERFACE;
00553     }
00554     else
00555     {
00556         FIXME("interface %s not implemented\n", debugstr_guid(riid));
00557         return E_NOINTERFACE;
00558     }
00559 
00560     IUnknown_AddRef((IUnknown*)*ppvObject);
00561 
00562     return S_OK;
00563 }
00564 
00565 
00566 static ULONG WINAPI domdoc_AddRef(
00567      IXMLDOMDocument2 *iface )
00568 {
00569     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00570     TRACE("%p\n", This );
00571     return InterlockedIncrement( &This->ref );
00572 }
00573 
00574 
00575 static ULONG WINAPI domdoc_Release(
00576      IXMLDOMDocument2 *iface )
00577 {
00578     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00579     LONG ref;
00580 
00581     TRACE("%p\n", This );
00582 
00583     ref = InterlockedDecrement( &This->ref );
00584     if ( ref == 0 )
00585     {
00586         if(This->bsc)
00587             detach_bsc(This->bsc);
00588 
00589         if (This->site)
00590             IUnknown_Release( This->site );
00591         destroy_xmlnode(&This->node);
00592         if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
00593         if (This->stream) IStream_Release(This->stream);
00594         HeapFree( GetProcessHeap(), 0, This );
00595     }
00596 
00597     return ref;
00598 }
00599 
00600 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
00601 {
00602     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00603 
00604     TRACE("(%p)->(%p)\n", This, pctinfo);
00605 
00606     *pctinfo = 1;
00607 
00608     return S_OK;
00609 }
00610 
00611 static HRESULT WINAPI domdoc_GetTypeInfo(
00612     IXMLDOMDocument2 *iface,
00613     UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
00614 {
00615     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00616     HRESULT hr;
00617 
00618     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
00619 
00620     hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
00621 
00622     return hr;
00623 }
00624 
00625 static HRESULT WINAPI domdoc_GetIDsOfNames(
00626     IXMLDOMDocument2 *iface,
00627     REFIID riid,
00628     LPOLESTR* rgszNames,
00629     UINT cNames,
00630     LCID lcid,
00631     DISPID* rgDispId)
00632 {
00633     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00634     ITypeInfo *typeinfo;
00635     HRESULT hr;
00636 
00637     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
00638           lcid, rgDispId);
00639 
00640     if(!rgszNames || cNames == 0 || !rgDispId)
00641         return E_INVALIDARG;
00642 
00643     hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
00644     if(SUCCEEDED(hr))
00645     {
00646         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
00647         ITypeInfo_Release(typeinfo);
00648     }
00649 
00650     return hr;
00651 }
00652 
00653 
00654 static HRESULT WINAPI domdoc_Invoke(
00655     IXMLDOMDocument2 *iface,
00656     DISPID dispIdMember,
00657     REFIID riid,
00658     LCID lcid,
00659     WORD wFlags,
00660     DISPPARAMS* pDispParams,
00661     VARIANT* pVarResult,
00662     EXCEPINFO* pExcepInfo,
00663     UINT* puArgErr)
00664 {
00665     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00666     ITypeInfo *typeinfo;
00667     HRESULT hr;
00668 
00669     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
00670           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
00671 
00672     hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
00673     if(SUCCEEDED(hr))
00674     {
00675         hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
00676                 pVarResult, pExcepInfo, puArgErr);
00677         ITypeInfo_Release(typeinfo);
00678     }
00679 
00680     return hr;
00681 }
00682 
00683 
00684 static HRESULT WINAPI domdoc_get_nodeName(
00685     IXMLDOMDocument2 *iface,
00686     BSTR* name )
00687 {
00688     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00689     return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), name );
00690 }
00691 
00692 
00693 static HRESULT WINAPI domdoc_get_nodeValue(
00694     IXMLDOMDocument2 *iface,
00695     VARIANT* value )
00696 {
00697     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00698     return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
00699 }
00700 
00701 
00702 static HRESULT WINAPI domdoc_put_nodeValue(
00703     IXMLDOMDocument2 *iface,
00704     VARIANT value)
00705 {
00706     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00707     return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
00708 }
00709 
00710 
00711 static HRESULT WINAPI domdoc_get_nodeType(
00712     IXMLDOMDocument2 *iface,
00713     DOMNodeType* type )
00714 {
00715     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00716     return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), type );
00717 }
00718 
00719 
00720 static HRESULT WINAPI domdoc_get_parentNode(
00721     IXMLDOMDocument2 *iface,
00722     IXMLDOMNode** parent )
00723 {
00724     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00725     return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(&This->node), parent );
00726 }
00727 
00728 
00729 static HRESULT WINAPI domdoc_get_childNodes(
00730     IXMLDOMDocument2 *iface,
00731     IXMLDOMNodeList** childList )
00732 {
00733     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00734     return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), childList );
00735 }
00736 
00737 
00738 static HRESULT WINAPI domdoc_get_firstChild(
00739     IXMLDOMDocument2 *iface,
00740     IXMLDOMNode** firstChild )
00741 {
00742     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00743     return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), firstChild );
00744 }
00745 
00746 
00747 static HRESULT WINAPI domdoc_get_lastChild(
00748     IXMLDOMDocument2 *iface,
00749     IXMLDOMNode** lastChild )
00750 {
00751     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00752     return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), lastChild );
00753 }
00754 
00755 
00756 static HRESULT WINAPI domdoc_get_previousSibling(
00757     IXMLDOMDocument2 *iface,
00758     IXMLDOMNode** previousSibling )
00759 {
00760     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00761     return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), previousSibling );
00762 }
00763 
00764 
00765 static HRESULT WINAPI domdoc_get_nextSibling(
00766     IXMLDOMDocument2 *iface,
00767     IXMLDOMNode** nextSibling )
00768 {
00769     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00770     return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), nextSibling );
00771 }
00772 
00773 
00774 static HRESULT WINAPI domdoc_get_attributes(
00775     IXMLDOMDocument2 *iface,
00776     IXMLDOMNamedNodeMap** attributeMap )
00777 {
00778     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00779     return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
00780 }
00781 
00782 
00783 static HRESULT WINAPI domdoc_insertBefore(
00784     IXMLDOMDocument2 *iface,
00785     IXMLDOMNode* newChild,
00786     VARIANT refChild,
00787     IXMLDOMNode** outNewChild )
00788 {
00789     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00790     return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newChild, refChild, outNewChild );
00791 }
00792 
00793 
00794 static HRESULT WINAPI domdoc_replaceChild(
00795     IXMLDOMDocument2 *iface,
00796     IXMLDOMNode* newChild,
00797     IXMLDOMNode* oldChild,
00798     IXMLDOMNode** outOldChild)
00799 {
00800     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00801     return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
00802 }
00803 
00804 
00805 static HRESULT WINAPI domdoc_removeChild(
00806     IXMLDOMDocument2 *iface,
00807     IXMLDOMNode* childNode,
00808     IXMLDOMNode** oldChild)
00809 {
00810     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00811     return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
00812 }
00813 
00814 
00815 static HRESULT WINAPI domdoc_appendChild(
00816     IXMLDOMDocument2 *iface,
00817     IXMLDOMNode* newChild,
00818     IXMLDOMNode** outNewChild)
00819 {
00820     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00821     return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
00822 }
00823 
00824 
00825 static HRESULT WINAPI domdoc_hasChildNodes(
00826     IXMLDOMDocument2 *iface,
00827     VARIANT_BOOL* hasChild)
00828 {
00829     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00830     return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
00831 }
00832 
00833 
00834 static HRESULT WINAPI domdoc_get_ownerDocument(
00835     IXMLDOMDocument2 *iface,
00836     IXMLDOMDocument** DOMDocument)
00837 {
00838     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00839     return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
00840 }
00841 
00842 
00843 static HRESULT WINAPI domdoc_cloneNode(
00844     IXMLDOMDocument2 *iface,
00845     VARIANT_BOOL deep,
00846     IXMLDOMNode** cloneRoot)
00847 {
00848     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00849     return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
00850 }
00851 
00852 
00853 static HRESULT WINAPI domdoc_get_nodeTypeString(
00854     IXMLDOMDocument2 *iface,
00855     BSTR* nodeType )
00856 {
00857     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00858     return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
00859 }
00860 
00861 
00862 static HRESULT WINAPI domdoc_get_text(
00863     IXMLDOMDocument2 *iface,
00864     BSTR* text )
00865 {
00866     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00867     return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
00868 }
00869 
00870 
00871 static HRESULT WINAPI domdoc_put_text(
00872     IXMLDOMDocument2 *iface,
00873     BSTR text )
00874 {
00875     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00876     return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
00877 }
00878 
00879 
00880 static HRESULT WINAPI domdoc_get_specified(
00881     IXMLDOMDocument2 *iface,
00882     VARIANT_BOOL* isSpecified )
00883 {
00884     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00885     return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
00886 }
00887 
00888 
00889 static HRESULT WINAPI domdoc_get_definition(
00890     IXMLDOMDocument2 *iface,
00891     IXMLDOMNode** definitionNode )
00892 {
00893     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00894     return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
00895 }
00896 
00897 
00898 static HRESULT WINAPI domdoc_get_nodeTypedValue(
00899     IXMLDOMDocument2 *iface,
00900     VARIANT* typedValue )
00901 {
00902     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00903     return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
00904 }
00905 
00906 static HRESULT WINAPI domdoc_put_nodeTypedValue(
00907     IXMLDOMDocument2 *iface,
00908     VARIANT typedValue )
00909 {
00910     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00911     return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
00912 }
00913 
00914 
00915 static HRESULT WINAPI domdoc_get_dataType(
00916     IXMLDOMDocument2 *iface,
00917     VARIANT* dataTypeName )
00918 {
00919     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00920     return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
00921 }
00922 
00923 
00924 static HRESULT WINAPI domdoc_put_dataType(
00925     IXMLDOMDocument2 *iface,
00926     BSTR dataTypeName )
00927 {
00928     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00929     return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
00930 }
00931 
00932 
00933 static HRESULT WINAPI domdoc_get_xml(
00934     IXMLDOMDocument2 *iface,
00935     BSTR* xmlString )
00936 {
00937     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00938     return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
00939 }
00940 
00941 
00942 static HRESULT WINAPI domdoc_transformNode(
00943     IXMLDOMDocument2 *iface,
00944     IXMLDOMNode* styleSheet,
00945     BSTR* xmlString )
00946 {
00947     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00948     return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
00949 }
00950 
00951 
00952 static HRESULT WINAPI domdoc_selectNodes(
00953     IXMLDOMDocument2 *iface,
00954     BSTR queryString,
00955     IXMLDOMNodeList** resultList )
00956 {
00957     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00958     return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
00959 }
00960 
00961 
00962 static HRESULT WINAPI domdoc_selectSingleNode(
00963     IXMLDOMDocument2 *iface,
00964     BSTR queryString,
00965     IXMLDOMNode** resultNode )
00966 {
00967     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00968     return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
00969 }
00970 
00971 
00972 static HRESULT WINAPI domdoc_get_parsed(
00973     IXMLDOMDocument2 *iface,
00974     VARIANT_BOOL* isParsed )
00975 {
00976     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00977     return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
00978 }
00979 
00980 
00981 static HRESULT WINAPI domdoc_get_namespaceURI(
00982     IXMLDOMDocument2 *iface,
00983     BSTR* namespaceURI )
00984 {
00985     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00986     return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
00987 }
00988 
00989 
00990 static HRESULT WINAPI domdoc_get_prefix(
00991     IXMLDOMDocument2 *iface,
00992     BSTR* prefixString )
00993 {
00994     domdoc *This = impl_from_IXMLDOMDocument2( iface );
00995     return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
00996 }
00997 
00998 
00999 static HRESULT WINAPI domdoc_get_baseName(
01000     IXMLDOMDocument2 *iface,
01001     BSTR* nameString )
01002 {
01003     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01004     return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
01005 }
01006 
01007 
01008 static HRESULT WINAPI domdoc_transformNodeToObject(
01009     IXMLDOMDocument2 *iface,
01010     IXMLDOMNode* stylesheet,
01011     VARIANT outputObject)
01012 {
01013     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01014     return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
01015 }
01016 
01017 
01018 static HRESULT WINAPI domdoc_get_doctype(
01019     IXMLDOMDocument2 *iface,
01020     IXMLDOMDocumentType** documentType )
01021 {
01022     domdoc *This = impl_from_IXMLDOMDocument2(iface);
01023     FIXME("(%p)\n", This);
01024     return E_NOTIMPL;
01025 }
01026 
01027 
01028 static HRESULT WINAPI domdoc_get_implementation(
01029     IXMLDOMDocument2 *iface,
01030     IXMLDOMImplementation** impl )
01031 {
01032     domdoc *This = impl_from_IXMLDOMDocument2(iface);
01033 
01034     TRACE("(%p)->(%p)\n", This, impl);
01035 
01036     if(!impl)
01037         return E_INVALIDARG;
01038 
01039     *impl = (IXMLDOMImplementation*)create_doc_Implementation();
01040 
01041     return S_OK;
01042 }
01043 
01044 static HRESULT WINAPI domdoc_get_documentElement(
01045     IXMLDOMDocument2 *iface,
01046     IXMLDOMElement** DOMElement )
01047 {
01048     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01049     xmlDocPtr xmldoc = NULL;
01050     xmlNodePtr root = NULL;
01051     IXMLDOMNode *element_node;
01052     HRESULT hr;
01053 
01054     TRACE("(%p)->(%p)\n", This, DOMElement);
01055 
01056     if(!DOMElement)
01057         return E_INVALIDARG;
01058 
01059     *DOMElement = NULL;
01060 
01061     xmldoc = get_doc( This );
01062 
01063     root = xmlDocGetRootElement( xmldoc );
01064     if ( !root )
01065         return S_FALSE;
01066 
01067     element_node = create_node( root );
01068     if(!element_node) return S_FALSE;
01069 
01070     hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
01071     IXMLDOMNode_Release(element_node);
01072 
01073     return hr;
01074 }
01075 
01076 
01077 static HRESULT WINAPI domdoc_put_documentElement(
01078     IXMLDOMDocument2 *iface,
01079     IXMLDOMElement* DOMElement )
01080 {
01081     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01082     IXMLDOMNode *elementNode;
01083     xmlNodePtr oldRoot;
01084     xmlnode *xmlNode;
01085     HRESULT hr;
01086 
01087     TRACE("(%p)->(%p)\n", This, DOMElement);
01088 
01089     hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
01090     if(FAILED(hr))
01091         return hr;
01092 
01093     xmlNode = impl_from_IXMLDOMNode( elementNode );
01094 
01095     if(!xmlNode->node->parent)
01096         if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
01097             WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
01098 
01099     oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
01100     IXMLDOMNode_Release( elementNode );
01101 
01102     if(oldRoot)
01103         xmldoc_add_orphan(oldRoot->doc, oldRoot);
01104 
01105     return S_OK;
01106 }
01107 
01108 
01109 static HRESULT WINAPI domdoc_createElement(
01110     IXMLDOMDocument2 *iface,
01111     BSTR tagname,
01112     IXMLDOMElement** element )
01113 {
01114     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01115     IXMLDOMNode *node;
01116     VARIANT type;
01117     HRESULT hr;
01118 
01119     TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element);
01120 
01121     if (!element || !tagname) return E_INVALIDARG;
01122 
01123     V_VT(&type) = VT_I1;
01124     V_I1(&type) = NODE_ELEMENT;
01125 
01126     hr = IXMLDOMDocument2_createNode(iface, type, tagname, NULL, &node);
01127     if (hr == S_OK)
01128     {
01129         IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
01130         IXMLDOMNode_Release(node);
01131     }
01132 
01133     return hr;
01134 }
01135 
01136 
01137 static HRESULT WINAPI domdoc_createDocumentFragment(
01138     IXMLDOMDocument2 *iface,
01139     IXMLDOMDocumentFragment** frag )
01140 {
01141     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01142     IXMLDOMNode *node;
01143     VARIANT type;
01144     HRESULT hr;
01145 
01146     TRACE("(%p)->(%p)\n", This, frag);
01147 
01148     if (!frag) return E_INVALIDARG;
01149 
01150     *frag = NULL;
01151 
01152     V_VT(&type) = VT_I1;
01153     V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
01154 
01155     hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
01156     if (hr == S_OK)
01157     {
01158         IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
01159         IXMLDOMNode_Release(node);
01160     }
01161 
01162     return hr;
01163 }
01164 
01165 
01166 static HRESULT WINAPI domdoc_createTextNode(
01167     IXMLDOMDocument2 *iface,
01168     BSTR data,
01169     IXMLDOMText** text )
01170 {
01171     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01172     IXMLDOMNode *node;
01173     VARIANT type;
01174     HRESULT hr;
01175 
01176     TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text);
01177 
01178     if (!text) return E_INVALIDARG;
01179 
01180     *text = NULL;
01181 
01182     V_VT(&type) = VT_I1;
01183     V_I1(&type) = NODE_TEXT;
01184 
01185     hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
01186     if (hr == S_OK)
01187     {
01188         IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
01189         IXMLDOMNode_Release(node);
01190         hr = IXMLDOMText_put_data(*text, data);
01191     }
01192 
01193     return hr;
01194 }
01195 
01196 
01197 static HRESULT WINAPI domdoc_createComment(
01198     IXMLDOMDocument2 *iface,
01199     BSTR data,
01200     IXMLDOMComment** comment )
01201 {
01202     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01203     VARIANT type;
01204     HRESULT hr;
01205     IXMLDOMNode *node;
01206 
01207     TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment);
01208 
01209     if (!comment) return E_INVALIDARG;
01210 
01211     *comment = NULL;
01212 
01213     V_VT(&type) = VT_I1;
01214     V_I1(&type) = NODE_COMMENT;
01215 
01216     hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
01217     if (hr == S_OK)
01218     {
01219         IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
01220         IXMLDOMNode_Release(node);
01221         hr = IXMLDOMComment_put_data(*comment, data);
01222     }
01223 
01224     return hr;
01225 }
01226 
01227 
01228 static HRESULT WINAPI domdoc_createCDATASection(
01229     IXMLDOMDocument2 *iface,
01230     BSTR data,
01231     IXMLDOMCDATASection** cdata )
01232 {
01233     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01234     IXMLDOMNode *node;
01235     VARIANT type;
01236     HRESULT hr;
01237 
01238     TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata);
01239 
01240     if (!cdata) return E_INVALIDARG;
01241 
01242     *cdata = NULL;
01243 
01244     V_VT(&type) = VT_I1;
01245     V_I1(&type) = NODE_CDATA_SECTION;
01246 
01247     hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
01248     if (hr == S_OK)
01249     {
01250         IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
01251         IXMLDOMNode_Release(node);
01252         hr = IXMLDOMCDATASection_put_data(*cdata, data);
01253     }
01254 
01255     return hr;
01256 }
01257 
01258 
01259 static HRESULT WINAPI domdoc_createProcessingInstruction(
01260     IXMLDOMDocument2 *iface,
01261     BSTR target,
01262     BSTR data,
01263     IXMLDOMProcessingInstruction** pi )
01264 {
01265     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01266     IXMLDOMNode *node;
01267     VARIANT type;
01268     HRESULT hr;
01269 
01270     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
01271 
01272     if (!pi) return E_INVALIDARG;
01273 
01274     *pi = NULL;
01275 
01276     V_VT(&type) = VT_I1;
01277     V_I1(&type) = NODE_PROCESSING_INSTRUCTION;
01278 
01279     hr = IXMLDOMDocument2_createNode(iface, type, target, NULL, &node);
01280     if (hr == S_OK)
01281     {
01282         VARIANT v_data;
01283 
01284         /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
01285         V_VT(&v_data)   = VT_BSTR;
01286         V_BSTR(&v_data) = data;
01287 
01288         hr = IXMLDOMNode_put_nodeValue( node, v_data );
01289 
01290         IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
01291         IXMLDOMNode_Release(node);
01292     }
01293 
01294     return hr;
01295 }
01296 
01297 
01298 static HRESULT WINAPI domdoc_createAttribute(
01299     IXMLDOMDocument2 *iface,
01300     BSTR name,
01301     IXMLDOMAttribute** attribute )
01302 {
01303     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01304     IXMLDOMNode *node;
01305     VARIANT type;
01306     HRESULT hr;
01307 
01308     TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute);
01309 
01310     if (!attribute || !name) return E_INVALIDARG;
01311 
01312     V_VT(&type) = VT_I1;
01313     V_I1(&type) = NODE_ATTRIBUTE;
01314 
01315     hr = IXMLDOMDocument2_createNode(iface, type, name, NULL, &node);
01316     if (hr == S_OK)
01317     {
01318         IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
01319         IXMLDOMNode_Release(node);
01320     }
01321 
01322     return hr;
01323 }
01324 
01325 
01326 static HRESULT WINAPI domdoc_createEntityReference(
01327     IXMLDOMDocument2 *iface,
01328     BSTR name,
01329     IXMLDOMEntityReference** entityref )
01330 {
01331     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01332     IXMLDOMNode *node;
01333     VARIANT type;
01334     HRESULT hr;
01335 
01336     TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref);
01337 
01338     if (!entityref) return E_INVALIDARG;
01339 
01340     *entityref = NULL;
01341 
01342     V_VT(&type) = VT_I1;
01343     V_I1(&type) = NODE_ENTITY_REFERENCE;
01344 
01345     hr = IXMLDOMDocument2_createNode(iface, type, name, NULL, &node);
01346     if (hr == S_OK)
01347     {
01348         IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
01349         IXMLDOMNode_Release(node);
01350     }
01351 
01352     return hr;
01353 }
01354 
01355 
01356 static HRESULT WINAPI domdoc_getElementsByTagName(
01357     IXMLDOMDocument2 *iface,
01358     BSTR tagName,
01359     IXMLDOMNodeList** resultList )
01360 {
01361     static const WCHAR xpathformat[] =
01362             { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
01363     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01364     LPWSTR szPattern;
01365     HRESULT hr;
01366     TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
01367 
01368     if (tagName[0] == '*' && tagName[1] == 0)
01369     {
01370         szPattern = heap_alloc(sizeof(WCHAR)*4);
01371         szPattern[0] = szPattern[1] = '/';
01372         szPattern[2] = '*';
01373         szPattern[3] = 0;
01374     }
01375     else
01376     {
01377         szPattern = heap_alloc(sizeof(WCHAR)*(20+lstrlenW(tagName)+1));
01378         wsprintfW(szPattern, xpathformat, tagName);
01379     }
01380 
01381     hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
01382     heap_free(szPattern);
01383 
01384     return hr;
01385 }
01386 
01387 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
01388 {
01389     VARIANT tmp;
01390     HRESULT hr;
01391 
01392     VariantInit(&tmp);
01393     hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
01394     if(FAILED(hr))
01395         return E_INVALIDARG;
01396 
01397     *type = V_I4(&tmp);
01398 
01399     return S_OK;
01400 }
01401 
01402 static HRESULT WINAPI domdoc_createNode(
01403     IXMLDOMDocument2 *iface,
01404     VARIANT Type,
01405     BSTR name,
01406     BSTR namespaceURI,
01407     IXMLDOMNode** node )
01408 {
01409     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01410     DOMNodeType node_type;
01411     xmlNodePtr xmlnode;
01412     xmlChar *xml_name;
01413     HRESULT hr;
01414 
01415     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
01416 
01417     if(!node) return E_INVALIDARG;
01418 
01419     if(namespaceURI && namespaceURI[0])
01420         FIXME("nodes with namespaces currently not supported.\n");
01421 
01422     hr = get_node_type(Type, &node_type);
01423     if(FAILED(hr)) return hr;
01424 
01425     TRACE("node_type %d\n", node_type);
01426 
01427     /* exit earlier for types that need name */
01428     switch(node_type)
01429     {
01430     case NODE_ELEMENT:
01431     case NODE_ATTRIBUTE:
01432     case NODE_ENTITY_REFERENCE:
01433     case NODE_PROCESSING_INSTRUCTION:
01434         if (!name || *name == 0) return E_FAIL;
01435     default:
01436         break;
01437     }
01438 
01439     xml_name = xmlChar_from_wchar(name);
01440 
01441     switch(node_type)
01442     {
01443     case NODE_ELEMENT:
01444         xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
01445         break;
01446     case NODE_ATTRIBUTE:
01447         xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
01448         break;
01449     case NODE_TEXT:
01450         xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
01451         break;
01452     case NODE_CDATA_SECTION:
01453         xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
01454         break;
01455     case NODE_ENTITY_REFERENCE:
01456         xmlnode = xmlNewReference(get_doc(This), xml_name);
01457         break;
01458     case NODE_PROCESSING_INSTRUCTION:
01459 #ifdef HAVE_XMLNEWDOCPI
01460         xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
01461 #else
01462         FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
01463         xmlnode = NULL;
01464 #endif
01465         break;
01466     case NODE_COMMENT:
01467         xmlnode = xmlNewDocComment(get_doc(This), NULL);
01468         break;
01469     case NODE_DOCUMENT_FRAGMENT:
01470         xmlnode = xmlNewDocFragment(get_doc(This));
01471         break;
01472     /* unsupported types */
01473     case NODE_DOCUMENT:
01474     case NODE_DOCUMENT_TYPE:
01475     case NODE_ENTITY:
01476     case NODE_NOTATION:
01477         heap_free(xml_name);
01478         return E_INVALIDARG;
01479     default:
01480         FIXME("unhandled node type %d\n", node_type);
01481         xmlnode = NULL;
01482         break;
01483     }
01484 
01485     *node = create_node(xmlnode);
01486     heap_free(xml_name);
01487 
01488     if(*node)
01489     {
01490         TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
01491         xmldoc_add_orphan(xmlnode->doc, xmlnode);
01492         return S_OK;
01493     }
01494 
01495     return E_FAIL;
01496 }
01497 
01498 static HRESULT WINAPI domdoc_nodeFromID(
01499     IXMLDOMDocument2 *iface,
01500     BSTR idString,
01501     IXMLDOMNode** node )
01502 {
01503     domdoc *This = impl_from_IXMLDOMDocument2(iface);
01504     FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node);
01505     return E_NOTIMPL;
01506 }
01507 
01508 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
01509 {
01510     domdoc *This = obj;
01511     xmlDocPtr xmldoc;
01512 
01513     xmldoc = doparse( ptr, len, NULL );
01514     if(xmldoc) {
01515         xmldoc->_private = create_priv();
01516         return attach_xmldoc(&This->node, xmldoc);
01517     }
01518 
01519     return S_OK;
01520 }
01521 
01522 static HRESULT doread( domdoc *This, LPWSTR filename )
01523 {
01524     bsc_t *bsc;
01525     HRESULT hr;
01526 
01527     hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
01528     if(FAILED(hr))
01529         return hr;
01530 
01531     if(This->bsc)
01532         detach_bsc(This->bsc);
01533 
01534     This->bsc = bsc;
01535     return S_OK;
01536 }
01537 
01538 static HRESULT WINAPI domdoc_load(
01539     IXMLDOMDocument2 *iface,
01540     VARIANT xmlSource,
01541     VARIANT_BOOL* isSuccessful )
01542 {
01543     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01544     LPWSTR filename = NULL;
01545     HRESULT hr = S_FALSE;
01546     IXMLDOMDocument2 *pNewDoc = NULL;
01547     IStream *pStream = NULL;
01548     xmlDocPtr xmldoc;
01549 
01550     TRACE("(%p)->type %d\n", This, V_VT(&xmlSource) );
01551 
01552     *isSuccessful = VARIANT_FALSE;
01553 
01554     assert( &This->node );
01555 
01556     switch( V_VT(&xmlSource) )
01557     {
01558     case VT_BSTR:
01559         filename = V_BSTR(&xmlSource);
01560         break;
01561     case VT_UNKNOWN:
01562         hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
01563         if(hr == S_OK)
01564         {
01565             if(pNewDoc)
01566             {
01567                 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
01568                 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
01569                 hr = attach_xmldoc(&This->node, xmldoc);
01570 
01571                 if(SUCCEEDED(hr))
01572                     *isSuccessful = VARIANT_TRUE;
01573 
01574                 return hr;
01575             }
01576         }
01577         hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
01578         if(hr == S_OK)
01579         {
01580             IPersistStream *pDocStream;
01581             hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
01582             if(hr == S_OK)
01583             {
01584                 hr = IPersistStream_Load(pDocStream, pStream);
01585                 IStream_Release(pStream);
01586                 if(hr == S_OK)
01587                 {
01588                     *isSuccessful = VARIANT_TRUE;
01589 
01590                     TRACE("Using IStream to load Document\n");
01591                     return S_OK;
01592                 }
01593                 else
01594                 {
01595                     ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
01596                 }
01597             }
01598             else
01599             {
01600                 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
01601             }
01602         }
01603         else
01604         {
01605             /* ISequentialStream */
01606             FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
01607         }
01608         break;
01609      default:
01610             FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
01611      }
01612 
01613     TRACE("filename (%s)\n", debugstr_w(filename));
01614 
01615     if ( filename )
01616     {
01617         hr = doread( This, filename );
01618     
01619         if ( FAILED(hr) )
01620             This->error = E_FAIL;
01621         else
01622         {
01623             hr = This->error = S_OK;
01624             *isSuccessful = VARIANT_TRUE;
01625         }
01626     }
01627 
01628     if(!filename || FAILED(hr)) {
01629         xmldoc = xmlNewDoc(NULL);
01630         xmldoc->_private = create_priv();
01631         hr = attach_xmldoc(&This->node, xmldoc);
01632         if(SUCCEEDED(hr))
01633             hr = S_FALSE;
01634     }
01635 
01636     TRACE("ret (%d)\n", hr);
01637 
01638     return hr;
01639 }
01640 
01641 
01642 static HRESULT WINAPI domdoc_get_readyState(
01643     IXMLDOMDocument2 *iface,
01644     LONG *value )
01645 {
01646     domdoc *This = impl_from_IXMLDOMDocument2(iface);
01647     FIXME("(%p)->(%p)\n", This, value);
01648     return E_NOTIMPL;
01649 }
01650 
01651 
01652 static HRESULT WINAPI domdoc_get_parseError(
01653     IXMLDOMDocument2 *iface,
01654     IXMLDOMParseError** errorObj )
01655 {
01656     BSTR error_string = NULL;
01657     static const WCHAR err[] = {'e','r','r','o','r',0};
01658     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01659 
01660     FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
01661 
01662     if(This->error)
01663         error_string = SysAllocString(err);
01664 
01665     *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
01666     if(!*errorObj) return E_OUTOFMEMORY;
01667     return S_OK;
01668 }
01669 
01670 
01671 static HRESULT WINAPI domdoc_get_url(
01672     IXMLDOMDocument2 *iface,
01673     BSTR* urlString )
01674 {
01675     domdoc *This = impl_from_IXMLDOMDocument2(iface);
01676     FIXME("(%p)->(%p)\n", This, urlString);
01677     return E_NOTIMPL;
01678 }
01679 
01680 
01681 static HRESULT WINAPI domdoc_get_async(
01682     IXMLDOMDocument2 *iface,
01683     VARIANT_BOOL* isAsync )
01684 {
01685     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01686 
01687     TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async);
01688     *isAsync = This->async;
01689     return S_OK;
01690 }
01691 
01692 
01693 static HRESULT WINAPI domdoc_put_async(
01694     IXMLDOMDocument2 *iface,
01695     VARIANT_BOOL isAsync )
01696 {
01697     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01698 
01699     TRACE("(%p)->(%d)\n", This, isAsync);
01700     This->async = isAsync;
01701     return S_OK;
01702 }
01703 
01704 
01705 static HRESULT WINAPI domdoc_abort(
01706     IXMLDOMDocument2 *iface )
01707 {
01708     domdoc *This = impl_from_IXMLDOMDocument2(iface);
01709     FIXME("%p\n", This);
01710     return E_NOTIMPL;
01711 }
01712 
01713 
01714 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
01715 {
01716     UINT len;
01717     LPSTR str;
01718 
01719     len = WideCharToMultiByte( CP_UTF8, 0, bstr, -1, NULL, 0, NULL, NULL );
01720     str = heap_alloc( len );
01721     if ( !str )
01722         return FALSE;
01723     WideCharToMultiByte( CP_UTF8, 0, bstr, -1, str, len, NULL, NULL );
01724     *plen = len;
01725     *pstr = str;
01726     return TRUE;
01727 }
01728 
01729 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
01730 static HRESULT WINAPI domdoc_loadXML(
01731     IXMLDOMDocument2 *iface,
01732     BSTR bstrXML,
01733     VARIANT_BOOL* isSuccessful )
01734 {
01735     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01736     xmlDocPtr xmldoc = NULL;
01737     char *str;
01738     int len;
01739     HRESULT hr = S_FALSE, hr2;
01740 
01741     TRACE("(%p)->(%s %p)\n", This, debugstr_w( bstrXML ), isSuccessful );
01742 
01743     assert ( &This->node );
01744 
01745     if ( isSuccessful )
01746     {
01747         *isSuccessful = VARIANT_FALSE;
01748 
01749         if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
01750         {
01751             xmldoc = doparse( str, len, "UTF-8" );
01752             heap_free( str );
01753             if ( !xmldoc )
01754                 This->error = E_FAIL;
01755             else
01756             {
01757                 hr = This->error = S_OK;
01758                 *isSuccessful = VARIANT_TRUE;
01759             }
01760         }
01761     }
01762     if(!xmldoc)
01763         xmldoc = xmlNewDoc(NULL);
01764 
01765     xmldoc->_private = create_priv();
01766     hr2 = attach_xmldoc( &This->node, xmldoc );
01767     if( FAILED(hr2) )
01768         hr = hr2;
01769 
01770     return hr;
01771 }
01772 
01773 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
01774                                              int len)
01775 {
01776     DWORD written = -1;
01777 
01778     if(!WriteFile(ctx, buffer, len, &written, NULL))
01779     {
01780         WARN("write error\n");
01781         return -1;
01782     }
01783     else
01784         return written;
01785 }
01786 
01787 static int XMLCALL domdoc_save_closecallback(void *ctx)
01788 {
01789     return CloseHandle(ctx) ? 0 : -1;
01790 }
01791 
01792 static HRESULT WINAPI domdoc_save(
01793     IXMLDOMDocument2 *iface,
01794     VARIANT destination )
01795 {
01796     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01797     HANDLE handle;
01798     xmlSaveCtxtPtr ctx;
01799     xmlNodePtr xmldecl;
01800     HRESULT ret = S_OK;
01801 
01802     TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
01803           V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
01804 
01805     if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
01806     {
01807         FIXME("Unhandled vt %d\n", V_VT(&destination));
01808         return S_FALSE;
01809     }
01810 
01811     if(V_VT(&destination) == VT_UNKNOWN)
01812     {
01813         IUnknown *pUnk = V_UNKNOWN(&destination);
01814         IXMLDOMDocument2 *pDocument;
01815 
01816         ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
01817         if(ret == S_OK)
01818         {
01819             BSTR bXML;
01820             VARIANT_BOOL bSuccessful;
01821 
01822             ret = IXMLDOMDocument2_get_xml(iface, &bXML);
01823             if(ret == S_OK)
01824             {
01825                 ret = IXMLDOMDocument2_loadXML(pDocument, bXML, &bSuccessful);
01826 
01827                 SysFreeString(bXML);
01828             }
01829 
01830             IXMLDOMDocument2_Release(pDocument);
01831         }
01832 
01833         TRACE("ret %d\n", ret);
01834 
01835         return ret;
01836     }
01837 
01838     handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
01839                           NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
01840     if( handle == INVALID_HANDLE_VALUE )
01841     {
01842         WARN("failed to create file\n");
01843         return S_FALSE;
01844     }
01845 
01846     /* disable top XML declaration */
01847     ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
01848                       handle, NULL, XML_SAVE_NO_DECL);
01849     if (!ctx)
01850     {
01851         CloseHandle(handle);
01852         return S_FALSE;
01853     }
01854 
01855     xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
01856     if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
01857     xmldoc_link_xmldecl(get_doc(This), xmldecl);
01858 
01859     /* will close file through close callback */
01860     xmlSaveClose(ctx);
01861 
01862     return ret;
01863 }
01864 
01865 static HRESULT WINAPI domdoc_get_validateOnParse(
01866     IXMLDOMDocument2 *iface,
01867     VARIANT_BOOL* isValidating )
01868 {
01869     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01870 
01871     TRACE("(%p)->(%p: %d)\n", This, isValidating, This->validating);
01872     *isValidating = This->validating;
01873     return S_OK;
01874 }
01875 
01876 
01877 static HRESULT WINAPI domdoc_put_validateOnParse(
01878     IXMLDOMDocument2 *iface,
01879     VARIANT_BOOL isValidating )
01880 {
01881     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01882 
01883     TRACE("(%p)->(%d)\n", This, isValidating);
01884     This->validating = isValidating;
01885     return S_OK;
01886 }
01887 
01888 
01889 static HRESULT WINAPI domdoc_get_resolveExternals(
01890     IXMLDOMDocument2 *iface,
01891     VARIANT_BOOL* isResolving )
01892 {
01893     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01894 
01895     TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving);
01896     *isResolving = This->resolving;
01897     return S_OK;
01898 }
01899 
01900 
01901 static HRESULT WINAPI domdoc_put_resolveExternals(
01902     IXMLDOMDocument2 *iface,
01903     VARIANT_BOOL isResolving )
01904 {
01905     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01906 
01907     TRACE("(%p)->(%d)\n", This, isResolving);
01908     This->resolving = isResolving;
01909     return S_OK;
01910 }
01911 
01912 
01913 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
01914     IXMLDOMDocument2 *iface,
01915     VARIANT_BOOL* isPreserving )
01916 {
01917     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01918 
01919     TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->preserving);
01920     *isPreserving = This->preserving;
01921     return S_OK;
01922 }
01923 
01924 
01925 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
01926     IXMLDOMDocument2 *iface,
01927     VARIANT_BOOL isPreserving )
01928 {
01929     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01930 
01931     TRACE("(%p)->(%d)\n", This, isPreserving);
01932     This->preserving = isPreserving;
01933     return S_OK;
01934 }
01935 
01936 
01937 static HRESULT WINAPI domdoc_put_onReadyStateChange(
01938     IXMLDOMDocument2 *iface,
01939     VARIANT readyStateChangeSink )
01940 {
01941     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01942     FIXME("%p\n", This);
01943     return E_NOTIMPL;
01944 }
01945 
01946 
01947 static HRESULT WINAPI domdoc_put_onDataAvailable(
01948     IXMLDOMDocument2 *iface,
01949     VARIANT onDataAvailableSink )
01950 {
01951     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01952     FIXME("%p\n", This);
01953     return E_NOTIMPL;
01954 }
01955 
01956 static HRESULT WINAPI domdoc_put_onTransformNode(
01957     IXMLDOMDocument2 *iface,
01958     VARIANT onTransformNodeSink )
01959 {
01960     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01961     FIXME("%p\n", This);
01962     return E_NOTIMPL;
01963 }
01964 
01965 static HRESULT WINAPI domdoc_get_namespaces(
01966     IXMLDOMDocument2* iface,
01967     IXMLDOMSchemaCollection** schemaCollection )
01968 {
01969     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01970     FIXME("(%p)->(%p)\n", This, schemaCollection);
01971     return E_NOTIMPL;
01972 }
01973 
01974 static HRESULT WINAPI domdoc_get_schemas(
01975     IXMLDOMDocument2* iface,
01976     VARIANT* var1 )
01977 {
01978     domdoc *This = impl_from_IXMLDOMDocument2( iface );
01979     HRESULT hr = S_FALSE;
01980     IXMLDOMSchemaCollection *cur_schema = This->schema;
01981 
01982     TRACE("(%p)->(%p)\n", This, var1);
01983 
01984     VariantInit(var1); /* Test shows we don't call VariantClear here */
01985     V_VT(var1) = VT_NULL;
01986 
01987     if(cur_schema)
01988     {
01989         hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
01990         if(SUCCEEDED(hr))
01991             V_VT(var1) = VT_DISPATCH;
01992     }
01993     return hr;
01994 }
01995 
01996 static HRESULT WINAPI domdoc_putref_schemas(
01997     IXMLDOMDocument2* iface,
01998     VARIANT var1)
01999 {
02000     domdoc *This = impl_from_IXMLDOMDocument2( iface );
02001     HRESULT hr = E_FAIL;
02002     IXMLDOMSchemaCollection *new_schema = NULL;
02003 
02004     FIXME("(%p): semi-stub\n", This);
02005     switch(V_VT(&var1))
02006     {
02007     case VT_UNKNOWN:
02008         hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
02009         break;
02010 
02011     case VT_DISPATCH:
02012         hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
02013         break;
02014 
02015     case VT_NULL:
02016     case VT_EMPTY:
02017         hr = S_OK;
02018         break;
02019 
02020     default:
02021         WARN("Can't get schema from vt %x\n", V_VT(&var1));
02022     }
02023 
02024     if(SUCCEEDED(hr))
02025     {
02026         IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
02027         if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
02028     }
02029 
02030     return hr;
02031 }
02032 
02033 static HRESULT WINAPI domdoc_validate(
02034     IXMLDOMDocument2* iface,
02035     IXMLDOMParseError** err)
02036 {
02037     domdoc *This = impl_from_IXMLDOMDocument2( iface );
02038     FIXME("(%p)->(%p)\n", This, err);
02039     return E_NOTIMPL;
02040 }
02041 
02042 static HRESULT WINAPI domdoc_setProperty(
02043     IXMLDOMDocument2* iface,
02044     BSTR p,
02045     VARIANT var)
02046 {
02047     domdoc *This = impl_from_IXMLDOMDocument2( iface );
02048 
02049     TRACE("(%p)->(%s)\n", This, debugstr_w(p));
02050 
02051     if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
02052     {
02053         VARIANT varStr;
02054         HRESULT hr;
02055         BSTR bstr;
02056 
02057         V_VT(&varStr) = VT_EMPTY;
02058         if (V_VT(&var) != VT_BSTR)
02059         {
02060             if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
02061                 return hr;
02062             bstr = V_BSTR(&varStr);
02063         }
02064         else
02065             bstr = V_BSTR(&var);
02066 
02067         hr = S_OK;
02068         if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
02069             This->bUseXPath = TRUE;
02070         else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
02071             This->bUseXPath = FALSE;
02072         else
02073             hr = E_FAIL;
02074 
02075         VariantClear(&varStr);
02076         return hr;
02077     }
02078 
02079     FIXME("Unknown property %s\n", wine_dbgstr_w(p));
02080     return E_FAIL;
02081 }
02082 
02083 static HRESULT WINAPI domdoc_getProperty(
02084     IXMLDOMDocument2* iface,
02085     BSTR p,
02086     VARIANT* var)
02087 {
02088     domdoc *This = impl_from_IXMLDOMDocument2( iface );
02089 
02090     TRACE("(%p)->(%p)\n", This, debugstr_w(p));
02091 
02092     if (var == NULL)
02093         return E_INVALIDARG;
02094     if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
02095     {
02096         V_VT(var) = VT_BSTR;
02097         if (This->bUseXPath)
02098             V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
02099         else
02100             V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
02101         return S_OK;
02102     }
02103 
02104     FIXME("Unknown property %s\n", wine_dbgstr_w(p));
02105     return E_FAIL;
02106 }
02107 
02108 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
02109 {
02110     domdoc_QueryInterface,
02111     domdoc_AddRef,
02112     domdoc_Release,
02113     domdoc_GetTypeInfoCount,
02114     domdoc_GetTypeInfo,
02115     domdoc_GetIDsOfNames,
02116     domdoc_Invoke,
02117     domdoc_get_nodeName,
02118     domdoc_get_nodeValue,
02119     domdoc_put_nodeValue,
02120     domdoc_get_nodeType,
02121     domdoc_get_parentNode,
02122     domdoc_get_childNodes,
02123     domdoc_get_firstChild,
02124     domdoc_get_lastChild,
02125     domdoc_get_previousSibling,
02126     domdoc_get_nextSibling,
02127     domdoc_get_attributes,
02128     domdoc_insertBefore,
02129     domdoc_replaceChild,
02130     domdoc_removeChild,
02131     domdoc_appendChild,
02132     domdoc_hasChildNodes,
02133     domdoc_get_ownerDocument,
02134     domdoc_cloneNode,
02135     domdoc_get_nodeTypeString,
02136     domdoc_get_text,
02137     domdoc_put_text,
02138     domdoc_get_specified,
02139     domdoc_get_definition,
02140     domdoc_get_nodeTypedValue,
02141     domdoc_put_nodeTypedValue,
02142     domdoc_get_dataType,
02143     domdoc_put_dataType,
02144     domdoc_get_xml,
02145     domdoc_transformNode,
02146     domdoc_selectNodes,
02147     domdoc_selectSingleNode,
02148     domdoc_get_parsed,
02149     domdoc_get_namespaceURI,
02150     domdoc_get_prefix,
02151     domdoc_get_baseName,
02152     domdoc_transformNodeToObject,
02153     domdoc_get_doctype,
02154     domdoc_get_implementation,
02155     domdoc_get_documentElement,
02156     domdoc_put_documentElement,
02157     domdoc_createElement,
02158     domdoc_createDocumentFragment,
02159     domdoc_createTextNode,
02160     domdoc_createComment,
02161     domdoc_createCDATASection,
02162     domdoc_createProcessingInstruction,
02163     domdoc_createAttribute,
02164     domdoc_createEntityReference,
02165     domdoc_getElementsByTagName,
02166     domdoc_createNode,
02167     domdoc_nodeFromID,
02168     domdoc_load,
02169     domdoc_get_readyState,
02170     domdoc_get_parseError,
02171     domdoc_get_url,
02172     domdoc_get_async,
02173     domdoc_put_async,
02174     domdoc_abort,
02175     domdoc_loadXML,
02176     domdoc_save,
02177     domdoc_get_validateOnParse,
02178     domdoc_put_validateOnParse,
02179     domdoc_get_resolveExternals,
02180     domdoc_put_resolveExternals,
02181     domdoc_get_preserveWhiteSpace,
02182     domdoc_put_preserveWhiteSpace,
02183     domdoc_put_onReadyStateChange,
02184     domdoc_put_onDataAvailable,
02185     domdoc_put_onTransformNode,
02186     domdoc_get_namespaces,
02187     domdoc_get_schemas,
02188     domdoc_putref_schemas,
02189     domdoc_validate,
02190     domdoc_setProperty,
02191     domdoc_getProperty
02192 };
02193 
02194 /* xmldoc implementation of IObjectWithSite */
02195 static HRESULT WINAPI
02196 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
02197 {
02198     domdoc *This = impl_from_IObjectWithSite(iface);
02199     return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
02200 }
02201 
02202 static ULONG WINAPI
02203 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
02204 {
02205     domdoc *This = impl_from_IObjectWithSite(iface);
02206     return IXMLDocument_AddRef((IXMLDocument *)This);
02207 }
02208 
02209 static ULONG WINAPI
02210 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
02211 {
02212     domdoc *This = impl_from_IObjectWithSite(iface);
02213     return IXMLDocument_Release((IXMLDocument *)This);
02214 }
02215 
02216 static HRESULT WINAPI
02217 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
02218 {
02219     domdoc *This = impl_from_IObjectWithSite(iface);
02220 
02221     TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite );
02222 
02223     if ( !This->site )
02224         return E_FAIL;
02225 
02226     return IUnknown_QueryInterface( This->site, iid, ppvSite );
02227 }
02228 
02229 static HRESULT WINAPI
02230 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
02231 {
02232     domdoc *This = impl_from_IObjectWithSite(iface);
02233 
02234     TRACE("(%p)->(%p)\n", iface, punk);
02235 
02236     if(!punk)
02237     {
02238         if(This->site)
02239         {
02240             IUnknown_Release( This->site );
02241             This->site = NULL;
02242         }
02243 
02244         return S_OK;
02245     }
02246 
02247     IUnknown_AddRef( punk );
02248 
02249     if(This->site)
02250         IUnknown_Release( This->site );
02251 
02252     This->site = punk;
02253 
02254     return S_OK;
02255 }
02256 
02257 static const IObjectWithSiteVtbl domdocObjectSite =
02258 {
02259     xmldoc_ObjectWithSite_QueryInterface,
02260     xmldoc_ObjectWithSite_AddRef,
02261     xmldoc_ObjectWithSite_Release,
02262     xmldoc_SetSite,
02263     xmldoc_GetSite,
02264 };
02265 
02266 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
02267 {
02268     domdoc *This = impl_from_IObjectSafety(iface);
02269     return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
02270 }
02271 
02272 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
02273 {
02274     domdoc *This = impl_from_IObjectSafety(iface);
02275     return IXMLDocument_AddRef((IXMLDocument *)This);
02276 }
02277 
02278 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
02279 {
02280     domdoc *This = impl_from_IObjectSafety(iface);
02281     return IXMLDocument_Release((IXMLDocument *)This);
02282 }
02283 
02284 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
02285 
02286 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
02287         DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
02288 {
02289     domdoc *This = impl_from_IObjectSafety(iface);
02290 
02291     TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
02292 
02293     if(!pdwSupportedOptions || !pdwEnabledOptions)
02294         return E_POINTER;
02295 
02296     *pdwSupportedOptions = SAFETY_SUPPORTED_OPTIONS;
02297     *pdwEnabledOptions = This->safeopt;
02298 
02299     return S_OK;
02300 }
02301 
02302 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
02303         DWORD dwOptionSetMask, DWORD dwEnabledOptions)
02304 {
02305     domdoc *This = impl_from_IObjectSafety(iface);
02306     TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
02307 
02308     if ((dwOptionSetMask & ~SAFETY_SUPPORTED_OPTIONS) != 0)
02309         return E_FAIL;
02310 
02311     This->safeopt = dwEnabledOptions & dwOptionSetMask & SAFETY_SUPPORTED_OPTIONS;
02312     return S_OK;
02313 }
02314 
02315 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
02316     xmldoc_Safety_QueryInterface,
02317     xmldoc_Safety_AddRef,
02318     xmldoc_Safety_Release,
02319     xmldoc_Safety_GetInterfaceSafetyOptions,
02320     xmldoc_Safety_SetInterfaceSafetyOptions
02321 };
02322 
02323 
02324 static const tid_t domdoc_iface_tids[] = {
02325     IXMLDOMNode_tid,
02326     IXMLDOMDocument_tid,
02327     IXMLDOMDocument2_tid,
02328     0
02329 };
02330 static dispex_static_data_t domdoc_dispex = {
02331     NULL,
02332     IXMLDOMDocument2_tid,
02333     NULL,
02334     domdoc_iface_tids
02335 };
02336 
02337 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
02338 {
02339     domdoc *doc;
02340 
02341     doc = heap_alloc( sizeof (*doc) );
02342     if( !doc )
02343         return E_OUTOFMEMORY;
02344 
02345     doc->lpVtbl = &domdoc_vtbl;
02346     doc->lpvtblIPersistStreamInit = &xmldoc_IPersistStreamInit_VTable;
02347     doc->lpvtblIObjectWithSite = &domdocObjectSite;
02348     doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
02349     doc->lpvtblISupportErrorInfo = &support_error_vtbl;
02350     doc->ref = 1;
02351     doc->async = VARIANT_TRUE;
02352     doc->validating = 0;
02353     doc->resolving = 0;
02354     doc->preserving = 0;
02355     doc->bUseXPath = FALSE;
02356     doc->error = S_OK;
02357     doc->schema = NULL;
02358     doc->stream = NULL;
02359     doc->site = NULL;
02360     doc->safeopt = 0;
02361     doc->bsc = NULL;
02362 
02363     init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
02364 
02365     *document = (IXMLDOMDocument2*)&doc->lpVtbl;
02366 
02367     TRACE("returning iface %p\n", *document);
02368     return S_OK;
02369 }
02370 
02371 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
02372 {
02373     xmlDocPtr xmldoc;
02374     HRESULT hr;
02375 
02376     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
02377 
02378     xmldoc = xmlNewDoc(NULL);
02379     if(!xmldoc)
02380         return E_OUTOFMEMORY;
02381 
02382     xmldoc->_private = create_priv();
02383 
02384     hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
02385     if(FAILED(hr))
02386         xmlFreeDoc(xmldoc);
02387 
02388     return hr;
02389 }
02390 
02391 IUnknown* create_domdoc( xmlNodePtr document )
02392 {
02393     HRESULT hr;
02394     LPVOID pObj = NULL;
02395 
02396     TRACE("(%p)\n", document);
02397 
02398     hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
02399     if (FAILED(hr))
02400         return NULL;
02401 
02402     return pObj;
02403 }
02404 
02405 #else
02406 
02407 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
02408 {
02409     MESSAGE("This program tried to use a DOMDocument object, but\n"
02410             "libxml2 support was not present at compile time.\n");
02411     return E_NOTIMPL;
02412 }
02413 
02414 #endif

Generated on Sun May 27 2012 04:25:23 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.