>From d81b50c0397c2148566f621e28fc9de7b025db39 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Sun, 13 Nov 2011 00:45:10 +0300
Subject: [PATCH 1/7] Support mupltiple IXMLDOMNamedNodeMap implementations

---
 dlls/msxml3/element.c       |  263 ++++++++++++++++++++++++++++++++++++++++++-
 dlls/msxml3/msxml_private.h |   33 ++++--
 dlls/msxml3/nodemap.c       |  227 ++++---------------------------------
 dlls/msxml3/pi.c            |   71 +++++++++++-
 4 files changed, 373 insertions(+), 221 deletions(-)

diff --git a/dlls/msxml3/element.c b/dlls/msxml3/element.c
index 834f39b..0863a16 100644
--- a/dlls/msxml3/element.c
+++ b/dlls/msxml3/element.c
@@ -53,6 +53,8 @@ typedef struct _domelem
     LONG ref;
 } domelem;
 
+static const struct nodemap_funcs domelem_attr_map;
+
 static inline domelem *impl_from_IXMLDOMElement( IXMLDOMElement *iface )
 {
     return CONTAINING_RECORD(iface, domelem, IXMLDOMElement_iface);
@@ -320,7 +322,7 @@ static HRESULT WINAPI domelem_get_attributes(
 
     TRACE("(%p)->(%p)\n", This, map);
 
-    *map = create_nodemap(This->node.node);
+    *map = create_nodemap(This->node.node, &domelem_attr_map);
     return S_OK;
 }
 
@@ -1382,6 +1384,265 @@ static const struct IXMLDOMElementVtbl domelem_vtbl =
     domelem_normalize,
 };
 
