summaryrefslogtreecommitdiffstats
path: root/libmsi
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2012-12-03 14:00:27 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2012-12-06 20:30:32 +0100
commit937ca216c6cdf3909d2bceec118c45977f2e1f3a (patch)
tree0eae13bbae408c7ff84cfa36688d2fc8f7aef51a /libmsi
parentacc802083d9241301a9673b7fd024658217579e4 (diff)
downloadmsitools-937ca216c6cdf3909d2bceec118c45977f2e1f3a.tar.gz
msitools-937ca216c6cdf3909d2bceec118c45977f2e1f3a.tar.xz
msitools-937ca216c6cdf3909d2bceec118c45977f2e1f3a.zip
move stream creation to database.c
Diffstat (limited to 'libmsi')
-rw-r--r--libmsi/database.c67
-rw-r--r--libmsi/msipriv.h3
-rw-r--r--libmsi/streams.c55
3 files changed, 74 insertions, 51 deletions
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);