summaryrefslogtreecommitdiffstats
path: root/libmsi/database.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2012-12-04 14:00:36 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2012-12-06 20:30:33 +0100
commit9cf89fe383cfc8c86a4b9d60a67aa85e1ba20402 (patch)
tree9ded8475f1793a74ebac008a18fa13bf13674ad0 /libmsi/database.c
parent2257784ffe556b815c1f952c9d2153ba1ae57c4b (diff)
downloadmsitools-9cf89fe383cfc8c86a4b9d60a67aa85e1ba20402.tar.gz
msitools-9cf89fe383cfc8c86a4b9d60a67aa85e1ba20402.tar.xz
msitools-9cf89fe383cfc8c86a4b9d60a67aa85e1ba20402.zip
delay reading streams to commit time
Store the external data in the STREAMS table.
Diffstat (limited to 'libmsi/database.c')
-rw-r--r--libmsi/database.c53
1 files changed, 16 insertions, 37 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;
}