msi: Preserve strings with embedded nulls in the record implementation.
This commit is contained in:
parent
8d28cc0ac7
commit
32aed60786
|
@ -823,6 +823,7 @@ extern MSIRECORD *MSI_CloneRecord( MSIRECORD * ) DECLSPEC_HIDDEN;
|
|||
extern BOOL MSI_RecordsAreEqual( MSIRECORD *, MSIRECORD * ) DECLSPEC_HIDDEN;
|
||||
extern BOOL MSI_RecordsAreFieldsEqual(MSIRECORD *a, MSIRECORD *b, UINT field) DECLSPEC_HIDDEN;
|
||||
extern UINT msi_record_set_string(MSIRECORD *, UINT, const WCHAR *, int) DECLSPEC_HIDDEN;
|
||||
extern const WCHAR *msi_record_get_string(const MSIRECORD *, UINT, int *) DECLSPEC_HIDDEN;
|
||||
|
||||
/* stream internals */
|
||||
extern void enum_stream_names( IStorage *stg ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -156,6 +156,17 @@ static BOOL string2intW( LPCWSTR str, int *out )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static WCHAR *msi_strdupW( const WCHAR *value, int len )
|
||||
{
|
||||
WCHAR *ret;
|
||||
|
||||
if (!value) return NULL;
|
||||
if (!(ret = msi_alloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
|
||||
memcpy( ret, value, len * sizeof(WCHAR) );
|
||||
ret[len] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT MSI_RecordCopyField( MSIRECORD *in_rec, UINT in_n,
|
||||
MSIRECORD *out_rec, UINT out_n )
|
||||
{
|
||||
|
@ -184,11 +195,12 @@ UINT MSI_RecordCopyField( MSIRECORD *in_rec, UINT in_n,
|
|||
out->u.pVal = in->u.pVal;
|
||||
break;
|
||||
case MSIFIELD_WSTR:
|
||||
str = strdupW( in->u.szwVal );
|
||||
if ( !str )
|
||||
r = ERROR_OUTOFMEMORY;
|
||||
else
|
||||
if ((str = msi_strdupW( in->u.szwVal, in->len )))
|
||||
{
|
||||
out->u.szwVal = str;
|
||||
out->len = in->len;
|
||||
}
|
||||
else r = ERROR_OUTOFMEMORY;
|
||||
break;
|
||||
case MSIFIELD_STREAM:
|
||||
IStream_AddRef( in->u.stream );
|
||||
|
@ -202,7 +214,6 @@ UINT MSI_RecordCopyField( MSIRECORD *in_rec, UINT in_n,
|
|||
}
|
||||
|
||||
msiobj_unlock( &in_rec->hdr );
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -380,7 +391,7 @@ BOOL WINAPI MsiRecordIsNull( MSIHANDLE handle, UINT iField )
|
|||
UINT MSI_RecordGetStringA(MSIRECORD *rec, UINT iField,
|
||||
LPSTR szValue, LPDWORD pcchValue)
|
||||
{
|
||||
UINT len=0, ret;
|
||||
UINT len = 0, ret = ERROR_SUCCESS;
|
||||
CHAR buffer[16];
|
||||
|
||||
TRACE("%p %d %p %p\n", rec, iField, szValue, pcchValue);
|
||||
|
@ -394,7 +405,6 @@ UINT MSI_RecordGetStringA(MSIRECORD *rec, UINT iField,
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
ret = ERROR_SUCCESS;
|
||||
switch( rec->fields[iField].type )
|
||||
{
|
||||
case MSIFIELD_INT:
|
||||
|
@ -404,11 +414,11 @@ UINT MSI_RecordGetStringA(MSIRECORD *rec, UINT iField,
|
|||
lstrcpynA(szValue, buffer, *pcchValue);
|
||||
break;
|
||||
case MSIFIELD_WSTR:
|
||||
len = WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1,
|
||||
NULL, 0 , NULL, NULL);
|
||||
len = WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal,
|
||||
rec->fields[iField].len + 1, NULL, 0 , NULL, NULL );
|
||||
if (szValue)
|
||||
WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1,
|
||||
szValue, *pcchValue, NULL, NULL);
|
||||
WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal,
|
||||
rec->fields[iField].len + 1, szValue, *pcchValue, NULL, NULL );
|
||||
if( szValue && *pcchValue && len>*pcchValue )
|
||||
szValue[*pcchValue-1] = 0;
|
||||
if( len )
|
||||
|
@ -448,23 +458,30 @@ UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, UINT iField,
|
|||
return ret;
|
||||
}
|
||||
|
||||
const WCHAR *msi_record_get_string( const MSIRECORD *rec, UINT field, int *len )
|
||||
{
|
||||
if (field > rec->count)
|
||||
return NULL;
|
||||
|
||||
if (rec->fields[field].type != MSIFIELD_WSTR)
|
||||
return NULL;
|
||||
|
||||
if (len) *len = rec->fields[field].len;
|
||||
|
||||
return rec->fields[field].u.szwVal;
|
||||
}
|
||||
|
||||
const WCHAR *MSI_RecordGetString( const MSIRECORD *rec, UINT iField )
|
||||
{
|
||||
if( iField > rec->count )
|
||||
return NULL;
|
||||
|
||||
if( rec->fields[iField].type != MSIFIELD_WSTR )
|
||||
return NULL;
|
||||
|
||||
return rec->fields[iField].u.szwVal;
|
||||
return msi_record_get_string( rec, iField, NULL );
|
||||
}
|
||||
|
||||
UINT MSI_RecordGetStringW(MSIRECORD *rec, UINT iField,
|
||||
LPWSTR szValue, LPDWORD pcchValue)
|
||||
{
|
||||
UINT len=0, ret;
|
||||
WCHAR buffer[16];
|
||||
static const WCHAR szFormat[] = {'%','d',0};
|
||||
UINT len = 0, ret = ERROR_SUCCESS;
|
||||
WCHAR buffer[16];
|
||||
|
||||
TRACE("%p %d %p %p\n", rec, iField, szValue, pcchValue);
|
||||
|
||||
|
@ -477,7 +494,6 @@ UINT MSI_RecordGetStringW(MSIRECORD *rec, UINT iField,
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
ret = ERROR_SUCCESS;
|
||||
switch( rec->fields[iField].type )
|
||||
{
|
||||
case MSIFIELD_INT:
|
||||
|
@ -487,9 +503,9 @@ UINT MSI_RecordGetStringW(MSIRECORD *rec, UINT iField,
|
|||
lstrcpynW(szValue, buffer, *pcchValue);
|
||||
break;
|
||||
case MSIFIELD_WSTR:
|
||||
len = lstrlenW( rec->fields[iField].u.szwVal );
|
||||
len = rec->fields[iField].len;
|
||||
if (szValue)
|
||||
lstrcpynW(szValue, rec->fields[iField].u.szwVal, *pcchValue);
|
||||
memcpy( szValue, rec->fields[iField].u.szwVal, min(len + 1, *pcchValue) * sizeof(WCHAR) );
|
||||
break;
|
||||
case MSIFIELD_NULL:
|
||||
if( szValue && *pcchValue > 0 )
|
||||
|
@ -548,7 +564,7 @@ static UINT MSI_RecordDataSize(MSIRECORD *rec, UINT iField)
|
|||
case MSIFIELD_INT:
|
||||
return sizeof (INT);
|
||||
case MSIFIELD_WSTR:
|
||||
return lstrlenW( rec->fields[iField].u.szwVal );
|
||||
return rec->fields[iField].len;
|
||||
case MSIFIELD_NULL:
|
||||
break;
|
||||
case MSIFIELD_STREAM:
|
||||
|
@ -598,16 +614,6 @@ UINT WINAPI MsiRecordSetStringA( MSIHANDLE handle, UINT iField, LPCSTR szValue )
|
|||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *msi_strdupW( const WCHAR *value, int len )
|
||||
{
|
||||
WCHAR *ret;
|
||||
|
||||
if (!(ret = msi_alloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
|
||||
memcpy( ret, value, len * sizeof(WCHAR) );
|
||||
ret[len] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT msi_record_set_string( MSIRECORD *rec, UINT field, const WCHAR *value, int len )
|
||||
{
|
||||
if (field > rec->count)
|
||||
|
@ -1008,8 +1014,9 @@ BOOL MSI_RecordsAreFieldsEqual(MSIRECORD *a, MSIRECORD *b, UINT field)
|
|||
break;
|
||||
|
||||
case MSIFIELD_WSTR:
|
||||
if (strcmpW(a->fields[field].u.szwVal, b->fields[field].u.szwVal))
|
||||
return FALSE;
|
||||
if (a->fields[field].len != b->fields[field].len) return FALSE;
|
||||
if (memcmp( a->fields[field].u.szwVal, b->fields[field].u.szwVal,
|
||||
a->fields[field].len * sizeof(WCHAR) )) return FALSE;
|
||||
break;
|
||||
|
||||
case MSIFIELD_STREAM:
|
||||
|
|
Loading…
Reference in New Issue