urlmon: Use wine lists to store namespaces and MIME filters.
[wine] / dlls / msxml3 / pi.c
1 /*
2  *    DOM processing instruction node implementation
3  *
4  * Copyright 2006 Huw Davies
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 _dom_pi
46 {
47     xmlnode node;
48     IXMLDOMProcessingInstruction IXMLDOMProcessingInstruction_iface;
49     LONG ref;
50 } dom_pi;
51
52 static const struct nodemap_funcs dom_pi_attr_map;
53
54 static const tid_t dompi_se_tids[] = {
55     IXMLDOMNode_tid,
56     IXMLDOMProcessingInstruction_tid,
57     0
58 };
59
60 static inline dom_pi *impl_from_IXMLDOMProcessingInstruction( IXMLDOMProcessingInstruction *iface )
61 {
62     return CONTAINING_RECORD(iface, dom_pi, IXMLDOMProcessingInstruction_iface);
63 }
64
65 static HRESULT WINAPI dom_pi_QueryInterface(
66     IXMLDOMProcessingInstruction *iface,
67     REFIID riid,
68     void** ppvObject )
69 {
70     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
71     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
72
73     if ( IsEqualGUID( riid, &IID_IXMLDOMProcessingInstruction ) ||
74          IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
75          IsEqualGUID( riid, &IID_IDispatch ) ||
76          IsEqualGUID( riid, &IID_IUnknown ) )
77     {
78         *ppvObject = iface;
79     }
80     else if(node_query_interface(&This->node, riid, ppvObject))
81     {
82         return *ppvObject ? S_OK : E_NOINTERFACE;
83     }
84     else if(IsEqualGUID( riid, &IID_ISupportErrorInfo ))
85     {
86         return node_create_supporterrorinfo(dompi_se_tids, ppvObject);
87     }
88     else
89     {
90         TRACE("Unsupported interface %s\n", debugstr_guid(riid));
91         *ppvObject = NULL;
92         return E_NOINTERFACE;
93     }
94
95     IUnknown_AddRef((IUnknown*)*ppvObject);
96     return S_OK;
97 }
98
99 static ULONG WINAPI dom_pi_AddRef(
100     IXMLDOMProcessingInstruction *iface )
101 {
102     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
103     ULONG ref = InterlockedIncrement( &This->ref );
104     TRACE("(%p)->(%d)\n", This, ref);
105     return ref;
106 }
107
108 static ULONG WINAPI dom_pi_Release(
109     IXMLDOMProcessingInstruction *iface )
110 {
111     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
112     ULONG ref = InterlockedDecrement( &This->ref );
113
114     TRACE("(%p)->(%d)\n", This, ref);
115     if ( ref == 0 )
116     {
117         destroy_xmlnode(&This->node);
118         heap_free( This );
119     }
120
121     return ref;
122 }
123
124 static HRESULT WINAPI dom_pi_GetTypeInfoCount(
125     IXMLDOMProcessingInstruction *iface,
126     UINT* pctinfo )
127 {
128     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
129
130     TRACE("(%p)->(%p)\n", This, pctinfo);
131
132     *pctinfo = 1;
133
134     return S_OK;
135 }
136
137 static HRESULT WINAPI dom_pi_GetTypeInfo(
138     IXMLDOMProcessingInstruction *iface,
139     UINT iTInfo, LCID lcid,
140     ITypeInfo** ppTInfo )
141 {
142     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
143
144     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
145
146     return get_typeinfo(IXMLDOMProcessingInstruction_tid, ppTInfo);
147 }
148
149 static HRESULT WINAPI dom_pi_GetIDsOfNames(
150     IXMLDOMProcessingInstruction *iface,
151     REFIID riid, LPOLESTR* rgszNames,
152     UINT cNames, LCID lcid, DISPID* rgDispId )
153 {
154     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
155     ITypeInfo *typeinfo;
156     HRESULT hr;
157
158     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
159           lcid, rgDispId);
160
161     if(!rgszNames || cNames == 0 || !rgDispId)
162         return E_INVALIDARG;
163
164     hr = get_typeinfo(IXMLDOMProcessingInstruction_tid, &typeinfo);
165     if(SUCCEEDED(hr))
166     {
167         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
168         ITypeInfo_Release(typeinfo);
169     }
170
171     return hr;
172 }
173
174 static HRESULT WINAPI dom_pi_Invoke(
175     IXMLDOMProcessingInstruction *iface,
176     DISPID dispIdMember, REFIID riid, LCID lcid,
177     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
178     EXCEPINFO* pExcepInfo, UINT* puArgErr )
179 {
180     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
181     ITypeInfo *typeinfo;
182     HRESULT hr;
183
184     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
185           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
186
187     hr = get_typeinfo(IXMLDOMProcessingInstruction_tid, &typeinfo);
188     if(SUCCEEDED(hr))
189     {
190        hr = ITypeInfo_Invoke(typeinfo, &This->IXMLDOMProcessingInstruction_iface, dispIdMember,
191                 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
192         ITypeInfo_Release(typeinfo);
193     }
194
195     return hr;
196 }
197
198 static HRESULT WINAPI dom_pi_get_nodeName(
199     IXMLDOMProcessingInstruction *iface,
200     BSTR* p )
201 {
202     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
203
204     TRACE("(%p)->(%p)\n", This, p);
205
206     return node_get_nodeName(&This->node, p);
207 }
208
209 static HRESULT WINAPI dom_pi_get_nodeValue(
210     IXMLDOMProcessingInstruction *iface,
211     VARIANT* value)
212 {
213     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
214
215     TRACE("(%p)->(%p)\n", This, value);
216
217     return node_get_content(&This->node, value);
218 }
219
220 static HRESULT WINAPI dom_pi_put_nodeValue(
221     IXMLDOMProcessingInstruction *iface,
222     VARIANT value)
223 {
224     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
225     BSTR target;
226     HRESULT hr;
227
228     TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));
229
230     /* Cannot set data to a PI node whose target is 'xml' */
231     hr = IXMLDOMProcessingInstruction_get_nodeName(iface, &target);
232     if(hr == S_OK)
233     {
234         static const WCHAR xmlW[] = {'x','m','l',0};
235         if(!strcmpW(target, xmlW))
236         {
237             SysFreeString(target);
238             return E_FAIL;
239         }
240
241         SysFreeString(target);
242     }
243
244     return node_put_value(&This->node, &value);
245 }
246
247 static HRESULT WINAPI dom_pi_get_nodeType(
248     IXMLDOMProcessingInstruction *iface,
249     DOMNodeType* domNodeType )
250 {
251     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
252
253     TRACE("(%p)->(%p)\n", This, domNodeType);
254
255     *domNodeType = NODE_PROCESSING_INSTRUCTION;
256     return S_OK;
257 }
258
259 static HRESULT WINAPI dom_pi_get_parentNode(
260     IXMLDOMProcessingInstruction *iface,
261     IXMLDOMNode** parent )
262 {
263     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
264
265     TRACE("(%p)->(%p)\n", This, parent);
266
267     return node_get_parent(&This->node, parent);
268 }
269
270 static HRESULT WINAPI dom_pi_get_childNodes(
271     IXMLDOMProcessingInstruction *iface,
272     IXMLDOMNodeList** outList)
273 {
274     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
275
276     TRACE("(%p)->(%p)\n", This, outList);
277
278     return node_get_child_nodes(&This->node, outList);
279 }
280
281 static HRESULT WINAPI dom_pi_get_firstChild(
282     IXMLDOMProcessingInstruction *iface,
283     IXMLDOMNode** domNode)
284 {
285     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
286
287     TRACE("(%p)->(%p)\n", This, domNode);
288
289     return return_null_node(domNode);
290 }
291
292 static HRESULT WINAPI dom_pi_get_lastChild(
293     IXMLDOMProcessingInstruction *iface,
294     IXMLDOMNode** domNode)
295 {
296     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
297
298     TRACE("(%p)->(%p)\n", This, domNode);
299
300     return return_null_node(domNode);
301 }
302
303 static HRESULT WINAPI dom_pi_get_previousSibling(
304     IXMLDOMProcessingInstruction *iface,
305     IXMLDOMNode** domNode)
306 {
307     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
308
309     TRACE("(%p)->(%p)\n", This, domNode);
310
311     return node_get_previous_sibling(&This->node, domNode);
312 }
313
314 static HRESULT WINAPI dom_pi_get_nextSibling(
315     IXMLDOMProcessingInstruction *iface,
316     IXMLDOMNode** domNode)
317 {
318     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
319
320     TRACE("(%p)->(%p)\n", This, domNode);
321
322     return node_get_next_sibling(&This->node, domNode);
323 }
324
325 static HRESULT WINAPI dom_pi_get_attributes(
326     IXMLDOMProcessingInstruction *iface,
327     IXMLDOMNamedNodeMap** map)
328 {
329     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
330     static const WCHAR xmlW[] = {'x','m','l',0};
331     HRESULT hr;
332     BSTR name;
333
334     TRACE("(%p)->(%p)\n", This, map);
335
336     if (!map) return E_INVALIDARG;
337
338     *map = NULL;
339
340     hr = node_get_nodeName(&This->node, &name);
341     if (hr != S_OK) return hr;
342
343     if (!strcmpW(name, xmlW))
344     {
345         FIXME("created dummy map for <?xml ?>\n");
346         *map = create_nodemap(This->node.node, &dom_pi_attr_map);
347         SysFreeString(name);
348         return S_OK;
349     }
350
351     SysFreeString(name);
352
353     return S_FALSE;
354 }
355
356 static HRESULT WINAPI dom_pi_insertBefore(
357     IXMLDOMProcessingInstruction *iface,
358     IXMLDOMNode* newNode, VARIANT refChild,
359     IXMLDOMNode** outOldNode)
360 {
361     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
362
363     FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode);
364
365     return node_insert_before(&This->node, newNode, &refChild, outOldNode);
366 }
367
368 static HRESULT WINAPI dom_pi_replaceChild(
369     IXMLDOMProcessingInstruction *iface,
370     IXMLDOMNode* newNode,
371     IXMLDOMNode* oldNode,
372     IXMLDOMNode** outOldNode)
373 {
374     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
375
376     FIXME("(%p)->(%p %p %p) needs test\n", This, newNode, oldNode, outOldNode);
377
378     return node_replace_child(&This->node, newNode, oldNode, outOldNode);
379 }
380
381 static HRESULT WINAPI dom_pi_removeChild(
382     IXMLDOMProcessingInstruction *iface,
383     IXMLDOMNode *child, IXMLDOMNode **oldChild)
384 {
385     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
386     TRACE("(%p)->(%p %p)\n", This, child, oldChild);
387     return node_remove_child(&This->node, child, oldChild);
388 }
389
390 static HRESULT WINAPI dom_pi_appendChild(
391     IXMLDOMProcessingInstruction *iface,
392     IXMLDOMNode *child, IXMLDOMNode **outChild)
393 {
394     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
395     TRACE("(%p)->(%p %p)\n", This, child, outChild);
396     return node_append_child(&This->node, child, outChild);
397 }
398
399 static HRESULT WINAPI dom_pi_hasChildNodes(
400     IXMLDOMProcessingInstruction *iface,
401     VARIANT_BOOL *ret)
402 {
403     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
404     TRACE("(%p)->(%p)\n", This, ret);
405     return node_has_childnodes(&This->node, ret);
406 }
407
408 static HRESULT WINAPI dom_pi_get_ownerDocument(
409     IXMLDOMProcessingInstruction *iface,
410     IXMLDOMDocument **doc)
411 {
412     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
413     TRACE("(%p)->(%p)\n", This, doc);
414     return node_get_owner_doc(&This->node, doc);
415 }
416
417 static HRESULT WINAPI dom_pi_cloneNode(
418     IXMLDOMProcessingInstruction *iface,
419     VARIANT_BOOL deep, IXMLDOMNode** outNode)
420 {
421     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
422     TRACE("(%p)->(%d %p)\n", This, deep, outNode);
423     return node_clone( &This->node, deep, outNode );
424 }
425
426 static HRESULT WINAPI dom_pi_get_nodeTypeString(
427     IXMLDOMProcessingInstruction *iface,
428     BSTR* p)
429 {
430     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
431     static const WCHAR processinginstructionW[] =
432         {'p','r','o','c','e','s','s','i','n','g','i','n','s','t','r','u','c','t','i','o','n',0};
433
434     TRACE("(%p)->(%p)\n", This, p);
435
436     return return_bstr(processinginstructionW, p);
437 }
438
439 static HRESULT WINAPI dom_pi_get_text(
440     IXMLDOMProcessingInstruction *iface,
441     BSTR* p)
442 {
443     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
444     TRACE("(%p)->(%p)\n", This, p);
445     return node_get_text(&This->node, p);
446 }
447
448 static HRESULT WINAPI dom_pi_put_text(
449     IXMLDOMProcessingInstruction *iface,
450     BSTR p)
451 {
452     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
453     TRACE("(%p)->(%s)\n", This, debugstr_w(p));
454     return node_put_text( &This->node, p );
455 }
456
457 static HRESULT WINAPI dom_pi_get_specified(
458     IXMLDOMProcessingInstruction *iface,
459     VARIANT_BOOL* isSpecified)
460 {
461     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
462     FIXME("(%p)->(%p) stub!\n", This, isSpecified);
463     *isSpecified = VARIANT_TRUE;
464     return S_OK;
465 }
466
467 static HRESULT WINAPI dom_pi_get_definition(
468     IXMLDOMProcessingInstruction *iface,
469     IXMLDOMNode** definitionNode)
470 {
471     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
472     FIXME("(%p)->(%p)\n", This, definitionNode);
473     return E_NOTIMPL;
474 }
475
476 static HRESULT WINAPI dom_pi_get_nodeTypedValue(
477     IXMLDOMProcessingInstruction *iface,
478     VARIANT* v)
479 {
480     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
481     TRACE("(%p)->(%p)\n", This, v);
482     return node_get_content(&This->node, v);
483 }
484
485 static HRESULT WINAPI dom_pi_put_nodeTypedValue(
486     IXMLDOMProcessingInstruction *iface,
487     VARIANT typedValue)
488 {
489     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
490     FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue));
491     return E_NOTIMPL;
492 }
493
494 static HRESULT WINAPI dom_pi_get_dataType(
495     IXMLDOMProcessingInstruction *iface,
496     VARIANT* typename)
497 {
498     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
499     TRACE("(%p)->(%p)\n", This, typename);
500     return return_null_var( typename );
501 }
502
503 static HRESULT WINAPI dom_pi_put_dataType(
504     IXMLDOMProcessingInstruction *iface,
505     BSTR p)
506 {
507     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
508
509     TRACE("(%p)->(%s)\n", This, debugstr_w(p));
510
511     if(!p)
512         return E_INVALIDARG;
513
514     return E_FAIL;
515 }
516
517 static HRESULT WINAPI dom_pi_get_xml(
518     IXMLDOMProcessingInstruction *iface,
519     BSTR* p)
520 {
521     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
522
523     TRACE("(%p)->(%p)\n", This, p);
524
525     return node_get_xml(&This->node, FALSE, FALSE, p);
526 }
527
528 static HRESULT WINAPI dom_pi_transformNode(
529     IXMLDOMProcessingInstruction *iface,
530     IXMLDOMNode *node, BSTR *p)
531 {
532     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
533     TRACE("(%p)->(%p %p)\n", This, node, p);
534     return node_transform_node(&This->node, node, p);
535 }
536
537 static HRESULT WINAPI dom_pi_selectNodes(
538     IXMLDOMProcessingInstruction *iface,
539     BSTR p, IXMLDOMNodeList** outList)
540 {
541     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
542     TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList);
543     return node_select_nodes(&This->node, p, outList);
544 }
545
546 static HRESULT WINAPI dom_pi_selectSingleNode(
547     IXMLDOMProcessingInstruction *iface,
548     BSTR p, IXMLDOMNode** outNode)
549 {
550     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
551     TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode);
552     return node_select_singlenode(&This->node, p, outNode);
553 }
554
555 static HRESULT WINAPI dom_pi_get_parsed(
556     IXMLDOMProcessingInstruction *iface,
557     VARIANT_BOOL* isParsed)
558 {
559     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
560     FIXME("(%p)->(%p) stub!\n", This, isParsed);
561     *isParsed = VARIANT_TRUE;
562     return S_OK;
563 }
564
565 static HRESULT WINAPI dom_pi_get_namespaceURI(
566     IXMLDOMProcessingInstruction *iface,
567     BSTR* p)
568 {
569     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
570     TRACE("(%p)->(%p)\n", This, p);
571     return node_get_namespaceURI(&This->node, p);
572 }
573
574 static HRESULT WINAPI dom_pi_get_prefix(
575     IXMLDOMProcessingInstruction *iface,
576     BSTR* prefix)
577 {
578     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
579     TRACE("(%p)->(%p)\n", This, prefix);
580     return return_null_bstr( prefix );
581 }
582
583 static HRESULT WINAPI dom_pi_get_baseName(
584     IXMLDOMProcessingInstruction *iface,
585     BSTR* name)
586 {
587     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
588     TRACE("(%p)->(%p)\n", This, name);
589     return node_get_base_name( &This->node, name );
590 }
591
592 static HRESULT WINAPI dom_pi_transformNodeToObject(
593     IXMLDOMProcessingInstruction *iface,
594     IXMLDOMNode* domNode, VARIANT var1)
595 {
596     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
597     FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1));
598     return E_NOTIMPL;
599 }
600
601 static HRESULT WINAPI dom_pi_get_target(
602     IXMLDOMProcessingInstruction *iface,
603     BSTR *p)
604 {
605     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
606
607     TRACE("(%p)->(%p)\n", This, p);
608
609     /* target returns the same value as nodeName property */
610     return node_get_nodeName(&This->node, p);
611 }
612
613 static HRESULT WINAPI dom_pi_get_data(
614     IXMLDOMProcessingInstruction *iface,
615     BSTR *p)
616 {
617     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
618     HRESULT hr;
619     VARIANT ret;
620
621     TRACE("(%p)->(%p)\n", This, p);
622
623     if(!p)
624         return E_INVALIDARG;
625
626     hr = IXMLDOMProcessingInstruction_get_nodeValue( iface, &ret );
627     if(hr == S_OK)
628     {
629         *p = V_BSTR(&ret);
630     }
631
632     return hr;
633 }
634
635 static HRESULT WINAPI dom_pi_put_data(
636     IXMLDOMProcessingInstruction *iface,
637     BSTR data)
638 {
639     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
640     VARIANT val;
641     BSTR target;
642     HRESULT hr;
643
644     TRACE("(%p)->(%s)\n", This, debugstr_w(data) );
645
646     /* Cannot set data to a PI node whose target is 'xml' */
647     hr = IXMLDOMProcessingInstruction_get_nodeName(iface, &target);
648     if(hr == S_OK)
649     {
650         static const WCHAR xmlW[] = {'x','m','l',0};
651         if(!strcmpW(target, xmlW))
652         {
653             SysFreeString(target);
654             return E_FAIL;
655         }
656
657         SysFreeString(target);
658     }
659
660     V_VT(&val) = VT_BSTR;
661     V_BSTR(&val) = data;
662
663     return IXMLDOMProcessingInstruction_put_nodeValue( iface, val );
664 }
665
666 static const struct IXMLDOMProcessingInstructionVtbl dom_pi_vtbl =
667 {
668     dom_pi_QueryInterface,
669     dom_pi_AddRef,
670     dom_pi_Release,
671     dom_pi_GetTypeInfoCount,
672     dom_pi_GetTypeInfo,
673     dom_pi_GetIDsOfNames,
674     dom_pi_Invoke,
675     dom_pi_get_nodeName,
676     dom_pi_get_nodeValue,
677     dom_pi_put_nodeValue,
678     dom_pi_get_nodeType,
679     dom_pi_get_parentNode,
680     dom_pi_get_childNodes,
681     dom_pi_get_firstChild,
682     dom_pi_get_lastChild,
683     dom_pi_get_previousSibling,
684     dom_pi_get_nextSibling,
685     dom_pi_get_attributes,
686     dom_pi_insertBefore,
687     dom_pi_replaceChild,
688     dom_pi_removeChild,
689     dom_pi_appendChild,
690     dom_pi_hasChildNodes,
691     dom_pi_get_ownerDocument,
692     dom_pi_cloneNode,
693     dom_pi_get_nodeTypeString,
694     dom_pi_get_text,
695     dom_pi_put_text,
696     dom_pi_get_specified,
697     dom_pi_get_definition,
698     dom_pi_get_nodeTypedValue,
699     dom_pi_put_nodeTypedValue,
700     dom_pi_get_dataType,
701     dom_pi_put_dataType,
702     dom_pi_get_xml,
703     dom_pi_transformNode,
704     dom_pi_selectNodes,
705     dom_pi_selectSingleNode,
706     dom_pi_get_parsed,
707     dom_pi_get_namespaceURI,
708     dom_pi_get_prefix,
709     dom_pi_get_baseName,
710     dom_pi_transformNodeToObject,
711
712     dom_pi_get_target,
713     dom_pi_get_data,
714     dom_pi_put_data
715 };
716
717 static HRESULT dom_pi_get_qualified_item(const xmlNodePtr node, BSTR name, BSTR uri,
718     IXMLDOMNode **item)
719 {
720     FIXME("(%p)->(%s %s %p): stub\n", node, debugstr_w(name), debugstr_w(uri), item);
721     return E_NOTIMPL;
722 }
723
724 static HRESULT dom_pi_get_named_item(const xmlNodePtr node, BSTR name, IXMLDOMNode **item)
725 {
726     FIXME("(%p)->(%s %p): stub\n", node, debugstr_w(name), item );
727     return E_NOTIMPL;
728 }
729
730 static HRESULT dom_pi_set_named_item(xmlNodePtr node, IXMLDOMNode *newItem, IXMLDOMNode **namedItem)
731 {
732     FIXME("(%p)->(%p %p): stub\n", node, newItem, namedItem );
733     return E_NOTIMPL;
734 }
735
736 static HRESULT dom_pi_remove_qualified_item(xmlNodePtr node, BSTR name, BSTR uri, IXMLDOMNode **item)
737 {
738     FIXME("(%p)->(%s %s %p): stub\n", node, debugstr_w(name), debugstr_w(uri), item);
739     return E_NOTIMPL;
740 }
741
742 static HRESULT dom_pi_remove_named_item(xmlNodePtr node, BSTR name, IXMLDOMNode **item)
743 {
744     FIXME("(%p)->(%s %p): stub\n", node, debugstr_w(name), item);
745     return E_NOTIMPL;
746 }
747
748 static HRESULT dom_pi_get_item(const xmlNodePtr node, LONG index, IXMLDOMNode **item)
749 {
750     FIXME("(%p)->(%d %p): stub\n", node, index, item);
751     return E_NOTIMPL;
752 }
753
754 static HRESULT dom_pi_get_length(const xmlNodePtr node, LONG *length)
755 {
756     FIXME("(%p)->(%p): stub\n", node, length);
757
758     *length = 0;
759     return S_OK;
760 }
761
762 static HRESULT dom_pi_next_node(const xmlNodePtr node, LONG *iter, IXMLDOMNode **nextNode)
763 {
764     FIXME("(%p)->(%d %p): stub\n", node, *iter, nextNode);
765     return E_NOTIMPL;
766 }
767
768 static const struct nodemap_funcs dom_pi_attr_map = {
769     dom_pi_get_named_item,
770     dom_pi_set_named_item,
771     dom_pi_remove_named_item,
772     dom_pi_get_item,
773     dom_pi_get_length,
774     dom_pi_get_qualified_item,
775     dom_pi_remove_qualified_item,
776     dom_pi_next_node
777 };
778
779 static const tid_t dompi_iface_tids[] = {
780     IXMLDOMProcessingInstruction_tid,
781     0
782 };
783
784 static dispex_static_data_t dompi_dispex = {
785     NULL,
786     IXMLDOMProcessingInstruction_tid,
787     NULL,
788     dompi_iface_tids
789 };
790
791 IUnknown* create_pi( xmlNodePtr pi )
792 {
793     dom_pi *This;
794
795     This = heap_alloc( sizeof *This );
796     if ( !This )
797         return NULL;
798
799     This->IXMLDOMProcessingInstruction_iface.lpVtbl = &dom_pi_vtbl;
800     This->ref = 1;
801
802     init_xmlnode(&This->node, pi, (IXMLDOMNode*)&This->IXMLDOMProcessingInstruction_iface, &dompi_dispex);
803
804     return (IUnknown*)&This->IXMLDOMProcessingInstruction_iface;
805 }
806
807 #endif