diff --git a/dlls/msi/database.c b/dlls/msi/database.c index b780b0e77ed..fb614db28ce 100644 --- a/dlls/msi/database.c +++ b/dlls/msi/database.c @@ -176,6 +176,37 @@ static void free_transforms( MSIDATABASE *db ) } } +void db_destroy_stream( MSIDATABASE *db, LPCWSTR stname ) +{ + MSISTREAM *stream, *stream2; + + LIST_FOR_EACH_ENTRY_SAFE( stream, stream2, &db->streams, MSISTREAM, entry ) + { + HRESULT r; + STATSTG stat; + + r = IStream_Stat( stream->stm, &stat, 0 ); + if (FAILED(r)) + { + WARN("failed to stat stream r = %08x\n", r); + continue; + } + + if (!strcmpW( stname, stat.pwcsName )) + { + TRACE("destroying %s\n", debugstr_w(stname)); + + list_remove( &stream->entry ); + IStream_Release( stream->stm ); + msi_free( stream ); + IStorage_DestroyElement( db->storage, stname ); + CoTaskMemFree( stat.pwcsName ); + break; + } + CoTaskMemFree( stat.pwcsName ); + } +} + static void free_streams( MSIDATABASE *db ) { while( !list_empty( &db->streams ) ) diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 55a0135d9a1..4546f5c419e 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -722,6 +722,7 @@ extern BOOL decode_streamname(LPCWSTR in, LPWSTR out); /* database internals */ extern UINT db_get_raw_stream( MSIDATABASE *, LPCWSTR, IStream ** ); +void db_destroy_stream( MSIDATABASE *, LPCWSTR ); extern UINT MSI_OpenDatabaseW( LPCWSTR, LPCWSTR, MSIDATABASE ** ); extern UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY ** ); extern UINT MSI_OpenQuery( MSIDATABASE *, MSIQUERY **, LPCWSTR, ... ); diff --git a/dlls/msi/streams.c b/dlls/msi/streams.c index 66bda767a00..fc660c82cd1 100644 --- a/dlls/msi/streams.c +++ b/dlls/msi/streams.c @@ -183,7 +183,7 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U } encname = encode_streamname(FALSE, name); - IStorage_DestroyElement(sv->db->storage, encname); + db_destroy_stream(sv->db, encname); r = write_stream_data(sv->db->storage, name, data, count, FALSE); if (r != ERROR_SUCCESS)