From 937ca216c6cdf3909d2bceec118c45977f2e1f3a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 3 Dec 2012 14:00:27 +0100 Subject: move stream creation to database.c --- libmsi/database.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- libmsi/msipriv.h | 3 ++- libmsi/streams.c | 55 +++++++-------------------------------------- 3 files changed, 74 insertions(+), 51 deletions(-) (limited to 'libmsi') diff --git a/libmsi/database.c b/libmsi/database.c index 87d0381..38ea337 100644 --- a/libmsi/database.c +++ b/libmsi/database.c @@ -282,7 +282,7 @@ static unsigned find_open_stream( LibmsiDatabase *db, IStorage *stg, const WCHAR } unsigned write_raw_stream_data( LibmsiDatabase *db, const WCHAR *stname, - const void *data, unsigned sz ) + const void *data, unsigned sz, IStream **outstm ) { HRESULT r; unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED; @@ -330,14 +330,75 @@ unsigned write_raw_stream_data( LibmsiDatabase *db, const WCHAR *stname, } } - ret = LIBMSI_RESULT_SUCCESS; + IStream_Release( stm ); + return msi_get_raw_stream( db, stname, outstm ); end: IStream_Release( stm ); - return ret; } +unsigned msi_create_stream( LibmsiDatabase *db, const WCHAR *stname, IStream *stm, IStream **outstm ) +{ + LibmsiStream *stream; + WCHAR *encname = NULL; + STATSTG stat; + HRESULT hr; + unsigned r = LIBMSI_RESULT_FUNCTION_FAILED; + unsigned count; + uint8_t *data; + + encname = encode_streamname(false, stname); + LIST_FOR_EACH_ENTRY( stream, &db->streams, LibmsiStream, entry ) + { + if (stream->stg != db->infile) continue; + + if( !strcmpW( encname, stream->name ) ) + { + msi_destroy_stream( db, encname ); + break; + } + } + + hr = IStream_Stat(stm, &stat, STATFLAG_NONAME); + if (FAILED(hr)) + { + WARN("failed to stat stream: %08x\n", hr); + goto end; + } + + if (stat.cbSize.QuadPart >> 32) + { + WARN("stream too large\n"); + goto end; + } + + data = msi_alloc(stat.cbSize.QuadPart); + if (!data) + goto end; + + hr = IStream_Read(stm, data, stat.cbSize.QuadPart, &count); + if (FAILED(hr) || count != stat.cbSize.QuadPart) + { + WARN("failed to read stream: %08x\n", hr); + msi_free(data); + goto end; + } + + r = write_raw_stream_data(db, encname, data, count, outstm); + if (r != LIBMSI_RESULT_SUCCESS) + { + WARN("failed to write stream data: %d\n", r); + msi_free(data); + return r; + } + + msi_free(data); +end: + msi_free(encname); + return r; +} + static void cache_infile_structure( LibmsiDatabase *db ) { IEnumSTATSTG *stgenum = NULL; diff --git a/libmsi/msipriv.h b/libmsi/msipriv.h index 8af6f09..8737403 100644 --- a/libmsi/msipriv.h +++ b/libmsi/msipriv.h @@ -321,7 +321,7 @@ extern unsigned read_stream_data( IStorage *stg, const WCHAR *stname, extern unsigned write_stream_data( LibmsiDatabase *db, const WCHAR *stname, const void *data, unsigned sz ); extern unsigned write_raw_stream_data( LibmsiDatabase *db, const WCHAR *stname, - const void *data, unsigned sz ); + const void *data, unsigned sz, IStream **outstm ); extern unsigned _libmsi_database_commit_streams( LibmsiDatabase *db ); /* transform functions */ @@ -355,6 +355,7 @@ extern WCHAR *encode_streamname(bool bTable, const WCHAR *in); extern void decode_streamname(const WCHAR *in, WCHAR *out); /* database internals */ +unsigned msi_create_stream( LibmsiDatabase *db, const WCHAR *stname, IStream *stm, IStream **outstm ); extern unsigned msi_get_raw_stream( LibmsiDatabase *, const WCHAR *, IStream **); extern unsigned msi_clone_open_stream( LibmsiDatabase *, IStorage *, const WCHAR *, IStream ** ); void msi_destroy_stream( LibmsiDatabase *, const WCHAR * ); diff --git a/libmsi/streams.c b/libmsi/streams.c index e565c57..3a8ad62 100644 --- a/libmsi/streams.c +++ b/libmsi/streams.c @@ -131,15 +131,10 @@ static unsigned streams_view_get_row( LibmsiView *view, unsigned row, LibmsiReco static unsigned streams_view_set_row(LibmsiView *view, unsigned row, LibmsiRecord *rec, unsigned mask) { LibmsiStreamsView *sv = (LibmsiStreamsView *)view; - STREAM *stream; + STREAM *stream = NULL; IStream *stm; - STATSTG stat; - WCHAR *encname = NULL; WCHAR *name = NULL; - uint16_t *data = NULL; - HRESULT hr; - unsigned count; - unsigned r = LIBMSI_RESULT_FUNCTION_FAILED; + unsigned r; TRACE("(%p, %d, %p, %08x)\n", view, row, rec, mask); @@ -150,30 +145,6 @@ static unsigned streams_view_set_row(LibmsiView *view, unsigned row, LibmsiRecor if (r != LIBMSI_RESULT_SUCCESS) return r; - hr = IStream_Stat(stm, &stat, STATFLAG_NONAME); - if (FAILED(hr)) - { - WARN("failed to stat stream: %08x\n", hr); - goto done; - } - - if (stat.cbSize.QuadPart >> 32) - { - WARN("stream too large\n"); - goto done; - } - - data = msi_alloc(stat.cbSize.QuadPart); - if (!data) - goto done; - - hr = IStream_Read(stm, data, stat.cbSize.QuadPart, &count); - if (FAILED(hr) || count != stat.cbSize.QuadPart) - { - WARN("failed to read stream: %08x\n", hr); - goto done; - } - name = strdupW(_libmsi_record_get_string_raw(rec, 1)); if (!name) { @@ -181,34 +152,24 @@ static unsigned streams_view_set_row(LibmsiView *view, unsigned row, LibmsiRecor goto done; } - encname = encode_streamname(false, name); - msi_destroy_stream(sv->db, encname); - - r = write_raw_stream_data(sv->db, encname, data, count); - if (r != LIBMSI_RESULT_SUCCESS) - { - WARN("failed to write stream data: %d\n", r); - goto done; - } - stream = create_stream(sv, name, false, NULL); if (!stream) goto done; - hr = IStorage_OpenStream(sv->db->infile, encname, 0, - STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream); - if (FAILED(hr)) + r = msi_create_stream(sv->db, name, stm, &stream->stream); + if (r != LIBMSI_RESULT_SUCCESS) { - WARN("failed to open stream: %08x\n", hr); + WARN("failed to create stream: %08x\n", r); goto done; } sv->streams[row] = stream; done: + if (r != LIBMSI_RESULT_SUCCESS) + msi_free(stream); + msi_free(name); - msi_free(data); - msi_free(encname); IStream_Release(stm); -- cgit