msi: Get rid of the open streams cache.
This commit is contained in:
parent
c6f3f72d61
commit
d954fbf8da
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue