From 123eba280124f4f3a520a333fed8119bd560c09b Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Tue, 17 Jan 2012 22:07:11 +0300 Subject: [PATCH] msi: Support MSIPATCH_DATATYPE_XMLBLOB when testing for applicable patch. --- dlls/msi/msi.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index fd2315fecdd..941a5478e72 100644 --- a/dlls/msi/msi.c +++ b/dlls/msi/msi.c @@ -42,6 +42,9 @@ #include "wintrust.h" #include "softpub.h" +#include "initguid.h" +#include "msxml2.h" + #include "wine/debug.h" #include "wine/unicode.h" @@ -304,7 +307,6 @@ done: return r; } - static UINT get_patch_product_codes( LPCWSTR szPatchPackage, WCHAR ***product_codes ) { MSIHANDLE patch, info = 0; @@ -580,17 +582,63 @@ static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch ) return r; } +/* IXMLDOMDocument should be set to XPath mode already */ +static UINT MSI_ApplicablePatchXML( MSIPACKAGE *package, IXMLDOMDocument *desc ) +{ + static const WCHAR queryW[] = {'M','s','i','P','a','t','c','h','/', + 'T','a','r','g','e','t','P','r','o','d','u','c','t','/', + 'T','a','r','g','e','t','P','r','o','d','u','c','t','C','o','d','e',0}; + UINT r = ERROR_FUNCTION_FAILED; + IXMLDOMNodeList *list; + LPWSTR product_code; + IXMLDOMNode *node; + HRESULT hr; + BSTR s; + + product_code = msi_dup_property( package->db, szProductCode ); + if (!product_code) + { + /* FIXME: the property ProductCode should be written into the DB somewhere */ + ERR("no product code to check\n"); + return ERROR_SUCCESS; + } + + s = SysAllocString(queryW); + hr = IXMLDOMDocument_selectNodes( desc, s, &list ); + SysFreeString(s); + if (hr != S_OK) + return ERROR_INVALID_PATCH_XML; + + while (IXMLDOMNodeList_nextNode( list, &node ) == S_OK && r != ERROR_SUCCESS) + { + hr = IXMLDOMNode_get_text( node, &s ); + IXMLDOMNode_Release( node ); + if (!strcmpW( s, product_code )) r = ERROR_SUCCESS; + SysFreeString(s); + } + IXMLDOMNodeList_Release( list ); + + if (r != ERROR_SUCCESS) + TRACE("patch not applicable\n"); + + msi_free( product_code ); + return r; +} + static UINT determine_patch_sequence( MSIPACKAGE *package, DWORD count, MSIPATCHSEQUENCEINFOW *info ) { + IXMLDOMDocument *desc = NULL; DWORD i; + if (count > 1) + FIXME("patch ordering not supported\n"); + for (i = 0; i < count; i++) { switch (info[i].ePatchDataType) { case MSIPATCH_DATATYPE_PATCHFILE: { - FIXME("patch ordering not supported\n"); if (MSI_ApplicablePatchW( package, info[i].szPatchData ) != ERROR_SUCCESS) { info[i].dwOrder = ~0u; @@ -603,6 +651,45 @@ static UINT determine_patch_sequence( MSIPACKAGE *package, DWORD count, MSIPATCH } break; } + case MSIPATCH_DATATYPE_XMLBLOB: + { + VARIANT_BOOL b; + HRESULT hr; + BSTR s; + + if (!desc) + { + hr = CoCreateInstance( &CLSID_DOMDocument30, NULL, CLSCTX_INPROC_SERVER, + &IID_IXMLDOMDocument, (void**)&desc ); + if (hr != S_OK) + { + ERR("failed to create DOMDocument30 instance, 0x%08x\n", hr); + return ERROR_FUNCTION_FAILED; + } + } + + s = SysAllocString( info[i].szPatchData ); + hr = IXMLDOMDocument_loadXML( desc, s, &b ); + SysFreeString( s ); + if ( hr != S_OK ) + { + ERR("failed to parse patch description\n"); + IXMLDOMDocument_Release( desc ); + break; + } + + if (MSI_ApplicablePatchXML( package, desc ) != ERROR_SUCCESS) + { + info[i].dwOrder = ~0u; + info[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND; + } + else + { + info[i].dwOrder = i; + info[i].uStatus = ERROR_SUCCESS; + } + break; + } default: { FIXME("patch data type %u not supported\n", info[i].ePatchDataType); @@ -611,11 +698,15 @@ static UINT determine_patch_sequence( MSIPACKAGE *package, DWORD count, MSIPATCH break; } } + TRACE("szPatchData: %s\n", debugstr_w(info[i].szPatchData)); TRACE("ePatchDataType: %u\n", info[i].ePatchDataType); TRACE("dwOrder: %u\n", info[i].dwOrder); TRACE("uStatus: %u\n", info[i].uStatus); } + + if (desc) IXMLDOMDocument_Release( desc ); + return ERROR_SUCCESS; } -- 2.11.4.GIT