mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 23:22:57 +00:00
[WINESYNC] msi: Add stub support for MSITRANSFORM_ERROR_VIEWTRANSFORM flag in MsiApplyTransform.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org> wine commit id 8bc835b4517728fac8ff8a9cfa5e59b843e9a8df by Piotr Caban <piotr@codeweavers.com>
This commit is contained in:
parent
8e75cb8a26
commit
1bbb87bb26
4 changed files with 161 additions and 15 deletions
|
@ -794,7 +794,7 @@ extern UINT write_stream_data( IStorage *stg, LPCWSTR stname,
|
||||||
LPCVOID data, UINT sz, BOOL bTable ) DECLSPEC_HIDDEN;
|
LPCVOID data, UINT sz, BOOL bTable ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* transform functions */
|
/* transform functions */
|
||||||
extern UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg ) DECLSPEC_HIDDEN;
|
extern UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg, int err_cond ) DECLSPEC_HIDDEN;
|
||||||
extern UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db,
|
extern UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db,
|
||||||
LPCWSTR szTransformFile, int iErrorCond ) DECLSPEC_HIDDEN;
|
LPCWSTR szTransformFile, int iErrorCond ) DECLSPEC_HIDDEN;
|
||||||
extern void append_storage_to_db( MSIDATABASE *db, IStorage *stg ) DECLSPEC_HIDDEN;
|
extern void append_storage_to_db( MSIDATABASE *db, IStorage *stg ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -907,7 +907,7 @@ UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db, const WCHAR *transform, int e
|
||||||
if (!IsEqualGUID( &stat.clsid, &CLSID_MsiTransform )) goto end;
|
if (!IsEqualGUID( &stat.clsid, &CLSID_MsiTransform )) goto end;
|
||||||
if (TRACE_ON( msi )) enum_stream_names( stg );
|
if (TRACE_ON( msi )) enum_stream_names( stg );
|
||||||
|
|
||||||
ret = msi_table_apply_transform( db, stg );
|
ret = msi_table_apply_transform( db, stg, error_cond );
|
||||||
|
|
||||||
end:
|
end:
|
||||||
IStorage_Release( stg );
|
IStorage_Release( stg );
|
||||||
|
@ -919,7 +919,7 @@ UINT WINAPI MsiDatabaseApplyTransformW( MSIHANDLE hdb, const WCHAR *transform, i
|
||||||
MSIDATABASE *db;
|
MSIDATABASE *db;
|
||||||
UINT r;
|
UINT r;
|
||||||
|
|
||||||
if (error_cond) FIXME( "ignoring error conditions\n" );
|
if (error_cond & ~MSITRANSFORM_ERROR_VIEWTRANSFORM) FIXME( "ignoring error conditions\n" );
|
||||||
|
|
||||||
if (!(db = msihandle2msiinfo(hdb, MSIHANDLETYPE_DATABASE)))
|
if (!(db = msihandle2msiinfo(hdb, MSIHANDLETYPE_DATABASE)))
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
|
|
@ -274,7 +274,7 @@ static UINT apply_substorage_transform( MSIPACKAGE *package, MSIDATABASE *patch_
|
||||||
{
|
{
|
||||||
ret = check_transform_applicable( package, stg );
|
ret = check_transform_applicable( package, stg );
|
||||||
if (ret == ERROR_SUCCESS)
|
if (ret == ERROR_SUCCESS)
|
||||||
msi_table_apply_transform( package->db, stg );
|
msi_table_apply_transform( package->db, stg, 0 );
|
||||||
else
|
else
|
||||||
TRACE("substorage transform %s wasn't applicable\n", debugstr_w(name));
|
TRACE("substorage transform %s wasn't applicable\n", debugstr_w(name));
|
||||||
IStorage_Release( stg );
|
IStorage_Release( stg );
|
||||||
|
|
|
@ -2220,6 +2220,112 @@ static UINT msi_record_stream_name( const MSITABLEVIEW *tv, MSIRECORD *rec, LPWS
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT TransformView_fetch_int( MSIVIEW *view, UINT row, UINT col, UINT *val )
|
||||||
|
{
|
||||||
|
FIXME("\n");
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT TransformView_fetch_stream( MSIVIEW *view, UINT row, UINT col, IStream **stm )
|
||||||
|
{
|
||||||
|
FIXME("\n");
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT TransformView_set_row( MSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
|
||||||
|
{
|
||||||
|
FIXME("\n");
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT TransformView_insert_row( MSIVIEW *view, MSIRECORD *rec, UINT row, BOOL temporary )
|
||||||
|
{
|
||||||
|
FIXME("\n");
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT TransformView_delete_row( MSIVIEW *view, UINT row )
|
||||||
|
{
|
||||||
|
FIXME("\n");
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT TransformView_execute( MSIVIEW *view, MSIRECORD *record )
|
||||||
|
{
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT TransformView_close( MSIVIEW *view )
|
||||||
|
{
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT TransformView_get_dimensions( MSIVIEW *view, UINT *rows, UINT *cols )
|
||||||
|
{
|
||||||
|
FIXME("\n");
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT TransformView_get_column_info( MSIVIEW *view, UINT n, LPCWSTR *name, UINT *type,
|
||||||
|
BOOL *temporary, LPCWSTR *table_name )
|
||||||
|
{
|
||||||
|
FIXME("\n");
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT TransformView_delete( MSIVIEW *view )
|
||||||
|
{
|
||||||
|
return TABLE_delete( view );
|
||||||
|
}
|
||||||
|
|
||||||
|
static const MSIVIEWOPS transform_view_ops =
|
||||||
|
{
|
||||||
|
TransformView_fetch_int,
|
||||||
|
TransformView_fetch_stream,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
TransformView_set_row,
|
||||||
|
TransformView_insert_row,
|
||||||
|
TransformView_delete_row,
|
||||||
|
TransformView_execute,
|
||||||
|
TransformView_close,
|
||||||
|
TransformView_get_dimensions,
|
||||||
|
TransformView_get_column_info,
|
||||||
|
NULL,
|
||||||
|
TransformView_delete,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
UINT TransformView_Create( MSIDATABASE *db, string_table *st, LPCWSTR name, MSIVIEW **view )
|
||||||
|
{
|
||||||
|
MSITABLEVIEW *tv;
|
||||||
|
UINT r;
|
||||||
|
|
||||||
|
r = TABLE_CreateView( db, name, view );
|
||||||
|
if (r == ERROR_INVALID_PARAMETER)
|
||||||
|
{
|
||||||
|
/* table does not exist */
|
||||||
|
FIXME("\n");
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
else if (r != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tv = (MSITABLEVIEW*)*view;
|
||||||
|
}
|
||||||
|
|
||||||
|
tv->view.ops = &transform_view_ops;
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
UINT MSI_CommitTables( MSIDATABASE *db )
|
UINT MSI_CommitTables( MSIDATABASE *db )
|
||||||
{
|
{
|
||||||
UINT r, bytes_per_strref;
|
UINT r, bytes_per_strref;
|
||||||
|
@ -2510,7 +2616,7 @@ typedef struct
|
||||||
|
|
||||||
static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
|
static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
|
||||||
string_table *st, TRANSFORMDATA *transform,
|
string_table *st, TRANSFORMDATA *transform,
|
||||||
UINT bytes_per_strref )
|
UINT bytes_per_strref, int err_cond )
|
||||||
{
|
{
|
||||||
BYTE *rawdata = NULL;
|
BYTE *rawdata = NULL;
|
||||||
MSITABLEVIEW *tv = NULL;
|
MSITABLEVIEW *tv = NULL;
|
||||||
|
@ -2536,7 +2642,10 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create a table view */
|
/* create a table view */
|
||||||
r = TABLE_CreateView( db, name, (MSIVIEW**) &tv );
|
if ( err_cond & MSITRANSFORM_ERROR_VIEWTRANSFORM )
|
||||||
|
r = TransformView_Create( db, st, name, (MSIVIEW**) &tv );
|
||||||
|
else
|
||||||
|
r = TABLE_CreateView( db, name, (MSIVIEW**) &tv );
|
||||||
if( r != ERROR_SUCCESS )
|
if( r != ERROR_SUCCESS )
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -2646,21 +2755,21 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
|
||||||
if (!mask)
|
if (!mask)
|
||||||
{
|
{
|
||||||
TRACE("deleting row [%d]:\n", row);
|
TRACE("deleting row [%d]:\n", row);
|
||||||
r = TABLE_delete_row( &tv->view, row );
|
r = tv->view.ops->delete_row( &tv->view, row );
|
||||||
if (r != ERROR_SUCCESS)
|
if (r != ERROR_SUCCESS)
|
||||||
WARN("failed to delete row %u\n", r);
|
WARN("failed to delete row %u\n", r);
|
||||||
}
|
}
|
||||||
else if (mask & 1)
|
else if (mask & 1)
|
||||||
{
|
{
|
||||||
TRACE("modifying full row [%d]:\n", row);
|
TRACE("modifying full row [%d]:\n", row);
|
||||||
r = TABLE_set_row( &tv->view, row, rec, (1 << tv->num_cols) - 1 );
|
r = tv->view.ops->set_row( &tv->view, row, rec, (1 << tv->num_cols) - 1 );
|
||||||
if (r != ERROR_SUCCESS)
|
if (r != ERROR_SUCCESS)
|
||||||
WARN("failed to modify row %u\n", r);
|
WARN("failed to modify row %u\n", r);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TRACE("modifying masked row [%d]:\n", row);
|
TRACE("modifying masked row [%d]:\n", row);
|
||||||
r = TABLE_set_row( &tv->view, row, rec, mask );
|
r = tv->view.ops->set_row( &tv->view, row, rec, mask );
|
||||||
if (r != ERROR_SUCCESS)
|
if (r != ERROR_SUCCESS)
|
||||||
WARN("failed to modify row %u\n", r);
|
WARN("failed to modify row %u\n", r);
|
||||||
}
|
}
|
||||||
|
@ -2668,12 +2777,13 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TRACE("inserting row\n");
|
TRACE("inserting row\n");
|
||||||
r = TABLE_insert_row( &tv->view, rec, -1, FALSE );
|
r = tv->view.ops->insert_row( &tv->view, rec, -1, FALSE );
|
||||||
if (r != ERROR_SUCCESS)
|
if (r != ERROR_SUCCESS)
|
||||||
WARN("failed to insert row %u\n", r);
|
WARN("failed to insert row %u\n", r);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wcscmp( name, szColumns ))
|
if (!(err_cond & MSITRANSFORM_ERROR_VIEWTRANSFORM) &&
|
||||||
|
!wcscmp( name, szColumns ))
|
||||||
msi_update_table_columns( db, table );
|
msi_update_table_columns( db, table );
|
||||||
|
|
||||||
msiobj_release( &rec->hdr );
|
msiobj_release( &rec->hdr );
|
||||||
|
@ -2696,7 +2806,7 @@ err:
|
||||||
*
|
*
|
||||||
* Enumerate the table transforms in a transform storage and apply each one.
|
* Enumerate the table transforms in a transform storage and apply each one.
|
||||||
*/
|
*/
|
||||||
UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg )
|
UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg, int err_cond )
|
||||||
{
|
{
|
||||||
struct list transforms;
|
struct list transforms;
|
||||||
IEnumSTATSTG *stgenum = NULL;
|
IEnumSTATSTG *stgenum = NULL;
|
||||||
|
@ -2708,6 +2818,7 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg )
|
||||||
UINT ret = ERROR_FUNCTION_FAILED;
|
UINT ret = ERROR_FUNCTION_FAILED;
|
||||||
UINT bytes_per_strref;
|
UINT bytes_per_strref;
|
||||||
BOOL property_update = FALSE;
|
BOOL property_update = FALSE;
|
||||||
|
BOOL free_transform_view = FALSE;
|
||||||
|
|
||||||
TRACE("%p %p\n", db, stg );
|
TRACE("%p %p\n", db, stg );
|
||||||
|
|
||||||
|
@ -2770,15 +2881,39 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg )
|
||||||
tv->view.ops->delete( &tv->view );
|
tv->view.ops->delete( &tv->view );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (err_cond & MSITRANSFORM_ERROR_VIEWTRANSFORM)
|
||||||
|
{
|
||||||
|
static const WCHAR create_query[] = L"CREATE TABLE `_TransformView` ( "
|
||||||
|
L"`Table` CHAR(0) NOT NULL TEMPORARY, `Column` CHAR(0) NOT NULL TEMPORARY, "
|
||||||
|
L"`Row` CHAR(0) TEMPORARY, `Data` CHAR(0) TEMPORARY, `Current` CHAR(0) TEMPORARY "
|
||||||
|
L"PRIMARY KEY `Table`, `Column`, `Row` ) HOLD";
|
||||||
|
MSIQUERY *query;
|
||||||
|
UINT r;
|
||||||
|
|
||||||
|
r = MSI_DatabaseOpenViewW( db, create_query, &query );
|
||||||
|
if (r != ERROR_SUCCESS)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
r = MSI_ViewExecute( query, NULL );
|
||||||
|
if (r == ERROR_SUCCESS)
|
||||||
|
MSI_ViewClose( query );
|
||||||
|
msiobj_release( &query->hdr );
|
||||||
|
if (r == ERROR_BAD_QUERY_SYNTAX)
|
||||||
|
FIXME( "support adding to _TransformView\n" );
|
||||||
|
if (r != ERROR_SUCCESS)
|
||||||
|
goto end;
|
||||||
|
free_transform_view = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Apply _Tables and _Columns transforms first so that
|
* Apply _Tables and _Columns transforms first so that
|
||||||
* the table metadata is correct, and empty tables exist.
|
* the table metadata is correct, and empty tables exist.
|
||||||
*/
|
*/
|
||||||
ret = msi_table_load_transform( db, stg, strings, tables, bytes_per_strref );
|
ret = msi_table_load_transform( db, stg, strings, tables, bytes_per_strref, err_cond );
|
||||||
if (ret != ERROR_SUCCESS && ret != ERROR_INVALID_TABLE)
|
if (ret != ERROR_SUCCESS && ret != ERROR_INVALID_TABLE)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
ret = msi_table_load_transform( db, stg, strings, columns, bytes_per_strref );
|
ret = msi_table_load_transform( db, stg, strings, columns, bytes_per_strref, err_cond );
|
||||||
if (ret != ERROR_SUCCESS && ret != ERROR_INVALID_TABLE)
|
if (ret != ERROR_SUCCESS && ret != ERROR_INVALID_TABLE)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
@ -2792,7 +2927,7 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg )
|
||||||
wcscmp( transform->name, szTables ) &&
|
wcscmp( transform->name, szTables ) &&
|
||||||
ret == ERROR_SUCCESS )
|
ret == ERROR_SUCCESS )
|
||||||
{
|
{
|
||||||
ret = msi_table_load_transform( db, stg, strings, transform, bytes_per_strref );
|
ret = msi_table_load_transform( db, stg, strings, transform, bytes_per_strref, err_cond );
|
||||||
}
|
}
|
||||||
|
|
||||||
list_remove( &transform->entry );
|
list_remove( &transform->entry );
|
||||||
|
@ -2811,6 +2946,17 @@ end:
|
||||||
IEnumSTATSTG_Release( stgenum );
|
IEnumSTATSTG_Release( stgenum );
|
||||||
if ( strings )
|
if ( strings )
|
||||||
msi_destroy_stringtable( strings );
|
msi_destroy_stringtable( strings );
|
||||||
|
if (ret != ERROR_SUCCESS && free_transform_view)
|
||||||
|
{
|
||||||
|
MSIQUERY *query;
|
||||||
|
if (MSI_DatabaseOpenViewW( db, L"ALTER TABLE `_TransformView` FREE",
|
||||||
|
&query ) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (MSI_ViewExecute( query, NULL ) == ERROR_SUCCESS)
|
||||||
|
MSI_ViewClose( query );
|
||||||
|
msiobj_release( &query->hdr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue