msxml3: Use fake IID to safely cast IXMLDOMNode interface to xmlnode object.
This commit is contained in:
parent
0670d092f1
commit
a92e95eab1
|
@ -1090,7 +1090,11 @@ static HRESULT WINAPI domdoc_put_documentElement(
|
|||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
xmlNode = impl_from_IXMLDOMNode( elementNode );
|
||||
xmlNode = get_node_obj( elementNode );
|
||||
if(!xmlNode) {
|
||||
FIXME("elementNode is not our object\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if(!xmlNode->node->parent)
|
||||
if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
|
||||
|
|
|
@ -150,11 +150,6 @@ typedef struct _xmlnode
|
|||
xmlNodePtr node;
|
||||
} xmlnode;
|
||||
|
||||
static inline xmlnode *impl_from_IXMLDOMNode( IXMLDOMNode *iface )
|
||||
{
|
||||
return (xmlnode *)((char*)iface - FIELD_OFFSET(xmlnode, lpVtbl));
|
||||
}
|
||||
|
||||
static inline IXMLDOMNode *IXMLDOMNode_from_impl(xmlnode *This)
|
||||
{
|
||||
return (IXMLDOMNode*)&This->lpVtbl;
|
||||
|
@ -163,6 +158,7 @@ static inline IXMLDOMNode *IXMLDOMNode_from_impl(xmlnode *This)
|
|||
extern void init_xmlnode(xmlnode*,xmlNodePtr,IXMLDOMNode*,dispex_static_data_t*);
|
||||
extern void destroy_xmlnode(xmlnode*);
|
||||
extern BOOL node_query_interface(xmlnode*,REFIID,void**);
|
||||
extern xmlnode *get_node_obj(IXMLDOMNode*);
|
||||
|
||||
extern HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document);
|
||||
|
||||
|
|
|
@ -66,14 +66,16 @@ static const WCHAR szFloat[] = {'f','l','o','a','t',0};
|
|||
static const WCHAR szUUID[] = {'u','u','i','d',0};
|
||||
static const WCHAR szBinHex[] = {'b','i','n','.','h','e','x',0};
|
||||
|
||||
static const IID IID_xmlnode = {0x4f2f4ba2,0xb822,0x11df,{0x8b,0x8a,0x68,0x50,0xdf,0xd7,0x20,0x85}};
|
||||
|
||||
xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type )
|
||||
{
|
||||
xmlnode *This;
|
||||
|
||||
if ( !iface )
|
||||
return NULL;
|
||||
This = impl_from_IXMLDOMNode( iface );
|
||||
if ( !This->node )
|
||||
This = get_node_obj( iface );
|
||||
if ( !This || !This->node )
|
||||
return NULL;
|
||||
if ( type && This->node->type != type )
|
||||
return NULL;
|
||||
|
@ -82,11 +84,32 @@ xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type )
|
|||
|
||||
BOOL node_query_interface(xmlnode *This, REFIID riid, void **ppv)
|
||||
{
|
||||
if(IsEqualGUID(&IID_xmlnode, riid)) {
|
||||
TRACE("(%p)->(IID_xmlnode %p)\n", This, ppv);
|
||||
*ppv = This;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if(This->dispex.outer)
|
||||
return dispex_query_interface(&This->dispex, riid, ppv);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xmlnode *get_node_obj(IXMLDOMNode *node)
|
||||
{
|
||||
xmlnode *obj;
|
||||
HRESULT hres;
|
||||
|
||||
hres = IXMLDOMNode_QueryInterface(node, &IID_xmlnode, (void**)&obj);
|
||||
return SUCCEEDED(hres) ? obj : NULL;
|
||||
}
|
||||
|
||||
static inline xmlnode *impl_from_IXMLDOMNode( IXMLDOMNode *iface )
|
||||
{
|
||||
return (xmlnode *)((char*)iface - FIELD_OFFSET(xmlnode, lpVtbl));
|
||||
}
|
||||
|
||||
static HRESULT WINAPI xmlnode_QueryInterface(
|
||||
IXMLDOMNode *iface,
|
||||
REFIID riid,
|
||||
|
@ -561,7 +584,8 @@ static HRESULT WINAPI xmlnode_insertBefore(
|
|||
{
|
||||
xmlnode *This = impl_from_IXMLDOMNode( iface );
|
||||
xmlNodePtr before_node, new_child_node;
|
||||
IXMLDOMNode *before = NULL, *new;
|
||||
IXMLDOMNode *before = NULL;
|
||||
xmlnode *node_obj;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->(%p var %p)\n",This,newChild,outNewChild);
|
||||
|
@ -590,8 +614,13 @@ static HRESULT WINAPI xmlnode_insertBefore(
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
IXMLDOMNode_QueryInterface(newChild, &IID_IXMLDOMNode, (LPVOID)&new);
|
||||
new_child_node = impl_from_IXMLDOMNode(new)->node;
|
||||
node_obj = get_node_obj(newChild);
|
||||
if(!node_obj) {
|
||||
FIXME("newChild is not our node implementation\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
new_child_node = node_obj->node;
|
||||
TRACE("new_child_node %p This->node %p\n", new_child_node, This->node);
|
||||
|
||||
if(!new_child_node->parent)
|
||||
|
@ -600,16 +629,21 @@ static HRESULT WINAPI xmlnode_insertBefore(
|
|||
|
||||
if(before)
|
||||
{
|
||||
before_node = impl_from_IXMLDOMNode(before)->node;
|
||||
xmlAddPrevSibling(before_node, new_child_node);
|
||||
node_obj = get_node_obj(before);
|
||||
IXMLDOMNode_Release(before);
|
||||
if(!node_obj) {
|
||||
FIXME("before node is not our node implementation\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
before_node = node_obj->node;
|
||||
xmlAddPrevSibling(before_node, new_child_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlAddChild(This->node, new_child_node);
|
||||
}
|
||||
|
||||
IXMLDOMNode_Release(new);
|
||||
IXMLDOMNode_AddRef(newChild);
|
||||
if(outNewChild)
|
||||
*outNewChild = newChild;
|
||||
|
@ -691,9 +725,7 @@ static HRESULT WINAPI xmlnode_removeChild(
|
|||
IXMLDOMNode** oldChild)
|
||||
{
|
||||
xmlnode *This = impl_from_IXMLDOMNode( iface );
|
||||
xmlNode *child_node_ptr;
|
||||
HRESULT hr;
|
||||
IXMLDOMNode *child;
|
||||
xmlnode *child_node;
|
||||
|
||||
TRACE("(%p)->(%p %p)\n", This, childNode, oldChild);
|
||||
|
||||
|
@ -702,21 +734,19 @@ static HRESULT WINAPI xmlnode_removeChild(
|
|||
if(oldChild)
|
||||
*oldChild = NULL;
|
||||
|
||||
hr = IXMLDOMNode_QueryInterface(childNode, &IID_IXMLDOMNode, (LPVOID)&child);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
child_node = get_node_obj(childNode);
|
||||
if(!child_node) {
|
||||
FIXME("childNode is not our node implementation\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
child_node_ptr = impl_from_IXMLDOMNode(child)->node;
|
||||
if(child_node_ptr->parent != This->node)
|
||||
if(child_node->node->parent != This->node)
|
||||
{
|
||||
WARN("childNode %p is not a child of %p\n", childNode, iface);
|
||||
IXMLDOMNode_Release(child);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
xmlUnlinkNode(child_node_ptr);
|
||||
|
||||
IXMLDOMNode_Release(child);
|
||||
xmlUnlinkNode(child_node->node);
|
||||
|
||||
if(oldChild)
|
||||
{
|
||||
|
@ -1454,7 +1484,6 @@ static HRESULT WINAPI xmlnode_transformNode(
|
|||
xmlnode *pStyleSheet = NULL;
|
||||
xsltStylesheetPtr xsltSS = NULL;
|
||||
xmlDocPtr result = NULL;
|
||||
IXMLDOMNode *ssNew;
|
||||
|
||||
TRACE("(%p)->(%p %p)\n", This, styleSheet, xmlString);
|
||||
|
||||
|
@ -1465,55 +1494,54 @@ static HRESULT WINAPI xmlnode_transformNode(
|
|||
|
||||
*xmlString = NULL;
|
||||
|
||||
if(IXMLDOMNode_QueryInterface(styleSheet, &IID_IXMLDOMNode, (LPVOID)&ssNew) == S_OK)
|
||||
pStyleSheet = get_node_obj(styleSheet);
|
||||
if(!pStyleSheet) {
|
||||
FIXME("styleSheet is not our xmlnode implementation\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
xsltSS = pxsltParseStylesheetDoc( pStyleSheet->node->doc);
|
||||
if(xsltSS)
|
||||
{
|
||||
pStyleSheet = impl_from_IXMLDOMNode( ssNew );
|
||||
|
||||
xsltSS = pxsltParseStylesheetDoc( pStyleSheet->node->doc);
|
||||
if(xsltSS)
|
||||
result = pxsltApplyStylesheet(xsltSS, This->node->doc, NULL);
|
||||
if(result)
|
||||
{
|
||||
result = pxsltApplyStylesheet(xsltSS, This->node->doc, NULL);
|
||||
if(result)
|
||||
const xmlChar *pContent;
|
||||
|
||||
if(result->type == XML_HTML_DOCUMENT_NODE)
|
||||
{
|
||||
const xmlChar *pContent;
|
||||
|
||||
if(result->type == XML_HTML_DOCUMENT_NODE)
|
||||
xmlOutputBufferPtr pOutput = xmlAllocOutputBuffer(NULL);
|
||||
if(pOutput)
|
||||
{
|
||||
xmlOutputBufferPtr pOutput = xmlAllocOutputBuffer(NULL);
|
||||
if(pOutput)
|
||||
{
|
||||
htmlDocContentDumpOutput(pOutput, result->doc, NULL);
|
||||
pContent = xmlBufferContent(pOutput->buffer);
|
||||
*xmlString = bstr_from_xmlChar(pContent);
|
||||
xmlOutputBufferClose(pOutput);
|
||||
}
|
||||
htmlDocContentDumpOutput(pOutput, result->doc, NULL);
|
||||
pContent = xmlBufferContent(pOutput->buffer);
|
||||
*xmlString = bstr_from_xmlChar(pContent);
|
||||
xmlOutputBufferClose(pOutput);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlBufferPtr pXmlBuf;
|
||||
int nSize;
|
||||
|
||||
pXmlBuf = xmlBufferCreate();
|
||||
if(pXmlBuf)
|
||||
{
|
||||
nSize = xmlNodeDump(pXmlBuf, NULL, (xmlNodePtr)result, 0, 0);
|
||||
if(nSize > 0)
|
||||
{
|
||||
pContent = xmlBufferContent(pXmlBuf);
|
||||
*xmlString = bstr_from_xmlChar(pContent);
|
||||
}
|
||||
xmlBufferFree(pXmlBuf);
|
||||
}
|
||||
}
|
||||
xmlFreeDoc(result);
|
||||
}
|
||||
/* libxslt "helpfully" frees the XML document the stylesheet was
|
||||
generated from, too */
|
||||
xsltSS->doc = NULL;
|
||||
pxsltFreeStylesheet(xsltSS);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlBufferPtr pXmlBuf;
|
||||
int nSize;
|
||||
|
||||
IXMLDOMNode_Release(ssNew);
|
||||
pXmlBuf = xmlBufferCreate();
|
||||
if(pXmlBuf)
|
||||
{
|
||||
nSize = xmlNodeDump(pXmlBuf, NULL, (xmlNodePtr)result, 0, 0);
|
||||
if(nSize > 0)
|
||||
{
|
||||
pContent = xmlBufferContent(pXmlBuf);
|
||||
*xmlString = bstr_from_xmlChar(pContent);
|
||||
}
|
||||
xmlBufferFree(pXmlBuf);
|
||||
}
|
||||
}
|
||||
xmlFreeDoc(result);
|
||||
}
|
||||
/* libxslt "helpfully" frees the XML document the stylesheet was
|
||||
generated from, too */
|
||||
xsltSS->doc = NULL;
|
||||
pxsltFreeStylesheet(xsltSS);
|
||||
}
|
||||
|
||||
if(*xmlString == NULL)
|
||||
|
|
|
@ -209,8 +209,8 @@ static HRESULT WINAPI xmlnodemap_setNamedItem(
|
|||
{
|
||||
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
||||
xmlNodePtr nodeNew;
|
||||
IXMLDOMNode *pAttr = NULL;
|
||||
xmlNodePtr node;
|
||||
xmlnode *ThisNew;
|
||||
|
||||
TRACE("(%p)->(%p %p)\n", This, newItem, namedItem );
|
||||
|
||||
|
@ -224,32 +224,24 @@ static HRESULT WINAPI xmlnodemap_setNamedItem(
|
|||
return E_FAIL;
|
||||
|
||||
/* Must be an Attribute */
|
||||
IUnknown_QueryInterface(newItem, &IID_IXMLDOMNode, (void**)&pAttr);
|
||||
if(pAttr)
|
||||
{
|
||||
xmlnode *ThisNew = impl_from_IXMLDOMNode( pAttr );
|
||||
|
||||
if(ThisNew->node->type != XML_ATTRIBUTE_NODE)
|
||||
{
|
||||
IUnknown_Release(pAttr);
|
||||
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 );
|
||||
|
||||
IUnknown_Release(pAttr);
|
||||
|
||||
return S_OK;
|
||||
ThisNew = get_node_obj( newItem );
|
||||
if(!ThisNew) {
|
||||
FIXME("ThisNew is not our node implementation\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return E_INVALIDARG;
|
||||
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 WINAPI xmlnodemap_removeNamedItem(
|
||||
|
|
Loading…
Reference in New Issue