- build a standard Wine list of features instead of using an array
- use feature pointers instead of array indexes
This commit is contained in:
parent
e5131213f6
commit
1da2858caa
|
@ -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));
|
||||
feature = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (MSIFEATURE) );
|
||||
if (!feature)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
memset(&package->features[index],0,sizeof(MSIFEATURE));
|
||||
|
||||
/*
|
||||
* 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,package->features[index].Directory,&sz);
|
||||
sz = IDENTIFIER_SIZE;
|
||||
if (!MSI_RecordIsNull(row,7))
|
||||
MSI_RecordGetStringW(row,7,feature->Directory,&sz);
|
||||
|
||||
package->features[index].Attributes= MSI_RecordGetInteger(row,8);
|
||||
feature->Attributes = MSI_RecordGetInteger(row,8);
|
||||
|
||||
package->features[index].Installed = INSTALLSTATE_ABSENT;
|
||||
package->features[index].Action = INSTALLSTATE_UNKNOWN;
|
||||
package->features[index].ActionRequest = INSTALLSTATE_UNKNOWN;
|
||||
feature->Installed = INSTALLSTATE_ABSENT;
|
||||
feature->Action = INSTALLSTATE_UNKNOWN;
|
||||
feature->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;
|
||||
|
|
Loading…
Reference in New Issue