diff options
Diffstat (limited to 'libmsi')
-rw-r--r-- | libmsi/database.c | 68 | ||||
-rw-r--r-- | libmsi/msiquery.c | 39 | ||||
-rw-r--r-- | libmsi/streams.c | 5 |
3 files changed, 62 insertions, 50 deletions
diff --git a/libmsi/database.c b/libmsi/database.c index 3f867d8..dcd1d23 100644 --- a/libmsi/database.c +++ b/libmsi/database.c @@ -301,9 +301,12 @@ unsigned write_raw_stream_data( LibmsiDatabase *db, const WCHAR *stname, unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED; unsigned count; IStream *stm = NULL; - ULARGE_INTEGER size; - LARGE_INTEGER pos; + HANDLE hGlob; LibmsiStream *stream; + ULARGE_INTEGER size; + + if (db->mode == LIBMSI_DB_OPEN_READONLY) + return LIBMSI_RESULT_FUNCTION_FAILED; LIST_FOR_EACH_ENTRY( stream, &db->streams, LibmsiStream, entry ) { @@ -314,53 +317,26 @@ unsigned write_raw_stream_data( LibmsiDatabase *db, const WCHAR *stname, } } - r = IStorage_CreateStream( db->outfile, stname, - STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm); - if( FAILED( r ) ) - { - WARN("open stream failed r = %08x\n", r); - return ret; - } + hGlob = GlobalAlloc(GMEM_FIXED, sz); + if (!hGlob) + return LIBMSI_RESULT_FUNCTION_FAILED; - size.QuadPart = sz; - r = IStream_SetSize( stm, size ); - if( FAILED( r ) ) - { - WARN("Failed to SetSize\n"); - goto end; - } + if (data || sz) + memcpy(hGlob, data, sz); - pos.QuadPart = 0; - r = IStream_Seek( stm, pos, STREAM_SEEK_SET, NULL ); + r = CreateStreamOnHGlobal(hGlob, true, &stm); if( FAILED( r ) ) { - WARN("Failed to Seek\n"); - goto end; - } - - if (sz) - { - r = IStream_Write(stm, data, sz, &count ); - if( FAILED( r ) || ( count != sz ) ) - { - WARN("Failed to Write\n"); - goto end; - } + GlobalFree(hGlob); + return LIBMSI_RESULT_FUNCTION_FAILED; } - ret = LIBMSI_RESULT_SUCCESS; - -end: - IStream_Release( stm ); - if ( ret == LIBMSI_RESULT_SUCCESS ) { - r = IStorage_OpenStream( db->outfile, stname, NULL, - STGM_READ | STGM_SHARE_EXCLUSIVE, 0, outstm); - if ( FAILED ( r ) ) - return LIBMSI_RESULT_FUNCTION_FAILED; - - msi_alloc_stream( db, stname, *outstm ); - } + /* set the correct size - CreateStreamOnHGlobal screws it up */ + size.QuadPart = sz; + IStream_SetSize(stm, size); + ret = msi_alloc_stream( db, stname, stm); + *outstm = stm; return ret; } @@ -598,7 +574,6 @@ void msi_destroy_stream( LibmsiDatabase *db, const WCHAR *stname ) list_remove( &stream->entry ); IStream_Release( stream->stm ); - IStorage_DestroyElement( db->infile, stname ); msi_free( stream ); break; } @@ -638,8 +613,13 @@ void append_storage_to_db( LibmsiDatabase *db, IStorage *stg ) IStorage_AddRef( stg ); list_add_head( &db->transforms, &t->entry ); - /* the transform may add or replace streams */ +#if 0 + /* the transform may add or replace streams... + * + * FIXME: Hmm, the MSI is always searched before the transform though. + * For now disable this. */ free_streams( db ); +#endif } static VOID _libmsi_database_destroy( LibmsiObject *arg ) diff --git a/libmsi/msiquery.c b/libmsi/msiquery.c index 5913bb0..aa0c7f7 100644 --- a/libmsi/msiquery.c +++ b/libmsi/msiquery.c @@ -600,6 +600,43 @@ LibmsiResult libmsi_database_apply_transform( LibmsiDatabase *db, return r; } +static unsigned commit_stream( const WCHAR *name, IStream *stm, void *opaque) +{ + LibmsiDatabase *db = opaque; + STATSTG stat; + IStream *outstm; + ULARGE_INTEGER cbRead, cbWritten; + unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED; + HRESULT r; + WCHAR decname[0x40]; + + decode_streamname(name, decname); + TRACE("%s(%s) %p %p\n", debugstr_w(name), debugstr_w(decname), stm, opaque); + + IStream_Stat(stm, &stat, STATFLAG_NONAME); + r = IStorage_CreateStream( db->outfile, name, + STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &outstm); + if ( FAILED(r) ) + return LIBMSI_RESULT_FUNCTION_FAILED; + + IStream_SetSize( outstm, stat.cbSize ); + + r = IStream_CopyTo( stm, outstm, stat.cbSize, &cbRead, &cbWritten ); + if ( FAILED(r) ) + goto end; + + if (cbRead.QuadPart != stat.cbSize.QuadPart) + goto end; + if (cbWritten.QuadPart != stat.cbSize.QuadPart) + goto end; + + ret = LIBMSI_RESULT_SUCCESS; + +end: + IStream_Release(outstm); + return ret; +} + LibmsiResult libmsi_database_commit( LibmsiDatabase *db ) { unsigned r = LIBMSI_RESULT_SUCCESS; @@ -631,7 +668,7 @@ LibmsiResult libmsi_database_commit( LibmsiDatabase *db ) goto end; } - r = _libmsi_database_commit_streams( db ); + r = msi_enum_db_streams( db, commit_stream, db ); if (r != LIBMSI_RESULT_SUCCESS) { WARN("failed to save streams r=%08x\n",r); diff --git a/libmsi/streams.c b/libmsi/streams.c index 2b379c9..0c4a4b7 100644 --- a/libmsi/streams.c +++ b/libmsi/streams.c @@ -411,8 +411,3 @@ unsigned streams_view_create(LibmsiDatabase *db, LibmsiView **view) return LIBMSI_RESULT_SUCCESS; } - -unsigned _libmsi_database_commit_streams( LibmsiDatabase *db ) -{ - return LIBMSI_RESULT_SUCCESS; -} |