+static HRESULT domelem_get_qualified_item(const xmlNodePtr node, BSTR name, BSTR uri,
+    IXMLDOMNode **item)
+{
+    xmlAttrPtr attr;
+    xmlChar *nameA;
+    xmlChar *href;
+
+    TRACE("(%p)->(%s %s %p)\n", node, debugstr_w(name), debugstr_w(uri), item);
+
+    if (!name || !item) return E_INVALIDARG;
+
+    if (uri && *uri)
+    {
+        href = xmlchar_from_wchar(uri);
+        if (!href) return E_OUTOFMEMORY;
+    }
+    else
+        href = NULL;
+
+    nameA = xmlchar_from_wchar(name);
+    if (!nameA)
+    {
+        heap_free(href);
+        return E_OUTOFMEMORY;
+    }
+
+    attr = xmlHasNsProp(node, nameA, href);
+
+    heap_free(nameA);
+    heap_free(href);
+
+    if (!attr)
+    {
+        *item = NULL;
+        return S_FALSE;
+    }
+
+    *item = create_node((xmlNodePtr)attr);
+
+    return S_OK;
+}
+
+static HRESULT domelem_get_named_item(const xmlNodePtr node, BSTR name, IXMLDOMNode **item)
+{
+    xmlChar *nameA, *local, *prefix;
+    BSTR uriW, localW;
+    xmlNsPtr ns;
+    HRESULT hr;
+
+    TRACE("(%p)->(%s %p)\n", node, debugstr_w(name), item );
+
+    nameA = xmlchar_from_wchar(name);
+    local = xmlSplitQName2(nameA, &prefix);
+    heap_free(nameA);
+
+    if (!local)
+        return domelem_get_qualified_item(node, name, NULL, item);
+
+    /* try to get namespace uri for supplied qualified name */
+    ns = xmlSearchNs(node->doc, node, prefix);
+
+    xmlFree(prefix);
+
+    if (!ns)
+    {
+        xmlFree(local);
+        if (item) *item = NULL;
+        return item ? S_FALSE : E_INVALIDARG;
+    }
+
+    uriW = bstr_from_xmlChar(ns->href);
+    localW = bstr_from_xmlChar(local);
+    xmlFree(local);
+
+    TRACE("got qualified node %s, uri=%s\n", debugstr_w(localW), debugstr_w(uriW));
+
+    hr = domelem_get_qualified_item(node, localW, uriW, item);
+
+    SysFreeString(localW);
+    SysFreeString(uriW);
+
+    return hr;
+}
+
+static HRESULT domelem_set_named_item(xmlNodePtr node, IXMLDOMNode *newItem, IXMLDOMNode **namedItem)
+{
+    xmlNodePtr nodeNew;
+    xmlnode *ThisNew;
+
+    TRACE("(%p)->(%p %p)\n", node, newItem, namedItem );
+
+    if(!newItem)
+        return E_INVALIDARG;
+
+    if(namedItem) *namedItem = NULL;
+
+    /* Must be an Attribute */
+    ThisNew = get_node_obj( newItem );
+    if(!ThisNew) return E_FAIL;
+
+    if(ThisNew->node->type != XML_ATTRIBUTE_NODE)
+        return E_FAIL;
+
+    if(!ThisNew->node->parent)
+        if(xmldoc_remove_orphan(ThisNew->node->doc, ThisNew->node) != S_OK)
+            WARN("%p is not an orphan of %p\n", ThisNew->node, ThisNew->node->doc);
+
+    nodeNew = xmlAddChild(node, ThisNew->node);
+
+    if(namedItem)
+        *namedItem = create_node( nodeNew );
+    return S_OK;
+}
+
+static HRESULT domelem_remove_qualified_item(xmlNodePtr node, BSTR name, BSTR uri, IXMLDOMNode **item)
+{
+    xmlChar *nameA, *href;
+    xmlAttrPtr attr;
+
+    TRACE("(%p)->(%s %s %p)\n", node, debugstr_w(name), debugstr_w(uri), item);
+
+    if (!name) return E_INVALIDARG;
+
+    if (uri && *uri)
+    {
+        href = xmlchar_from_wchar(uri);
+        if (!href) return E_OUTOFMEMORY;
+    }
+    else
+        href = NULL;
+
+    nameA = xmlchar_from_wchar(name);
+    if (!nameA)
+    {
+        heap_free(href);
+        return E_OUTOFMEMORY;
+    }
+
+    attr = xmlHasNsProp(node, nameA, href);
+
+    heap_free(nameA);
+    heap_free(href);
+
+    if (!attr)
+    {
+        if (item) *item = NULL;
+        return S_FALSE;
+    }
+
+    if (item)
+    {
+        xmlUnlinkNode( (xmlNodePtr) attr );
+        xmldoc_add_orphan( attr->doc, (xmlNodePtr) attr );
+        *item = create_node( (xmlNodePtr) attr );
+    }
+    else
+    {
+        if (xmlRemoveProp(attr) == -1)
+            ERR("xmlRemoveProp failed\n");
+    }
+
+    return S_OK;
+}
+
+static HRESULT domelem_remove_named_item(xmlNodePtr node, BSTR name, IXMLDOMNode **item)
+{
+    TRACE("(%p)->(%s %p)\n", node, debugstr_w(name), item);
+    return domelem_remove_qualified_item(node, name, NULL, item);
+}
+
+static HRESULT domelem_get_item(const xmlNodePtr node, LONG index, IXMLDOMNode **item)
+{
+    xmlAttrPtr curr;
+    LONG attrIndex;
+
+    TRACE("(%p)->(%d %p)\n", node, index, item);
+
+    *item = NULL;
+
+    if (index < 0)
+        return S_FALSE;
+
+    curr = node->properties;
+
+    for (attrIndex = 0; attrIndex < index; attrIndex++) {
+        if (curr->next == NULL)
+            return S_FALSE;
+        else
+            curr = curr->next;
+    }
+
+    *item = create_node( (xmlNodePtr) curr );
+
+    return S_OK;
+}
+
+static HRESULT domelem_get_length(const xmlNodePtr node, LONG *length)
+{
+    xmlAttrPtr first;
+    xmlAttrPtr curr;
+    LONG attrCount;
+
+    TRACE("(%p)->(%p)\n", node, length);
+
+    if( !length )
+        return E_INVALIDARG;
+
+    first = node->properties;
+    if (first == NULL) {
+	*length = 0;
+	return S_OK;
+    }
+
+    curr = first;
+    attrCount = 1;
+    while (curr->next) {
+        attrCount++;
+        curr = curr->next;
+    }
+    *length = attrCount;
+
+    return S_OK;
+}
+
+static HRESULT domelem_next_node(const xmlNodePtr node, LONG *iter, IXMLDOMNode **nextNode)
+{
+    xmlAttrPtr curr;
+    LONG i;
+
+    TRACE("(%p)->(%d: %p)\n", node, *iter, nextNode);
+
+    *nextNode = NULL;
+
+    curr = node->properties;
+
+    for (i = 0; i < *iter; i++) {
+        if (curr->next == NULL)
+            return S_FALSE;
+        else
+            curr = curr->next;
+    }
+
+    (*iter)++;
+    *nextNode = create_node((xmlNodePtr)curr);
+
+    return S_OK;
+}
+
+static const struct nodemap_funcs domelem_attr_map = {
+    domelem_get_named_item,
+    domelem_set_named_item,
+    domelem_remove_named_item,
+    domelem_get_item,
+    domelem_get_length,
+    domelem_get_qualified_item,
+    domelem_remove_qualified_item,
+    domelem_next_node
+};
+
 static const tid_t domelem_iface_tids[] = {
     IXMLDOMElement_tid,
     0
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index 5c2ed4d..9a51886 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -228,6 +228,28 @@ static inline xmlNodePtr wine_xmlFirstElementChild(xmlNodePtr parent)
 #define xmlFirstElementChild wine_xmlFirstElementChild
 #endif
 
+/* IXMLDOMNode Internal Structure */
+typedef struct _xmlnode
+{
+    DispatchEx   dispex;
+    IXMLDOMNode *iface;
+    IXMLDOMNode *parent;
+    xmlNodePtr   node;
+} xmlnode;
+
+/* IXMLDOMNamedNodeMap custom function table */
+struct nodemap_funcs
+{
+    HRESULT (*get_named_item)(const xmlNodePtr,BSTR,IXMLDOMNode**);
+    HRESULT (*set_named_item)(xmlNodePtr,IXMLDOMNode*,IXMLDOMNode**);
+    HRESULT (*remove_named_item)(xmlNodePtr,BSTR,IXMLDOMNode**);
+    HRESULT (*get_item)(xmlNodePtr,LONG,IXMLDOMNode**);
+    HRESULT (*get_length)(xmlNodePtr,LONG*);
+    HRESULT (*get_qualified_item)(const xmlNodePtr,BSTR,BSTR,IXMLDOMNode**);
+    HRESULT (*remove_qualified_item)(xmlNodePtr,BSTR,BSTR,IXMLDOMNode**);
+    HRESULT (*next_node)(const xmlNodePtr,LONG*,IXMLDOMNode**);
+};
+
 /* constructors */
 extern IUnknown         *create_domdoc( xmlNodePtr ) DECLSPEC_HIDDEN;
 extern IUnknown         *create_xmldoc( void ) DECLSPEC_HIDDEN;
@@ -239,7 +261,7 @@ extern IUnknown         *create_pi( xmlNodePtr ) DECLSPEC_HIDDEN;
 extern IUnknown         *create_comment( xmlNodePtr ) DECLSPEC_HIDDEN;
 extern IUnknown         *create_cdata( xmlNodePtr ) DECLSPEC_HIDDEN;
 extern IXMLDOMNodeList  *create_children_nodelist( xmlNodePtr ) DECLSPEC_HIDDEN;
-extern IXMLDOMNamedNodeMap *create_nodemap( const xmlNodePtr ) DECLSPEC_HIDDEN;
+extern IXMLDOMNamedNodeMap *create_nodemap( xmlNodePtr, const struct nodemap_funcs* ) DECLSPEC_HIDDEN;
 extern IUnknown         *create_doc_Implementation(void) DECLSPEC_HIDDEN;
 extern IUnknown         *create_doc_fragment( xmlNodePtr ) DECLSPEC_HIDDEN;
 extern IUnknown         *create_doc_entity_ref( xmlNodePtr ) DECLSPEC_HIDDEN;
@@ -282,15 +304,6 @@ extern BOOL is_preserving_whitespace(xmlNodePtr node) DECLSPEC_HIDDEN;
 extern BOOL is_xpathmode(const xmlDocPtr doc) DECLSPEC_HIDDEN;
 extern void set_xpathmode(xmlDocPtr doc, BOOL xpath) DECLSPEC_HIDDEN;
 
-/* IXMLDOMNode Internal Structure */
-typedef struct _xmlnode
-{
-    DispatchEx   dispex;
-    IXMLDOMNode *iface;
-    IXMLDOMNode *parent;
-    xmlNodePtr   node;
-} xmlnode;
-
 extern void init_xmlnode(xmlnode*,xmlNodePtr,IXMLDOMNode*,dispex_static_data_t*) DECLSPEC_HIDDEN;
 extern void destroy_xmlnode(xmlnode*) DECLSPEC_HIDDEN;
 extern BOOL node_query_interface(xmlnode*,REFIID,void**) DECLSPEC_HIDDEN;
diff --git a/dlls/msxml3/nodemap.c b/dlls/msxml3/nodemap.c
index 47adcd9..027416f 100644
--- a/dlls/msxml3/nodemap.c
+++ b/dlls/msxml3/nodemap.c
@@ -53,6 +53,8 @@ typedef struct _xmlnodemap
 
     xmlNodePtr node;
     LONG iterator;
+
+    const struct nodemap_funcs *funcs;
 } xmlnodemap;
 
 static inline xmlnodemap *impl_from_IXMLDOMNamedNodeMap( IXMLDOMNamedNodeMap *iface )
