Store the component information in a standard Wine list.
This commit is contained in:
parent
602f0c10c7
commit
3f2d5d7fbb
|
@ -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 );
|
||||
|
||||
|
@ -1102,6 +1110,14 @@ static UINT load_feature(MSIRECORD * row, LPVOID param)
|
|||
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
@ -901,6 +913,7 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TRACE("Result (%i): Component %s (Installed %i, Action %i, Request %i)\n",
|
||||
newstate, debugstr_w(component->Component), component->Installed,
|
||||
component->Action, component->ActionRequest);
|
||||
|
|
Loading…
Reference in New Issue