Module: wine Branch: master Commit: d9568722aa1c60ae402f18f7a079cb0988dd8c58 URL: http://source.winehq.org/git/wine.git/?a=commit;h=d9568722aa1c60ae402f18f7a0...
Author: Hib Eris hib@hiberis.nl Date: Sun May 24 18:51:58 2009 +0200
msi: Support transforms with binary OBJECTS.
---
dlls/msi/msipriv.h | 1 + dlls/msi/record.c | 2 +- dlls/msi/table.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 85 insertions(+), 4 deletions(-)
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index ccfd6e3..408c968 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -701,6 +701,7 @@ extern UINT MSI_RecordGetStringW( MSIRECORD * , UINT, LPWSTR, LPDWORD); extern UINT MSI_RecordGetStringA( MSIRECORD *, UINT, LPSTR, LPDWORD); extern int MSI_RecordGetInteger( MSIRECORD *, UINT ); extern UINT MSI_RecordReadStream( MSIRECORD *, UINT, char *, LPDWORD); +extern UINT MSI_RecordSetStream(MSIRECORD *, UINT, IStream *); extern UINT MSI_RecordGetFieldCount( const MSIRECORD *rec ); extern UINT MSI_RecordStreamToFile( MSIRECORD *, UINT, LPCWSTR ); extern UINT MSI_RecordCopyField( MSIRECORD *, UINT, MSIRECORD *, UINT ); diff --git a/dlls/msi/record.c b/dlls/msi/record.c index 283c418..9211e1c 100644 --- a/dlls/msi/record.c +++ b/dlls/msi/record.c @@ -661,7 +661,7 @@ static UINT RECORD_StreamFromFile(LPCWSTR szFile, IStream **pstm) return ERROR_SUCCESS; }
-static UINT MSI_RecordSetStream(MSIRECORD *rec, UINT iField, IStream *stream) +UINT MSI_RecordSetStream(MSIRECORD *rec, UINT iField, IStream *stream) { if ( (iField == 0) || (iField > rec->count) ) return ERROR_INVALID_PARAMETER; diff --git a/dlls/msi/table.c b/dlls/msi/table.c index 8bb607c..885c0dd 100644 --- a/dlls/msi/table.c +++ b/dlls/msi/table.c @@ -2373,7 +2373,67 @@ static UINT read_raw_int(const BYTE *data, UINT col, UINT bytes) return ret; }
+static UINT msi_record_encoded_stream_name( const MSITABLEVIEW *tv, MSIRECORD *rec, LPWSTR *pstname ) +{ + static const WCHAR szDot[] = { '.', 0 }; + LPWSTR stname = NULL, sval, p; + DWORD len; + UINT i, r; + + TRACE("%p %p\n", tv, rec); + + len = lstrlenW( tv->name ) + 1; + stname = msi_alloc( len*sizeof(WCHAR) ); + if ( !stname ) + { + r = ERROR_OUTOFMEMORY; + goto err; + } + + lstrcpyW( stname, tv->name ); + + for ( i = 0; i < tv->num_cols; i++ ) + { + if ( tv->columns[i].type & MSITYPE_KEY ) + { + sval = msi_dup_record_field( rec, i + 1 ); + if ( !sval ) + { + r = ERROR_OUTOFMEMORY; + goto err; + } + + len += lstrlenW( szDot ) + lstrlenW ( sval ); + p = msi_realloc ( stname, len*sizeof(WCHAR) ); + if ( !p ) + { + r = ERROR_OUTOFMEMORY; + goto err; + } + stname = p; + + lstrcatW( stname, szDot ); + lstrcatW( stname, sval ); + + msi_free( sval ); + } + else + continue; + } + + *pstname = encode_streamname( FALSE, stname ); + msi_free( stname ); + + return ERROR_SUCCESS; + +err: + msi_free ( stname ); + *pstname = NULL; + return r; +} + static MSIRECORD *msi_get_transform_record( const MSITABLEVIEW *tv, const string_table *st, + IStorage *stg, const BYTE *rawdata, UINT bytes_per_strref ) { UINT i, val, ofs = 0; @@ -2397,8 +2457,28 @@ static MSIRECORD *msi_get_transform_record( const MSITABLEVIEW *tv, const string if ( (~mask&1) && (~columns[i].type & MSITYPE_KEY) && ((1<<i) & ~mask) ) continue;
- if( (columns[i].type & MSITYPE_STRING) && - ! MSITYPE_IS_BINARY(tv->columns[i].type) ) + if( MSITYPE_IS_BINARY(tv->columns[i].type) ) + { + LPWSTR encname; + IStream *stm = NULL; + UINT r; + + ofs += bytes_per_column( tv->db, &columns[i] ); + + r = msi_record_encoded_stream_name( tv, rec, &encname ); + if ( r != ERROR_SUCCESS ) + return NULL; + + r = IStorage_OpenStream( stg, encname, NULL, + STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm ); + msi_free( encname ); + if ( r != ERROR_SUCCESS ) + return NULL; + + MSI_RecordSetStream( rec, i+1, stm ); + TRACE(" field %d [%s]\n", i+1, debugstr_w(encname)); + } + else if( columns[i].type & MSITYPE_STRING ) { LPCWSTR sval;
@@ -2659,7 +2739,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg, break; }
- rec = msi_get_transform_record( tv, st, &rawdata[n], bytes_per_strref ); + rec = msi_get_transform_record( tv, st, stg, &rawdata[n], bytes_per_strref ); if (rec) { if ( mask & 1 )