Commit 1da2858c authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

- build a standard Wine list of features instead of using an array

- use feature pointers instead of array indexes
parent e5131213
......@@ -1007,7 +1007,7 @@ static MSICOMPONENT* load_component( MSIRECORD * row )
typedef struct {
MSIPACKAGE *package;
INT index;
MSIFEATURE *feature;
} _ilfs;
static UINT add_feature_component( MSIFEATURE *feature, MSICOMPONENT *comp )
......@@ -1018,7 +1018,7 @@ static UINT add_feature_component( MSIFEATURE *feature, MSICOMPONENT *comp )
if ( !cl )
return ERROR_NOT_ENOUGH_MEMORY;
cl->component = comp;
list_add_tail( feature->Components, &cl->entry );
list_add_tail( &feature->Components, &cl->entry );
return ERROR_SUCCESS;
}
......@@ -1027,6 +1027,7 @@ static UINT iterate_component_check( MSIRECORD *row, LPVOID param )
{
_ilfs* ilfs= (_ilfs*)param;
MSIPACKAGE *package = ilfs->package;
MSIFEATURE *feature = ilfs->feature;
MSICOMPONENT *comp;
comp = load_component( row );
......@@ -1034,7 +1035,7 @@ static UINT iterate_component_check( MSIRECORD *row, LPVOID param )
return ERROR_FUNCTION_FAILED;
list_add_tail( &package->components, &comp->entry );
add_feature_component( &package->features[ilfs->index], comp );
add_feature_component( feature, comp );
TRACE("Loaded new component %p\n", comp);
......@@ -1062,7 +1063,7 @@ static UINT iterate_load_featurecomponents(MSIRECORD *row, LPVOID param)
if (comp)
{
TRACE("Component %s already loaded\n", debugstr_w(component) );
add_feature_component( &ilfs->package->features[ilfs->index], comp );
add_feature_component( ilfs->feature, comp );
return ERROR_SUCCESS;
}
......@@ -1079,7 +1080,7 @@ static UINT iterate_load_featurecomponents(MSIRECORD *row, LPVOID param)
static UINT load_feature(MSIRECORD * row, LPVOID param)
{
MSIPACKAGE* package = (MSIPACKAGE*)param;
int index = package->loaded_features;
MSIFEATURE* feature;
DWORD sz;
static const WCHAR Query1[] =
{'S','E','L','E','C','T',' ',
......@@ -1092,67 +1093,57 @@ static UINT load_feature(MSIRECORD * row, LPVOID param)
UINT rc;
_ilfs ilfs;
ilfs.package = package;
ilfs.index = index;
/* fill in the data */
package->loaded_features ++;
if (package->loaded_features == 1)
package->features = HeapAlloc(GetProcessHeap(),0,sizeof(MSIFEATURE));
else
package->features = HeapReAlloc(GetProcessHeap(),0,package->features,
package->loaded_features * sizeof(MSIFEATURE));
memset(&package->features[index],0,sizeof(MSIFEATURE));
feature = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (MSIFEATURE) );
if (!feature)
return ERROR_NOT_ENOUGH_MEMORY;
/*
* Can't use struct list in features because the address keeps changing
* due to the above HeapReAlloc, so allocate a struct list instead
*/
package->features[index].Components =
HeapAlloc( GetProcessHeap(), 0, sizeof (struct list) );
list_init( package->features[index].Components );
list_init( &feature->Components );
sz = IDENTIFIER_SIZE;
MSI_RecordGetStringW(row,1,package->features[index].Feature,&sz);
MSI_RecordGetStringW(row,1,feature->Feature,&sz);
TRACE("Loading feature %s\n",debugstr_w(package->features[index].Feature));
TRACE("Loading feature %s\n",debugstr_w(feature->Feature));
sz = IDENTIFIER_SIZE;
if (!MSI_RecordIsNull(row,2))
MSI_RecordGetStringW(row,2,package->features[index].Feature_Parent,&sz);
MSI_RecordGetStringW(row,2,feature->Feature_Parent,&sz);
sz = 0x100;
if (!MSI_RecordIsNull(row,3))
MSI_RecordGetStringW(row,3,package->features[index].Title,&sz);
if (!MSI_RecordIsNull(row,3))
MSI_RecordGetStringW(row,3,feature->Title,&sz);
sz = 0x100;
if (!MSI_RecordIsNull(row,4))
MSI_RecordGetStringW(row,4,package->features[index].Description,&sz);
sz = 0x100;
if (!MSI_RecordIsNull(row,4))
MSI_RecordGetStringW(row,4,feature->Description,&sz);
if (!MSI_RecordIsNull(row,5))
package->features[index].Display = MSI_RecordGetInteger(row,5);
feature->Display = MSI_RecordGetInteger(row,5);
package->features[index].Level= MSI_RecordGetInteger(row,6);
feature->Level= MSI_RecordGetInteger(row,6);
sz = IDENTIFIER_SIZE;
if (!MSI_RecordIsNull(row,7))
MSI_RecordGetStringW(row,7,feature->Directory,&sz);
sz = IDENTIFIER_SIZE;
if (!MSI_RecordIsNull(row,7))
MSI_RecordGetStringW(row,7,package->features[index].Directory,&sz);
feature->Attributes = MSI_RecordGetInteger(row,8);
package->features[index].Attributes= MSI_RecordGetInteger(row,8);
feature->Installed = INSTALLSTATE_ABSENT;
feature->Action = INSTALLSTATE_UNKNOWN;
feature->ActionRequest = INSTALLSTATE_UNKNOWN;
package->features[index].Installed = INSTALLSTATE_ABSENT;
package->features[index].Action = INSTALLSTATE_UNKNOWN;
package->features[index].ActionRequest = INSTALLSTATE_UNKNOWN;
list_add_tail( &package->features, &feature->entry );
/* load feature components */
rc = MSI_OpenQuery(package->db, &view, Query1,
package->features[index].Feature);
rc = MSI_OpenQuery( package->db, &view, Query1, feature->Feature );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
ilfs.package = package;
ilfs.feature = feature;
MSI_IterateRecords(view, NULL, iterate_load_featurecomponents , &ilfs);
msiobj_release(&view->hdr);
......@@ -1420,7 +1411,7 @@ static INT load_folder(MSIPACKAGE *package, const WCHAR* dir)
static void ACTION_UpdateInstallStates(MSIPACKAGE *package)
{
MSICOMPONENT *comp;
int i;
MSIFEATURE *feature;
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{
......@@ -1432,13 +1423,12 @@ static void ACTION_UpdateInstallStates(MSIPACKAGE *package)
comp->Installed = res;
}
for (i = 0; i < package->loaded_features; i++)
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
ComponentList *cl;
INSTALLSTATE res = -10;
LIST_FOR_EACH_ENTRY( cl, package->features[i].Components,
ComponentList, entry )
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
{
comp= cl->component;
......@@ -1461,19 +1451,19 @@ static BOOL process_state_property (MSIPACKAGE* package, LPCWSTR property,
{
static const WCHAR all[]={'A','L','L',0};
LPWSTR override = NULL;
INT i;
BOOL rc = FALSE;
MSIFEATURE *feature;
override = load_dynamic_property(package, property, NULL);
if (override)
{
rc = TRUE;
for(i = 0; i < package->loaded_features; i++)
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
if (strcmpiW(override,all)==0)
{
package->features[i].ActionRequest= state;
package->features[i].Action = state;
feature->ActionRequest= state;
feature->Action = state;
}
else
{
......@@ -1483,12 +1473,11 @@ static BOOL process_state_property (MSIPACKAGE* package, LPCWSTR property,
while (ptr)
{
if ((ptr2 &&
strncmpW(ptr,package->features[i].Feature, ptr2-ptr)==0)
|| (!ptr2 &&
strcmpW(ptr,package->features[i].Feature)==0))
strncmpW(ptr,feature->Feature, ptr2-ptr)==0)
|| (!ptr2 && strcmpW(ptr,feature->Feature)==0))
{
package->features[i].ActionRequest= state;
package->features[i].Action = state;
feature->ActionRequest= state;
feature->Action = state;
break;
}
if (ptr2)
......@@ -1511,7 +1500,6 @@ static UINT SetFeatureStates(MSIPACKAGE *package)
{
LPWSTR level;
INT install_level;
DWORD i;
static const WCHAR szlevel[] =
{'I','N','S','T','A','L','L','L','E','V','E','L',0};
static const WCHAR szAddLocal[] =
......@@ -1520,6 +1508,8 @@ static UINT SetFeatureStates(MSIPACKAGE *package)
{'R','E','M','O','V','E',0};
BOOL override = FALSE;
MSICOMPONENT* component;
MSIFEATURE *feature;
/* I do not know if this is where it should happen.. but */
......@@ -1561,30 +1551,27 @@ static UINT SetFeatureStates(MSIPACKAGE *package)
if (!override)
{
for(i = 0; i < package->loaded_features; i++)
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
BOOL feature_state = ((package->features[i].Level > 0) &&
(package->features[i].Level <= install_level));
BOOL feature_state = ((feature->Level > 0) &&
(feature->Level <= install_level));
if ((feature_state) &&
(package->features[i].Action == INSTALLSTATE_UNKNOWN))
if ((feature_state) && (feature->Action == INSTALLSTATE_UNKNOWN))
{
if (package->features[i].Attributes &
msidbFeatureAttributesFavorSource)
if (feature->Attributes & msidbFeatureAttributesFavorSource)
{
package->features[i].ActionRequest = INSTALLSTATE_SOURCE;
package->features[i].Action = INSTALLSTATE_SOURCE;
feature->ActionRequest = INSTALLSTATE_SOURCE;
feature->Action = INSTALLSTATE_SOURCE;
}
else if (package->features[i].Attributes &
msidbFeatureAttributesFavorAdvertise)
else if (feature->Attributes & msidbFeatureAttributesFavorAdvertise)
{
package->features[i].ActionRequest =INSTALLSTATE_ADVERTISED;
package->features[i].Action =INSTALLSTATE_ADVERTISED;
feature->ActionRequest = INSTALLSTATE_ADVERTISED;
feature->Action = INSTALLSTATE_ADVERTISED;
}
else
{
package->features[i].ActionRequest = INSTALLSTATE_LOCAL;
package->features[i].Action = INSTALLSTATE_LOCAL;
feature->ActionRequest = INSTALLSTATE_LOCAL;
feature->Action = INSTALLSTATE_LOCAL;
}
}
}
......@@ -1602,16 +1589,15 @@ static UINT SetFeatureStates(MSIPACKAGE *package)
* now we want to enable or disable components base on feature
*/
for(i = 0; i < package->loaded_features; i++)
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
MSIFEATURE* feature = &package->features[i];
ComponentList *cl;
TRACE("Examining Feature %s (Installed %i, Action %i, Request %i)\n",
debugstr_w(feature->Feature), feature->Installed, feature->Action,
feature->ActionRequest);
LIST_FOR_EACH_ENTRY( cl, feature->Components, ComponentList, entry )
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
{
component = cl->component;
......@@ -1692,14 +1678,14 @@ static UINT ITERATE_CostFinalizeDirectories(MSIRECORD *row, LPVOID param)
static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param)
{
MSIPACKAGE *package = (MSIPACKAGE*)param;
LPCWSTR Feature;
int feature_index;
LPCWSTR name;
MSIFEATURE *feature;
Feature = MSI_RecordGetString(row,1);
name = MSI_RecordGetString( row, 1 );
feature_index = get_loaded_feature(package,Feature);
if (feature_index < 0)
ERR("FAILED to find loaded feature %s\n",debugstr_w(Feature));
feature = get_loaded_feature( package, name );
if (!feature)
ERR("FAILED to find loaded feature %s\n",debugstr_w(name));
else
{
LPCWSTR Condition;
......@@ -1708,9 +1694,8 @@ static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param)
if (MSI_EvaluateConditionW(package,Condition) == MSICONDITION_TRUE)
{
int level = MSI_RecordGetInteger(row,2);
TRACE("Reseting feature %s to level %i\n", debugstr_w(Feature),
level);
package->features[feature_index].Level = level;
TRACE("Reseting feature %s to level %i\n", debugstr_w(name), level);
feature->Level = level;
}
}
return ERROR_SUCCESS;
......@@ -2212,6 +2197,7 @@ static UINT ACTION_InstallValidate(MSIPACKAGE *package)
UINT rc;
MSIQUERY * view;
MSIRECORD * row = 0;
MSIFEATURE *feature;
int i;
TRACE(" InstallValidate \n");
......@@ -2251,9 +2237,8 @@ static UINT ACTION_InstallValidate(MSIPACKAGE *package)
total += package->files[i].FileSize;
ui_progress(package,0,total,0,0);
for(i = 0; i < package->loaded_features; i++)
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
MSIFEATURE* feature = &package->features[i];
TRACE("Feature: %s; Installed: %i; Action %i; Request %i\n",
debugstr_w(feature->Feature), feature->Installed, feature->Action,
feature->ActionRequest);
......@@ -2423,6 +2408,7 @@ static UINT ACTION_WriteSharedDLLsCount(LPCWSTR path, UINT count)
*/
static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp )
{
MSIFEATURE *feature;
INT count = 0;
BOOL write = FALSE;
INT j;
......@@ -2442,30 +2428,28 @@ static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp )
}
/* increment counts */
for (j = 0; j < package->loaded_features; j++)
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
ComponentList *cl;
if (!ACTION_VerifyFeatureForAction(package,j,INSTALLSTATE_LOCAL))
if (!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_LOCAL ))
continue;
LIST_FOR_EACH_ENTRY( cl, package->features[j].Components,
ComponentList, entry )
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
{
if ( cl->component == comp )
count++;
}
}
/* decrement counts */
for (j = 0; j < package->loaded_features; j++)
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
ComponentList *cl;
if (!ACTION_VerifyFeatureForAction(package,j,INSTALLSTATE_ABSENT))
if (!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ABSENT ))
continue;
LIST_FOR_EACH_ENTRY( cl, package->features[j].Components,
ComponentList, entry )
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
{
if ( cl->component == comp )
count--;
......@@ -3310,8 +3294,8 @@ static UINT ACTION_SelfRegModules(MSIPACKAGE *package)
static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
{
MSIFEATURE *feature;
UINT rc;
DWORD i;
HKEY hkey=0;
HKEY hukey=0;
......@@ -3327,7 +3311,7 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
goto end;
/* here the guids are base 85 encoded */
for (i = 0; i < package->loaded_features; i++)
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
ComponentList *cl;
LPWSTR data = NULL;
......@@ -3335,25 +3319,23 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
INT size;
BOOL absent = FALSE;
if (!ACTION_VerifyFeatureForAction(package,i,INSTALLSTATE_LOCAL) &&
!ACTION_VerifyFeatureForAction(package,i,INSTALLSTATE_SOURCE) &&
!ACTION_VerifyFeatureForAction(package,i,INSTALLSTATE_ADVERTISED))
if (!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_LOCAL ) &&
!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_SOURCE ) &&
!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ADVERTISED ))
absent = TRUE;
size = 1;
LIST_FOR_EACH_ENTRY( cl, package->features[i].Components,
ComponentList, entry )
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
{
size += 21;
}
if (package->features[i].Feature_Parent[0])
size += strlenW(package->features[i].Feature_Parent)+2;
if (feature->Feature_Parent[0])
size += strlenW( feature->Feature_Parent )+2;
data = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
data[0] = 0;
LIST_FOR_EACH_ENTRY( cl, package->features[i].Components,
ComponentList, entry )
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
{
MSICOMPONENT* component = cl->component;
WCHAR buf[21];
......@@ -3368,32 +3350,30 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
strcatW(data,buf);
}
}
if (package->features[i].Feature_Parent[0])
if (feature->Feature_Parent[0])
{
static const WCHAR sep[] = {'\2',0};
strcatW(data,sep);
strcatW(data,package->features[i].Feature_Parent);
strcatW(data,feature->Feature_Parent);
}
size = (strlenW(data)+1)*sizeof(WCHAR);
RegSetValueExW(hkey,package->features[i].Feature,0,REG_SZ,
(LPBYTE)data,size);
RegSetValueExW( hkey, feature->Feature, 0, REG_SZ, (LPBYTE)data,size );
HeapFree(GetProcessHeap(),0,data);
if (!absent)
{
size = strlenW(package->features[i].Feature_Parent)*sizeof(WCHAR);
RegSetValueExW(hukey,package->features[i].Feature,0,REG_SZ,
(LPBYTE)package->features[i].Feature_Parent,size);
size = strlenW(feature->Feature_Parent)*sizeof(WCHAR);
RegSetValueExW(hukey,feature->Feature,0,REG_SZ,
(LPBYTE)feature->Feature_Parent,size);
}
else
{
size = (strlenW(package->features[i].Feature_Parent)+2)*
sizeof(WCHAR);
size = (strlenW(feature->Feature_Parent)+2)* sizeof(WCHAR);
data = HeapAlloc(GetProcessHeap(),0,size);
data[0] = 0x6;
strcpyW(&data[1],package->features[i].Feature_Parent);
RegSetValueExW(hukey,package->features[i].Feature,0,REG_SZ,
strcpyW( &data[1], feature->Feature_Parent );
RegSetValueExW(hukey,feature->Feature,0,REG_SZ,
(LPBYTE)data,size);
HeapFree(GetProcessHeap(),0,data);
}
......
......@@ -24,6 +24,7 @@
typedef struct tagMSIFEATURE
{
struct list entry;
WCHAR Feature[IDENTIFIER_SIZE];
WCHAR Feature_Parent[IDENTIFIER_SIZE];
WCHAR Title[0x100];
......@@ -37,7 +38,7 @@ typedef struct tagMSIFEATURE
INSTALLSTATE ActionRequest;
INSTALLSTATE Action;
struct list *Components;
struct list Components;
INT Cost;
} MSIFEATURE;
......@@ -127,7 +128,7 @@ typedef struct tagMSICLASS
LPWSTR DefInprocHandler;
LPWSTR DefInprocHandler32;
LPWSTR Argument;
INT FeatureIndex;
MSIFEATURE *Feature;
INT Attributes;
/* not in the table, set during installation */
BOOL Installed;
......@@ -140,7 +141,7 @@ typedef struct tagMSIEXTENSION
INT ProgIDIndex;
LPWSTR ProgIDText;
INT MIMEIndex;
INT FeatureIndex;
MSIFEATURE *Feature;
/* not in the table, set during installation */
BOOL Installed;
INT VerbCount;
......@@ -236,7 +237,7 @@ LPWSTR load_dynamic_property(MSIPACKAGE *package, LPCWSTR prop, UINT* rc);
LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
BOOL set_prop, MSIFOLDER **folder);
MSICOMPONENT *get_loaded_component( MSIPACKAGE* package, LPCWSTR Component );
int get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature );
MSIFEATURE *get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature );
int get_loaded_file(MSIPACKAGE* package, LPCWSTR file);
int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path);
UINT schedule_action(MSIPACKAGE *package, UINT script, LPCWSTR action);
......@@ -245,7 +246,7 @@ DWORD build_version_dword(LPCWSTR);
LPWSTR build_directory_name(DWORD , ...);
BOOL create_full_pathW(const WCHAR *path);
BOOL ACTION_VerifyComponentForAction(MSIPACKAGE*, MSICOMPONENT*, INSTALLSTATE);
BOOL ACTION_VerifyFeatureForAction(MSIPACKAGE*, INT, INSTALLSTATE);
BOOL ACTION_VerifyFeatureForAction(MSIFEATURE*, INSTALLSTATE);
void reduce_to_longfilename(WCHAR*);
void reduce_to_shortfilename(WCHAR*);
LPWSTR create_component_advertise_string(MSIPACKAGE*, MSICOMPONENT*, LPCWSTR);
......
......@@ -329,7 +329,7 @@ static INT load_class(MSIPACKAGE* package, MSIRECORD *row)
deformat_string(package,buffer,&package->classes[index].Argument);
buffer = MSI_RecordGetString(row,12);
package->classes[index].FeatureIndex = get_loaded_feature(package,buffer);
package->classes[index].Feature = get_loaded_feature(package,buffer);
package->classes[index].Attributes = MSI_RecordGetInteger(row,13);
......@@ -475,8 +475,7 @@ static INT load_extension(MSIPACKAGE* package, MSIRECORD *row)
package->extensions[index].MIMEIndex = load_given_mime(package,buffer);
buffer = MSI_RecordGetString(row,5);
package->extensions[index].FeatureIndex =
get_loaded_feature(package,buffer);
package->extensions[index].Feature = get_loaded_feature(package,buffer);
return index;
}
......@@ -919,28 +918,28 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
for (i = 0; i < package->loaded_classes; i++)
{
MSICOMPONENT *comp;
INT index, f_index;
INT index;
DWORD size, sz;
LPWSTR argument;
MSIFEATURE *feature;
comp = package->classes[i].Component;
if ( !comp )
continue;
f_index = package->classes[i].FeatureIndex;
feature = package->classes[i].Feature;
/*
* yes. MSDN says that these are based on _Feature_ not on
* Component. So verify the feature is to be installed
*/
if ((!ACTION_VerifyFeatureForAction(package, f_index,
INSTALLSTATE_LOCAL)) &&
!(install_on_demand && ACTION_VerifyFeatureForAction(package,
f_index, INSTALLSTATE_ADVERTISED)))
if ((!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_LOCAL )) &&
!(install_on_demand &&
ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ADVERTISED )))
{
TRACE("Skipping class %s reg due to disabled feature %s\n",
debugstr_w(package->classes[i].CLSID),
debugstr_w(package->features[f_index].Feature));
debugstr_w(feature->Feature));
continue;
}
......@@ -1347,12 +1346,12 @@ static UINT register_verb(MSIPACKAGE *package, LPCWSTR progid,
HeapFree(GetProcessHeap(),0,command);
advertise = create_component_advertise_string(package, component,
package->features[extension->FeatureIndex].Feature);
extension->Feature->Feature);
size = strlenW(advertise);
if (verb->Argument)
size += strlenW(verb->Argument);
size += strlenW(verb->Argument);
size += 4;
command = HeapAlloc(GetProcessHeap(),0, size * sizeof (WCHAR));
......@@ -1361,7 +1360,7 @@ static UINT register_verb(MSIPACKAGE *package, LPCWSTR progid,
strcpyW(command,advertise);
if (verb->Argument)
{
static const WCHAR szSpace[] = {' ',0};
static const WCHAR szSpace[] = {' ',0};
strcatW(command,szSpace);
strcatW(command,verb->Argument);
}
......@@ -1422,25 +1421,24 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package)
for (i = 0; i < package->loaded_extensions; i++)
{
WCHAR extension[257];
INT f_index;
MSIFEATURE *feature;
if (!package->extensions[i].Component)
continue;
f_index = package->extensions[i].FeatureIndex;
feature = package->extensions[i].Feature;
/*
* yes. MSDN says that these are based on _Feature_ not on
* Component. So verify the feature is to be installed
*/
if ((!ACTION_VerifyFeatureForAction(package, f_index,
INSTALLSTATE_LOCAL)) &&
!(install_on_demand && ACTION_VerifyFeatureForAction(package,
f_index, INSTALLSTATE_ADVERTISED)))
if ((!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_LOCAL )) &&
!(install_on_demand &&
ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ADVERTISED )))
{
TRACE("Skipping extension %s reg due to disabled feature %s\n",
debugstr_w(package->extensions[i].Extension),
debugstr_w(package->features[f_index].Feature));
debugstr_w(feature->Feature));
continue;
}
......
......@@ -170,7 +170,7 @@ static UINT ControlEvent_AddLocal(MSIPACKAGE* package, LPCWSTR argument,
msi_dialog* dialog)
{
static const WCHAR szAll[] = {'A','L','L',0};
int i;
MSIFEATURE *feature = NULL;
if (lstrcmpW(szAll,argument))
{
......@@ -178,10 +178,10 @@ static UINT ControlEvent_AddLocal(MSIPACKAGE* package, LPCWSTR argument,
}
else
{
for (i = 0; i < package->loaded_features; i++)
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
package->features[i].ActionRequest = INSTALLSTATE_LOCAL;
package->features[i].Action = INSTALLSTATE_LOCAL;
feature->ActionRequest = INSTALLSTATE_LOCAL;
feature->Action = INSTALLSTATE_LOCAL;
}
ACTION_UpdateComponentStates(package,argument);
}
......@@ -192,7 +192,7 @@ static UINT ControlEvent_Remove(MSIPACKAGE* package, LPCWSTR argument,
msi_dialog* dialog)
{
static const WCHAR szAll[] = {'A','L','L',0};
int i;
MSIFEATURE *feature = NULL;
if (lstrcmpW(szAll,argument))
{
......@@ -200,10 +200,10 @@ static UINT ControlEvent_Remove(MSIPACKAGE* package, LPCWSTR argument,
}
else
{
for (i = 0; i < package->loaded_features; i++)
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
package->features[i].ActionRequest = INSTALLSTATE_ABSENT;
package->features[i].Action= INSTALLSTATE_ABSENT;
feature->ActionRequest = INSTALLSTATE_ABSENT;
feature->Action= INSTALLSTATE_ABSENT;
}
ACTION_UpdateComponentStates(package,argument);
}
......@@ -214,7 +214,7 @@ static UINT ControlEvent_AddSource(MSIPACKAGE* package, LPCWSTR argument,
msi_dialog* dialog)
{
static const WCHAR szAll[] = {'A','L','L',0};
int i;
MSIFEATURE *feature = NULL;
if (lstrcmpW(szAll,argument))
{
......@@ -222,10 +222,10 @@ static UINT ControlEvent_AddSource(MSIPACKAGE* package, LPCWSTR argument,
}
else
{
for (i = 0; i < package->loaded_features; i++)
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
package->features[i].ActionRequest = INSTALLSTATE_SOURCE;
package->features[i].Action = INSTALLSTATE_SOURCE;
feature->ActionRequest = INSTALLSTATE_SOURCE;
feature->Action = INSTALLSTATE_SOURCE;
}
ACTION_UpdateComponentStates(package,argument);
}
......
......@@ -179,20 +179,16 @@ MSICOMPONENT* get_loaded_component( MSIPACKAGE* package, LPCWSTR Component )
return NULL;
}
int get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature )
MSIFEATURE* get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature )
{
int rc = -1;
DWORD i;
MSIFEATURE *feature = NULL;
for (i = 0; i < package->loaded_features; i++)
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
if (strcmpW(Feature,package->features[i].Feature)==0)
{
rc = i;
break;
}
if (lstrcmpW( Feature, feature->Feature )==0)
return feature;
}
return rc;
return NULL;
}
int get_loaded_file(MSIPACKAGE* package, LPCWSTR file)
......@@ -449,6 +445,20 @@ static void remove_tracked_tempfiles(MSIPACKAGE* package)
}
}
static void free_feature( MSIFEATURE *feature )
{
struct list *item, *cursor;
LIST_FOR_EACH_SAFE( item, cursor, &feature->Components )
{
ComponentList *cl = LIST_ENTRY( item, ComponentList, entry );
list_remove( &cl->entry );
HeapFree( GetProcessHeap(), 0, cl );
}
HeapFree( GetProcessHeap(), 0, feature );
}
/* Called when the package is being closed */
void ACTION_free_package_structures( MSIPACKAGE* package)
{
......@@ -459,16 +469,11 @@ void ACTION_free_package_structures( MSIPACKAGE* package)
remove_tracked_tempfiles(package);
if (package->features)
LIST_FOR_EACH_SAFE( item, cursor, &package->features )
{
LIST_FOR_EACH_SAFE( item, cursor, package->features->Components )
{
ComponentList *cl = LIST_ENTRY( item, ComponentList, entry );
list_remove( &cl->entry );
HeapFree(GetProcessHeap(), 0, cl);
}
HeapFree(GetProcessHeap(),0,package->features->Components);
HeapFree(GetProcessHeap(),0,package->features);
MSIFEATURE *feature = LIST_ENTRY( item, MSIFEATURE, entry );
list_remove( &feature->entry );
free_feature( feature );
}
for (i = 0; i < package->loaded_folders; i++)
......@@ -773,13 +778,12 @@ BOOL ACTION_VerifyComponentForAction(MSIPACKAGE* package, MSICOMPONENT* comp,
return FALSE;
}
BOOL ACTION_VerifyFeatureForAction(MSIPACKAGE* package, INT index,
INSTALLSTATE check )
BOOL ACTION_VerifyFeatureForAction( MSIFEATURE* feature, INSTALLSTATE check )
{
if (package->features[index].Installed == check)
if (feature->Installed == check)
return FALSE;
if (package->features[index].ActionRequest == check)
if (feature->ActionRequest == check)
return TRUE;
else
return FALSE;
......@@ -852,19 +856,17 @@ LPWSTR create_component_advertise_string(MSIPACKAGE* package,
/* update compoennt state based on a feature change */
void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
{
int i;
INSTALLSTATE newstate;
MSIFEATURE *feature;
ComponentList *cl;
i = get_loaded_feature(package,szFeature);
if (i < 0)
feature = get_loaded_feature(package,szFeature);
if (!feature)
return;
feature = &package->features[i];
newstate = feature->ActionRequest;
LIST_FOR_EACH_ENTRY( cl, feature->Components, ComponentList, entry )
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
{
MSICOMPONENT* component = cl->component;
......@@ -883,27 +885,25 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
}
else
{
int j;
ComponentList *clist;
MSIFEATURE *f;
component->ActionRequest = newstate;
component->Action = newstate;
/*if any other feature wants is local we need to set it local*/
for (j = 0;
j < package->loaded_features &&
component->ActionRequest != INSTALLSTATE_LOCAL;
j++)
LIST_FOR_EACH_ENTRY( f, &package->features, MSIFEATURE, entry )
{
LIST_FOR_EACH_ENTRY( clist, package->features[j].Components,
ComponentList, entry )
if ( component->ActionRequest != INSTALLSTATE_LOCAL )
break;
LIST_FOR_EACH_ENTRY( clist, &f->Components, ComponentList, entry )
{
if ( clist->component == cl->component )
if ( clist->component == component )
{
if (package->features[j].ActionRequest ==
INSTALLSTATE_LOCAL)
if (f->ActionRequest == INSTALLSTATE_LOCAL)
{
TRACE("Saved by %s\n", debugstr_w(package->features[j].Feature));
TRACE("Saved by %s\n", debugstr_w(f->Feature));
component->ActionRequest = INSTALLSTATE_LOCAL;
component->Action = INSTALLSTATE_LOCAL;
}
......
......@@ -416,30 +416,29 @@ UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE* package, LPCWSTR szFeature,
INSTALLSTATE iState)
{
INT index, i;
UINT rc = ERROR_SUCCESS;
MSIFEATURE *feature, *child;
TRACE(" %s to %i\n",debugstr_w(szFeature), iState);
index = get_loaded_feature(package,szFeature);
if (index < 0)
feature = get_loaded_feature(package,szFeature);
if (!feature)
return ERROR_UNKNOWN_FEATURE;
if (iState == INSTALLSTATE_ADVERTISED &&
package->features[index].Attributes &
msidbFeatureAttributesDisallowAdvertise)
feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
return ERROR_FUNCTION_FAILED;
package->features[index].ActionRequest= iState;
package->features[index].Action= iState;
feature->ActionRequest = iState;
feature->Action = iState;
ACTION_UpdateComponentStates(package,szFeature);
/* update all the features that are children of this feature */
for (i = 0; i < package->loaded_features; i++)
LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry )
{
if (strcmpW(szFeature, package->features[i].Feature_Parent) == 0)
MSI_SetFeatureStateW(package, package->features[i].Feature, iState);
if (lstrcmpW(szFeature, child->Feature_Parent) == 0)
MSI_SetFeatureStateW(package, child->Feature, iState);
}
return rc;
......@@ -487,19 +486,19 @@ UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPSTR szFeature,
UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPWSTR szFeature,
INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
{
INT index;
MSIFEATURE *feature;
index = get_loaded_feature(package,szFeature);
if (index < 0)
feature = get_loaded_feature(package,szFeature);
if (!feature)
return ERROR_UNKNOWN_FEATURE;
if (piInstalled)
*piInstalled = package->features[index].Installed;
*piInstalled = feature->Installed;
if (piAction)
*piAction = package->features[index].Action;
*piAction = feature->Action;
TRACE("returning %i %i\n",*piInstalled,*piAction);
TRACE("returning %i %i\n", feature->Installed, feature->Action);
return ERROR_SUCCESS;
}
......@@ -547,8 +546,8 @@ UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPWSTR szComponent,
{
MSICOMPONENT *comp;
TRACE("%p %s %p %p\n", package, debugstr_w(szComponent), piInstalled,
piAction);
TRACE("%p %s %p %p\n", package, debugstr_w(szComponent),
piInstalled, piAction);
comp = get_loaded_component(package,szComponent);
if (!comp)
......@@ -560,8 +559,7 @@ piAction);
if (piAction)
*piAction = comp->Action;
TRACE("states (%i, %i)\n",
(piInstalled)?*piInstalled:-1,(piAction)?*piAction:-1);
TRACE("states (%i, %i)\n", comp->Installed, comp->Action );
return ERROR_SUCCESS;
}
......
......@@ -186,11 +186,10 @@ typedef struct tagMSIPACKAGE
{
MSIOBJECTHDR hdr;
MSIDATABASE *db;
struct tagMSIFEATURE *features;
UINT loaded_features;
struct tagMSIFOLDER *folders;
UINT loaded_folders;
struct list components;
struct list features;
struct tagMSIFILE *files;
UINT loaded_files;
LPWSTR ActionFormat;
......
......@@ -377,11 +377,10 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db )
msiobj_addref( &db->hdr );
package->db = db;
package->features = NULL;
list_init( &package->features );
package->folders = NULL;
list_init( &package->components );
package->files = NULL;
package->loaded_features = 0;
package->loaded_folders = 0;
package->loaded_files = 0;
package->ActionFormat = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment