diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2012-12-04 14:00:36 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2012-12-06 20:30:33 +0100 |
commit | 9cf89fe383cfc8c86a4b9d60a67aa85e1ba20402 (patch) | |
tree | 9ded8475f1793a74ebac008a18fa13bf13674ad0 | |
parent | 2257784ffe556b815c1f952c9d2153ba1ae57c4b (diff) | |
download | msitools-9cf89fe383cfc8c86a4b9d60a67aa85e1ba20402.tar.gz msitools-9cf89fe383cfc8c86a4b9d60a67aa85e1ba20402.tar.xz msitools-9cf89fe383cfc8c86a4b9d60a67aa85e1ba20402.zip |
delay reading streams to commit time
Store the external data in the STREAMS table.
-rw-r--r-- | libmsi/database.c | 53 | ||||
-rw-r--r-- | libmsi/msipriv.h | 2 | ||||
-rw-r--r-- | libmsi/streams.c | 11 |
3 files changed, 21 insertions, 45 deletions
diff --git a/libmsi/database.c b/libmsi/database.c index dcd1d23..1ea1eda 100644 --- a/libmsi/database.c +++ b/libmsi/database.c @@ -340,57 +340,36 @@ unsigned write_raw_stream_data( LibmsiDatabase *db, const WCHAR *stname, return ret; } -unsigned msi_create_stream( LibmsiDatabase *db, const WCHAR *stname, IStream *stm, IStream **outstm ) +unsigned msi_create_stream( LibmsiDatabase *db, const WCHAR *stname, IStream *stm ) { LibmsiStream *stream; WCHAR *encname = NULL; - STATSTG stat; - HRESULT hr; unsigned r = LIBMSI_RESULT_FUNCTION_FAILED; - unsigned count; - uint8_t *data; + bool found = false; if ( db->mode == LIBMSI_DB_OPEN_READONLY ) return LIBMSI_RESULT_ACCESS_DENIED; encname = encode_streamname(false, stname); - 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) + LIST_FOR_EACH_ENTRY( stream, &db->streams, LibmsiStream, entry ) { - WARN("failed to read stream: %08x\n", hr); - msi_free(data); - goto end; + if( !strcmpW( encname, stream->name ) ) + { + found = true; + break; + } } - 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; - } + if (found) { + if (stream->stm) + IStream_Release(stream->stm); + stream->stm = stm; + IStream_AddRef(stream->stm); + r = LIBMSI_RESULT_SUCCESS; + } else + r = msi_alloc_stream( db, encname, stm ); - msi_free(data); -end: - msi_free(encname); return r; } diff --git a/libmsi/msipriv.h b/libmsi/msipriv.h index a39a0ac..1697391 100644 --- a/libmsi/msipriv.h +++ b/libmsi/msipriv.h @@ -356,7 +356,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 ); +unsigned msi_create_stream( LibmsiDatabase *db, const WCHAR *stname, IStream *stm ); extern unsigned msi_get_raw_stream( LibmsiDatabase *, const WCHAR *, IStream **); void msi_destroy_stream( LibmsiDatabase *, const WCHAR * ); extern unsigned msi_enum_db_streams(LibmsiDatabase *, unsigned (*fn)(const WCHAR *, IStream *, void *), void *); diff --git a/libmsi/streams.c b/libmsi/streams.c index 0c4a4b7..a486d01 100644 --- a/libmsi/streams.c +++ b/libmsi/streams.c @@ -155,25 +155,22 @@ static unsigned streams_view_set_row(LibmsiView *view, unsigned row, LibmsiRecor goto done; } - stream = create_stream(sv, name, false, NULL); + stream = create_stream(sv, name, false, stm); if (!stream) goto done; - r = msi_create_stream(sv->db, name, stm, &stream->stream); + r = msi_create_stream(sv->db, name, stm); if (r != LIBMSI_RESULT_SUCCESS) { WARN("failed to create stream: %08x\n", r); + IStream_Release(stream->stream); + msi_free(stream); goto done; } sv->streams[row] = stream; done: - if (r != LIBMSI_RESULT_SUCCESS) - { - msi_free(stream); - } - msi_free(name); IStream_Release(stm); |