diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 783e6a161ec..114057749f0 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -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); diff --git a/dlls/msi/action.h b/dlls/msi/action.h index b8914074b9c..47ba17b833f 100644 --- a/dlls/msi/action.h +++ b/dlls/msi/action.h @@ -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; diff --git a/dlls/msi/helpers.c b/dlls/msi/helpers.c index f44e339e22e..10056ff4d0d 100644 --- a/dlls/msi/helpers.c +++ b/dlls/msi/helpers.c @@ -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; } + } } } }