@@ -202,44 +204,10 @@ static HRESULT WINAPI xmlnodemap_getNamedItem(
     IXMLDOMNode** item)
 {
     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
-    xmlChar *nameA, *local, *prefix;
-    BSTR uriW, localW;
-    xmlNsPtr ns;
-    HRESULT hr;
 
     TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), item );
 
-    nameA = xmlchar_from_wchar(name);
-    local = xmlSplitQName2(nameA, &prefix);
-    heap_free(nameA);
-
-    if (!local)
-        return IXMLDOMNamedNodeMap_getQualifiedItem(iface, name, NULL, item);
-
-    /* try to get namespace uri for supplied qualified name */
-    ns = xmlSearchNs(This->node->doc, This->node, prefix);
-
-    xmlFree(prefix);
-
-    if (!ns)
-    {
-        xmlFree(local);
-        if (item) *item = NULL;
-        return item ? S_FALSE : E_INVALIDARG;
-    }
-
-    uriW = bstr_from_xmlChar(ns->href);
-    localW = bstr_from_xmlChar(local);
-    xmlFree(local);
-
-    TRACE("got qualified node %s, uri=%s\n", debugstr_w(localW), debugstr_w(uriW));
-
-    hr = IXMLDOMNamedNodeMap_getQualifiedItem(iface, localW, uriW, item);
-
-    SysFreeString(localW);
-    SysFreeString(uriW);
-
-    return hr;
+    return This->funcs->get_named_item(This->node, name, item);
 }
 
 static HRESULT WINAPI xmlnodemap_setNamedItem(
@@ -248,32 +216,10 @@ static HRESULT WINAPI xmlnodemap_setNamedItem(
     IXMLDOMNode** namedItem)
 {
     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
-    xmlNodePtr nodeNew;
-    xmlnode *ThisNew;
 
     TRACE("(%p)->(%p %p)\n", This, newItem, namedItem );
 
-    if(!newItem)
-        return E_INVALIDARG;
-
-    if(namedItem) *namedItem = NULL;
-
-    /* Must be an Attribute */
-    ThisNew = get_node_obj( newItem );
-    if(!ThisNew) return E_FAIL;
-
-    if(ThisNew->node->type != XML_ATTRIBUTE_NODE)
-        return E_FAIL;
-
-    if(!ThisNew->node->parent)
-        if(xmldoc_remove_orphan(ThisNew->node->doc, ThisNew->node) != S_OK)
-            WARN("%p is not an orphan of %p\n", ThisNew->node, ThisNew->node->doc);
-
-    nodeNew = xmlAddChild(This->node, ThisNew->node);
-
-    if(namedItem)
-        *namedItem = create_node( nodeNew );
-    return S_OK;
+    return This->funcs->set_named_item(This->node, newItem, namedItem);
 }
 
 static HRESULT WINAPI xmlnodemap_removeNamedItem(
@@ -282,172 +228,59 @@ static HRESULT WINAPI xmlnodemap_removeNamedItem(
     IXMLDOMNode** namedItem)
 {
     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
+
     TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), namedItem );
-    return IXMLDOMNamedNodeMap_removeQualifiedItem(iface, name, NULL, namedItem);
+
+    return This->funcs->remove_named_item(This->node, name, namedItem);
 }
 
 static HRESULT WINAPI xmlnodemap_get_item(
     IXMLDOMNamedNodeMap *iface,
     LONG index,
-    IXMLDOMNode** listItem)
+    IXMLDOMNode** item)
 {
     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
-    xmlAttrPtr curr;
-    LONG attrIndex;
-
-    TRACE("(%p)->(%d %p)\n", This, index, listItem);
 
-    *listItem = NULL;
+    TRACE("(%p)->(%d %p)\n", This, index, item);
 
-    if (index < 0)
-        return S_FALSE;
-
-    curr = This->node->properties;
-
-    for (attrIndex = 0; attrIndex < index; attrIndex++) {
-        if (curr->next == NULL)
-            return S_FALSE;
-        else
-            curr = curr->next;
-    }
-    
-    *listItem = create_node( (xmlNodePtr) curr );
-
-    return S_OK;
+    return This->funcs->get_item(This->node, index, item);
 }
 
 static HRESULT WINAPI xmlnodemap_get_length(
     IXMLDOMNamedNodeMap *iface,
-    LONG *listLength)
+    LONG *length)
 {
-    xmlAttrPtr first;
-    xmlAttrPtr curr;
-    LONG attrCount;
-
     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
 
-    TRACE("(%p)->(%p)\n", This, listLength);
-
-    if( !listLength )
-        return E_INVALIDARG;
-
-    first = This->node->properties;
-    if (first == NULL) {
-	*listLength = 0;
-	return S_OK;
-    }
+    TRACE("(%p)->(%p)\n", This, length);
 
-    curr = first;
-    attrCount = 1;
-    while (curr->next) {
-        attrCount++;
-        curr = curr->next;
-    }
-    *listLength = attrCount;
- 
-    return S_OK;
+    return This->funcs->get_length(This->node, length);
 }
 
 static HRESULT WINAPI xmlnodemap_getQualifiedItem(
     IXMLDOMNamedNodeMap *iface,
     BSTR baseName,
     BSTR namespaceURI,
-    IXMLDOMNode** qualifiedItem)
+    IXMLDOMNode** item)
 {
     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
-    xmlAttrPtr attr;
-    xmlChar *href;
-    xmlChar *name;
-
-    TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), qualifiedItem);
-
-    if (!baseName || !qualifiedItem) return E_INVALIDARG;
 
