msi: Move MSITRANSFORM and MSISTREAM and associated methods to the dabatase implementation file as they are database objects/methods.
This commit is contained in:
parent
a2f5d0e270
commit
6b403d1a31
|
@ -51,14 +51,220 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
|||
* Any binary data in a table is a reference to a stream.
|
||||
*/
|
||||
|
||||
typedef struct tagMSITRANSFORM {
|
||||
struct list entry;
|
||||
IStorage *stg;
|
||||
} MSITRANSFORM;
|
||||
|
||||
typedef struct tagMSISTREAM {
|
||||
struct list entry;
|
||||
IStream *stm;
|
||||
} MSISTREAM;
|
||||
|
||||
static UINT find_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
|
||||
{
|
||||
MSISTREAM *stream;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( stream, &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( !lstrcmpW( 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;
|
||||
}
|
||||
|
||||
static UINT clone_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
|
||||
{
|
||||
IStream *stream;
|
||||
|
||||
if (find_open_stream( db, 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 db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
|
||||
{
|
||||
LPWSTR encname;
|
||||
HRESULT r;
|
||||
|
||||
encname = encode_streamname(FALSE, stname);
|
||||
|
||||
TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname));
|
||||
|
||||
if (clone_open_stream( db, encname, stm ) == ERROR_SUCCESS)
|
||||
{
|
||||
msi_free( encname );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
r = IStorage_OpenStream( db->storage, encname, NULL,
|
||||
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
|
||||
if( FAILED( r ) )
|
||||
{
|
||||
MSITRANSFORM *transform;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( transform, &db->transforms, MSITRANSFORM, entry )
|
||||
{
|
||||
TRACE("looking for %s in transform storage\n", debugstr_w(stname) );
|
||||
r = IStorage_OpenStream( transform->stg, encname, NULL,
|
||||
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
|
||||
if (SUCCEEDED(r))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
msi_free( encname );
|
||||
|
||||
if( SUCCEEDED(r) )
|
||||
{
|
||||
MSISTREAM *stream;
|
||||
|
||||
stream = msi_alloc( sizeof(MSISTREAM) );
|
||||
if( !stream )
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
stream->stm = *stm;
|
||||
IStream_AddRef( *stm );
|
||||
list_add_tail( &db->streams, &stream->entry );
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname,
|
||||
USHORT **pdata, UINT *psz )
|
||||
{
|
||||
HRESULT r;
|
||||
UINT ret = ERROR_FUNCTION_FAILED;
|
||||
VOID *data;
|
||||
ULONG sz, count;
|
||||
IStream *stm = NULL;
|
||||
STATSTG stat;
|
||||
|
||||
r = db_get_raw_stream( db, stname, &stm );
|
||||
if( r != ERROR_SUCCESS)
|
||||
return ret;
|
||||
r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
|
||||
if( FAILED( r ) )
|
||||
{
|
||||
WARN("open stream failed r = %08x!\n", r);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if( stat.cbSize.QuadPart >> 32 )
|
||||
{
|
||||
WARN("Too big!\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
sz = stat.cbSize.QuadPart;
|
||||
data = msi_alloc( sz );
|
||||
if( !data )
|
||||
{
|
||||
WARN("couldn't allocate memory r=%08x!\n", r);
|
||||
ret = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
r = IStream_Read(stm, data, sz, &count );
|
||||
if( FAILED( r ) || ( count != sz ) )
|
||||
{
|
||||
msi_free( data );
|
||||
WARN("read stream failed r = %08x!\n", r);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*pdata = data;
|
||||
*psz = sz;
|
||||
ret = ERROR_SUCCESS;
|
||||
|
||||
end:
|
||||
IStream_Release( stm );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void append_storage_to_db( MSIDATABASE *db, IStorage *stg )
|
||||
{
|
||||
MSITRANSFORM *t;
|
||||
|
||||
t = msi_alloc( sizeof *t );
|
||||
t->stg = stg;
|
||||
IStorage_AddRef( stg );
|
||||
list_add_tail( &db->transforms, &t->entry );
|
||||
}
|
||||
|
||||
static void free_transforms( MSIDATABASE *db )
|
||||
{
|
||||
while( !list_empty( &db->transforms ) )
|
||||
{
|
||||
MSITRANSFORM *t = LIST_ENTRY( list_head( &db->transforms ),
|
||||
MSITRANSFORM, entry );
|
||||
list_remove( &t->entry );
|
||||
IStorage_Release( t->stg );
|
||||
msi_free( t );
|
||||
}
|
||||
}
|
||||
|
||||
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 );
|
||||
msi_free( s );
|
||||
}
|
||||
}
|
||||
|
||||
static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
|
||||
{
|
||||
MSIDATABASE *db = (MSIDATABASE *) arg;
|
||||
|
||||
msi_free(db->path);
|
||||
free_cached_tables( db );
|
||||
msi_free_streams( db );
|
||||
msi_free_transforms( db );
|
||||
free_streams( db );
|
||||
free_transforms( db );
|
||||
msi_destroy_stringtable( db->strings );
|
||||
IStorage_Release( db->storage );
|
||||
if (db->deletefile)
|
||||
|
|
|
@ -650,8 +650,6 @@ extern void msiobj_unlock(MSIOBJECTHDR *);
|
|||
extern void msi_free_handle_table(void);
|
||||
|
||||
extern void free_cached_tables( MSIDATABASE *db );
|
||||
extern void msi_free_streams( MSIDATABASE *db );
|
||||
extern void msi_free_transforms( MSIDATABASE *db );
|
||||
extern UINT MSI_CommitTables( MSIDATABASE *db );
|
||||
|
||||
|
||||
|
@ -721,11 +719,12 @@ extern MSIRECORD *MSI_CloneRecord( MSIRECORD * );
|
|||
extern BOOL MSI_RecordsAreEqual( MSIRECORD *, MSIRECORD * );
|
||||
|
||||
/* stream internals */
|
||||
extern UINT get_raw_stream( MSIHANDLE hdb, LPCWSTR stname, IStream **stm );
|
||||
extern void enum_stream_names( IStorage *stg );
|
||||
extern LPWSTR encode_streamname(BOOL bTable, LPCWSTR in);
|
||||
extern BOOL decode_streamname(LPCWSTR in, LPWSTR out);
|
||||
|
||||
/* database internals */
|
||||
extern UINT db_get_raw_stream( MSIDATABASE *, LPCWSTR, IStream ** );
|
||||
extern UINT MSI_OpenDatabaseW( LPCWSTR, LPCWSTR, MSIDATABASE ** );
|
||||
extern UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY ** );
|
||||
extern UINT MSI_OpenQuery( MSIDATABASE *, MSIQUERY **, LPCWSTR, ... );
|
||||
|
|
208
dlls/msi/table.c
208
dlls/msi/table.c
|
@ -83,16 +83,6 @@ struct tagMSITABLE
|
|||
WCHAR name[1];
|
||||
};
|
||||
|
||||
typedef struct tagMSITRANSFORM {
|
||||
struct list entry;
|
||||
IStorage *stg;
|
||||
} MSITRANSFORM;
|
||||
|
||||
typedef struct tagMSISTREAM {
|
||||
struct list entry;
|
||||
IStream *stm;
|
||||
} MSISTREAM;
|
||||
|
||||
static const WCHAR szStringData[] = {
|
||||
'_','S','t','r','i','n','g','D','a','t','a',0 };
|
||||
static const WCHAR szStringPool[] = {
|
||||
|
@ -159,7 +149,7 @@ static int utf2mime(int x)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static LPWSTR encode_streamname(BOOL bTable, LPCWSTR in)
|
||||
LPWSTR encode_streamname(BOOL bTable, LPCWSTR in)
|
||||
{
|
||||
DWORD count = MAX_STREAM_NAME;
|
||||
DWORD ch, next;
|
||||
|
@ -337,168 +327,6 @@ end:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static UINT find_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
|
||||
{
|
||||
MSISTREAM *stream;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( stream, &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( !lstrcmpW( 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;
|
||||
}
|
||||
|
||||
static UINT clone_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
|
||||
{
|
||||
IStream *stream;
|
||||
|
||||
if (find_open_stream( db, 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;
|
||||
}
|
||||
|
||||
static UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
|
||||
{
|
||||
LPWSTR encname;
|
||||
HRESULT r;
|
||||
|
||||
encname = encode_streamname(FALSE, stname);
|
||||
|
||||
TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname));
|
||||
|
||||
if (clone_open_stream( db, encname, stm ) == ERROR_SUCCESS)
|
||||
{
|
||||
msi_free( encname );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
r = IStorage_OpenStream(db->storage, encname, NULL,
|
||||
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm);
|
||||
if( FAILED( r ) )
|
||||
{
|
||||
MSITRANSFORM *transform;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( transform, &db->transforms, MSITRANSFORM, entry )
|
||||
{
|
||||
TRACE("looking for %s in transform storage\n", debugstr_w(stname) );
|
||||
r = IStorage_OpenStream( transform->stg, encname, NULL,
|
||||
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
|
||||
if (SUCCEEDED(r))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
msi_free( encname );
|
||||
|
||||
if( SUCCEEDED(r) )
|
||||
{
|
||||
MSISTREAM *stream;
|
||||
|
||||
stream = msi_alloc( sizeof(MSISTREAM) );
|
||||
if( !stream )
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
stream->stm = *stm;
|
||||
IStream_AddRef( *stm );
|
||||
list_add_tail( &db->streams, &stream->entry );
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname,
|
||||
USHORT **pdata, UINT *psz )
|
||||
{
|
||||
HRESULT r;
|
||||
UINT ret = ERROR_FUNCTION_FAILED;
|
||||
VOID *data;
|
||||
ULONG sz, count;
|
||||
IStream *stm = NULL;
|
||||
STATSTG stat;
|
||||
|
||||
r = db_get_raw_stream( db, stname, &stm );
|
||||
if( r != ERROR_SUCCESS)
|
||||
return ret;
|
||||
r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
|
||||
if( FAILED( r ) )
|
||||
{
|
||||
WARN("open stream failed r = %08x!\n", r);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if( stat.cbSize.QuadPart >> 32 )
|
||||
{
|
||||
WARN("Too big!\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
sz = stat.cbSize.QuadPart;
|
||||
data = msi_alloc( sz );
|
||||
if( !data )
|
||||
{
|
||||
WARN("couldn't allocate memory r=%08x!\n", r);
|
||||
ret = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
r = IStream_Read(stm, data, sz, &count );
|
||||
if( FAILED( r ) || ( count != sz ) )
|
||||
{
|
||||
msi_free( data );
|
||||
WARN("read stream failed r = %08x!\n", r);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*pdata = data;
|
||||
*psz = sz;
|
||||
ret = ERROR_SUCCESS;
|
||||
|
||||
end:
|
||||
IStream_Release( stm );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT write_stream_data( IStorage *stg, LPCWSTR stname,
|
||||
LPCVOID data, UINT sz, BOOL bTable )
|
||||
{
|
||||
|
@ -3103,37 +2931,3 @@ end:
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void append_storage_to_db( MSIDATABASE *db, IStorage *stg )
|
||||
{
|
||||
MSITRANSFORM *t;
|
||||
|
||||
t = msi_alloc( sizeof *t );
|
||||
t->stg = stg;
|
||||
IStorage_AddRef( stg );
|
||||
list_add_tail( &db->transforms, &t->entry );
|
||||
}
|
||||
|
||||
void msi_free_transforms( MSIDATABASE *db )
|
||||
{
|
||||
while( !list_empty( &db->transforms ) )
|
||||
{
|
||||
MSITRANSFORM *t = LIST_ENTRY( list_head( &db->transforms ),
|
||||
MSITRANSFORM, entry );
|
||||
list_remove( &t->entry );
|
||||
IStorage_Release( t->stg );
|
||||
msi_free( t );
|
||||
}
|
||||
}
|
||||
|
||||
void msi_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 );
|
||||
msi_free( s );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue