msi: Remove stream from streams cache before destroying it.
authorHans Leidekker <hans@codeweavers.com>
Tue, 23 Mar 2010 10:48:23 +0000 (11:48 +0100)
committerAlexandre Julliard <julliard@winehq.org>
Tue, 23 Mar 2010 12:24:27 +0000 (13:24 +0100)
dlls/msi/database.c
dlls/msi/msipriv.h
dlls/msi/streams.c

index b780b0e77ed688dde2fe5103a5c238cee7f6b4a2..fb614db28ced4c1ee75b4b2492943f39c0be7e5c 100644 (file)
@@ -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 ) )
index 55a0135d9a17adfcf1a31cf93e4608c41374b126..4546f5c419e46a93ba6bd09d75388c440ee94baf 100644 (file)
@@ -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, ... );
index 66bda767a00deec10668f1c3ce4825c747a398e3..fc660c82cd13388d2790d1f6107e3a34ce5cbdbc 100644 (file)
@@ -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)