James Hawkins : msi: Change the property variant if the types don't match.

Alexandre Julliard julliard at winehq.org
Wed Feb 27 08:03:27 CST 2008


Module: wine
Branch: master
Commit: 9101665233433d3705737b3a43b72bf22e056c1e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9101665233433d3705737b3a43b72bf22e056c1e

Author: James Hawkins <jhawkins at codeweavers.com>
Date:   Wed Feb 27 02:39:21 2008 -0600

msi: Change the property variant if the types don't match.

---

 dlls/msi/suminfo.c |   78 ++++++++++++++++++++++++++++++++++------------------
 1 files changed, 51 insertions(+), 27 deletions(-)

diff --git a/dlls/msi/suminfo.c b/dlls/msi/suminfo.c
index 2f9e7f4..5dd3297 100644
--- a/dlls/msi/suminfo.c
+++ b/dlls/msi/suminfo.c
@@ -34,6 +34,7 @@
 #include "msidefs.h"
 #include "msipriv.h"
 #include "objidl.h"
+#include "propvarutil.h"
 #include "msiserver.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(msi);
@@ -78,6 +79,10 @@ typedef struct {
  
 #include "poppack.h"
 
+static HRESULT (WINAPI *pPropVariantChangeType)
+    (PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc,
+     PROPVAR_CHANGE_FLAGS flags, VARTYPE vt);
+
 #define SECT_HDR_SIZE (sizeof(PROPERTYSECTIONHEADER))
 
 static const WCHAR szSumInfo[] = { 5 ,'S','u','m','m','a','r','y',
@@ -144,6 +149,22 @@ static UINT get_property_count( const PROPVARIANT *property )
     return n;
 }
 
+static UINT propvar_changetype(PROPVARIANT *changed, PROPVARIANT *property, VARTYPE vt)
+{
+    HRESULT hr;
+    HMODULE propsys = LoadLibraryA("propsys.dll");
+    pPropVariantChangeType = (void *)GetProcAddress(propsys, "PropVariantChangeType");
+
+    if (!pPropVariantChangeType)
+    {
+        ERR("PropVariantChangeType function missing!\n");
+        return ERROR_FUNCTION_FAILED;
+    }
+
+    hr = pPropVariantChangeType(changed, property, 0, vt);
+    return (hr == S_OK) ? ERROR_SUCCESS : ERROR_FUNCTION_FAILED;
+}
+
 /* FIXME: doesn't deal with endian conversion */
 static void read_properties_from_data( PROPVARIANT *prop, LPBYTE data, DWORD sz )
 {
@@ -151,7 +172,8 @@ static void read_properties_from_data( PROPVARIANT *prop, LPBYTE data, DWORD sz
     DWORD i;
     int size;
     PROPERTY_DATA *propdata;
-    PROPVARIANT *property;
+    PROPVARIANT property, *ptr;
+    PROPVARIANT changed;
     PROPERTYIDOFFSET *idofs;
     PROPERTYSECTIONHEADER *section_hdr;
 
@@ -161,6 +183,12 @@ static void read_properties_from_data( PROPVARIANT *prop, LPBYTE data, DWORD sz
     /* now set all the properties */
     for( i = 0; i < section_hdr->cProperties; i++ )
     {
+        if( idofs[i].propid >= MSI_MAX_PROPS )
+        {
+            ERR("Unknown property ID %d\n", idofs[i].propid );
+            break;
+        }
+
         type = get_type( idofs[i].propid );
         if( type == VT_EMPTY )
         {
@@ -170,45 +198,41 @@ static void read_properties_from_data( PROPVARIANT *prop, LPBYTE data, DWORD sz
 
         propdata = (PROPERTY_DATA*) &data[ idofs[i].dwOffset ];
 
-        /* check the type is the same as we expect */
-        if( type != propdata->type )
-        {
-            ERR("wrong type %d != %d\n", type, propdata->type);
-            break;
-        }
-
         /* check we don't run off the end of the data */
         size = sz - idofs[i].dwOffset - sizeof(DWORD);
         if( sizeof(DWORD) > size ||
-            ( type == VT_FILETIME && sizeof(FILETIME) > size ) ||
-            ( type == VT_LPSTR && (propdata->u.str.len + sizeof(DWORD)) > size ) )
+            ( propdata->type == VT_FILETIME && sizeof(FILETIME) > size ) ||
+            ( propdata->type == VT_LPSTR && (propdata->u.str.len + sizeof(DWORD)) > size ) )
         {
             ERR("not enough data\n");
             break;
         }
 
-        if( idofs[i].propid >= MSI_MAX_PROPS )
-        {
-            ERR("Unknown property ID %d\n", idofs[i].propid );
-            break;
-        }
-
-        property = &prop[ idofs[i].propid ];
-        property->vt = type;
-
-        if( type == VT_LPSTR )
+        property.vt = propdata->type;
+        if( propdata->type == VT_LPSTR )
         {
             LPSTR str = msi_alloc( propdata->u.str.len );
             memcpy( str, propdata->u.str.str, propdata->u.str.len );
             str[ propdata->u.str.len - 1 ] = 0;
-            property->u.pszVal = str;
+            property.u.pszVal = str;
+        }
+        else if( propdata->type == VT_FILETIME )
+            property.u.filetime = propdata->u.ft;
+        else if( propdata->type == VT_I2 )
+            property.u.iVal = propdata->u.i2;
+        else if( propdata->type == VT_I4 )
+            property.u.lVal = propdata->u.i4;
+
+        /* check the type is the same as we expect */
+        if( type != propdata->type )
+        {
+            propvar_changetype(&changed, &property, type);
+            ptr = &changed;
         }
-        else if( type == VT_FILETIME )
-            property->u.filetime = propdata->u.ft;
-        else if( type == VT_I2 )
-            property->u.iVal = propdata->u.i2;
-        else if( type == VT_I4 )
-            property->u.lVal = propdata->u.i4;
+        else
+            ptr = &property;
+
+        memcpy(&prop[ idofs[i].propid ], ptr, sizeof(PROPVARIANT));
     }
 }
 




More information about the wine-cvs mailing list