Module: wine Branch: master Commit: 9101665233433d3705737b3a43b72bf22e056c1e URL: http://source.winehq.org/git/wine.git/?a=commit;h=9101665233433d3705737b3a43...
Author: James Hawkins jhawkins@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)); } }