msi: Get rid of msi_component_set_state and msi_feature_set_state.

This commit is contained in:
Hans Leidekker 2011-02-10 15:56:15 +01:00 committed by Alexandre Julliard
parent ef05072e27
commit ba9f1f770a
7 changed files with 131 additions and 172 deletions

View File

@ -162,98 +162,6 @@ static const WCHAR szValidateProductID[] =
static const WCHAR szWriteEnvironmentStrings[] = static const WCHAR szWriteEnvironmentStrings[] =
{'W','r','i','t','e','E','n','v','i','r','o','n','m','e','n','t','S','t','r','i','n','g','s',0}; {'W','r','i','t','e','E','n','v','i','r','o','n','m','e','n','t','S','t','r','i','n','g','s',0};
/********************************************************
* helper functions
********************************************************/
void msi_feature_set_state( MSIPACKAGE *package, MSIFEATURE *feature, INSTALLSTATE state )
{
if (!package->ProductCode)
{
feature->ActionRequest = state;
feature->Action = state;
}
else if (state == INSTALLSTATE_ABSENT)
{
switch (feature->Installed)
{
case INSTALLSTATE_ABSENT:
feature->ActionRequest = INSTALLSTATE_UNKNOWN;
feature->Action = INSTALLSTATE_UNKNOWN;
break;
default:
feature->ActionRequest = state;
feature->Action = state;
}
}
else if (state == INSTALLSTATE_SOURCE)
{
switch (feature->Installed)
{
case INSTALLSTATE_ABSENT:
case INSTALLSTATE_SOURCE:
feature->ActionRequest = state;
feature->Action = state;
break;
case INSTALLSTATE_LOCAL:
feature->ActionRequest = INSTALLSTATE_LOCAL;
feature->Action = INSTALLSTATE_LOCAL;
break;
default:
feature->ActionRequest = INSTALLSTATE_UNKNOWN;
feature->Action = INSTALLSTATE_UNKNOWN;
}
}
else
{
feature->ActionRequest = state;
feature->Action = state;
}
}
void msi_component_set_state( MSIPACKAGE *package, MSICOMPONENT *comp, INSTALLSTATE state )
{
if (!package->ProductCode)
{
comp->ActionRequest = state;
comp->Action = state;
}
else if (state == INSTALLSTATE_ABSENT)
{
switch (comp->Installed)
{
case INSTALLSTATE_LOCAL:
case INSTALLSTATE_SOURCE:
case INSTALLSTATE_DEFAULT:
comp->ActionRequest = state;
comp->Action = state;
break;
default:
comp->ActionRequest = INSTALLSTATE_UNKNOWN;
comp->Action = INSTALLSTATE_UNKNOWN;
}
}
else if (state == INSTALLSTATE_SOURCE)
{
if (comp->Installed == INSTALLSTATE_ABSENT ||
(comp->Installed == INSTALLSTATE_SOURCE && comp->hasLocalFeature))
{
comp->ActionRequest = state;
comp->Action = state;
}
else
{
comp->ActionRequest = INSTALLSTATE_UNKNOWN;
comp->Action = INSTALLSTATE_UNKNOWN;
}
}
else
{
comp->ActionRequest = state;
comp->Action = state;
}
}
static void ui_actionstart(MSIPACKAGE *package, LPCWSTR action) static void ui_actionstart(MSIPACKAGE *package, LPCWSTR action)
{ {
static const WCHAR Query_t[] = static const WCHAR Query_t[] =
@ -1463,7 +1371,8 @@ static UINT load_feature(MSIRECORD * row, LPVOID param)
feature->Attributes = MSI_RecordGetInteger(row,8); feature->Attributes = MSI_RecordGetInteger(row,8);
feature->Installed = INSTALLSTATE_UNKNOWN; feature->Installed = INSTALLSTATE_UNKNOWN;
msi_feature_set_state(package, feature, INSTALLSTATE_UNKNOWN); feature->Action = INSTALLSTATE_UNKNOWN;
feature->ActionRequest = INSTALLSTATE_UNKNOWN;
list_add_tail( &package->features, &feature->entry ); list_add_tail( &package->features, &feature->entry );
@ -1834,50 +1743,40 @@ static UINT ACTION_FileCost(MSIPACKAGE *package)
static void ACTION_GetComponentInstallStates(MSIPACKAGE *package) static void ACTION_GetComponentInstallStates(MSIPACKAGE *package)
{ {
MSICOMPONENT *comp; MSICOMPONENT *comp;
INSTALLSTATE state = MsiQueryProductStateW( package->ProductCode );
UINT r; UINT r;
LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry) LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry)
{ {
if (!comp->ComponentId) continue; if (!comp->ComponentId) continue;
if (state != INSTALLSTATE_LOCAL && state != INSTALLSTATE_DEFAULT) r = MsiQueryComponentStateW( package->ProductCode, NULL,
comp->Installed = INSTALLSTATE_ABSENT; MSIINSTALLCONTEXT_USERMANAGED, comp->ComponentId,
else &comp->Installed );
{ if (r != ERROR_SUCCESS)
r = MsiQueryComponentStateW( package->ProductCode, NULL, r = MsiQueryComponentStateW( package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED, comp->ComponentId, MSIINSTALLCONTEXT_USERUNMANAGED, comp->ComponentId,
&comp->Installed ); &comp->Installed );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
r = MsiQueryComponentStateW( package->ProductCode, NULL, r = MsiQueryComponentStateW( package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERUNMANAGED, comp->ComponentId, MSIINSTALLCONTEXT_MACHINE, comp->ComponentId,
&comp->Installed ); &comp->Installed );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
r = MsiQueryComponentStateW( package->ProductCode, NULL, comp->Installed = INSTALLSTATE_ABSENT;
MSIINSTALLCONTEXT_MACHINE, comp->ComponentId,
&comp->Installed );
if (r != ERROR_SUCCESS)
comp->Installed = INSTALLSTATE_ABSENT;
}
} }
} }
static void ACTION_GetFeatureInstallStates(MSIPACKAGE *package) static void ACTION_GetFeatureInstallStates(MSIPACKAGE *package)
{ {
MSIFEATURE *feature; MSIFEATURE *feature;
INSTALLSTATE state;
state = MsiQueryProductStateW(package->ProductCode);
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{ {
if (state != INSTALLSTATE_LOCAL && state != INSTALLSTATE_DEFAULT) INSTALLSTATE state = MsiQueryFeatureStateW( package->ProductCode, feature->Feature );
if (state == INSTALLSTATE_UNKNOWN || state == INSTALLSTATE_INVALIDARG)
feature->Installed = INSTALLSTATE_ABSENT; feature->Installed = INSTALLSTATE_ABSENT;
else else
{ feature->Installed = state;
feature->Installed = MsiQueryFeatureStateW(package->ProductCode,
feature->Feature);
}
} }
} }
@ -1904,7 +1803,13 @@ static BOOL process_state_property(MSIPACKAGE* package, int level,
if (!strcmpW(property, szReinstall)) state = feature->Installed; if (!strcmpW(property, szReinstall)) state = feature->Installed;
if (!strcmpiW( override, szAll )) if (!strcmpiW( override, szAll ))
msi_feature_set_state(package, feature, state); {
if (feature->Installed != state)
{
feature->Action = state;
feature->ActionRequest = state;
}
}
else else
{ {
LPWSTR ptr = override; LPWSTR ptr = override;
@ -1917,7 +1822,11 @@ static BOOL process_state_property(MSIPACKAGE* package, int level,
if ((ptr2 && strlenW(feature->Feature) == len && !strncmpW(ptr, feature->Feature, len)) if ((ptr2 && strlenW(feature->Feature) == len && !strncmpW(ptr, feature->Feature, len))
|| (!ptr2 && !strcmpW(ptr, feature->Feature))) || (!ptr2 && !strcmpW(ptr, feature->Feature)))
{ {
msi_feature_set_state(package, feature, state); if (feature->Installed != state)
{
feature->Action = state;
feature->ActionRequest = state;
}
break; break;
} }
if (ptr2) if (ptr2)
@ -1931,7 +1840,6 @@ static BOOL process_state_property(MSIPACKAGE* package, int level,
} }
} }
msi_free(override); msi_free(override);
return TRUE; return TRUE;
} }
@ -1994,11 +1902,20 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
if (feature->ActionRequest == INSTALLSTATE_UNKNOWN) if (feature->ActionRequest == INSTALLSTATE_UNKNOWN)
{ {
if (feature->Attributes & msidbFeatureAttributesFavorSource) if (feature->Attributes & msidbFeatureAttributesFavorSource)
msi_feature_set_state(package, feature, INSTALLSTATE_SOURCE); {
feature->Action = INSTALLSTATE_SOURCE;
feature->ActionRequest = INSTALLSTATE_SOURCE;
}
else if (feature->Attributes & msidbFeatureAttributesFavorAdvertise) else if (feature->Attributes & msidbFeatureAttributesFavorAdvertise)
msi_feature_set_state(package, feature, INSTALLSTATE_ADVERTISED); {
feature->Action = INSTALLSTATE_ADVERTISED;
feature->ActionRequest = INSTALLSTATE_ADVERTISED;
}
else else
msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL); {
feature->Action = INSTALLSTATE_LOCAL;
feature->ActionRequest = INSTALLSTATE_LOCAL;
}
} }
} }
@ -2010,7 +1927,10 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
if (is_feature_selected( feature, level )) continue; if (is_feature_selected( feature, level )) continue;
LIST_FOR_EACH_ENTRY( fl, &feature->Children, FeatureList, entry ) LIST_FOR_EACH_ENTRY( fl, &feature->Children, FeatureList, entry )
msi_feature_set_state(package, fl->feature, INSTALLSTATE_UNKNOWN); {
fl->feature->Action = INSTALLSTATE_UNKNOWN;
fl->feature->ActionRequest = INSTALLSTATE_UNKNOWN;
}
} }
} }
else /* preselected */ else /* preselected */
@ -2021,14 +1941,21 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
if (feature->ActionRequest == INSTALLSTATE_UNKNOWN) if (feature->ActionRequest == INSTALLSTATE_UNKNOWN)
{ {
msi_feature_set_state(package, feature, feature->Installed); if (feature->Installed == INSTALLSTATE_ABSENT)
{
feature->Action = INSTALLSTATE_UNKNOWN;
feature->ActionRequest = INSTALLSTATE_UNKNOWN;
}
else
{
feature->Action = feature->Installed;
feature->ActionRequest = feature->Installed;
}
} }
} }
} }
/* /* now we want to set component state based based on feature state */
* now we want to enable or disable components based on feature
*/
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{ {
ComponentList *cl; ComponentList *cl;
@ -2045,7 +1972,8 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
if (cl->component->ForceLocalState && if (cl->component->ForceLocalState &&
feature->ActionRequest == INSTALLSTATE_SOURCE) feature->ActionRequest == INSTALLSTATE_SOURCE)
{ {
msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL); feature->Action = INSTALLSTATE_LOCAL;
feature->ActionRequest = INSTALLSTATE_LOCAL;
break; break;
} }
} }
@ -2090,34 +2018,44 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
{ {
if ((component->Attributes & msidbComponentAttributesSourceOnly) && if ((component->Attributes & msidbComponentAttributesSourceOnly) &&
!component->ForceLocalState) !component->ForceLocalState)
msi_component_set_state(package, component, INSTALLSTATE_SOURCE); {
component->Action = INSTALLSTATE_SOURCE;
component->ActionRequest = INSTALLSTATE_SOURCE;
}
else else
msi_component_set_state(package, component, INSTALLSTATE_LOCAL); {
component->Action = INSTALLSTATE_LOCAL;
component->ActionRequest = INSTALLSTATE_LOCAL;
}
continue; continue;
} }
/* if any feature is local, the component must be local too */ /* if any feature is local, the component must be local too */
if (component->hasLocalFeature) if (component->hasLocalFeature)
{ {
msi_component_set_state(package, component, INSTALLSTATE_LOCAL); component->Action = INSTALLSTATE_LOCAL;
component->ActionRequest = INSTALLSTATE_LOCAL;
continue; continue;
} }
if (component->hasSourceFeature) if (component->hasSourceFeature)
{ {
msi_component_set_state(package, component, INSTALLSTATE_SOURCE); component->Action = INSTALLSTATE_SOURCE;
component->ActionRequest = INSTALLSTATE_SOURCE;
continue; continue;
} }
if (component->hasAdvertiseFeature) if (component->hasAdvertiseFeature)
{ {
msi_component_set_state(package, component, INSTALLSTATE_ADVERTISED); component->Action = INSTALLSTATE_ADVERTISED;
component->ActionRequest = INSTALLSTATE_ADVERTISED;
continue; continue;
} }
TRACE("nobody wants component %s\n", debugstr_w(component->Component)); TRACE("nobody wants component %s\n", debugstr_w(component->Component));
if (component->anyAbsent) if (component->anyAbsent &&
msi_component_set_state(package, component, INSTALLSTATE_ABSENT); (component->Installed == INSTALLSTATE_LOCAL || component->Installed == INSTALLSTATE_SOURCE))
{
component->Action = INSTALLSTATE_ABSENT;
component->ActionRequest = INSTALLSTATE_ABSENT;
}
} }
LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry ) LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry )
@ -2125,7 +2063,16 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
if (component->ActionRequest == INSTALLSTATE_DEFAULT) if (component->ActionRequest == INSTALLSTATE_DEFAULT)
{ {
TRACE("%s was default, setting to local\n", debugstr_w(component->Component)); TRACE("%s was default, setting to local\n", debugstr_w(component->Component));
msi_component_set_state(package, component, INSTALLSTATE_LOCAL); component->Action = INSTALLSTATE_LOCAL;
component->ActionRequest = INSTALLSTATE_LOCAL;
}
if (component->ActionRequest == INSTALLSTATE_SOURCE &&
component->Installed == INSTALLSTATE_SOURCE &&
component->hasSourceFeature)
{
component->Action = INSTALLSTATE_UNKNOWN;
component->ActionRequest = INSTALLSTATE_UNKNOWN;
} }
TRACE("Result: Component %s (Installed %d Request %d Action %d)\n", TRACE("Result: Component %s (Installed %d Request %d Action %d)\n",

View File

@ -2125,7 +2125,7 @@ static void
msi_seltree_update_feature_installstate( HWND hwnd, HTREEITEM hItem, msi_seltree_update_feature_installstate( HWND hwnd, HTREEITEM hItem,
MSIPACKAGE *package, MSIFEATURE *feature, INSTALLSTATE state ) MSIPACKAGE *package, MSIFEATURE *feature, INSTALLSTATE state )
{ {
msi_feature_set_state( package, feature, state ); feature->ActionRequest = state;
msi_seltree_sync_item_state( hwnd, feature, hItem ); msi_seltree_sync_item_state( hwnd, feature, hItem );
ACTION_UpdateComponentStates( package, feature ); ACTION_UpdateComponentStates( package, feature );
} }

View File

@ -888,25 +888,25 @@ static BOOL verify_comp_for_removal(MSICOMPONENT *comp, UINT install_mode)
{ {
INSTALLSTATE request = comp->ActionRequest; INSTALLSTATE request = comp->ActionRequest;
if (request == INSTALLSTATE_UNKNOWN) /* special case */
return FALSE; if (request != INSTALLSTATE_SOURCE &&
comp->Attributes & msidbComponentAttributesSourceOnly &&
(install_mode == msidbRemoveFileInstallModeOnRemove ||
install_mode == msidbRemoveFileInstallModeOnBoth)) return TRUE;
if (install_mode == msidbRemoveFileInstallModeOnInstall && switch (request)
(request == INSTALLSTATE_LOCAL || request == INSTALLSTATE_SOURCE))
return TRUE;
if (request == INSTALLSTATE_ABSENT)
{ {
if (!comp->ComponentId) case INSTALLSTATE_LOCAL:
return FALSE; case INSTALLSTATE_SOURCE:
if (install_mode == msidbRemoveFileInstallModeOnInstall ||
if (install_mode == msidbRemoveFileInstallModeOnRemove) install_mode == msidbRemoveFileInstallModeOnBoth) return TRUE;
return TRUE; break;
case INSTALLSTATE_ABSENT:
if (install_mode == msidbRemoveFileInstallModeOnRemove ||
install_mode == msidbRemoveFileInstallModeOnBoth) return TRUE;
break;
default: break;
} }
if (install_mode == msidbRemoveFileInstallModeOnBoth)
return TRUE;
return FALSE; return FALSE;
} }
@ -935,7 +935,7 @@ static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param)
if (!verify_comp_for_removal(comp, install_mode)) if (!verify_comp_for_removal(comp, install_mode))
{ {
TRACE("Skipping removal due to missing conditions\n"); TRACE("Skipping removal due to install mode\n");
comp->Action = comp->Installed; comp->Action = comp->Installed;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }

View File

@ -675,7 +675,10 @@ void ACTION_UpdateComponentStates( MSIPACKAGE *package, MSIFEATURE *feature )
component->Action, component->ActionRequest); component->Action, component->ActionRequest);
if (newstate == INSTALLSTATE_LOCAL) if (newstate == INSTALLSTATE_LOCAL)
msi_component_set_state(package, component, INSTALLSTATE_LOCAL); {
component->Action = INSTALLSTATE_LOCAL;
component->ActionRequest = INSTALLSTATE_LOCAL;
}
else else
{ {
ComponentList *clist; ComponentList *clist;
@ -683,9 +686,10 @@ void ACTION_UpdateComponentStates( MSIPACKAGE *package, MSIFEATURE *feature )
component->hasLocalFeature = FALSE; component->hasLocalFeature = FALSE;
msi_component_set_state(package, component, newstate); component->Action = newstate;
component->ActionRequest = newstate;
/*if any other feature wants is local we need to set it local*/ /* if any other feature wants it local we need to set it local */
LIST_FOR_EACH_ENTRY( f, &package->features, MSIFEATURE, entry ) LIST_FOR_EACH_ENTRY( f, &package->features, MSIFEATURE, entry )
{ {
if ( f->ActionRequest != INSTALLSTATE_LOCAL && if ( f->ActionRequest != INSTALLSTATE_LOCAL &&
@ -706,14 +710,26 @@ void ACTION_UpdateComponentStates( MSIPACKAGE *package, MSIFEATURE *feature )
if (component->Attributes & msidbComponentAttributesOptional) if (component->Attributes & msidbComponentAttributesOptional)
{ {
if (f->Attributes & msidbFeatureAttributesFavorSource) if (f->Attributes & msidbFeatureAttributesFavorSource)
msi_component_set_state(package, component, INSTALLSTATE_SOURCE); {
component->Action = INSTALLSTATE_SOURCE;
component->ActionRequest = INSTALLSTATE_SOURCE;
}
else else
msi_component_set_state(package, component, INSTALLSTATE_LOCAL); {
component->Action = INSTALLSTATE_LOCAL;
component->ActionRequest = INSTALLSTATE_LOCAL;
}
} }
else if (component->Attributes & msidbComponentAttributesSourceOnly) else if (component->Attributes & msidbComponentAttributesSourceOnly)
msi_component_set_state(package, component, INSTALLSTATE_SOURCE); {
component->Action = INSTALLSTATE_SOURCE;
component->ActionRequest = INSTALLSTATE_SOURCE;
}
else else
msi_component_set_state(package, component, INSTALLSTATE_LOCAL); {
component->Action = INSTALLSTATE_LOCAL;
component->ActionRequest = INSTALLSTATE_LOCAL;
}
} }
} }
} }

