diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 56c9340b6ac..897353e7c50 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -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; diff --git a/dlls/msi/record.c b/dlls/msi/record.c index 263ea2cc906..d42dd819024 100644 --- a/dlls/msi/record.c +++ b/dlls/msi/record.c @@ -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; + static const WCHAR szFormat[] = {'%','d',0}; + UINT len = 0, ret = ERROR_SUCCESS; WCHAR buffer[16]; - static const WCHAR szFormat[] = { '%','d',0 }; 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: