msxml3: Accept S_FALSE as a valid callback result when msxml6 is used.
[wine] / dlls / msxml3 / entityref.c
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 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
42
43 #ifdef HAVE_LIBXML2
44
45 typedef struct _entityref
46 {
47     xmlnode node;
48     IXMLDOMEntityReference IXMLDOMEntityReference_iface;
49     LONG ref;
50 } entityref;
51
52 static inline entityref *impl_from_IXMLDOMEntityReference( IXMLDOMEntityReference *iface )
53 {
54     return CONTAINING_RECORD(iface, entityref, IXMLDOMEntityReference_iface);
55 }
56
57 static HRESULT WINAPI entityref_QueryInterface(
58     IXMLDOMEntityReference *iface,
59     REFIID riid,
60     void** ppvObject )
61 {
62     entityref *This = impl_from_IXMLDOMEntityReference( iface );
63     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
64
65     if ( IsEqualGUID( riid, &IID_IXMLDOMEntityReference ) ||
66          IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
67          IsEqualGUID( riid, &IID_IDispatch ) ||
68          IsEqualGUID( riid, &IID_IUnknown ) )
69     {
70         *ppvObject = iface;
71     }
72     else if(node_query_interface(&This->node, riid, ppvObject))
73     {
74         return *ppvObject ? S_OK : E_NOINTERFACE;
75     }
76     else
77     {
78         TRACE("Unsupported interface %s\n", debugstr_guid(riid));
79         *ppvObject = NULL;
80         return E_NOINTERFACE;
81     }
82
83     IUnknown_AddRef((IUnknown*)*ppvObject);
84     return S_OK;
85 }
86
87 static ULONG WINAPI entityref_AddRef(
88     IXMLDOMEntityReference *iface )
89 {
90     entityref *This = impl_from_IXMLDOMEntityReference( iface );
91     ULONG ref = InterlockedIncrement( &This->ref );
92     TRACE("(%p)->(%d)\n", This, ref);
93     return ref;
94 }
95
96 static ULONG WINAPI entityref_Release(
97     IXMLDOMEntityReference *iface )
98 {
99     entityref *This = impl_from_IXMLDOMEntityReference( iface );
100     ULONG ref = InterlockedDecrement( &This->ref );
101
102     TRACE("(%p)->(%d)\n", This, ref);
103     if ( ref == 0 )
104     {
105         destroy_xmlnode(&This->node);
106         heap_free( This );
107     }
108
109     return ref;
110 }
111
112 static HRESULT WINAPI entityref_GetTypeInfoCount(
113     IXMLDOMEntityReference *iface,
114     UINT* pctinfo )
115 {
116     entityref *This = impl_from_IXMLDOMEntityReference( iface );
117     TRACE("(%p)->(%p)\n", This, pctinfo);
118
119     *pctinfo = 1;
120
121     return S_OK;
122 }
123
124 static HRESULT WINAPI entityref_GetTypeInfo(
125     IXMLDOMEntityReference *iface,
126     UINT iTInfo, LCID lcid,
127     ITypeInfo** ppTInfo )
128 {
129     entityref *This = impl_from_IXMLDOMEntityReference( iface );
130     HRESULT hr;
131
132     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
133
134     hr = get_typeinfo(IXMLDOMEntityReference_tid, ppTInfo);
135
136     return hr;
137 }
138
139 static HRESULT WINAPI entityref_GetIDsOfNames(
140     IXMLDOMEntityReference *iface,
141     REFIID riid, LPOLESTR* rgszNames,
142     UINT cNames, LCID lcid, DISPID* rgDispId )
143 {
144     entityref *This = impl_from_IXMLDOMEntityReference( iface );
145     ITypeInfo *typeinfo;
146     HRESULT hr;
147
148     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
149           lcid, rgDispId);
150
151     if(!rgszNames || cNames == 0 || !rgDispId)
152         return E_INVALIDARG;
153
154     hr = get_typeinfo(IXMLDOMEntityReference_tid, &typeinfo);
155     if(SUCCEEDED(hr))
156     {
157         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
158         ITypeInfo_Release(typeinfo);
159     }
160
161     return hr;
162 }
163
164 static HRESULT WINAPI entityref_Invoke(
165     IXMLDOMEntityReference *iface,
166     DISPID dispIdMember, REFIID riid, LCID lcid,
167     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
168     EXCEPINFO* pExcepInfo, UINT* puArgErr )
169 {
170     entityref *This = impl_from_IXMLDOMEntityReference( iface );
171     ITypeInfo *typeinfo;
172     HRESULT hr;
173
174     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
175           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
176
177     hr = get_typeinfo(IXMLDOMEntityReference_tid, &typeinfo);
178     if(SUCCEEDED(hr))
179     {
180         hr = ITypeInfo_Invoke(typeinfo, &This->IXMLDOMEntityReference_iface, dispIdMember, wFlags,
181                 pDispParams, pVarResult, pExcepInfo, puArgErr);
182         ITypeInfo_Release(typeinfo);
183     }
184
185     return hr;
186 }
187
188 static HRESULT WINAPI entityref_get_nodeName(
189     IXMLDOMEntityReference *iface,
190     BSTR* p )
191 {
192     entityref *This = impl_from_IXMLDOMEntityReference( iface );
193
194     FIXME("(%p)->(%p)\n", This, p);
195
196     return node_get_nodeName(&This->node, p);
197 }
198
199 static HRESULT WINAPI entityref_get_nodeValue(
200     IXMLDOMEntityReference *iface,
201     VARIANT* value)
202 {
203     entityref *This = impl_from_IXMLDOMEntityReference( iface );
204
205     FIXME("(%p)->(%p)\n", This, value);
206
207     if(!value)
208         return E_INVALIDARG;
209
210     V_VT(value) = VT_NULL;
211     return S_FALSE;
212 }
213
214 static HRESULT WINAPI entityref_put_nodeValue(
215     IXMLDOMEntityReference *iface,
216     VARIANT value)
217 {
218     entityref *This = impl_from_IXMLDOMEntityReference( iface );
219     TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));
220     return E_FAIL;
221 }
222
223 static HRESULT WINAPI entityref_get_nodeType(
224     IXMLDOMEntityReference *iface,
225     DOMNodeType* domNodeType )
226 {
227     entityref *This = impl_from_IXMLDOMEntityReference( iface );
228
229     TRACE("(%p)->(%p)\n", This, domNodeType);
230
231     *domNodeType = NODE_ENTITY_REFERENCE;
232     return S_OK;
233 }
234
235 static HRESULT WINAPI entityref_get_parentNode(
236     IXMLDOMEntityReference *iface,
237     IXMLDOMNode** parent )
238 {
239     entityref *This = impl_from_IXMLDOMEntityReference( iface );
240
241     TRACE("(%p)->(%p)\n", This, parent);
242
243     return node_get_parent(&This->node, parent);
244 }
245
246 static HRESULT WINAPI entityref_get_childNodes(
247     IXMLDOMEntityReference *iface,
248     IXMLDOMNodeList** outList)
249 {
250     entityref *This = impl_from_IXMLDOMEntityReference( iface );
251
252     TRACE("(%p)->(%p)\n", This, outList);
253
254     return node_get_child_nodes(&This->node, outList);
255 }
256
257 static HRESULT WINAPI entityref_get_firstChild(
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_first_child(&This->node, domNode);
266 }
267
268 static HRESULT WINAPI entityref_get_lastChild(
269     IXMLDOMEntityReference *iface,
270     IXMLDOMNode** domNode)
271 {
272     entityref *This = impl_from_IXMLDOMEntityReference( iface );
273
274     TRACE("(%p)->(%p)\n", This, domNode);
275
276     return node_get_last_child(&This->node, domNode);
277 }
278
279 static HRESULT WINAPI entityref_get_previousSibling(
280     IXMLDOMEntityReference *iface,
281     IXMLDOMNode** domNode)
282 {
283     entityref *This = impl_from_IXMLDOMEntityReference( iface );
284
285     TRACE("(%p)->(%p)\n", This, domNode);
286
287     return node_get_previous_sibling(&This->node, domNode);
288 }
289
290 static HRESULT WINAPI entityref_get_nextSibling(
291     IXMLDOMEntityReference *iface,
292     IXMLDOMNode** domNode)
293 {
294     entityref *This = impl_from_IXMLDOMEntityReference( iface );
295
296     TRACE("(%p)->(%p)\n", This, domNode);
297
298     return node_get_next_sibling(&This->node, domNode);
299 }
300
301 static HRESULT WINAPI entityref_get_attributes(
302     IXMLDOMEntityReference *iface,
303     IXMLDOMNamedNodeMap** attributeMap)
304 {
305     entityref *This = impl_from_IXMLDOMEntityReference( iface );
306
307     TRACE("(%p)->(%p)\n", This, attributeMap);
308
309     return return_null_ptr((void**)attributeMap);
310 }
311
312 static HRESULT WINAPI entityref_insertBefore(
313     IXMLDOMEntityReference *iface,
314     IXMLDOMNode* newNode, VARIANT refChild,
315     IXMLDOMNode** outOldNode)
316 {
317     entityref *This = impl_from_IXMLDOMEntityReference( iface );
318
319     FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode);
320
321     return node_insert_before(&This->node, newNode, &refChild, outOldNode);
322 }
323
324 static HRESULT WINAPI entityref_replaceChild(
325     IXMLDOMEntityReference *iface,
326     IXMLDOMNode* newNode,
327     IXMLDOMNode* oldNode,
328     IXMLDOMNode** outOldNode)
329 {
330     entityref *This = impl_from_IXMLDOMEntityReference( iface );
331
332     FIXME("(%p)->(%p %p %p) needs test\n", This, newNode, oldNode, outOldNode);
333
334     return node_replace_child(&This->node, newNode, oldNode, outOldNode);
335 }
336
337 static HRESULT WINAPI entityref_removeChild(
338     IXMLDOMEntityReference *iface,
339     IXMLDOMNode *child, IXMLDOMNode **oldChild)
340 {
341     entityref *This = impl_from_IXMLDOMEntityReference( iface );
342     TRACE("(%p)->(%p %p)\n", This, child, oldChild);
343     return node_remove_child(&This->node, child, oldChild);
344 }
345
346 static HRESULT WINAPI entityref_appendChild(
347     IXMLDOMEntityReference *iface,
348     IXMLDOMNode *child, IXMLDOMNode **outChild)
349 {
350     entityref *This = impl_from_IXMLDOMEntityReference( iface );
351     TRACE("(%p)->(%p %p)\n", This, child, outChild);
352     return node_append_child(&This->node, child, outChild);
353 }
354
355 static HRESULT WINAPI entityref_hasChildNodes(
356     IXMLDOMEntityReference *iface,
357     VARIANT_BOOL *ret)
358 {
359     entityref *This = impl_from_IXMLDOMEntityReference( iface );
360     TRACE("(%p)->(%p)\n", This, ret);
361     return node_has_childnodes(&This->node, ret);
362 }
363
364 static HRESULT WINAPI entityref_get_ownerDocument(
365     IXMLDOMEntityReference *iface,
366     IXMLDOMDocument **doc)
367 {
368     entityref *This = impl_from_IXMLDOMEntityReference( iface );
369     TRACE("(%p)->(%p)\n", This, doc);
370     return node_get_owner_doc(&This->node, doc);
371 }
372
373 static HRESULT WINAPI entityref_cloneNode(
374     IXMLDOMEntityReference *iface,
375     VARIANT_BOOL deep, IXMLDOMNode** outNode)
376 {
377     entityref *This = impl_from_IXMLDOMEntityReference( iface );
378     TRACE("(%p)->(%d %p)\n", This, deep, outNode);
379     return node_clone( &This->node, deep, outNode );
380 }
381
382 static HRESULT WINAPI entityref_get_nodeTypeString(
383     IXMLDOMEntityReference *iface,
384     BSTR* p)
385 {
386     entityref *This = impl_from_IXMLDOMEntityReference( iface );
387     static const WCHAR entityreferenceW[] = {'e','n','t','i','t','y','r','e','f','e','r','e','n','c','e',0};
388
389     TRACE("(%p)->(%p)\n", This, p);
390
391     return return_bstr(entityreferenceW, p);
392 }
393
394 static HRESULT WINAPI entityref_get_text(
395     IXMLDOMEntityReference *iface,
396     BSTR* p)
397 {
398     entityref *This = impl_from_IXMLDOMEntityReference( iface );
399     TRACE("(%p)->(%p)\n", This, p);
400     return node_get_text(&This->node, p);
401 }
402
403 static HRESULT WINAPI entityref_put_text(
404     IXMLDOMEntityReference *iface,
405     BSTR p)
406 {
407     entityref *This = impl_from_IXMLDOMEntityReference( iface );
408     TRACE("(%p)->(%s)\n", This, debugstr_w(p));
409     return node_put_text( &This->node, p );
410 }
411
412 static HRESULT WINAPI entityref_get_specified(
413     IXMLDOMEntityReference *iface,
414     VARIANT_BOOL* isSpecified)
415 {
416     entityref *This = impl_from_IXMLDOMEntityReference( iface );
417     FIXME("(%p)->(%p) stub!\n", This, isSpecified);
418     *isSpecified = VARIANT_TRUE;
419     return S_OK;
420 }
421
422 static HRESULT WINAPI entityref_get_definition(
423     IXMLDOMEntityReference *iface,
424     IXMLDOMNode** definitionNode)
425 {
426     entityref *This = impl_from_IXMLDOMEntityReference( iface );
427     FIXME("(%p)->(%p)\n", This, definitionNode);
428     return E_NOTIMPL;
429 }
430
431 static HRESULT WINAPI entityref_get_nodeTypedValue(
432     IXMLDOMEntityReference *iface,
433     VARIANT* var1)
434 {
435     entityref *This = impl_from_IXMLDOMEntityReference( iface );
436     FIXME("(%p)->(%p)\n", This, var1);
437     return return_null_var(var1);
438 }
439
440 static HRESULT WINAPI entityref_put_nodeTypedValue(
441     IXMLDOMEntityReference *iface,
442     VARIANT typedValue)
443 {
444     entityref *This = impl_from_IXMLDOMEntityReference( iface );
445     FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue));
446     return E_NOTIMPL;
447 }
448
449 static HRESULT WINAPI entityref_get_dataType(
450     IXMLDOMEntityReference *iface,
451     VARIANT* typename)
452 {
453     entityref *This = impl_from_IXMLDOMEntityReference( iface );
454     FIXME("(%p)->(%p): should return a valid value\n", This, typename);
455     return return_null_var( typename );
456 }
457
458 static HRESULT WINAPI entityref_put_dataType(
459     IXMLDOMEntityReference *iface,
460     BSTR p)
461 {
462     entityref *This = impl_from_IXMLDOMEntityReference( iface );
463
464     FIXME("(%p)->(%s)\n", This, debugstr_w(p));
465
466     if(!p)
467         return E_INVALIDARG;
468
469     return E_FAIL;
470 }
471
472 static HRESULT WINAPI entityref_get_xml(
473     IXMLDOMEntityReference *iface,
474     BSTR* p)
475 {
476     entityref *This = impl_from_IXMLDOMEntityReference( iface );
477
478     TRACE("(%p)->(%p)\n", This, p);
479
480     return node_get_xml(&This->node, FALSE, FALSE, p);
481 }
482
483 static HRESULT WINAPI entityref_transformNode(
484     IXMLDOMEntityReference *iface,
485     IXMLDOMNode *node, BSTR *p)
486 {
487     entityref *This = impl_from_IXMLDOMEntityReference( iface );
488     TRACE("(%p)->(%p %p)\n", This, node, p);
489     return node_transform_node(&This->node, node, p);
490 }
491
492 static HRESULT WINAPI entityref_selectNodes(
493     IXMLDOMEntityReference *iface,
494     BSTR p, IXMLDOMNodeList** outList)
495 {
496     entityref *This = impl_from_IXMLDOMEntityReference( iface );
497     TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList);
498     return node_select_nodes(&This->node, p, outList);
499 }
500
501 static HRESULT WINAPI entityref_selectSingleNode(
502     IXMLDOMEntityReference *iface,
503     BSTR p, IXMLDOMNode** outNode)
504 {
505     entityref *This = impl_from_IXMLDOMEntityReference( iface );
506     TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode);
507     return node_select_singlenode(&This->node, p, outNode);
508 }
509
510 static HRESULT WINAPI entityref_get_parsed(
511     IXMLDOMEntityReference *iface,
512     VARIANT_BOOL* isParsed)
513 {
514     entityref *This = impl_from_IXMLDOMEntityReference( iface );
515     FIXME("(%p)->(%p) stub!\n", This, isParsed);
516     *isParsed = VARIANT_TRUE;
517     return S_OK;
518 }
519
520 static HRESULT WINAPI entityref_get_namespaceURI(
521     IXMLDOMEntityReference *iface,
522     BSTR* p)
523 {
524     entityref *This = impl_from_IXMLDOMEntityReference( iface );
525     TRACE("(%p)->(%p)\n", This, p);
526     return node_get_namespaceURI(&This->node, p);
527 }
528
529 static HRESULT WINAPI entityref_get_prefix(
530     IXMLDOMEntityReference *iface,
531     BSTR* prefix)
532 {
533     entityref *This = impl_from_IXMLDOMEntityReference( iface );
534     TRACE("(%p)->(%p)\n", This, prefix);
535     return node_get_prefix( &This->node, prefix );
536 }
537
538 static HRESULT WINAPI entityref_get_baseName(
539     IXMLDOMEntityReference *iface,
540     BSTR* name)
541 {
542     entityref *This = impl_from_IXMLDOMEntityReference( iface );
543     FIXME("(%p)->(%p): needs test\n", This, name);
544     return return_null_bstr( name );
545 }
546
547 static HRESULT WINAPI entityref_transformNodeToObject(
548     IXMLDOMEntityReference *iface,
549     IXMLDOMNode* domNode, VARIANT var1)
550 {
551     entityref *This = impl_from_IXMLDOMEntityReference( iface );
552     FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1));
553     return E_NOTIMPL;
554 }
555
556 static const struct IXMLDOMEntityReferenceVtbl entityref_vtbl =
557 {
558     entityref_QueryInterface,
559     entityref_AddRef,
560     entityref_Release,
561     entityref_GetTypeInfoCount,
562     entityref_GetTypeInfo,
563     entityref_GetIDsOfNames,
564     entityref_Invoke,
565     entityref_get_nodeName,
566     entityref_get_nodeValue,
567     entityref_put_nodeValue,
568     entityref_get_nodeType,
569     entityref_get_parentNode,
570     entityref_get_childNodes,
571     entityref_get_firstChild,
572     entityref_get_lastChild,
573     entityref_get_previousSibling,
574     entityref_get_nextSibling,
575     entityref_get_attributes,
576     entityref_insertBefore,
577     entityref_replaceChild,
578     entityref_removeChild,
579     entityref_appendChild,
580     entityref_hasChildNodes,
581     entityref_get_ownerDocument,
582     entityref_cloneNode,
583     entityref_get_nodeTypeString,
584     entityref_get_text,
585     entityref_put_text,
586     entityref_get_specified,
587     entityref_get_definition,
588     entityref_get_nodeTypedValue,
589     entityref_put_nodeTypedValue,
590     entityref_get_dataType,
591     entityref_put_dataType,
592     entityref_get_xml,
593     entityref_transformNode,
594     entityref_selectNodes,
595     entityref_selectSingleNode,
596     entityref_get_parsed,
597     entityref_get_namespaceURI,
598     entityref_get_prefix,
599     entityref_get_baseName,
600     entityref_transformNodeToObject,
601 };
602
603 IUnknown* create_doc_entity_ref( xmlNodePtr entity )
604 {
605     entityref *This;
606
607     This = heap_alloc( sizeof *This );
608     if ( !This )
609         return NULL;
610
611     This->IXMLDOMEntityReference_iface.lpVtbl = &entityref_vtbl;
612     This->ref = 1;
613
614     init_xmlnode(&This->node, entity, (IXMLDOMNode*)&This->IXMLDOMEntityReference_iface, NULL);
615
616     return (IUnknown*)&This->IXMLDOMEntityReference_iface;
617 }
618
619 #endif