Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendomdoc.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
1.7.6.1
|