Store the component information in a standard Wine list.

This commit is contained in:
Mike McCormack 2005-08-19 10:03:11 +00:00 committed by Alexandre Julliard
parent 602f0c10c7
commit 3f2d5d7fbb
3 changed files with 87 additions and 42 deletions

View File

@ -1016,18 +1016,29 @@ static int load_component(MSIPACKAGE* package, MSIRECORD * row)
typedef struct {
MSIPACKAGE *package;
INT index;
INT cnt;
} _ilfs;
static UINT add_feature_component( MSIFEATURE *feature, int index )
{
ComponentList *cl;
cl = HeapAlloc( GetProcessHeap(), 0, sizeof (*cl) );
if ( !cl )
return ERROR_NOT_ENOUGH_MEMORY;
cl->component = index;
list_add_tail( feature->Components, &cl->entry );
return ERROR_SUCCESS;
}
static UINT iterate_component_check(MSIRECORD *row, LPVOID param)
{
_ilfs* ilfs= (_ilfs*)param;
INT c_indx;
c_indx = load_component(ilfs->package,row);
add_feature_component( &ilfs->package->features[ilfs->index], c_indx );
ilfs->package->features[ilfs->index].Components[ilfs->cnt] = c_indx;
ilfs->package->features[ilfs->index].ComponentCount ++;
TRACE("Loaded new component to index %i\n",c_indx);
return ERROR_SUCCESS;
@ -1039,7 +1050,6 @@ static UINT iterate_load_featurecomponents(MSIRECORD *row, LPVOID param)
LPCWSTR component;
DWORD rc;
INT c_indx;
INT cnt = ilfs->package->features[ilfs->index].ComponentCount;
MSIQUERY * view;
static const WCHAR Query[] =
{'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ',
@ -1056,8 +1066,7 @@ static UINT iterate_load_featurecomponents(MSIRECORD *row, LPVOID param)
{
TRACE("Component %s already loaded at %i\n", debugstr_w(component),
c_indx);
ilfs->package->features[ilfs->index].Components[cnt] = c_indx;
ilfs->package->features[ilfs->index].ComponentCount ++;
add_feature_component( &ilfs->package->features[ilfs->index], c_indx );
return ERROR_SUCCESS;
}
@ -1065,7 +1074,6 @@ static UINT iterate_load_featurecomponents(MSIRECORD *row, LPVOID param)
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
ilfs->cnt = cnt;
rc = MSI_IterateRecords(view, NULL, iterate_component_check, ilfs);
msiobj_release( &view->hdr );
@ -1101,6 +1109,14 @@ static UINT load_feature(MSIRECORD * row, LPVOID param)
package->loaded_features * sizeof(MSIFEATURE));
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 );
sz = IDENTIFIER_SIZE;
MSI_RecordGetStringW(row,1,package->features[index].Feature,&sz);
@ -1421,12 +1437,14 @@ static void ACTION_UpdateInstallStates(MSIPACKAGE *package)
for (i = 0; i < package->loaded_features; i++)
{
ComponentList *cl;
INSTALLSTATE res = -10;
int j;
for (j = 0; j < package->features[i].ComponentCount; j++)
LIST_FOR_EACH_ENTRY( cl, package->features[i].Components,
ComponentList, entry )
{
MSICOMPONENT* component = &package->components[package->features[i].
Components[j]];
MSICOMPONENT* component = &package->components[cl->component];
if (res == -10)
res = component->Installed;
else
@ -1497,7 +1515,6 @@ static UINT SetFeatureStates(MSIPACKAGE *package)
LPWSTR level;
INT install_level;
DWORD i;
INT j;
static const WCHAR szlevel[] =
{'I','N','S','T','A','L','L','L','E','V','E','L',0};
static const WCHAR szAddLocal[] =
@ -1590,14 +1607,15 @@ static UINT SetFeatureStates(MSIPACKAGE *package)
for(i = 0; i < package->loaded_features; i++)
{
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);
for( j = 0; j < feature->ComponentCount; j++)
LIST_FOR_EACH_ENTRY( cl, feature->Components, ComponentList, entry )
{
MSICOMPONENT* component = &package->components[
feature->Components[j]];
MSICOMPONENT* component = &package->components[cl->component];
if (!component->Enabled)
{
@ -2435,27 +2453,30 @@ static void ACTION_RefCountComponent( MSIPACKAGE* package, UINT index)
/* increment counts */
for (j = 0; j < package->loaded_features; j++)
{
int i;
ComponentList *cl;
if (!ACTION_VerifyFeatureForAction(package,j,INSTALLSTATE_LOCAL))
continue;
for (i = 0; i < package->features[j].ComponentCount; i++)
LIST_FOR_EACH_ENTRY( cl, package->features[j].Components,
ComponentList, entry )
{
if (package->features[j].Components[i] == index)
if ( cl->component == index )
count++;
}
}
/* decrement counts */
for (j = 0; j < package->loaded_features; j++)
{
int i;
ComponentList *cl;
if (!ACTION_VerifyFeatureForAction(package,j,INSTALLSTATE_ABSENT))
continue;
for (i = 0; i < package->features[j].ComponentCount; i++)
LIST_FOR_EACH_ENTRY( cl, package->features[j].Components,
ComponentList, entry )
{
if (package->features[j].Components[i] == index)
if ( cl->component == index )
count--;
}
}
@ -3324,9 +3345,9 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
/* here the guids are base 85 encoded */
for (i = 0; i < package->loaded_features; i++)
{
ComponentList *cl;
LPWSTR data = NULL;
GUID clsid;
int j;
INT size;
BOOL absent = FALSE;
@ -3335,26 +3356,29 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
!ACTION_VerifyFeatureForAction(package,i,INSTALLSTATE_ADVERTISED))
absent = TRUE;
size = package->features[i].ComponentCount*21;
size +=1;
size = 1;
LIST_FOR_EACH_ENTRY( cl, package->features[i].Components,
ComponentList, entry )
{
size += 21;
}
if (package->features[i].Feature_Parent[0])
size += strlenW(package->features[i].Feature_Parent)+2;
data = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
data[0] = 0;
for (j = 0; j < package->features[i].ComponentCount; j++)
LIST_FOR_EACH_ENTRY( cl, package->features[i].Components,
ComponentList, entry )
{
MSICOMPONENT* component = &package->components[cl->component];
WCHAR buf[21];
memset(buf,0,sizeof(buf));
if (package->components
[package->features[i].Components[j]].ComponentId[0]!=0)
if ( component->ComponentId[0] )
{
TRACE("From %s\n",debugstr_w(package->components
[package->features[i].Components[j]].ComponentId));
CLSIDFromString(package->components
[package->features[i].Components[j]].ComponentId,
&clsid);
TRACE("From %s\n",debugstr_w(component->ComponentId));
CLSIDFromString(component->ComponentId, &clsid);
encode_base85_guid(&clsid,buf);
TRACE("to %s\n",debugstr_w(buf));
strcatW(data,buf);

View File

@ -18,6 +18,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "wine/list.h"
#define IDENTIFIER_SIZE 96
typedef struct tagMSIFEATURE
@ -35,8 +37,8 @@ typedef struct tagMSIFEATURE
INSTALLSTATE ActionRequest;
INSTALLSTATE Action;
INT ComponentCount;
INT Components[1024]; /* yes hardcoded limit.... I am bad */
struct list *Components;
INT Cost;
} MSIFEATURE;
@ -61,6 +63,12 @@ typedef struct tagMSICOMPONENT
LPWSTR AdvertiseString;
} MSICOMPONENT;
typedef struct tagComponentList
{
struct list entry;
int component;
} ComponentList;
typedef struct tagMSIFOLDER
{
LPWSTR Directory;

View File

@ -457,14 +457,23 @@ static void remove_tracked_tempfiles(MSIPACKAGE* package)
void ACTION_free_package_structures( MSIPACKAGE* package)
{
INT i;
struct list *item, *cursor;
TRACE("Freeing package action data\n");
remove_tracked_tempfiles(package);
/* No dynamic buffers in features */
if (package->features && package->loaded_features > 0)
if (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);
}
for (i = 0; i < package->loaded_folders; i++)
{
@ -847,6 +856,7 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
int i;
INSTALLSTATE newstate;
MSIFEATURE *feature;
ComponentList *cl;
i = get_loaded_feature(package,szFeature);
if (i < 0)
@ -855,9 +865,9 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
feature = &package->features[i];
newstate = feature->ActionRequest;
for( i = 0; i < feature->ComponentCount; i++)
LIST_FOR_EACH_ENTRY( cl, feature->Components, ComponentList, entry )
{
MSICOMPONENT* component = &package->components[feature->Components[i]];
MSICOMPONENT* component = &package->components[cl->component];
TRACE("MODIFYING(%i): Component %s (Installed %i, Action %i, Request %i)\n",
newstate, debugstr_w(component->Component), component->Installed,
@ -874,7 +884,8 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
}
else
{
int j,k;
int j;
ComponentList *clist;
component->ActionRequest = newstate;
component->Action = newstate;
@ -885,9 +896,10 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
component->ActionRequest != INSTALLSTATE_LOCAL;
j++)
{
for (k = 0; k < package->features[j].ComponentCount; k++)
if ( package->features[j].Components[k] ==
feature->Components[i] )
LIST_FOR_EACH_ENTRY( clist, package->features[j].Components,
ComponentList, entry )
{
if ( clist->component == cl->component )
{
if (package->features[j].ActionRequest ==
INSTALLSTATE_LOCAL)
@ -898,6 +910,7 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
}
break;
}
}
}
}
}