Nikolay Sivov : msi: Support MSIPATCH_DATATYPE_XMLBLOB when testing for applicable patch.
Alexandre Julliard
julliard at winehq.org
Wed Jan 18 14:03:37 CST 2012
Module: wine
Branch: master
Commit: 123eba280124f4f3a520a333fed8119bd560c09b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=123eba280124f4f3a520a333fed8119bd560c09b
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Tue Jan 17 22:07:11 2012 +0300
msi: Support MSIPATCH_DATATYPE_XMLBLOB when testing for applicable patch.
---
dlls/msi/msi.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 93 insertions(+), 2 deletions(-)
diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c
index fd2315f..941a547 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;
}
More information about the wine-cvs
mailing list