msi: Get rid of the open streams cache.

This commit is contained in:
Hans Leidekker 2015-02-13 13:37:49 +01:00 committed by Alexandre Julliard
parent c6f3f72d61
commit d954fbf8da
4 changed files with 11 additions and 158 deletions

View File

@ -59,116 +59,26 @@ typedef struct tagMSITRANSFORM {
IStorage *stg;
} 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 )
{
HRESULT r;
IStorage *stg;
WCHAR decoded[MAX_STREAM_NAME_LEN + 1];
decode_streamname( stname, decoded );
TRACE("%s -> %s\n", debugstr_w(stname), debugstr_w(decoded));
if (msi_clone_open_stream( db, db->storage, stname, stm ) == ERROR_SUCCESS)
return ERROR_SUCCESS;
r = IStorage_OpenStream( db->storage, stname, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
if( FAILED( r ) )
r = IStorage_OpenStream( db->storage, stname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
if (FAILED( r ))
{
MSITRANSFORM *transform;
LIST_FOR_EACH_ENTRY( transform, &db->transforms, MSITRANSFORM, entry )
{
r = IStorage_OpenStream( transform->stg, stname, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
if (SUCCEEDED(r))
{
stg = transform->stg;
r = IStorage_OpenStream( transform->stg, stname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
if (SUCCEEDED( r ))
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;
}
@ -177,58 +87,13 @@ static void free_transforms( MSIDATABASE *db )
{
while( !list_empty( &db->transforms ) )
{
MSITRANSFORM *t = LIST_ENTRY( list_head( &db->transforms ),
MSITRANSFORM, entry );
MSITRANSFORM *t = LIST_ENTRY( list_head( &db->transforms ), MSITRANSFORM, entry );
list_remove( &t->entry );
IStorage_Release( t->stg );
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 )
{
MSITRANSFORM *t;
@ -237,9 +102,6 @@ void append_storage_to_db( MSIDATABASE *db, IStorage *stg )
t->stg = stg;
IStorage_AddRef( stg );
list_add_head( &db->transforms, &t->entry );
/* the transform may add or replace streams */
free_streams( db );
}
static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
@ -248,7 +110,6 @@ static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
msi_free(db->path);
free_cached_tables( db );
free_streams( db );
free_transforms( db );
if (db->strings) msi_destroy_stringtable( db->strings );
IStorage_Release( db->storage );
@ -431,7 +292,6 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
db->deletefile = strdupW( szDBPath );
list_init( &db->tables );
list_init( &db->transforms );
list_init( &db->streams );
db->strings = msi_load_string_table( stg, &db->bytes_per_strref );
if( !db->strings )

View File

@ -227,15 +227,12 @@ static INT_PTR CDECL cabinet_open_stream( char *pszFile, int oflag, int pmode )
WARN("failed to encode stream name\n");
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 );
if (FAILED(hr))
{
WARN("failed to open stream 0x%08x\n", hr);
msi_free( encoded );
return -1;
}
WARN("failed to open stream 0x%08x\n", hr);
msi_free( encoded );
return -1;
}
msi_free( encoded );
return (INT_PTR)stream;

View File

@ -93,7 +93,6 @@ typedef struct tagMSIDATABASE
UINT media_transform_disk_id;
struct list tables;
struct list transforms;
struct list streams;
} MSIDATABASE;
typedef struct tagMSIVIEW MSIVIEW;
@ -830,7 +829,6 @@ extern BOOL decode_streamname(LPCWSTR in, LPWSTR out) DECLSPEC_HIDDEN;
/* database internals */
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;

View File

@ -181,9 +181,6 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U
goto done;
}
encname = encode_streamname(FALSE, name);
msi_destroy_stream(sv->db, encname);
r = write_stream_data(sv->db->storage, name, data, count, FALSE);
if (r != ERROR_SUCCESS)
{
@ -195,6 +192,7 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U
if (!stream)
goto done;
encname = encode_streamname(FALSE, name);
hr = IStorage_OpenStream(sv->db->storage, encname, 0,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream);
if (FAILED(hr))