-    if (namespaceURI && *namespaceURI)
-    {
-        href = xmlchar_from_wchar(namespaceURI);
-        if (!href) return E_OUTOFMEMORY;
-    }
-    else
-        href = NULL;
-
-    name = xmlchar_from_wchar(baseName);
-    if (!name)
-    {
-        heap_free(href);
-        return E_OUTOFMEMORY;
-    }
-
-    attr = xmlHasNsProp(This->node, name, href);
-
-    heap_free(name);
-    heap_free(href);
-
-    if (!attr)
-    {
-        *qualifiedItem = NULL;
-        return S_FALSE;
-    }
+    TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), item);
 
-    *qualifiedItem = create_node((xmlNodePtr)attr);
-
-    return S_OK;
+    return This->funcs->get_qualified_item(This->node, baseName, namespaceURI, item);
 }
 
 static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
     IXMLDOMNamedNodeMap *iface,
     BSTR baseName,
     BSTR namespaceURI,
-    IXMLDOMNode** qualifiedItem)
+    IXMLDOMNode** item)
 {
     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
-    xmlAttrPtr attr;
-    xmlChar *name;
-    xmlChar *href;
-
-    TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), qualifiedItem);
-
-    if (!baseName) return E_INVALIDARG;
 
-    if (namespaceURI && *namespaceURI)
-    {
-        href = xmlchar_from_wchar(namespaceURI);
-        if (!href) return E_OUTOFMEMORY;
-    }
-    else
-        href = NULL;
+    ERR("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), item);
 
-    name = xmlchar_from_wchar(baseName);
-    if (!name)
-    {
-        heap_free(href);
-        return E_OUTOFMEMORY;
-    }
-
-    attr = xmlHasNsProp( This->node, name, href );
-
-    heap_free(name);
-    heap_free(href);
-
-    if ( !attr )
-    {
-        if (qualifiedItem) *qualifiedItem = NULL;
-        return S_FALSE;
-    }
-
-    if ( qualifiedItem )
-    {
-        xmlUnlinkNode( (xmlNodePtr) attr );
-        xmldoc_add_orphan( attr->doc, (xmlNodePtr) attr );
-        *qualifiedItem = create_node( (xmlNodePtr) attr );
-    }
-    else
-    {
-        if (xmlRemoveProp(attr) == -1)
-            ERR("xmlRemoveProp failed\n");
-    }
-
-    return S_OK;
+    return This->funcs->remove_qualified_item(This->node, baseName, namespaceURI, item);
 }
 
 static HRESULT WINAPI xmlnodemap_nextNode(
@@ -455,27 +288,10 @@ static HRESULT WINAPI xmlnodemap_nextNode(
     IXMLDOMNode** nextItem)
 {
     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
-    xmlAttrPtr curr;
-    LONG attrIndex;
 
     TRACE("(%p)->(%p: %d)\n", This, nextItem, This->iterator);
 
-    *nextItem = NULL;
-
-    curr = This->node->properties;
-
-    for (attrIndex = 0; attrIndex < This->iterator; attrIndex++) {
-        if (curr->next == NULL)
-            return S_FALSE;
-        else
-            curr = curr->next;
-    }
-
-    This->iterator++;
-
-    *nextItem = create_node( (xmlNodePtr) curr );
-
-    return S_OK;
+    return This->funcs->next_node(This->node, &This->iterator, nextItem);
 }
 
 static HRESULT WINAPI xmlnodemap_reset(
@@ -626,7 +442,7 @@ static dispex_static_data_t xmlnodemap_dispex = {
     xmlnodemap_iface_tids
 };
 
-IXMLDOMNamedNodeMap *create_nodemap( const xmlNodePtr node )
+IXMLDOMNamedNodeMap *create_nodemap(xmlNodePtr node, const struct nodemap_funcs *funcs)
 {
     xmlnodemap *This;
 
@@ -639,6 +455,7 @@ IXMLDOMNamedNodeMap *create_nodemap( const xmlNodePtr node )
     This->node = node;
     This->ref = 1;
     This->iterator = 0;
+    This->funcs = funcs;
 
     init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNamedNodeMap_iface, &xmlnodemap_dispex);
 
diff --git a/dlls/msxml3/pi.c b/dlls/msxml3/pi.c
index 13b03a4..b7a9c3a 100644
--- a/dlls/msxml3/pi.c
+++ b/dlls/msxml3/pi.c
@@ -49,6 +49,8 @@ typedef struct _dom_pi
     LONG ref;
 } dom_pi;
 
+static const struct nodemap_funcs dom_pi_attr_map;
+
 static inline dom_pi *impl_from_IXMLDOMProcessingInstruction( IXMLDOMProcessingInstruction *iface )
 {
     return CONTAINING_RECORD(iface, dom_pi, IXMLDOMProcessingInstruction_iface);
@@ -128,13 +130,10 @@ static HRESULT WINAPI dom_pi_GetTypeInfo(
     ITypeInfo** ppTInfo )
 {
     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
-    HRESULT hr;
 
     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
 
-    hr = get_typeinfo(IXMLDOMProcessingInstruction_tid, ppTInfo);
-
-    return hr;
+    return get_typeinfo(IXMLDOMProcessingInstruction_tid, ppTInfo);
 }
 
 static HRESULT WINAPI dom_pi_GetIDsOfNames(
@@ -334,7 +333,7 @@ static HRESULT WINAPI dom_pi_get_attributes(
     if (!strcmpW(name, xmlW))
     {
         FIXME("created dummy map for <?xml ?>\n");
-        *map = create_nodemap(This->node.node);
+        *map = create_nodemap(This->node.node, &dom_pi_attr_map);
         SysFreeString(name);
         return S_OK;
     }
@@ -705,6 +704,68 @@ static const struct IXMLDOMProcessingInstructionVtbl dom_pi_vtbl =
     dom_pi_put_data
 };
 
+static HRESULT dom_pi_get_qualified_item(const xmlNodePtr node, BSTR name, BSTR uri,
+    IXMLDOMNode **item)
+{
+    FIXME("(%p)->(%s %s %p): stub\n", node, debugstr_w(name), debugstr_w(uri), item);
+    return E_NOTIMPL;
+}
+
+static HRESULT dom_pi_get_named_item(const xmlNodePtr node, BSTR name, IXMLDOMNode **item)
+{
+    FIXME("(%p)->(%s %p): stub\n", node, debugstr_w(name), item );
+    return E_NOTIMPL;
+}
+
+static HRESULT dom_pi_set_named_item(xmlNodePtr node, IXMLDOMNode *newItem, IXMLDOMNode **namedItem)
+{
+    FIXME("(%p)->(%p %p): stub\n", node, newItem, namedItem );
+    return E_NOTIMPL;
+}
+
+static HRESULT dom_pi_remove_qualified_item(xmlNodePtr node, BSTR name, BSTR uri, IXMLDOMNode **item)
+{
+    FIXME("(%p)->(%s %s %p): stub\n", node, debugstr_w(name), debugstr_w(uri), item);
+    return E_NOTIMPL;
+}
+
+static HRESULT dom_pi_remove_named_item(xmlNodePtr node, BSTR name, IXMLDOMNode **item)
+{
+    FIXME("(%p)->(%s %p): stub\n", node, debugstr_w(name), item);
+    return E_NOTIMPL;
+}
+
+static HRESULT dom_pi_get_item(const xmlNodePtr node, LONG index, IXMLDOMNode **item)
+{
+    FIXME("(%p)->(%d %p): stub\n", node, index, item);
+    return E_NOTIMPL;
+}
+
+static HRESULT dom_pi_get_length(const xmlNodePtr node, LONG *length)
+{
+    FIXME("(%p)->(%p): stub\n", node, length);
+
+    *length = 0;
+    return S_OK;
+}
+
+static HRESULT dom_pi_next_node(const xmlNodePtr node, LONG *iter, IXMLDOMNode **nextNode)
+{
+    FIXME("(%p)->(%d %p): stub\n", node, *iter, nextNode);
+    return E_NOTIMPL;
+}
+
+static const struct nodemap_funcs dom_pi_attr_map = {
+    dom_pi_get_named_item,
+    dom_pi_set_named_item,
+    dom_pi_remove_named_item,
+    dom_pi_get_item,
+    dom_pi_get_length,
+    dom_pi_get_qualified_item,
+    dom_pi_remove_qualified_item,
+    dom_pi_next_node
+};
+
 static const tid_t dompi_iface_tids[] = {
     IXMLDOMProcessingInstruction_tid,
     0
-- 
1.5.6.5



