Commit 4f9971f5 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msi: Keep track of a stream's storage.

parent 6b8a8d75
...@@ -61,10 +61,11 @@ typedef struct tagMSITRANSFORM { ...@@ -61,10 +61,11 @@ typedef struct tagMSITRANSFORM {
typedef struct tagMSISTREAM { typedef struct tagMSISTREAM {
struct list entry; struct list entry;
IStorage *stg;
IStream *stm; IStream *stm;
} MSISTREAM; } 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; MSISTREAM *stream;
...@@ -73,6 +74,8 @@ static UINT find_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm ) ...@@ -73,6 +74,8 @@ static UINT find_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
HRESULT r; HRESULT r;
STATSTG stat; STATSTG stat;
if (stream->stg != stg) continue;
r = IStream_Stat( stream->stm, &stat, 0 ); r = IStream_Stat( stream->stm, &stat, 0 );
if( FAILED( r ) ) if( FAILED( r ) )
{ {
...@@ -94,11 +97,11 @@ static UINT find_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm ) ...@@ -94,11 +97,11 @@ static UINT find_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
return ERROR_FUNCTION_FAILED; 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; IStream *stream;
if (find_open_stream( db, name, &stream ) == ERROR_SUCCESS) if (find_open_stream( db, stg, name, &stream ) == ERROR_SUCCESS)
{ {
HRESULT r; HRESULT r;
LARGE_INTEGER pos; LARGE_INTEGER pos;
...@@ -124,15 +127,16 @@ static UINT clone_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm ) ...@@ -124,15 +127,16 @@ static UINT clone_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
return ERROR_FUNCTION_FAILED; 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; HRESULT r;
IStorage *stg;
WCHAR decoded[MAX_STREAM_NAME_LEN]; WCHAR decoded[MAX_STREAM_NAME_LEN];
decode_streamname( stname, decoded ); decode_streamname( stname, decoded );
TRACE("%s -> %s\n", debugstr_w(stname), debugstr_w(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; return ERROR_SUCCESS;
r = IStorage_OpenStream( db->storage, stname, NULL, r = IStorage_OpenStream( db->storage, stname, NULL,
...@@ -146,18 +150,21 @@ UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm ) ...@@ -146,18 +150,21 @@ UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
r = IStorage_OpenStream( transform->stg, stname, NULL, r = IStorage_OpenStream( transform->stg, stname, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm ); STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
if (SUCCEEDED(r)) if (SUCCEEDED(r))
{
stg = transform->stg;
break; break;
}
} }
} }
else stg = db->storage;
if( SUCCEEDED(r) ) if( SUCCEEDED(r) )
{ {
MSISTREAM *stream; MSISTREAM *stream;
stream = msi_alloc( sizeof(MSISTREAM) ); if (!(stream = msi_alloc( sizeof(MSISTREAM) ))) return ERROR_NOT_ENOUGH_MEMORY;
if( !stream ) stream->stg = stg;
return ERROR_NOT_ENOUGH_MEMORY; IStream_AddRef( stg );
stream->stm = *stm; stream->stm = *stm;
IStream_AddRef( *stm ); IStream_AddRef( *stm );
list_add_tail( &db->streams, &stream->entry ); list_add_tail( &db->streams, &stream->entry );
...@@ -178,7 +185,7 @@ static void free_transforms( MSIDATABASE *db ) ...@@ -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; MSISTREAM *stream, *stream2;
...@@ -200,8 +207,9 @@ void db_destroy_stream( MSIDATABASE *db, LPCWSTR stname ) ...@@ -200,8 +207,9 @@ void db_destroy_stream( MSIDATABASE *db, LPCWSTR stname )
list_remove( &stream->entry ); list_remove( &stream->entry );
IStream_Release( stream->stm ); IStream_Release( stream->stm );
IStream_Release( stream->stg );
IStorage_DestroyElement( stream->stg, stname );
msi_free( stream ); msi_free( stream );
IStorage_DestroyElement( db->storage, stname );
CoTaskMemFree( stat.pwcsName ); CoTaskMemFree( stat.pwcsName );
break; break;
} }
...@@ -213,10 +221,10 @@ static void free_streams( MSIDATABASE *db ) ...@@ -213,10 +221,10 @@ static void free_streams( MSIDATABASE *db )
{ {
while( !list_empty( &db->streams ) ) while( !list_empty( &db->streams ) )
{ {
MSISTREAM *s = LIST_ENTRY( list_head( &db->streams ), MSISTREAM *s = LIST_ENTRY(list_head( &db->streams ), MSISTREAM, entry);
MSISTREAM, entry );
list_remove( &s->entry ); list_remove( &s->entry );
IStream_Release( s->stm ); IStream_Release( s->stm );
IStream_Release( s->stg );
msi_free( s ); msi_free( s );
} }
} }
......
...@@ -799,8 +799,9 @@ extern LPWSTR encode_streamname(BOOL bTable, LPCWSTR in) DECLSPEC_HIDDEN; ...@@ -799,8 +799,9 @@ extern LPWSTR encode_streamname(BOOL bTable, LPCWSTR in) DECLSPEC_HIDDEN;
extern BOOL decode_streamname(LPCWSTR in, LPWSTR out) DECLSPEC_HIDDEN; extern BOOL decode_streamname(LPCWSTR in, LPWSTR out) DECLSPEC_HIDDEN;
/* database internals */ /* database internals */
extern UINT db_get_raw_stream( MSIDATABASE *, LPCWSTR, IStream ** ) DECLSPEC_HIDDEN; extern UINT msi_get_raw_stream( MSIDATABASE *, LPCWSTR, IStream ** ) DECLSPEC_HIDDEN;
void db_destroy_stream( MSIDATABASE *, LPCWSTR ) 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_OpenDatabaseW( LPCWSTR, LPCWSTR, MSIDATABASE ** ) DECLSPEC_HIDDEN;
extern UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY ** ) DECLSPEC_HIDDEN; extern UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY ** ) DECLSPEC_HIDDEN;
extern UINT MSI_OpenQuery( MSIDATABASE *, MSIQUERY **, LPCWSTR, ... ) DECLSPEC_HIDDEN; extern UINT MSI_OpenQuery( MSIDATABASE *, MSIQUERY **, LPCWSTR, ... ) DECLSPEC_HIDDEN;
......
...@@ -182,7 +182,7 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U ...@@ -182,7 +182,7 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U
} }
encname = encode_streamname(FALSE, name); 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); r = write_stream_data(sv->db->storage, name, data, count, FALSE);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
...@@ -529,12 +529,12 @@ static INT add_streams_to_table(MSISTREAMSVIEW *sv) ...@@ -529,12 +529,12 @@ static INT add_streams_to_table(MSISTREAMSVIEW *sv)
/* these streams appear to be unencoded */ /* these streams appear to be unencoded */
if (*stat.pwcsName == 0x0005) 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 else
{ {
encname = encode_streamname(FALSE, stat.pwcsName); 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); msi_free(encname);
} }
CoTaskMemFree(stat.pwcsName); CoTaskMemFree(stat.pwcsName);
......
...@@ -1221,7 +1221,7 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt ...@@ -1221,7 +1221,7 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
} }
encname = encode_streamname( FALSE, full_name ); 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 ) if( r )
ERR("fetching stream %s, error = %d\n",debugstr_w(full_name), r); ERR("fetching stream %s, error = %d\n",debugstr_w(full_name), r);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment