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

View File

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

View File

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