kernel32: Update function docs for GetBinayType.
[wine] / dlls / msxml3 / element.c
1 /*
2  *    DOM Document implementation
3  *
4  * Copyright 2005 Mike McCormack
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 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winnls.h"
30 #include "ole2.h"
31 #include "msxml6.h"
32
33 #include "msxml_private.h"
34
35 #include "wine/debug.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
38
39 #ifdef HAVE_LIBXML2
40
41 typedef struct _domelem
42 {
43     xmlnode node;
44     const struct IXMLDOMElementVtbl *lpVtbl;
45     LONG ref;
46 } domelem;
47
48 static inline domelem *impl_from_IXMLDOMElement( IXMLDOMElement *iface )
49 {
50     return (domelem *)((char*)iface - FIELD_OFFSET(domelem, lpVtbl));
51 }
52
53 static inline xmlNodePtr get_element( const domelem *This )
54 {
55     return This->node.node;
56 }
57
58 static HRESULT WINAPI domelem_QueryInterface(
59     IXMLDOMElement *iface,
60     REFIID riid,
61     void** ppvObject )
62 {
63     domelem *This = impl_from_IXMLDOMElement( iface );
64
65     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
66
67     if ( IsEqualGUID( riid, &IID_IXMLDOMElement ) ||
68          IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
69          IsEqualGUID( riid, &IID_IDispatch ) ||
70          IsEqualGUID( riid, &IID_IUnknown ) )
71     {
72         *ppvObject = &This->lpVtbl;
73     }
74     else if(node_query_interface(&This->node, riid, ppvObject))
75     {
76         return *ppvObject ? S_OK : E_NOINTERFACE;
77     }
78     else
79     {
80         FIXME("interface %s not implemented\n", debugstr_guid(riid));
81         return E_NOINTERFACE;
82     }
83
84     IUnknown_AddRef( (IUnknown*)*ppvObject );
85     return S_OK;
86 }
87
88 static ULONG WINAPI domelem_AddRef(
89     IXMLDOMElement *iface )
90 {
91     domelem *This = impl_from_IXMLDOMElement( iface );
92     LONG ref = InterlockedIncrement(&This->ref);
93
94     TRACE("(%p) ref=%d\n", This, ref);
95
96     return ref;
97 }
98
99 static ULONG WINAPI domelem_Release(
100     IXMLDOMElement *iface )
101 {
102     domelem *This = impl_from_IXMLDOMElement( iface );
103     ULONG ref = InterlockedDecrement(&This->ref);
104
105     TRACE("(%p) ref=%d\n", This, ref);
106
107     if(!ref) {
108         destroy_xmlnode(&This->node);
109         heap_free(This);
110     }
111
112     return ref;
113 }
114
115 static HRESULT WINAPI domelem_GetTypeInfoCount(
116     IXMLDOMElement *iface,
117     UINT* pctinfo )
118 {
119     domelem *This = impl_from_IXMLDOMElement( iface );
120
121     TRACE("(%p)->(%p)\n", This, pctinfo);
122
123     *pctinfo = 1;
124
125     return S_OK;
126 }
127
128 static HRESULT WINAPI domelem_GetTypeInfo(
129     IXMLDOMElement *iface,
130     UINT iTInfo, LCID lcid,
131     ITypeInfo** ppTInfo )
132 {
133     domelem *This = impl_from_IXMLDOMElement( iface );
134     HRESULT hr;
135
136     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
137
138     hr = get_typeinfo(IXMLDOMElement_tid, ppTInfo);
139
140     return hr;
141 }
142
143 static HRESULT WINAPI domelem_GetIDsOfNames(
144     IXMLDOMElement *iface,
145     REFIID riid, LPOLESTR* rgszNames,
146     UINT cNames, LCID lcid, DISPID* rgDispId )
147 {
148     domelem *This = impl_from_IXMLDOMElement( iface );
149     ITypeInfo *typeinfo;
150     HRESULT hr;
151
152     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
153           lcid, rgDispId);
154
155     if(!rgszNames || cNames == 0 || !rgDispId)
156         return E_INVALIDARG;
157
158     hr = get_typeinfo(IXMLDOMElement_tid, &typeinfo);
159     if(SUCCEEDED(hr))
160     {
161         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
162         ITypeInfo_Release(typeinfo);
163     }
164
165     return hr;
166 }
167
168 static HRESULT WINAPI domelem_Invoke(
169     IXMLDOMElement *iface,
170     DISPID dispIdMember, REFIID riid, LCID lcid,
171     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
172     EXCEPINFO* pExcepInfo, UINT* puArgErr )
173 {
174     domelem *This = impl_from_IXMLDOMElement( iface );
175     ITypeInfo *typeinfo;
176     HRESULT hr;
177
178     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
179           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
180
181     hr = get_typeinfo(IXMLDOMElement_tid, &typeinfo);
182     if(SUCCEEDED(hr))
183     {
184         hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
185                 pVarResult, pExcepInfo, puArgErr);
186         ITypeInfo_Release(typeinfo);
187     }
188
189     return hr;
190 }
191
192 static HRESULT WINAPI domelem_get_nodeName(
193     IXMLDOMElement *iface,
194     BSTR* p )
195 {
196     domelem *This = impl_from_IXMLDOMElement( iface );
197
198     TRACE("(%p)->(%p)\n", This, p);
199
200     return node_get_nodeName(&This->node, p);
201 }
202
203 static HRESULT WINAPI domelem_get_nodeValue(
204     IXMLDOMElement *iface,
205     VARIANT* value)
206 {
207     domelem *This = impl_from_IXMLDOMElement( iface );
208
209     TRACE("(%p)->(%p)\n", This, value);
210
211     if(!value)
212         return E_INVALIDARG;
213
214     V_VT(value) = VT_NULL;
215     V_BSTR(value) = NULL; /* tests show that we should do this */
216     return S_FALSE;
217 }
218
219 static HRESULT WINAPI domelem_put_nodeValue(
220     IXMLDOMElement *iface,
221     VARIANT value)
222 {
223     domelem *This = impl_from_IXMLDOMElement( iface );
224     FIXME("(%p)->(v%d)\n", This, V_VT(&value));
225     return E_FAIL;
226 }
227
228 static HRESULT WINAPI domelem_get_nodeType(
229     IXMLDOMElement *iface,
230     DOMNodeType* domNodeType )
231 {
232     domelem *This = impl_from_IXMLDOMElement( iface );
233
234     TRACE("(%p)->(%p)\n", This, domNodeType);
235
236     *domNodeType = NODE_ELEMENT;
237     return S_OK;
238 }
239
240 static HRESULT WINAPI domelem_get_parentNode(
241     IXMLDOMElement *iface,
242     IXMLDOMNode** parent )
243 {
244     domelem *This = impl_from_IXMLDOMElement( iface );
245
246     TRACE("(%p)->(%p)\n", This, parent);
247
248     return node_get_parent(&This->node, parent);
249 }
250
251 static HRESULT WINAPI domelem_get_childNodes(
252     IXMLDOMElement *iface,
253     IXMLDOMNodeList** outList)
254 {
255     domelem *This = impl_from_IXMLDOMElement( iface );
256
257     TRACE("(%p)->(%p)\n", This, outList);
258
259     return node_get_child_nodes(&This->node, outList);
260 }
261
262 static HRESULT WINAPI domelem_get_firstChild(
263     IXMLDOMElement *iface,
264     IXMLDOMNode** domNode)
265 {
266     domelem *This = impl_from_IXMLDOMElement( iface );
267
268     TRACE("(%p)->(%p)\n", This, domNode);
269
270     return node_get_first_child(&This->node, domNode);
271 }
272
273 static HRESULT WINAPI domelem_get_lastChild(
274     IXMLDOMElement *iface,
275     IXMLDOMNode** domNode)
276 {
277     domelem *This = impl_from_IXMLDOMElement( iface );
278
279     TRACE("(%p)->(%p)\n", This, domNode);
280
281     return node_get_last_child(&This->node, domNode);
282 }
283
284 static HRESULT WINAPI domelem_get_previousSibling(
285     IXMLDOMElement *iface,
286     IXMLDOMNode** domNode)
287 {
288     domelem *This = impl_from_IXMLDOMElement( iface );
289
290     TRACE("(%p)->(%p)\n", This, domNode);
291
292     return node_get_previous_sibling(&This->node, domNode);
293 }
294
295 static HRESULT WINAPI domelem_get_nextSibling(
296     IXMLDOMElement *iface,
297     IXMLDOMNode** domNode)
298 {
299     domelem *This = impl_from_IXMLDOMElement( iface );
300
301     TRACE("(%p)->(%p)\n", This, domNode);
302
303     return node_get_next_sibling(&This->node, domNode);
304 }
305
306 static HRESULT WINAPI domelem_get_attributes(
307     IXMLDOMElement *iface,
308     IXMLDOMNamedNodeMap** attributeMap)
309 {
310     domelem *This = impl_from_IXMLDOMElement( iface );
311
312     TRACE("(%p)->(%p)\n", This, attributeMap);
313
314     *attributeMap = create_nodemap((IXMLDOMNode*)&This->lpVtbl);
315     return S_OK;
316 }
317
318 static HRESULT WINAPI domelem_insertBefore(
319     IXMLDOMElement *iface,
320     IXMLDOMNode* newNode, VARIANT refChild,
321     IXMLDOMNode** outOldNode)
322 {
323     domelem *This = impl_from_IXMLDOMElement( iface );
324
325     TRACE("(%p)->(%p x%d %p)\n", This, newNode, V_VT(&refChild), outOldNode);
326
327     return node_insert_before(&This->node, newNode, &refChild, outOldNode);
328 }
329
330 static HRESULT WINAPI domelem_replaceChild(
331     IXMLDOMElement *iface,
332     IXMLDOMNode* newNode,
333     IXMLDOMNode* oldNode,
334     IXMLDOMNode** outOldNode)
335 {
336     domelem *This = impl_from_IXMLDOMElement( iface );
337
338     TRACE("(%p)->(%p %p %p)\n", This, newNode, oldNode, outOldNode);
339
340     return node_replace_child(&This->node, newNode, oldNode, outOldNode);
341 }
342
343 static HRESULT WINAPI domelem_removeChild(
344     IXMLDOMElement *iface,
345     IXMLDOMNode* domNode, IXMLDOMNode** oldNode)
346 {
347     domelem *This = impl_from_IXMLDOMElement( iface );
348     return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), domNode, oldNode );
349 }
350
351 static HRESULT WINAPI domelem_appendChild(
352     IXMLDOMElement *iface,
353     IXMLDOMNode* newNode, IXMLDOMNode** outNewNode)
354 {
355     domelem *This = impl_from_IXMLDOMElement( iface );
356     return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newNode, outNewNode );
357 }
358
359 static HRESULT WINAPI domelem_hasChildNodes(
360     IXMLDOMElement *iface,
361     VARIANT_BOOL* pbool)
362 {
363     domelem *This = impl_from_IXMLDOMElement( iface );
364     return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), pbool );
365 }
366
367 static HRESULT WINAPI domelem_get_ownerDocument(
368     IXMLDOMElement *iface,
369     IXMLDOMDocument** domDocument)
370 {
371     domelem *This = impl_from_IXMLDOMElement( iface );
372     return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), domDocument );
373 }
374
375 static HRESULT WINAPI domelem_cloneNode(
376     IXMLDOMElement *iface,
377     VARIANT_BOOL pbool, IXMLDOMNode** outNode)
378 {
379     domelem *This = impl_from_IXMLDOMElement( iface );
380     return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), pbool, outNode );
381 }
382
383 static HRESULT WINAPI domelem_get_nodeTypeString(
384     IXMLDOMElement *iface,
385     BSTR* p)
386 {
387     domelem *This = impl_from_IXMLDOMElement( iface );
388     return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), p );
389 }
390
391 static HRESULT WINAPI domelem_get_text(
392     IXMLDOMElement *iface,
393     BSTR* p)
394 {
395     domelem *This = impl_from_IXMLDOMElement( iface );
396     return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), p );
397 }
398
399 static HRESULT WINAPI domelem_put_text(
400     IXMLDOMElement *iface,
401     BSTR p)
402 {
403     domelem *This = impl_from_IXMLDOMElement( iface );
404     TRACE("(%p)->(%s)\n", This, debugstr_w(p));
405     return node_put_text( &This->node, p );
406 }
407
408 static HRESULT WINAPI domelem_get_specified(
409     IXMLDOMElement *iface,
410     VARIANT_BOOL* isSpecified)
411 {
412     domelem *This = impl_from_IXMLDOMElement( iface );
413     FIXME("(%p)->(%p) stub!\n", This, isSpecified);
414     *isSpecified = VARIANT_TRUE;
415     return S_OK;
416 }
417
418 static HRESULT WINAPI domelem_get_definition(
419     IXMLDOMElement *iface,
420     IXMLDOMNode** definitionNode)
421 {
422     domelem *This = impl_from_IXMLDOMElement( iface );
423     FIXME("(%p)->(%p)\n", This, definitionNode);
424     return E_NOTIMPL;
425 }
426
427 static HRESULT WINAPI domelem_get_nodeTypedValue(
428     IXMLDOMElement *iface,
429     VARIANT* var1)
430 {
431     domelem *This = impl_from_IXMLDOMElement( iface );
432     return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), var1 );
433 }
434
435 static HRESULT WINAPI domelem_put_nodeTypedValue(
436     IXMLDOMElement *iface,
437     VARIANT var1)
438 {
439     domelem *This = impl_from_IXMLDOMElement( iface );
440     return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), var1 );
441 }
442
443 static HRESULT WINAPI domelem_get_dataType(
444     IXMLDOMElement *iface,
445     VARIANT* typename)
446 {
447     domelem *This = impl_from_IXMLDOMElement( iface );
448     xmlChar *pVal = xmlGetNsProp(get_element(This), (const xmlChar*)"dt",
449                                  (const xmlChar*)"urn:schemas-microsoft-com:datatypes");
450
451     TRACE("(%p)->(%p)\n", This, typename);
452
453     V_VT(typename) = VT_NULL;
454
455     if (pVal)
456     {
457         V_VT(typename) = VT_BSTR;
458         V_BSTR(typename) = bstr_from_xmlChar( pVal );
459         xmlFree(pVal);
460     }
461
462     return (V_VT(typename) != VT_NULL) ? S_OK : S_FALSE;
463 }
464
465 static HRESULT WINAPI domelem_put_dataType(
466     IXMLDOMElement *iface,
467     BSTR p)
468 {
469     domelem *This = impl_from_IXMLDOMElement( iface );
470     return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), p );
471 }
472
473 static HRESULT WINAPI domelem_get_xml(
474     IXMLDOMElement *iface,
475     BSTR* p)
476 {
477     domelem *This = impl_from_IXMLDOMElement( iface );
478     return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), p );
479 }
480
481 static HRESULT WINAPI domelem_transformNode(
482     IXMLDOMElement *iface,
483     IXMLDOMNode* domNode, BSTR* p)
484 {
485     domelem *This = impl_from_IXMLDOMElement( iface );
486     return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), domNode, p );
487 }
488
489 static HRESULT WINAPI domelem_selectNodes(
490     IXMLDOMElement *iface,
491     BSTR p, IXMLDOMNodeList** outList)
492 {
493     domelem *This = impl_from_IXMLDOMElement( iface );
494     return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), p, outList );
495 }
496
497 static HRESULT WINAPI domelem_selectSingleNode(
498     IXMLDOMElement *iface,
499     BSTR p, IXMLDOMNode** outNode)
500 {
501     domelem *This = impl_from_IXMLDOMElement( iface );
502     return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), p, outNode );
503 }
504
505 static HRESULT WINAPI domelem_get_parsed(
506     IXMLDOMElement *iface,
507     VARIANT_BOOL* isParsed)
508 {
509     domelem *This = impl_from_IXMLDOMElement( iface );
510     FIXME("(%p)->(%p) stub!\n", This, isParsed);
511     *isParsed = VARIANT_TRUE;
512     return S_OK;
513 }
514
515 static HRESULT WINAPI domelem_get_namespaceURI(
516     IXMLDOMElement *iface,
517     BSTR* p)
518 {
519     domelem *This = impl_from_IXMLDOMElement( iface );
520     return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), p );
521 }
522
523 static HRESULT WINAPI domelem_get_prefix(
524     IXMLDOMElement *iface,
525     BSTR* p)
526 {
527     domelem *This = impl_from_IXMLDOMElement( iface );
528     return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), p );
529 }
530
531 static HRESULT WINAPI domelem_get_baseName(
532     IXMLDOMElement *iface,
533     BSTR* p)
534 {
535     domelem *This = impl_from_IXMLDOMElement( iface );
536     return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), p );
537 }
538
539 static HRESULT WINAPI domelem_transformNodeToObject(
540     IXMLDOMElement *iface,
541     IXMLDOMNode* domNode, VARIANT var1)
542 {
543     domelem *This = impl_from_IXMLDOMElement( iface );
544     return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), domNode, var1 );
545 }
546
547 static HRESULT WINAPI domelem_get_tagName(
548     IXMLDOMElement *iface,
549     BSTR* p)
550 {
551     domelem *This = impl_from_IXMLDOMElement( iface );
552     xmlNodePtr element;
553     const xmlChar *prefix;
554     xmlChar *qname;
555
556     TRACE("(%p)->(%p)\n", This, p );
557
558     if (!p) return E_INVALIDARG;
559
560     element = get_element( This );
561     if ( !element )
562         return E_FAIL;
563
564     prefix = element->ns ? element->ns->prefix : NULL;
565     qname = xmlBuildQName(element->name, prefix, NULL, 0);
566
567     *p = bstr_from_xmlChar(qname);
568     if (qname != element->name) xmlFree(qname);
569
570     return *p ? S_OK : E_OUTOFMEMORY;
571 }
572
573 static HRESULT WINAPI domelem_getAttribute(
574     IXMLDOMElement *iface,
575     BSTR name, VARIANT* value)
576 {
577     domelem *This = impl_from_IXMLDOMElement( iface );
578     xmlNodePtr element;
579     xmlChar *xml_name, *xml_value = NULL;
580     HRESULT hr = S_FALSE;
581
582     TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), value);
583
584     if(!value || !name)
585         return E_INVALIDARG;
586
587     element = get_element( This );
588     if ( !element )
589         return E_FAIL;
590
591     V_BSTR(value) = NULL;
592     V_VT(value) = VT_NULL;
593
594     xml_name = xmlChar_from_wchar( name );
595
596     if(!xmlValidateNameValue(xml_name))
597         hr = E_FAIL;
598     else
599         xml_value = xmlGetNsProp(element, xml_name, NULL);
600
601     heap_free(xml_name);
602     if(xml_value)
603     {
604         V_VT(value) = VT_BSTR;
605         V_BSTR(value) = bstr_from_xmlChar( xml_value );
606         xmlFree(xml_value);
607         hr = S_OK;
608     }
609
610     return hr;
611 }
612
613 static HRESULT WINAPI domelem_setAttribute(
614     IXMLDOMElement *iface,
615     BSTR name, VARIANT value)
616 {
617     domelem *This = impl_from_IXMLDOMElement( iface );
618     xmlNodePtr element;
619     xmlChar *xml_name, *xml_value;
620     HRESULT hr;
621     VARIANT var;
622
623     TRACE("(%p)->(%s var)\n", This, debugstr_w(name));
624
625     element = get_element( This );
626     if ( !element )
627         return E_FAIL;
628
629     VariantInit(&var);
630     hr = VariantChangeType(&var, &value, 0, VT_BSTR);
631     if(hr != S_OK)
632     {
633         FIXME("VariantChangeType failed\n");
634         return hr;
635     }
636
637     xml_name = xmlChar_from_wchar( name );
638     xml_value = xmlChar_from_wchar( V_BSTR(&var) );
639
640     if(!xmlSetNsProp(element, NULL,  xml_name, xml_value))
641         hr = E_FAIL;
642
643     heap_free(xml_value);
644     heap_free(xml_name);
645     VariantClear(&var);
646
647     return hr;
648 }
649
650 static HRESULT WINAPI domelem_removeAttribute(
651     IXMLDOMElement *iface,
652     BSTR p)
653 {
654     domelem *This = impl_from_IXMLDOMElement( iface );
655     IXMLDOMNamedNodeMap *attr;
656     HRESULT hr;
657
658     TRACE("(%p)->(%s)\n", This, debugstr_w(p));
659
660     hr = IXMLDOMElement_get_attributes(iface, &attr);
661     if (hr != S_OK) return hr;
662
663     hr = IXMLDOMNamedNodeMap_removeNamedItem(attr, p, NULL);
664     IXMLDOMNamedNodeMap_Release(attr);
665
666     return hr;
667 }
668
669 static HRESULT WINAPI domelem_getAttributeNode(
670     IXMLDOMElement *iface,
671     BSTR p, IXMLDOMAttribute** attributeNode )
672 {
673     domelem *This = impl_from_IXMLDOMElement( iface );
674     xmlChar *xml_name;
675     xmlNodePtr element;
676     xmlAttrPtr attr;
677     IUnknown *unk;
678     HRESULT hr = S_FALSE;
679
680     TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), attributeNode);
681
682     if(!attributeNode)
683         return E_FAIL;
684
685     *attributeNode = NULL;
686
687     element = get_element( This );
688     if ( !element )
689         return E_FAIL;
690
691     xml_name = xmlChar_from_wchar(p);
692
693     if(!xmlValidateNameValue(xml_name))
694     {
695         heap_free(xml_name);
696         return E_FAIL;
697     }
698
699     attr = xmlHasProp(element, xml_name);
700     if(attr) {
701         unk = create_attribute((xmlNodePtr)attr);
702         hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMAttribute, (void**)attributeNode);
703         IUnknown_Release(unk);
704     }
705
706     heap_free(xml_name);
707
708     return hr;
709 }
710
711 static HRESULT WINAPI domelem_setAttributeNode(
712     IXMLDOMElement *iface,
713     IXMLDOMAttribute* attribute,
714     IXMLDOMAttribute** old)
715 {
716     domelem *This = impl_from_IXMLDOMElement( iface );
717     xmlChar *name, *value;
718     BSTR nameW, prefix;
719     xmlAttrPtr attr;
720     VARIANT valueW;
721     HRESULT hr;
722
723     FIXME("(%p)->(%p %p): semi-stub\n", This, attribute, old);
724
725     if (!attribute) return E_INVALIDARG;
726
727     if (old) *old = NULL;
728
729     hr = IXMLDOMAttribute_get_nodeName(attribute, &nameW);
730     if (hr != S_OK) return hr;
731
732     hr = IXMLDOMAttribute_get_nodeValue(attribute, &valueW);
733     if (hr != S_OK)
734     {
735         SysFreeString(nameW);
736         return hr;
737     }
738
739     TRACE("attribute: %s=%s\n", debugstr_w(nameW), debugstr_w(V_BSTR(&valueW)));
740
741     hr = IXMLDOMAttribute_get_prefix(attribute, &prefix);
742     if (hr == S_OK)
743     {
744         FIXME("namespaces not supported: %s\n", debugstr_w(prefix));
745         SysFreeString(prefix);
746     }
747
748     name = xmlChar_from_wchar(nameW);
749     value = xmlChar_from_wchar(V_BSTR(&valueW));
750
751     if (!name || !value)
752     {
753         SysFreeString(nameW);
754         VariantClear(&valueW);
755         heap_free(name);
756         heap_free(value);
757         return E_OUTOFMEMORY;
758     }
759
760     attr = xmlSetNsProp(get_element(This), NULL, name, value);
761
762     SysFreeString(nameW);
763     VariantClear(&valueW);
764     heap_free(name);
765     heap_free(value);
766
767     return attr ? S_OK : E_FAIL;
768 }
769
770 static HRESULT WINAPI domelem_removeAttributeNode(
771     IXMLDOMElement *iface,
772     IXMLDOMAttribute* domAttribute,
773     IXMLDOMAttribute** attributeNode)
774 {
775     domelem *This = impl_from_IXMLDOMElement( iface );
776     FIXME("(%p)->(%p %p)\n", This, domAttribute, attributeNode);
777     return E_NOTIMPL;
778 }
779
780 static HRESULT WINAPI domelem_getElementsByTagName(
781     IXMLDOMElement *iface,
782     BSTR tagName, IXMLDOMNodeList** resultList)
783 {
784     domelem *This = impl_from_IXMLDOMElement( iface );
785     xmlNodePtr element;
786     HRESULT hr;
787
788     TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
789
790     if (!tagName || !resultList) return E_INVALIDARG;
791     if (!(element = get_element(This))) return E_FAIL;
792
793     if (tagName[0] == '*' && tagName[1] == 0)
794     {
795         static const WCHAR formatallW[] = {'/','/','*',0};
796         hr = queryresult_create(element, formatallW, resultList);
797     }
798     else
799     {
800         static const WCHAR xpathformat[] =
801             { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'' };
802         static const WCHAR closeW[] = { '\'',']',0 };
803
804         LPWSTR pattern;
805         WCHAR *ptr;
806         INT length;
807
808         length = lstrlenW(tagName);
809
810         /* without two WCHARs from format specifier */
811         ptr = pattern = heap_alloc(sizeof(xpathformat) + length*sizeof(WCHAR) + sizeof(closeW));
812
813         memcpy(ptr, xpathformat, sizeof(xpathformat));
814         ptr += sizeof(xpathformat)/sizeof(WCHAR);
815         memcpy(ptr, tagName, length*sizeof(WCHAR));
816         ptr += length;
817         memcpy(ptr, closeW, sizeof(closeW));
818
819         TRACE("%s\n", debugstr_w(pattern));
820         hr = queryresult_create(element, pattern, resultList);
821         heap_free(pattern);
822     }
823
824     return hr;
825 }
826
827 static HRESULT WINAPI domelem_normalize(
828     IXMLDOMElement *iface )
829 {
830     domelem *This = impl_from_IXMLDOMElement( iface );
831     FIXME("%p\n", This);
832     return E_NOTIMPL;
833 }
834
835 static const struct IXMLDOMElementVtbl domelem_vtbl =
836 {
837     domelem_QueryInterface,
838     domelem_AddRef,
839     domelem_Release,
840     domelem_GetTypeInfoCount,
841     domelem_GetTypeInfo,
842     domelem_GetIDsOfNames,
843     domelem_Invoke,
844     domelem_get_nodeName,
845     domelem_get_nodeValue,
846     domelem_put_nodeValue,
847     domelem_get_nodeType,
848     domelem_get_parentNode,
849     domelem_get_childNodes,
850     domelem_get_firstChild,
851     domelem_get_lastChild,
852     domelem_get_previousSibling,
853     domelem_get_nextSibling,
854     domelem_get_attributes,
855     domelem_insertBefore,
856     domelem_replaceChild,
857     domelem_removeChild,
858     domelem_appendChild,
859     domelem_hasChildNodes,
860     domelem_get_ownerDocument,
861     domelem_cloneNode,
862     domelem_get_nodeTypeString,
863     domelem_get_text,
864     domelem_put_text,
865     domelem_get_specified,
866     domelem_get_definition,
867     domelem_get_nodeTypedValue,
868     domelem_put_nodeTypedValue,
869     domelem_get_dataType,
870     domelem_put_dataType,
871     domelem_get_xml,
872     domelem_transformNode,
873     domelem_selectNodes,
874     domelem_selectSingleNode,
875     domelem_get_parsed,
876     domelem_get_namespaceURI,
877     domelem_get_prefix,
878     domelem_get_baseName,
879     domelem_transformNodeToObject,
880     domelem_get_tagName,
881     domelem_getAttribute,
882     domelem_setAttribute,
883     domelem_removeAttribute,
884     domelem_getAttributeNode,
885     domelem_setAttributeNode,
886     domelem_removeAttributeNode,
887     domelem_getElementsByTagName,
888     domelem_normalize,
889 };
890
891 static const tid_t domelem_iface_tids[] = {
892     IXMLDOMElement_tid,
893     0
894 };
895
896 static dispex_static_data_t domelem_dispex = {
897     NULL,
898     IXMLDOMElement_tid,
899     NULL,
900     domelem_iface_tids
901 };
902
903 IUnknown* create_element( xmlNodePtr element )
904 {
905     domelem *This;
906
907     This = heap_alloc( sizeof *This );
908     if ( !This )
909         return NULL;
910
911     This->lpVtbl = &domelem_vtbl;
912     This->ref = 1;
913
914     init_xmlnode(&This->node, element, (IXMLDOMNode*)&This->lpVtbl, &domelem_dispex);
915
916     return (IUnknown*) &This->lpVtbl;
917 }
918
919 #endif