summaryrefslogtreecommitdiffstats
path: root/libmsi
diff options
context:
space:
mode:
Diffstat (limited to 'libmsi')
-rw-r--r--libmsi/database.c68
-rw-r--r--libmsi/msiquery.c39
-rw-r--r--libmsi/streams.c5
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;
-}