Hans Leidekker : msi: Keep track of a stream's storage.

Alexandre Julliard julliard at winehq.org
Fri May 6 13:44:14 CDT 2011


Module: wine
Branch: master
Commit: 4f9971f5f8bac5df4d5a4c160185b1f4a3a6345c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4f9971f5f8bac5df4d5a4c160185b1f4a3a6345c

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Fri May  6 14:40:48 2011 +0200

msi: Keep track of a stream's storage.

---

 dlls/msi/database.c |   34 +++++++++++++++++++++-------------
 dlls/msi/msipriv.h  |    5 +++--
 dlls/msi/streams.c  |    6 +++---
 dlls/msi/table.c    |    2 +-
 4 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/dlls/msi/database.c b/dlls/msi/database.c
index 2cb9ec4..02fc007 100644
--- a/dlls/msi/database.c
+++ b/dlls/msi/database.c
@@ -61,10 +61,11 @@ typedef struct tagMSITRANSFORM {
 
 typedef struct tagMSISTREAM {
     struct list entry;
+    IStorage *stg;
     IStream *stm;
 } MSISTREAM;
 
-static UINT find_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
+static UINT find_open_stream( MSIDATABASE *db, IStorage *stg, LPCWSTR name, IStream **stm )
 {
     MSISTREAM *stream;
 
@@ -73,6 +74,8 @@ static UINT find_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
         HRESULT r;
         STATSTG stat;
 
+        if (stream->stg != stg) continue;
+
         r = IStream_Stat( stream->stm, &stat, 0 );
         if( FAILED( r ) )
         {
@@ -94,11 +97,11 @@ static UINT find_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
     return ERROR_FUNCTION_FAILED;
 }
 
-static UINT clone_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
+UINT msi_clone_open_stream( MSIDATABASE *db, IStorage *stg, LPCWSTR name, IStream **stm )
 {
     IStream *stream;
 
-    if (find_open_stream( db, name, &stream ) == ERROR_SUCCESS)
+    if (find_open_stream( db, stg, name, &stream ) == ERROR_SUCCESS)
     {
         HRESULT r;
         LARGE_INTEGER pos;
@@ -124,15 +127,16 @@ static UINT clone_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
     return ERROR_FUNCTION_FAILED;
 }
 
-UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
+UINT msi_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
 {
     HRESULT r;
+    IStorage *stg;
     WCHAR decoded[MAX_STREAM_NAME_LEN];
 
     decode_streamname( stname, decoded );
     TRACE("%s -> %s\n", debugstr_w(stname), debugstr_w(decoded));
 
-    if (clone_open_stream( db, stname, stm ) == ERROR_SUCCESS)
+    if (msi_clone_open_stream( db, db->storage, stname, stm ) == ERROR_SUCCESS)
         return ERROR_SUCCESS;
 
     r = IStorage_OpenStream( db->storage, stname, NULL,
@@ -146,18 +150,21 @@ UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
             r = IStorage_OpenStream( transform->stg, stname, NULL,
                                      STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
             if (SUCCEEDED(r))
+            {
+                stg = transform->stg;
                 break;
+            }
         }
     }
+    else stg = db->storage;
 
     if( SUCCEEDED(r) )
     {
         MSISTREAM *stream;
 
-        stream = msi_alloc( sizeof(MSISTREAM) );
-        if( !stream )
-            return ERROR_NOT_ENOUGH_MEMORY;
-
+        if (!(stream = msi_alloc( sizeof(MSISTREAM) ))) return ERROR_NOT_ENOUGH_MEMORY;
+        stream->stg = stg;
+        IStream_AddRef( stg );
         stream->stm = *stm;
         IStream_AddRef( *stm );
         list_add_tail( &db->streams, &stream->entry );
@@ -178,7 +185,7 @@ static void free_transforms( MSIDATABASE *db )
     }
 }
 
-void db_destroy_stream( MSIDATABASE *db, LPCWSTR stname )
+void msi_destroy_stream( MSIDATABASE *db, const WCHAR *stname )
 {
     MSISTREAM *stream, *stream2;
 
@@ -200,8 +207,9 @@ void db_destroy_stream( MSIDATABASE *db, LPCWSTR stname )
 
             list_remove( &stream->entry );
             IStream_Release( stream->stm );
+            IStream_Release( stream->stg );
+            IStorage_DestroyElement( stream->stg, stname );
             msi_free( stream );
-            IStorage_DestroyElement( db->storage, stname );
             CoTaskMemFree( stat.pwcsName );
             break;
         }
@@ -213,10 +221,10 @@ static void free_streams( MSIDATABASE *db )
 {
     while( !list_empty( &db->streams ) )
     {
-        MSISTREAM *s = LIST_ENTRY( list_head( &db->streams ),
-                                   MSISTREAM, entry );
+        MSISTREAM *s = LIST_ENTRY(list_head( &db->streams ), MSISTREAM, entry);
         list_remove( &s->entry );
         IStream_Release( s->stm );
+        IStream_Release( s->stg );
         msi_free( s );
     }
 }
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 11ccfca..2cc7daf 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -799,8 +799,9 @@ extern LPWSTR encode_streamname(BOOL bTable, LPCWSTR in) DECLSPEC_HIDDEN;
 extern BOOL decode_streamname(LPCWSTR in, LPWSTR out) DECLSPEC_HIDDEN;
 
 /* database internals */
-extern UINT db_get_raw_stream( MSIDATABASE *, LPCWSTR, IStream ** ) DECLSPEC_HIDDEN;
-void db_destroy_stream( MSIDATABASE *, LPCWSTR ) DECLSPEC_HIDDEN;
+extern UINT msi_get_raw_stream( MSIDATABASE *, LPCWSTR, IStream ** ) DECLSPEC_HIDDEN;
+extern UINT msi_clone_open_stream( MSIDATABASE *, IStorage *, const WCHAR *, IStream ** ) DECLSPEC_HIDDEN;
+void msi_destroy_stream( MSIDATABASE *, const WCHAR * ) DECLSPEC_HIDDEN;
 extern UINT MSI_OpenDatabaseW( LPCWSTR, LPCWSTR, MSIDATABASE ** ) DECLSPEC_HIDDEN;
 extern UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY ** ) DECLSPEC_HIDDEN;
 extern UINT MSI_OpenQuery( MSIDATABASE *, MSIQUERY **, LPCWSTR, ... ) DECLSPEC_HIDDEN;
diff --git a/dlls/msi/streams.c b/dlls/msi/streams.c
index 44c4e67..c9c2d3e 100644
--- a/dlls/msi/streams.c
+++ b/dlls/msi/streams.c
@@ -182,7 +182,7 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U
     }
 
     encname = encode_streamname(FALSE, name);
-    db_destroy_stream(sv->db, encname);
+    msi_destroy_stream(sv->db, encname);
 
     r = write_stream_data(sv->db->storage, name, data, count, FALSE);
     if (r != ERROR_SUCCESS)
@@ -529,12 +529,12 @@ static INT add_streams_to_table(MSISTREAMSVIEW *sv)
         /* these streams appear to be unencoded */
         if (*stat.pwcsName == 0x0005)
         {
-            r = db_get_raw_stream(sv->db, stat.pwcsName, &stream->stream);
+            r = msi_get_raw_stream(sv->db, stat.pwcsName, &stream->stream);
         }
         else
         {
             encname = encode_streamname(FALSE, stat.pwcsName);
-            r = db_get_raw_stream(sv->db, encname, &stream->stream);
+            r = msi_get_raw_stream(sv->db, encname, &stream->stream);
             msi_free(encname);
         }
         CoTaskMemFree(stat.pwcsName);
diff --git a/dlls/msi/table.c b/dlls/msi/table.c
index f53b817..91f3676 100644
--- a/dlls/msi/table.c
+++ b/dlls/msi/table.c
@@ -1221,7 +1221,7 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
     }
 
     encname = encode_streamname( FALSE, full_name );
-    r = db_get_raw_stream( tv->db, encname, stm );
+    r = msi_get_raw_stream( tv->db, encname, stm );
     if( r )
         ERR("fetching stream %s, error = %d\n",debugstr_w(full_name), r);
 




More information about the wine-cvs mailing list