1 /* 2 * DOM Entity Reference implementation 3 * 4 * Copyright 2007 Alistair Leslie-Hughes 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #define COBJMACROS 22 23 #include "config.h" 24 25 #include <stdarg.h> 26 #ifdef HAVE_LIBXML2 27 # include <libxml/parser.h> 28 # include <libxml/xmlerror.h> 29 #endif 30 31 #include "windef.h" 32 #include "winbase.h" 33 #include "winuser.h" 34 #include "ole2.h" 35 #include "msxml6.h" 36 37 #include "msxml_private.h" 38 39 #include "wine/debug.h" 40 41 #ifdef HAVE_LIBXML2 42 43 WINE_DEFAULT_DEBUG_CHANNEL(msxml); 44 45 typedef struct _entityref 46 { 47 xmlnode node; 48 IXMLDOMEntityReference IXMLDOMEntityReference_iface; 49 LONG ref; 50 } entityref; 51 52 static const tid_t domentityref_se_tids[] = { 53 IXMLDOMNode_tid, 54 IXMLDOMEntityReference_tid, 55 NULL_tid 56 }; 57 58 static inline entityref *impl_from_IXMLDOMEntityReference( IXMLDOMEntityReference *iface ) 59 { 60 return CONTAINING_RECORD(iface, entityref, IXMLDOMEntityReference_iface); 61 } 62 63 static HRESULT WINAPI entityref_QueryInterface( 64 IXMLDOMEntityReference *iface, 65 REFIID riid, 66 void** ppvObject ) 67 { 68 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 69 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); 70 71 if ( IsEqualGUID( riid, &IID_IXMLDOMEntityReference ) || 72 IsEqualGUID( riid, &IID_IXMLDOMNode ) || 73 IsEqualGUID( riid, &IID_IDispatch ) || 74 IsEqualGUID( riid, &IID_IUnknown ) ) 75 { 76 *ppvObject = iface; 77 } 78 else if(node_query_interface(&This->node, riid, ppvObject)) 79 { 80 return *ppvObject ? S_OK : E_NOINTERFACE; 81 } 82 else if (IsEqualGUID( riid, &IID_ISupportErrorInfo )) 83 { 84 return node_create_supporterrorinfo(domentityref_se_tids, ppvObject); 85 } 86 else 87 { 88 TRACE("Unsupported interface %s\n", debugstr_guid(riid)); 89 *ppvObject = NULL; 90 return E_NOINTERFACE; 91 } 92 93 IUnknown_AddRef((IUnknown*)*ppvObject); 94 return S_OK; 95 } 96 97 static ULONG WINAPI entityref_AddRef( 98 IXMLDOMEntityReference *iface ) 99 { 100 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 101 ULONG ref = InterlockedIncrement( &This->ref ); 102 TRACE("(%p)->(%d)\n", This, ref); 103 return ref; 104 } 105 106 static ULONG WINAPI entityref_Release( 107 IXMLDOMEntityReference *iface ) 108 { 109 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 110 ULONG ref = InterlockedDecrement( &This->ref ); 111 112 TRACE("(%p)->(%d)\n", This, ref); 113 if ( ref == 0 ) 114 { 115 destroy_xmlnode(&This->node); 116 heap_free( This ); 117 } 118 119 return ref; 120 } 121 122 static HRESULT WINAPI entityref_GetTypeInfoCount( 123 IXMLDOMEntityReference *iface, 124 UINT* pctinfo ) 125 { 126 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 127 return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); 128 } 129 130 static HRESULT WINAPI entityref_GetTypeInfo( 131 IXMLDOMEntityReference *iface, 132 UINT iTInfo, LCID lcid, 133 ITypeInfo** ppTInfo ) 134 { 135 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 136 return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, 137 iTInfo, lcid, ppTInfo); 138 } 139 140 static HRESULT WINAPI entityref_GetIDsOfNames( 141 IXMLDOMEntityReference *iface, 142 REFIID riid, LPOLESTR* rgszNames, 143 UINT cNames, LCID lcid, DISPID* rgDispId ) 144 { 145 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 146 return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, 147 riid, rgszNames, cNames, lcid, rgDispId); 148 } 149 150 static HRESULT WINAPI entityref_Invoke( 151 IXMLDOMEntityReference *iface, 152 DISPID dispIdMember, REFIID riid, LCID lcid, 153 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, 154 EXCEPINFO* pExcepInfo, UINT* puArgErr ) 155 { 156 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 157 return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, 158 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 159 } 160 161 static HRESULT WINAPI entityref_get_nodeName( 162 IXMLDOMEntityReference *iface, 163 BSTR* p ) 164 { 165 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 166 167 FIXME("(%p)->(%p)\n", This, p); 168 169 return node_get_nodeName(&This->node, p); 170 } 171 172 static HRESULT WINAPI entityref_get_nodeValue( 173 IXMLDOMEntityReference *iface, 174 VARIANT* value) 175 { 176 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 177 TRACE("(%p)->(%p)\n", This, value); 178 return return_null_var(value); 179 } 180 181 static HRESULT WINAPI entityref_put_nodeValue( 182 IXMLDOMEntityReference *iface, 183 VARIANT value) 184 { 185 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 186 TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); 187 return E_FAIL; 188 } 189 190 static HRESULT WINAPI entityref_get_nodeType( 191 IXMLDOMEntityReference *iface, 192 DOMNodeType* domNodeType ) 193 { 194 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 195 196 TRACE("(%p)->(%p)\n", This, domNodeType); 197 198 *domNodeType = NODE_ENTITY_REFERENCE; 199 return S_OK; 200 } 201 202 static HRESULT WINAPI entityref_get_parentNode( 203 IXMLDOMEntityReference *iface, 204 IXMLDOMNode** parent ) 205 { 206 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 207 208 TRACE("(%p)->(%p)\n", This, parent); 209 210 return node_get_parent(&This->node, parent); 211 } 212 213 static HRESULT WINAPI entityref_get_childNodes( 214 IXMLDOMEntityReference *iface, 215 IXMLDOMNodeList** outList) 216 { 217 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 218 219 TRACE("(%p)->(%p)\n", This, outList); 220 221 return node_get_child_nodes(&This->node, outList); 222 } 223 224 static HRESULT WINAPI entityref_get_firstChild( 225 IXMLDOMEntityReference *iface, 226 IXMLDOMNode** domNode) 227 { 228 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 229 230 TRACE("(%p)->(%p)\n", This, domNode); 231 232 return node_get_first_child(&This->node, domNode); 233 } 234 235 static HRESULT WINAPI entityref_get_lastChild( 236 IXMLDOMEntityReference *iface, 237 IXMLDOMNode** domNode) 238 { 239 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 240 241 TRACE("(%p)->(%p)\n", This, domNode); 242 243 return node_get_last_child(&This->node, domNode); 244 } 245 246 static HRESULT WINAPI entityref_get_previousSibling( 247 IXMLDOMEntityReference *iface, 248 IXMLDOMNode** domNode) 249 { 250 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 251 252 TRACE("(%p)->(%p)\n", This, domNode); 253 254 return node_get_previous_sibling(&This->node, domNode); 255 } 256 257 static HRESULT WINAPI entityref_get_nextSibling( 258 IXMLDOMEntityReference *iface, 259 IXMLDOMNode** domNode) 260 { 261 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 262 263 TRACE("(%p)->(%p)\n", This, domNode); 264 265 return node_get_next_sibling(&This->node, domNode); 266 } 267 268 static HRESULT WINAPI entityref_get_attributes( 269 IXMLDOMEntityReference *iface, 270 IXMLDOMNamedNodeMap** attributeMap) 271 { 272 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 273 274 TRACE("(%p)->(%p)\n", This, attributeMap); 275 276 return return_null_ptr((void**)attributeMap); 277 } 278 279 static HRESULT WINAPI entityref_insertBefore( 280 IXMLDOMEntityReference *iface, 281 IXMLDOMNode* newNode, VARIANT refChild, 282 IXMLDOMNode** outOldNode) 283 { 284 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 285 286 FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode); 287 288 return node_insert_before(&This->node, newNode, &refChild, outOldNode); 289 } 290 291 static HRESULT WINAPI entityref_replaceChild( 292 IXMLDOMEntityReference *iface, 293 IXMLDOMNode* newNode, 294 IXMLDOMNode* oldNode, 295 IXMLDOMNode** outOldNode) 296 { 297 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 298 299 FIXME("(%p)->(%p %p %p) needs test\n", This, newNode, oldNode, outOldNode); 300 301 return node_replace_child(&This->node, newNode, oldNode, outOldNode); 302 } 303 304 static HRESULT WINAPI entityref_removeChild( 305 IXMLDOMEntityReference *iface, 306 IXMLDOMNode *child, IXMLDOMNode **oldChild) 307 { 308 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 309 TRACE("(%p)->(%p %p)\n", This, child, oldChild); 310 return node_remove_child(&This->node, child, oldChild); 311 } 312 313 static HRESULT WINAPI entityref_appendChild( 314 IXMLDOMEntityReference *iface, 315 IXMLDOMNode *child, IXMLDOMNode **outChild) 316 { 317 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 318 TRACE("(%p)->(%p %p)\n", This, child, outChild); 319 return node_append_child(&This->node, child, outChild); 320 } 321 322 static HRESULT WINAPI entityref_hasChildNodes( 323 IXMLDOMEntityReference *iface, 324 VARIANT_BOOL *ret) 325 { 326 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 327 TRACE("(%p)->(%p)\n", This, ret); 328 return node_has_childnodes(&This->node, ret); 329 } 330 331 static HRESULT WINAPI entityref_get_ownerDocument( 332 IXMLDOMEntityReference *iface, 333 IXMLDOMDocument **doc) 334 { 335 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 336 TRACE("(%p)->(%p)\n", This, doc); 337 return node_get_owner_doc(&This->node, doc); 338 } 339 340 static HRESULT WINAPI entityref_cloneNode( 341 IXMLDOMEntityReference *iface, 342 VARIANT_BOOL deep, IXMLDOMNode** outNode) 343 { 344 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 345 TRACE("(%p)->(%d %p)\n", This, deep, outNode); 346 return node_clone( &This->node, deep, outNode ); 347 } 348 349 static HRESULT WINAPI entityref_get_nodeTypeString( 350 IXMLDOMEntityReference *iface, 351 BSTR* p) 352 { 353 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 354 static const WCHAR entityreferenceW[] = {'e','n','t','i','t','y','r','e','f','e','r','e','n','c','e',0}; 355 356 TRACE("(%p)->(%p)\n", This, p); 357 358 return return_bstr(entityreferenceW, p); 359 } 360 361 static HRESULT WINAPI entityref_get_text( 362 IXMLDOMEntityReference *iface, 363 BSTR* p) 364 { 365 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 366 TRACE("(%p)->(%p)\n", This, p); 367 return node_get_text(&This->node, p); 368 } 369 370 static HRESULT WINAPI entityref_put_text( 371 IXMLDOMEntityReference *iface, 372 BSTR p) 373 { 374 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 375 TRACE("(%p)->(%s)\n", This, debugstr_w(p)); 376 return node_put_text( &This->node, p ); 377 } 378 379 static HRESULT WINAPI entityref_get_specified( 380 IXMLDOMEntityReference *iface, 381 VARIANT_BOOL* isSpecified) 382 { 383 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 384 FIXME("(%p)->(%p) stub!\n", This, isSpecified); 385 *isSpecified = VARIANT_TRUE; 386 return S_OK; 387 } 388 389 static HRESULT WINAPI entityref_get_definition( 390 IXMLDOMEntityReference *iface, 391 IXMLDOMNode** definitionNode) 392 { 393 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 394 FIXME("(%p)->(%p)\n", This, definitionNode); 395 return E_NOTIMPL; 396 } 397 398 static HRESULT WINAPI entityref_get_nodeTypedValue( 399 IXMLDOMEntityReference *iface, 400 VARIANT* var1) 401 { 402 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 403 FIXME("(%p)->(%p)\n", This, var1); 404 return return_null_var(var1); 405 } 406 407 static HRESULT WINAPI entityref_put_nodeTypedValue( 408 IXMLDOMEntityReference *iface, 409 VARIANT typedValue) 410 { 411 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 412 FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue)); 413 return E_NOTIMPL; 414 } 415 416 static HRESULT WINAPI entityref_get_dataType( 417 IXMLDOMEntityReference *iface, 418 VARIANT* typename) 419 { 420 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 421 FIXME("(%p)->(%p): should return a valid value\n", This, typename); 422 return return_null_var( typename ); 423 } 424 425 static HRESULT WINAPI entityref_put_dataType( 426 IXMLDOMEntityReference *iface, 427 BSTR p) 428 { 429 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 430 431 TRACE("(%p)->(%s)\n", This, debugstr_w(p)); 432 433 if(!p) 434 return E_INVALIDARG; 435 436 return E_FAIL; 437 } 438 439 static HRESULT WINAPI entityref_get_xml( 440 IXMLDOMEntityReference *iface, 441 BSTR* p) 442 { 443 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 444 445 TRACE("(%p)->(%p)\n", This, p); 446 447 return node_get_xml(&This->node, FALSE, p); 448 } 449 450 static HRESULT WINAPI entityref_transformNode( 451 IXMLDOMEntityReference *iface, 452 IXMLDOMNode *node, BSTR *p) 453 { 454 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 455 TRACE("(%p)->(%p %p)\n", This, node, p); 456 return node_transform_node(&This->node, node, p); 457 } 458 459 static HRESULT WINAPI entityref_selectNodes( 460 IXMLDOMEntityReference *iface, 461 BSTR p, IXMLDOMNodeList** outList) 462 { 463 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 464 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); 465 return node_select_nodes(&This->node, p, outList); 466 } 467 468 static HRESULT WINAPI entityref_selectSingleNode( 469 IXMLDOMEntityReference *iface, 470 BSTR p, IXMLDOMNode** outNode) 471 { 472 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 473 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); 474 return node_select_singlenode(&This->node, p, outNode); 475 } 476 477 static HRESULT WINAPI entityref_get_parsed( 478 IXMLDOMEntityReference *iface, 479 VARIANT_BOOL* isParsed) 480 { 481 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 482 FIXME("(%p)->(%p) stub!\n", This, isParsed); 483 *isParsed = VARIANT_TRUE; 484 return S_OK; 485 } 486 487 static HRESULT WINAPI entityref_get_namespaceURI( 488 IXMLDOMEntityReference *iface, 489 BSTR* p) 490 { 491 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 492 TRACE("(%p)->(%p)\n", This, p); 493 return node_get_namespaceURI(&This->node, p); 494 } 495 496 static HRESULT WINAPI entityref_get_prefix( 497 IXMLDOMEntityReference *iface, 498 BSTR* prefix) 499 { 500 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 501 FIXME("(%p)->(%p): stub\n", This, prefix); 502 return return_null_bstr( prefix ); 503 } 504 505 static HRESULT WINAPI entityref_get_baseName( 506 IXMLDOMEntityReference *iface, 507 BSTR* name) 508 { 509 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 510 FIXME("(%p)->(%p): needs test\n", This, name); 511 return return_null_bstr( name ); 512 } 513 514 static HRESULT WINAPI entityref_transformNodeToObject( 515 IXMLDOMEntityReference *iface, 516 IXMLDOMNode* domNode, VARIANT var1) 517 { 518 entityref *This = impl_from_IXMLDOMEntityReference( iface ); 519 FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); 520 return E_NOTIMPL; 521 } 522 523 static const struct IXMLDOMEntityReferenceVtbl entityref_vtbl = 524 { 525 entityref_QueryInterface, 526 entityref_AddRef, 527 entityref_Release, 528 entityref_GetTypeInfoCount, 529 entityref_GetTypeInfo, 530 entityref_GetIDsOfNames, 531 entityref_Invoke, 532 entityref_get_nodeName, 533 entityref_get_nodeValue, 534 entityref_put_nodeValue, 535 entityref_get_nodeType, 536 entityref_get_parentNode, 537 entityref_get_childNodes, 538 entityref_get_firstChild, 539 entityref_get_lastChild, 540 entityref_get_previousSibling, 541 entityref_get_nextSibling, 542 entityref_get_attributes, 543 entityref_insertBefore, 544 entityref_replaceChild, 545 entityref_removeChild, 546 entityref_appendChild, 547 entityref_hasChildNodes, 548 entityref_get_ownerDocument, 549 entityref_cloneNode, 550 entityref_get_nodeTypeString, 551 entityref_get_text, 552 entityref_put_text, 553 entityref_get_specified, 554 entityref_get_definition, 555 entityref_get_nodeTypedValue, 556 entityref_put_nodeTypedValue, 557 entityref_get_dataType, 558 entityref_put_dataType, 559 entityref_get_xml, 560 entityref_transformNode, 561 entityref_selectNodes, 562 entityref_selectSingleNode, 563 entityref_get_parsed, 564 entityref_get_namespaceURI, 565 entityref_get_prefix, 566 entityref_get_baseName, 567 entityref_transformNodeToObject, 568 }; 569 570 static const tid_t domentityref_iface_tids[] = { 571 IXMLDOMEntityReference_tid, 572 0 573 }; 574 575 static dispex_static_data_t domentityref_dispex = { 576 NULL, 577 IXMLDOMEntityReference_tid, 578 NULL, 579 domentityref_iface_tids 580 }; 581 582 IUnknown* create_doc_entity_ref( xmlNodePtr entity ) 583 { 584 entityref *This; 585 586 This = heap_alloc( sizeof *This ); 587 if ( !This ) 588 return NULL; 589 590 This->IXMLDOMEntityReference_iface.lpVtbl = &entityref_vtbl; 591 This->ref = 1; 592 593 init_xmlnode(&This->node, entity, (IXMLDOMNode*)&This->IXMLDOMEntityReference_iface, &domentityref_dispex); 594 595 return (IUnknown*)&This->IXMLDOMEntityReference_iface; 596 } 597 598 #endif 599