diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2012-12-04 12:57:01 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2012-12-06 20:30:33 +0100 |
commit | 58d6c16e312abd964decc9ec1ef15254c4d325b9 (patch) | |
tree | e79c374f7dc3787a1986a3d54b2b08361e561bcd /libmsi | |
parent | 6d135208c01e4df83bcd2f4dc900b36048116a6b (diff) | |
download | msitools-58d6c16e312abd964decc9ec1ef15254c4d325b9.tar.gz msitools-58d6c16e312abd964decc9ec1ef15254c4d325b9.tar.xz msitools-58d6c16e312abd964decc9ec1ef15254c4d325b9.zip |
special-case db->infile streams
Diffstat (limited to 'libmsi')
-rw-r--r-- | libmsi/database.c | 56 | ||||
-rw-r--r-- | libmsi/msipriv.h | 1 |
2 files changed, 31 insertions, 26 deletions
diff --git a/libmsi/database.c b/libmsi/database.c index f4ac940..24dc610 100644 --- a/libmsi/database.c +++ b/libmsi/database.c @@ -265,13 +265,13 @@ void msi_destroy_storage( LibmsiDatabase *db, const WCHAR *stname ) } } -static unsigned find_open_stream( LibmsiDatabase *db, IStorage *stg, const WCHAR *name, IStream **stm ) +static unsigned find_infile_stream( LibmsiDatabase *db, const WCHAR *name, IStream **stm ) { LibmsiStream *stream; LIST_FOR_EACH_ENTRY( stream, &db->streams, LibmsiStream, entry ) { - if (stream->stg != stg) continue; + if (stream->stg != NULL) continue; if( !strcmpW( name, stream->name ) ) { @@ -357,7 +357,7 @@ unsigned msi_create_stream( LibmsiDatabase *db, const WCHAR *stname, IStream *st encname = encode_streamname(false, stname); LIST_FOR_EACH_ENTRY( stream, &db->streams, LibmsiStream, entry ) { - if (stream->stg != db->infile) continue; + if (stream->stg != NULL) continue; if( !strcmpW( encname, stream->name ) ) { @@ -469,7 +469,7 @@ unsigned msi_enum_db_streams(LibmsiDatabase *db, { IStream *stm; - if (stream->stg != db->infile) continue; + if (stream->stg != NULL) continue; stm = stream->stm; IStream_AddRef(stm); @@ -508,11 +508,11 @@ unsigned msi_enum_db_storages(LibmsiDatabase *db, return LIBMSI_RESULT_SUCCESS; } -unsigned msi_clone_open_stream( LibmsiDatabase *db, IStorage *stg, const WCHAR *name, IStream **stm ) +unsigned clone_infile_stream( LibmsiDatabase *db, const WCHAR *name, IStream **stm ) { IStream *stream; - if (find_open_stream( db, stg, name, &stream ) == LIBMSI_RESULT_SUCCESS) + if (find_infile_stream( db, name, &stream ) == LIBMSI_RESULT_SUCCESS) { HRESULT r; LARGE_INTEGER pos; @@ -538,16 +538,31 @@ unsigned msi_clone_open_stream( LibmsiDatabase *db, IStorage *stg, const WCHAR * return LIBMSI_RESULT_FUNCTION_FAILED; } +static unsigned msi_alloc_stream( LibmsiDatabase *db, const WCHAR *stname, IStorage *stg, IStream *stm) +{ + LibmsiStream *stream; + + if (!(stream = msi_alloc( sizeof(LibmsiStream) ))) return LIBMSI_RESULT_NOT_ENOUGH_MEMORY; + stream->name = strdupW( stname ); + stream->stg = stg; + if (stg) + IStorage_AddRef( stg ); + stream->stm = stm; + IStream_AddRef( stm ); + list_add_tail( &db->streams, &stream->entry ); + return LIBMSI_RESULT_SUCCESS; +} + unsigned msi_get_raw_stream( LibmsiDatabase *db, const WCHAR *stname, IStream **stm ) { HRESULT r; - IStorage *stg; + IStorage *stg = NULL; WCHAR decoded[MAX_STREAM_NAME_LEN]; decode_streamname( stname, decoded ); TRACE("%s -> %s\n", debugstr_w(stname), debugstr_w(decoded)); - if (msi_clone_open_stream( db, db->infile, stname, stm ) == LIBMSI_RESULT_SUCCESS) + if (clone_infile_stream( db, stname, stm ) == LIBMSI_RESULT_SUCCESS) return LIBMSI_RESULT_SUCCESS; r = IStorage_OpenStream( db->infile, stname, NULL, @@ -567,22 +582,11 @@ unsigned msi_get_raw_stream( LibmsiDatabase *db, const WCHAR *stname, IStream ** } } } - else stg = db->infile; - - if( SUCCEEDED(r) ) - { - LibmsiStream *stream; - if (!(stream = msi_alloc( sizeof(LibmsiStream) ))) return LIBMSI_RESULT_NOT_ENOUGH_MEMORY; - stream->name = strdupW( stname ); - stream->stg = stg; - IStorage_AddRef( stg ); - stream->stm = *stm; - IStream_AddRef( *stm ); - list_add_tail( &db->streams, &stream->entry ); - } + if( FAILED(r) ) + return LIBMSI_RESULT_FUNCTION_FAILED; - return SUCCEEDED(r) ? LIBMSI_RESULT_SUCCESS : LIBMSI_RESULT_FUNCTION_FAILED; + return msi_alloc_stream(db, stname, stg, *stm); } static void free_transforms( LibmsiDatabase *db ) @@ -609,8 +613,9 @@ void msi_destroy_stream( LibmsiDatabase *db, const WCHAR *stname ) list_remove( &stream->entry ); IStream_Release( stream->stm ); - IStorage_Release( stream->stg ); - IStorage_DestroyElement( stream->stg, stname ); + if ( stream->stg ) + IStorage_Release( stream->stg ); + IStorage_DestroyElement( stream->stg?:db->infile, stname ); msi_free( stream ); break; } @@ -636,7 +641,8 @@ static void free_streams( LibmsiDatabase *db ) LibmsiStream *s = LIST_ENTRY(list_head( &db->streams ), LibmsiStream, entry); list_remove( &s->entry ); IStream_Release( s->stm ); - IStorage_Release( s->stg ); + if (s->stg) + IStorage_Release( s->stg ); msi_free( s->name ); msi_free( s ); } diff --git a/libmsi/msipriv.h b/libmsi/msipriv.h index 9b91585..a39a0ac 100644 --- a/libmsi/msipriv.h +++ b/libmsi/msipriv.h @@ -358,7 +358,6 @@ 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 * ); extern unsigned msi_enum_db_streams(LibmsiDatabase *, unsigned (*fn)(const WCHAR *, IStream *, void *), void *); unsigned msi_create_storage( LibmsiDatabase *db, const WCHAR *stname, IStream *stm ); |