View File

@ -1163,7 +1163,7 @@ static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
return ERROR_UNKNOWN_COMPONENT; return ERROR_UNKNOWN_COMPONENT;
if (comp->Enabled) if (comp->Enabled)
comp->Installed = iState; comp->Action = iState;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }

View File

@ -955,8 +955,6 @@ extern UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid,
MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value); MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value);
extern UINT msi_get_local_package_name(LPWSTR path, LPCWSTR suffix); extern UINT msi_get_local_package_name(LPWSTR path, LPCWSTR suffix);
extern UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace); extern UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace);
extern void msi_component_set_state(MSIPACKAGE *, MSICOMPONENT *, INSTALLSTATE);
extern void msi_feature_set_state(MSIPACKAGE *, MSIFEATURE *, INSTALLSTATE);
extern MSIASSEMBLY *load_assembly(MSIPACKAGE *, MSICOMPONENT *); extern MSIASSEMBLY *load_assembly(MSIPACKAGE *, MSICOMPONENT *);
extern UINT install_assembly(MSIPACKAGE *, MSICOMPONENT *); extern UINT install_assembly(MSIPACKAGE *, MSICOMPONENT *);
extern WCHAR *font_version_from_file(const WCHAR *); extern WCHAR *font_version_from_file(const WCHAR *);

View File

@ -7860,10 +7860,8 @@ static void test_removefiles(void)
installed = action = 0xdeadbeef; installed = action = 0xdeadbeef;
r = MsiGetComponentState( hpkg, "hydrogen", &installed, &action ); r = MsiGetComponentState( hpkg, "hydrogen", &installed, &action );
ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
todo_wine {
ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); todo_wine ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
}
r = MsiSetComponentState( hpkg, "helium", INSTALLSTATE_LOCAL ); r = MsiSetComponentState( hpkg, "helium", INSTALLSTATE_LOCAL );
ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);