Commit d954fbf8 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msi: Get rid of the open streams cache.

parent c6f3f72d
...@@ -59,116 +59,26 @@ typedef struct tagMSITRANSFORM { ...@@ -59,116 +59,26 @@ typedef struct tagMSITRANSFORM {
IStorage *stg; IStorage *stg;
} MSITRANSFORM; } MSITRANSFORM;
typedef struct tagMSISTREAM {
struct list entry;
IStorage *stg;
IStream *stm;
} MSISTREAM;
static UINT find_open_stream( MSIDATABASE *db, IStorage *stg, LPCWSTR name, IStream **stm )
{
MSISTREAM *stream;
LIST_FOR_EACH_ENTRY( stream, &db->streams, MSISTREAM, entry )
{
HRESULT r;
STATSTG stat;
if (stream->stg != stg) continue;
r = IStream_Stat( stream->stm, &stat, 0 );
if( FAILED( r ) )
{
WARN("failed to stat stream r = %08x!\n", r);
continue;
}
if( !strcmpW( name, stat.pwcsName ) )
{
TRACE("found %s\n", debugstr_w(name));
*stm = stream->stm;
CoTaskMemFree( stat.pwcsName );
return ERROR_SUCCESS;
}
CoTaskMemFree( stat.pwcsName );
}
return ERROR_FUNCTION_FAILED;
}
UINT msi_clone_open_stream( MSIDATABASE *db, IStorage *stg, LPCWSTR name, IStream **stm )
{
IStream *stream;
if (find_open_stream( db, stg, name, &stream ) == ERROR_SUCCESS)
{
HRESULT r;
LARGE_INTEGER pos;
r = IStream_Clone( stream, stm );
if( FAILED( r ) )
{
WARN("failed to clone stream r = %08x!\n", r);
return ERROR_FUNCTION_FAILED;
}
pos.QuadPart = 0;
r = IStream_Seek( *stm, pos, STREAM_SEEK_SET, NULL );
if( FAILED( r ) )
{
IStream_Release( *stm );
return ERROR_FUNCTION_FAILED;
}
return ERROR_SUCCESS;
}
return ERROR_FUNCTION_FAILED;
}
UINT msi_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 + 1]; WCHAR decoded[MAX_STREAM_NAME_LEN + 1];
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 (msi_clone_open_stream( db, db->storage, stname, stm ) == ERROR_SUCCESS) r = IStorage_OpenStream( db->storage, stname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
return ERROR_SUCCESS; if (FAILED( r ))
r = IStorage_OpenStream( db->storage, stname, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
if( FAILED( r ) )
{ {
MSITRANSFORM *transform; MSITRANSFORM *transform;
LIST_FOR_EACH_ENTRY( transform, &db->transforms, MSITRANSFORM, entry ) LIST_FOR_EACH_ENTRY( transform, &db->transforms, MSITRANSFORM, entry )
{ {
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) )
{
MSISTREAM *stream;
if (!(stream = msi_alloc( sizeof(MSISTREAM) ))) return ERROR_NOT_ENOUGH_MEMORY;
stream->stg = stg;
IStorage_AddRef( stg );
stream->stm = *stm;
IStream_AddRef( *stm );
list_add_tail( &db->streams, &stream->entry );
}
return SUCCEEDED(r) ? ERROR_SUCCESS : ERROR_FUNCTION_FAILED; return SUCCEEDED(r) ? ERROR_SUCCESS : ERROR_FUNCTION_FAILED;
} }
...@@ -177,58 +87,13 @@ static void free_transforms( MSIDATABASE *db ) ...@@ -177,58 +87,13 @@ static void free_transforms( MSIDATABASE *db )
{ {
while( !list_empty( &db->transforms ) ) while( !list_empty( &db->transforms ) )
{ {
MSITRANSFORM *t = LIST_ENTRY( list_head( &db->transforms ), MSITRANSFORM *t = LIST_ENTRY( list_head( &db->transforms ), MSITRANSFORM, entry );
MSITRANSFORM, entry );
list_remove( &t->entry ); list_remove( &t->entry );
IStorage_Release( t->stg ); IStorage_Release( t->stg );
msi_free( t ); msi_free( t );
} }
} }
void msi_destroy_stream( MSIDATABASE *db, const WCHAR *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 );
IStorage_Release( stream->stg );
IStorage_DestroyElement( stream->stg, stname );
msi_free( stream );
CoTaskMemFree( stat.pwcsName );
break;
}
CoTaskMemFree( stat.pwcsName );
}
}
static void free_streams( MSIDATABASE *db )
{
while( !list_empty( &db->streams ) )
{
MSISTREAM *s = LIST_ENTRY(list_head( &db->streams ), MSISTREAM, entry);
list_remove( &s->entry );
IStream_Release( s->stm );
IStorage_Release( s->stg );
msi_free( s );
}
}
void append_storage_to_db( MSIDATABASE *db, IStorage *stg ) void append_storage_to_db( MSIDATABASE *db, IStorage *stg )
{ {
MSITRANSFORM *t; MSITRANSFORM *t;
...@@ -237,9 +102,6 @@ void append_storage_to_db( MSIDATABASE *db, IStorage *stg ) ...@@ -237,9 +102,6 @@ void append_storage_to_db( MSIDATABASE *db, IStorage *stg )
t->stg = stg; t->stg = stg;
IStorage_AddRef( stg ); IStorage_AddRef( stg );
list_add_head( &db->transforms, &t->entry ); list_add_head( &db->transforms, &t->entry );
/* the transform may add or replace streams */
free_streams( db );
} }
static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg ) static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
...@@ -248,7 +110,6 @@ static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg ) ...@@ -248,7 +110,6 @@ static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
msi_free(db->path); msi_free(db->path);
free_cached_tables( db ); free_cached_tables( db );
free_streams( db );
free_transforms( db ); free_transforms( db );
if (db->strings) msi_destroy_stringtable( db->strings ); if (db->strings) msi_destroy_stringtable( db->strings );
IStorage_Release( db->storage ); IStorage_Release( db->storage );
...@@ -431,7 +292,6 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) ...@@ -431,7 +292,6 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
db->deletefile = strdupW( szDBPath ); db->deletefile = strdupW( szDBPath );
list_init( &db->tables ); list_init( &db->tables );
list_init( &db->transforms ); list_init( &db->transforms );
list_init( &db->streams );
db->strings = msi_load_string_table( stg, &db->bytes_per_strref ); db->strings = msi_load_string_table( stg, &db->bytes_per_strref );
if( !db->strings ) if( !db->strings )
......
...@@ -227,15 +227,12 @@ static INT_PTR CDECL cabinet_open_stream( char *pszFile, int oflag, int pmode ) ...@@ -227,15 +227,12 @@ static INT_PTR CDECL cabinet_open_stream( char *pszFile, int oflag, int pmode )
WARN("failed to encode stream name\n"); WARN("failed to encode stream name\n");
return -1; return -1;
} }
if (msi_clone_open_stream( package_disk.package->db, cab->storage, encoded, &stream ) != ERROR_SUCCESS) hr = IStorage_OpenStream( cab->storage, encoded, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &stream );
if (FAILED(hr))
{ {
hr = IStorage_OpenStream( cab->storage, encoded, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &stream ); WARN("failed to open stream 0x%08x\n", hr);
if (FAILED(hr)) msi_free( encoded );
{ return -1;
WARN("failed to open stream 0x%08x\n", hr);
msi_free( encoded );
return -1;
}
} }
msi_free( encoded ); msi_free( encoded );
return (INT_PTR)stream; return (INT_PTR)stream;
......
...@@ -93,7 +93,6 @@ typedef struct tagMSIDATABASE ...@@ -93,7 +93,6 @@ typedef struct tagMSIDATABASE
UINT media_transform_disk_id; UINT media_transform_disk_id;
struct list tables; struct list tables;
struct list transforms; struct list transforms;
struct list streams;
} MSIDATABASE; } MSIDATABASE;
typedef struct tagMSIVIEW MSIVIEW; typedef struct tagMSIVIEW MSIVIEW;
...@@ -830,7 +829,6 @@ extern BOOL decode_streamname(LPCWSTR in, LPWSTR out) DECLSPEC_HIDDEN; ...@@ -830,7 +829,6 @@ extern BOOL decode_streamname(LPCWSTR in, LPWSTR out) DECLSPEC_HIDDEN;
/* database internals */ /* database internals */
extern UINT msi_get_raw_stream( MSIDATABASE *, LPCWSTR, IStream ** ) 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; 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;
......
...@@ -181,9 +181,6 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U ...@@ -181,9 +181,6 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U
goto done; goto done;
} }
encname = encode_streamname(FALSE, name);
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)
{ {
...@@ -195,6 +192,7 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U ...@@ -195,6 +192,7 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U
if (!stream) if (!stream)
goto done; goto done;
encname = encode_streamname(FALSE, name);
hr = IStorage_OpenStream(sv->db->storage, encname, 0, hr = IStorage_OpenStream(sv->db->storage, encname, 0,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream); STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream);
if (FAILED(hr)) if (FAILED(hr))
......
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