diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2012-12-03 13:38:54 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2012-12-06 20:30:32 +0100 |
commit | acc802083d9241301a9673b7fd024658217579e4 (patch) | |
tree | 1b4571dafad4f18bd90e675705b29b06b566d645 /libmsi | |
parent | 8b908b15450ce80833731d05e5c77941267ab64e (diff) | |
download | msitools-acc802083d9241301a9673b7fd024658217579e4.tar.gz msitools-acc802083d9241301a9673b7fd024658217579e4.tar.xz msitools-acc802083d9241301a9673b7fd024658217579e4.zip |
add cache_infile_structure
Diffstat (limited to 'libmsi')
-rw-r--r-- | libmsi/database.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/libmsi/database.c b/libmsi/database.c index 6cf65c9..87d0381 100644 --- a/libmsi/database.c +++ b/libmsi/database.c @@ -338,6 +338,47 @@ end: return ret; } +static void cache_infile_structure( LibmsiDatabase *db ) +{ + IEnumSTATSTG *stgenum = NULL; + STATSTG stat; + IStream *stream; + HRESULT hr; + unsigned r, size; + + hr = IStorage_EnumElements(db->infile, 0, NULL, 0, &stgenum); + if (FAILED(hr)) + return; + + while (true) + { + size = 0; + hr = IEnumSTATSTG_Next(stgenum, 1, &stat, &size); + if (FAILED(hr) || !size) + break; + + /* table streams are not in the _Streams table */ + if (stat.type == STGTY_STREAM && *stat.pwcsName == 0x4840) + { + CoTaskMemFree(stat.pwcsName); + continue; + } + + if (stat.type == STGTY_STREAM) { + r = msi_get_raw_stream(db, stat.pwcsName, &stream); + if ( r == 0 ) { + IStream_Release(stream); + } + } else { + msi_open_storage(db, stat.pwcsName); + } + + CoTaskMemFree(stat.pwcsName); + } + + IEnumSTATSTG_Release(stgenum); +} + unsigned msi_clone_open_stream( LibmsiDatabase *db, IStorage *stg, const WCHAR *name, IStream **stm ) { IStream *stream; @@ -673,6 +714,7 @@ LibmsiResult libmsi_database_open(const char *szDBPath, const char *szPersist, L } } + cache_infile_structure( db ); db->strings = msi_load_string_table( db->infile, &db->bytes_per_strref ); if( !db->strings ) goto end; |