mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[WINESYNC] msi: Install feature when new component is added.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49350 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 877540b522c46134aa1b843519fa5694adb187ce by Piotr Caban <piotr@codeweavers.com>
This commit is contained in:
parent
aa0312d7cb
commit
1cdb30ec0d
4 changed files with 110 additions and 11 deletions
|
@ -1381,6 +1381,49 @@ static UINT load_all_patches(MSIPACKAGE *package)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static UINT iterate_patched_component( MSIRECORD *row, LPVOID param )
|
||||
{
|
||||
MSIPACKAGE *package = param;
|
||||
const WCHAR *name;
|
||||
MSICOMPONENT *c;
|
||||
|
||||
name = MSI_RecordGetString( row, 1 );
|
||||
TRACE( "found patched component: %s\n", wine_dbgstr_w(name) );
|
||||
c = msi_get_loaded_component( package, name );
|
||||
if (!c)
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
c->updated = 1;
|
||||
if (!wcscmp( MSI_RecordGetString( row, 2 ), L"INSERT" ))
|
||||
c->added = 1;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static void mark_patched_components( MSIPACKAGE *package )
|
||||
{
|
||||
static const WCHAR select[] = L"SELECT `Row`, `Column` FROM `_TransformView` WHERE `Table`='Component'";
|
||||
MSIQUERY *q;
|
||||
UINT r;
|
||||
|
||||
r = MSI_OpenQuery( package->db, &q, select );
|
||||
if (r != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
MSI_IterateRecords( q, NULL, iterate_patched_component, package );
|
||||
msiobj_release( &q->hdr );
|
||||
|
||||
while (1)
|
||||
{
|
||||
r = MSI_OpenQuery( package->db, &q, L"ALTER TABLE `_TransformView` FREE" );
|
||||
if (r != ERROR_SUCCESS)
|
||||
return;
|
||||
r = MSI_ViewExecute( q, NULL );
|
||||
msiobj_release( &q->hdr );
|
||||
if (r != ERROR_SUCCESS)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static UINT load_folder_persistence( MSIPACKAGE *package, MSIFOLDER *folder )
|
||||
{
|
||||
static const WCHAR query[] = {
|
||||
|
@ -1525,6 +1568,7 @@ static UINT ACTION_CostInitialize(MSIPACKAGE *package)
|
|||
msi_load_all_features( package );
|
||||
load_all_files( package );
|
||||
load_all_patches( package );
|
||||
mark_patched_components( package );
|
||||
load_all_media( package );
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
|
@ -1809,12 +1853,6 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
|
|||
}
|
||||
}
|
||||
}
|
||||
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
|
||||
{
|
||||
if (feature->Feature_Parent) continue;
|
||||
disable_children( feature, level );
|
||||
follow_parent( feature );
|
||||
}
|
||||
}
|
||||
else if (!msi_get_property_int( package->db, szInstalled, 0 ))
|
||||
{
|
||||
|
@ -1841,15 +1879,69 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
|
|||
}
|
||||
}
|
||||
}
|
||||
/* disable child features of unselected parent or follow parent */
|
||||
}
|
||||
else
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
|
||||
{
|
||||
if (feature->Feature_Parent) continue;
|
||||
disable_children( feature, level );
|
||||
follow_parent( feature );
|
||||
ComponentList *cl;
|
||||
MSIFEATURE *cur;
|
||||
|
||||
if (!is_feature_selected( feature, level )) continue;
|
||||
if (feature->ActionRequest != INSTALLSTATE_UNKNOWN) continue;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
|
||||
{
|
||||
if (!cl->component->updated && !cl->component->added)
|
||||
continue;
|
||||
|
||||
cur = feature;
|
||||
while (cur)
|
||||
{
|
||||
if (cur->ActionRequest != INSTALLSTATE_UNKNOWN)
|
||||
break;
|
||||
|
||||
if (cur->Installed != INSTALLSTATE_ABSENT)
|
||||
{
|
||||
cur->Action = cur->Installed;
|
||||
cur->ActionRequest = cur->Installed;
|
||||
}
|
||||
else if (!cl->component->added)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (cur->Attributes & msidbFeatureAttributesFavorSource)
|
||||
{
|
||||
cur->Action = INSTALLSTATE_SOURCE;
|
||||
cur->ActionRequest = INSTALLSTATE_SOURCE;
|
||||
}
|
||||
else if (cur->Attributes & msidbFeatureAttributesFavorAdvertise)
|
||||
{
|
||||
cur->Action = INSTALLSTATE_ADVERTISED;
|
||||
cur->ActionRequest = INSTALLSTATE_ADVERTISED;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur->Action = INSTALLSTATE_LOCAL;
|
||||
cur->ActionRequest = INSTALLSTATE_LOCAL;
|
||||
}
|
||||
|
||||
if (!cur->Feature_Parent)
|
||||
break;
|
||||
cur = msi_get_loaded_feature(package, cur->Feature_Parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* disable child features of unselected parent or follow parent */
|
||||
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
|
||||
{
|
||||
if (feature->Feature_Parent) continue;
|
||||
disable_children( feature, level );
|
||||
follow_parent( feature );
|
||||
}
|
||||
|
||||
/* now we want to set component state based based on feature state */
|
||||
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
|
||||
{
|
||||
|
|
|
@ -544,6 +544,8 @@ typedef struct tagMSICOMPONENT
|
|||
unsigned int hasAdvertisedFeature:1;
|
||||
unsigned int hasLocalFeature:1;
|
||||
unsigned int hasSourceFeature:1;
|
||||
unsigned int added:1;
|
||||
unsigned int updated:1;
|
||||
} MSICOMPONENT;
|
||||
|
||||
typedef struct tagComponentList
|
||||
|
|
|
@ -274,9 +274,14 @@ static UINT apply_substorage_transform( MSIPACKAGE *package, MSIDATABASE *patch_
|
|||
{
|
||||
ret = check_transform_applicable( package, stg );
|
||||
if (ret == ERROR_SUCCESS)
|
||||
{
|
||||
msi_table_apply_transform( package->db, stg, MSITRANSFORM_ERROR_VIEWTRANSFORM );
|
||||
msi_table_apply_transform( package->db, stg, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("substorage transform %s wasn't applicable\n", debugstr_w(name));
|
||||
}
|
||||
IStorage_Release( stg );
|
||||
}
|
||||
else
|
||||
|
|
|
@ -844,7 +844,7 @@ static void test_simple_patch( void )
|
|||
size = get_pf_file_size( "msitest\\patch.txt" );
|
||||
ok( size == 1002, "expected 1002, got %u\n", size );
|
||||
size = get_pf_file_size( "msitest\\file.txt" );
|
||||
todo_wine ok( size == 1000, "expected 1000, got %u\n", size );
|
||||
ok( size == 1000, "expected 1000, got %u\n", size );
|
||||
|
||||
/* show that MsiOpenPackage applies registered patches */
|
||||
r = MsiOpenPackageA( path, &hpackage );
|
||||
|
|
Loading…
Reference in a new issue