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 {
|
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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue