msi: Change the property variant if the types don't match.
This commit is contained in:
parent
47120f5003
commit
9101665233
|
@ -34,6 +34,7 @@
|
||||||
#include "msidefs.h"
|
#include "msidefs.h"
|
||||||
#include "msipriv.h"
|
#include "msipriv.h"
|
||||||
#include "objidl.h"
|
#include "objidl.h"
|
||||||
|
#include "propvarutil.h"
|
||||||
#include "msiserver.h"
|
#include "msiserver.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
||||||
|
@ -78,6 +79,10 @@ typedef struct {
|
||||||
|
|
||||||
#include "poppack.h"
|
#include "poppack.h"
|
||||||
|
|
||||||
|
static HRESULT (WINAPI *pPropVariantChangeType)
|
||||||
|
(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc,
|
||||||
|
PROPVAR_CHANGE_FLAGS flags, VARTYPE vt);
|
||||||
|
|
||||||
#define SECT_HDR_SIZE (sizeof(PROPERTYSECTIONHEADER))
|
#define SECT_HDR_SIZE (sizeof(PROPERTYSECTIONHEADER))
|
||||||
|
|
||||||
static const WCHAR szSumInfo[] = { 5 ,'S','u','m','m','a','r','y',
|
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;
|
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 */
|
/* FIXME: doesn't deal with endian conversion */
|
||||||
static void read_properties_from_data( PROPVARIANT *prop, LPBYTE data, DWORD sz )
|
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;
|
DWORD i;
|
||||||
int size;
|
int size;
|
||||||
PROPERTY_DATA *propdata;
|
PROPERTY_DATA *propdata;
|
||||||
PROPVARIANT *property;
|
PROPVARIANT property, *ptr;
|
||||||
|
PROPVARIANT changed;
|
||||||
PROPERTYIDOFFSET *idofs;
|
PROPERTYIDOFFSET *idofs;
|
||||||
PROPERTYSECTIONHEADER *section_hdr;
|
PROPERTYSECTIONHEADER *section_hdr;
|
||||||
|
|
||||||
|
@ -161,6 +183,12 @@ static void read_properties_from_data( PROPVARIANT *prop, LPBYTE data, DWORD sz
|
||||||
/* now set all the properties */
|
/* now set all the properties */
|
||||||
for( i = 0; i < section_hdr->cProperties; i++ )
|
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 );
|
type = get_type( idofs[i].propid );
|
||||||
if( type == VT_EMPTY )
|
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 ];
|
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 */
|
/* check we don't run off the end of the data */
|
||||||
size = sz - idofs[i].dwOffset - sizeof(DWORD);
|
size = sz - idofs[i].dwOffset - sizeof(DWORD);
|
||||||
if( sizeof(DWORD) > size ||
|
if( sizeof(DWORD) > size ||
|
||||||
( type == VT_FILETIME && sizeof(FILETIME) > size ) ||
|
( propdata->type == VT_FILETIME && sizeof(FILETIME) > size ) ||
|
||||||
( type == VT_LPSTR && (propdata->u.str.len + sizeof(DWORD)) > size ) )
|
( propdata->type == VT_LPSTR && (propdata->u.str.len + sizeof(DWORD)) > size ) )
|
||||||
{
|
{
|
||||||
ERR("not enough data\n");
|
ERR("not enough data\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( idofs[i].propid >= MSI_MAX_PROPS )
|
property.vt = propdata->type;
|
||||||
{
|
if( propdata->type == VT_LPSTR )
|
||||||
ERR("Unknown property ID %d\n", idofs[i].propid );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
property = &prop[ idofs[i].propid ];
|
|
||||||
property->vt = type;
|
|
||||||
|
|
||||||
if( type == VT_LPSTR )
|
|
||||||
{
|
{
|
||||||
LPSTR str = msi_alloc( propdata->u.str.len );
|
LPSTR str = msi_alloc( propdata->u.str.len );
|
||||||
memcpy( str, propdata->u.str.str, propdata->u.str.len );
|
memcpy( str, propdata->u.str.str, propdata->u.str.len );
|
||||||
str[ propdata->u.str.len - 1 ] = 0;
|
str[ propdata->u.str.len - 1 ] = 0;
|
||||||
property->u.pszVal = str;
|
property.u.pszVal = str;
|
||||||
}
|
}
|
||||||
else if( type == VT_FILETIME )
|
else if( propdata->type == VT_FILETIME )
|
||||||
property->u.filetime = propdata->u.ft;
|
property.u.filetime = propdata->u.ft;
|
||||||
else if( type == VT_I2 )
|
else if( propdata->type == VT_I2 )
|
||||||
property->u.iVal = propdata->u.i2;
|
property.u.iVal = propdata->u.i2;
|
||||||
else if( type == VT_I4 )
|
else if( propdata->type == VT_I4 )
|
||||||
property->u.lVal = propdata->u.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
|
||||||
|
ptr = &property;
|
||||||
|
|
||||||
|
memcpy(&prop[ idofs[i].propid ], ptr, sizeof(PROPVARIANT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue