Sync to Wine-20050830: Francois Gouget fgouget@free.fr - Change some Dll* functions so they are exported by name like on Windows. Update the documentation accordingly. Johan Dahlin jdahlin@async.com.br - Implemented MsiSetComponentState*. - Added stubs for MsiSetComponentStateA and MsiSetComponentStateW. - Added a null check for component. Alexandre Julliard julliard@winehq.org - Don't prefix the functions DllCanUnloadNow, DllGetClassObject and Dll(Un)RegisterServer with the dll name so that the compiler can check the prototypes. Vincent Beron vberon@mecano.gme.usherb.ca - Correct mismatches between spec files and comments about export number. Aric Stewart aric@codeweavers.com - Display the correct text string in the action text field for the dialog boxes. Also the string should be deformatted. - Make index INT not UINT because it can be -1. - Fixed a memory overflow and leak identified by Mike McCormack. - Add some body to ResolveSource because it is possible to need it when an install is begun but the media is not in the drive, such as in install-on-demand cases. - The file name used in the ui messages is the target name not the source name. Yuri Kozlov kozlov.y@gmail.com - Remove duplicate declaration of MSI_SetPropertyW. Mike McCormack mike@codeweavers.com - Handle loading strings over 64k from the string table. - build a standard Wine list of folders instead of using an array - use folder pointers instead of array indexes - build a standard Wine list of files instead of using an array - use file pointers instead of array indexes - build a standard Wine list of features instead of using an array - use feature pointers instead of array indexes - build a standard Wine list of components instead of using an array - use component pointers instead of array indexes - Store the component information in a standard Wine list. - Add include guard to header and make functions extern. - build a standard Wine list of extensions instead of using an array - use extension pointers instead of array indexes - build a standard Wine list of appids instead of using an array - use appid pointers instead of array indexes - build a standard Wine list of mime types instead of using an array - use mime type pointers instead of array indexes - Add the allocated mime type to the mime type list. - build a standard Wine list of classes instead of using an array - use class pointers instead of array indexes - Fix a small bug introduced when converting appids to a list. - Implement MsiModifyView (MSIMODIFY_INSERT_TEMPORARY). - Better stub for MsiViewGetError. - Don't dereference variables in a trace. - the combination of all table keys must be unique, not each key - MsiViewExecute may not be called before MsiModifyView - Make sure to save the result calculated in ACTION_UpdateInstallStates. Steven Edwards steven_ed4153@yahoo.com - Add real stub for MsiConfigureFeatureW. Modified: trunk/reactos/lib/msi/action.c Modified: trunk/reactos/lib/msi/action.h Modified: trunk/reactos/lib/msi/classes.c Modified: trunk/reactos/lib/msi/create.c Modified: trunk/reactos/lib/msi/custom.c Modified: trunk/reactos/lib/msi/delete.c Modified: trunk/reactos/lib/msi/events.c Modified: trunk/reactos/lib/msi/files.c Modified: trunk/reactos/lib/msi/format.c Modified: trunk/reactos/lib/msi/helpers.c Modified: trunk/reactos/lib/msi/insert.c Modified: trunk/reactos/lib/msi/install.c Modified: trunk/reactos/lib/msi/msi.c Modified: trunk/reactos/lib/msi/msi.spec Modified: trunk/reactos/lib/msi/msipriv.h Modified: trunk/reactos/lib/msi/msiquery.c Modified: trunk/reactos/lib/msi/package.c Modified: trunk/reactos/lib/msi/regsvr.c Modified: trunk/reactos/lib/msi/select.c Modified: trunk/reactos/lib/msi/table.c Modified: trunk/reactos/w32api/include/msi.h Modified: trunk/reactos/w32api/include/msiquery.h _____
Modified: trunk/reactos/lib/msi/action.c --- trunk/reactos/lib/msi/action.c 2005-09-05 21:19:23 UTC (rev 17671) +++ trunk/reactos/lib/msi/action.c 2005-09-05 21:34:19 UTC (rev 17672) @@ -379,6 +379,7 @@
WCHAR timet[0x100]; MSIRECORD * row = 0; LPCWSTR ActionText; + LPWSTR deformated;
GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);
@@ -387,8 +388,10 @@ return;
ActionText = MSI_RecordGetString(row,2); + deformat_string(package, ActionText, &deformated);
- sprintfW(message,template_s,timet,action,ActionText); + sprintfW(message,template_s,timet,action,deformated); + ce_actiontext(package, deformated); msiobj_release(&row->hdr);
row = MSI_CreateRecord(1); @@ -396,6 +399,7 @@
MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONSTART, row); msiobj_release(&row->hdr); + HeapFree(GetProcessHeap(),0,deformated); }
static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start, @@ -799,7 +803,6 @@ { if (strcmpW(StandardActions[i].action, action)==0) { - ce_actiontext(package, action); if (!run) { ui_actioninfo(package, action, TRUE, 0); @@ -965,71 +968,80 @@ return rc; }
-static int load_component(MSIPACKAGE* package, MSIRECORD * row) +static MSICOMPONENT* load_component( MSIRECORD * row ) { - int index = package->loaded_components; + MSICOMPONENT *comp; DWORD sz;
+ comp = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSICOMPONENT) ); + if (!comp) + return comp; + /* fill in the data */ - - package->loaded_components++; - if (package->loaded_components == 1) - package->components = HeapAlloc(GetProcessHeap(),0, - sizeof(MSICOMPONENT)); - else - package->components = HeapReAlloc(GetProcessHeap(),0, - package->components, package->loaded_components * - sizeof(MSICOMPONENT)); - - memset(&package->components[index],0,sizeof(MSICOMPONENT)); - sz = IDENTIFIER_SIZE; - MSI_RecordGetStringW(row,1,package->components[index].Component,&sz); + MSI_RecordGetStringW(row,1,comp->Component,&sz);
TRACE("Loading Component %s\n", - debugstr_w(package->components[index].Component)); + debugstr_w(comp->Component));
sz = 0x100; if (!MSI_RecordIsNull(row,2)) - MSI_RecordGetStringW(row,2,package->components[index].ComponentId,&sz); + MSI_RecordGetStringW(row,2,comp->ComponentId,&sz);
sz = IDENTIFIER_SIZE; - MSI_RecordGetStringW(row,3,package->components[index].Directory,&sz); + MSI_RecordGetStringW(row,3,comp->Directory,&sz);
- package->components[index].Attributes = MSI_RecordGetInteger(row,4); + comp->Attributes = MSI_RecordGetInteger(row,4);
sz = 0x100; - MSI_RecordGetStringW(row,5,package->components[index].Condition,&sz); + MSI_RecordGetStringW(row,5,comp->Condition,&sz);
sz = IDENTIFIER_SIZE; - MSI_RecordGetStringW(row,6,package->components[index].KeyPath,&sz); + MSI_RecordGetStringW(row,6,comp->KeyPath,&sz);
- package->components[index].Installed = INSTALLSTATE_ABSENT; - package->components[index].Action = INSTALLSTATE_UNKNOWN; - package->components[index].ActionRequest = INSTALLSTATE_UNKNOWN; + comp->Installed = INSTALLSTATE_ABSENT; + comp->Action = INSTALLSTATE_UNKNOWN; + comp->ActionRequest = INSTALLSTATE_UNKNOWN;
- package->components[index].Enabled = TRUE; + comp->Enabled = TRUE;
- return index; + return comp; }
typedef struct { MSIPACKAGE *package; - INT index; - INT cnt; + MSIFEATURE *feature; } _ilfs;
-static UINT iterate_component_check(MSIRECORD *row, LPVOID param) +static UINT add_feature_component( MSIFEATURE *feature, MSICOMPONENT *comp ) { + ComponentList *cl; + + cl = HeapAlloc( GetProcessHeap(), 0, sizeof (*cl) ); + if ( !cl ) + return ERROR_NOT_ENOUGH_MEMORY; + cl->component = comp; + 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; + MSIPACKAGE *package = ilfs->package; + MSIFEATURE *feature = ilfs->feature; + MSICOMPONENT *comp;
- c_indx = load_component(ilfs->package,row); + comp = load_component( row ); + if (!comp) + return ERROR_FUNCTION_FAILED;
- 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); + list_add_tail( &package->components, &comp->entry ); + add_feature_component( feature, comp );
+ TRACE("Loaded new component %p\n", comp); + return ERROR_SUCCESS; }
@@ -1038,8 +1050,7 @@ _ilfs* ilfs= (_ilfs*)param; LPCWSTR component; DWORD rc; - INT c_indx; - INT cnt = ilfs->package->features[ilfs->index].ComponentCount; + MSICOMPONENT *comp; MSIQUERY * view; static const WCHAR Query[] = {'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ', @@ -1051,13 +1062,11 @@ component = MSI_RecordGetString(row,1);
/* check to see if the component is already loaded */ - c_indx = get_loaded_component(ilfs->package,component); - if (c_indx != -1) + comp = get_loaded_component( ilfs->package, component ); + if (comp) { - 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 ++; + TRACE("Component %s already loaded\n", debugstr_w(component) ); + add_feature_component( ilfs->feature, comp ); return ERROR_SUCCESS; }
@@ -1065,7 +1074,6 @@ if (rc != ERROR_SUCCESS) return ERROR_SUCCESS;
- ilfs->cnt = cnt; rc = MSI_IterateRecords(view, NULL, iterate_component_check, ilfs); msiobj_release( &view->hdr );
@@ -1075,7 +1083,7 @@ static UINT load_feature(MSIRECORD * row, LPVOID param) { MSIPACKAGE* package = (MSIPACKAGE*)param; - int index = package->loaded_features; + MSIFEATURE* feature; DWORD sz; static const WCHAR Query1[] = {'S','E','L','E','C','T',' ', @@ -1088,59 +1096,57 @@ UINT rc; _ilfs ilfs;
- ilfs.package = package; - ilfs.index = index; - /* fill in the data */
- package->loaded_features ++; - if (package->loaded_features == 1) - package->features = HeapAlloc(GetProcessHeap(),0,sizeof(MSIFEATURE)); - else - package->features = HeapReAlloc(GetProcessHeap(),0,package->features, - package->loaded_features * sizeof(MSIFEATURE)); + feature = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (MSIFEATURE) ); + if (!feature) + return ERROR_NOT_ENOUGH_MEMORY;
- memset(&package->features[index],0,sizeof(MSIFEATURE)); + list_init( &feature->Components );
sz = IDENTIFIER_SIZE; - MSI_RecordGetStringW(row,1,package->features[index].Feature,&sz); + MSI_RecordGetStringW(row,1,feature->Feature,&sz);
- TRACE("Loading feature %s\n",debugstr_w(package->features[index].Feature)); + TRACE("Loading feature %s\n",debugstr_w(feature->Feature));
sz = IDENTIFIER_SIZE; if (!MSI_RecordIsNull(row,2)) - MSI_RecordGetStringW(row,2,package->features[index].Feature_Parent,&sz); + MSI_RecordGetStringW(row,2,feature->Feature_Parent,&sz);
sz = 0x100; - if (!MSI_RecordIsNull(row,3)) - MSI_RecordGetStringW(row,3,package->features[index].Title,&sz); + if (!MSI_RecordIsNull(row,3)) + MSI_RecordGetStringW(row,3,feature->Title,&sz);
- sz = 0x100; - if (!MSI_RecordIsNull(row,4)) - MSI_RecordGetStringW(row,4,package->features[index].Description,&sz); + sz = 0x100; + if (!MSI_RecordIsNull(row,4)) + MSI_RecordGetStringW(row,4,feature->Description,&sz);
if (!MSI_RecordIsNull(row,5)) - package->features[index].Display = MSI_RecordGetInteger(row,5); + feature->Display = MSI_RecordGetInteger(row,5);
- package->features[index].Level= MSI_RecordGetInteger(row,6); + feature->Level= MSI_RecordGetInteger(row,6);
- sz = IDENTIFIER_SIZE; - if (!MSI_RecordIsNull(row,7)) - MSI_RecordGetStringW(row,7,package->features[index].Directory,&sz); + sz = IDENTIFIER_SIZE; + if (!MSI_RecordIsNull(row,7)) + MSI_RecordGetStringW(row,7,feature->Directory,&sz);
- package->features[index].Attributes= MSI_RecordGetInteger(row,8); + feature->Attributes = MSI_RecordGetInteger(row,8);
- package->features[index].Installed = INSTALLSTATE_ABSENT; - package->features[index].Action = INSTALLSTATE_UNKNOWN; - package->features[index].ActionRequest = INSTALLSTATE_UNKNOWN; + feature->Installed = INSTALLSTATE_ABSENT; + feature->Action = INSTALLSTATE_UNKNOWN; + feature->ActionRequest = INSTALLSTATE_UNKNOWN;
+ list_add_tail( &package->features, &feature->entry ); + /* load feature components */
- rc = MSI_OpenQuery(package->db, &view, Query1, - package->features[index].Feature); + rc = MSI_OpenQuery( package->db, &view, Query1, feature->Feature ); if (rc != ERROR_SUCCESS) return ERROR_SUCCESS;
+ ilfs.package = package; + ilfs.feature = feature; + MSI_IterateRecords(view, NULL, iterate_load_featurecomponents , &ilfs); msiobj_release(&view->hdr);
@@ -1150,45 +1156,41 @@ static UINT load_file(MSIRECORD *row, LPVOID param) { MSIPACKAGE* package = (MSIPACKAGE*)param; - DWORD index = package->loaded_files; LPCWSTR component; + MSIFILE *file;
/* fill in the data */
- package->loaded_files++; - if (package->loaded_files== 1) - package->files = HeapAlloc(GetProcessHeap(),0,sizeof(MSIFILE)); - else - package->files = HeapReAlloc(GetProcessHeap(),0, - package->files , package->loaded_files * sizeof(MSIFILE)); - - memset(&package->files[index],0,sizeof(MSIFILE)); + file = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (MSIFILE) ); + if (!file) + return ERROR_NOT_ENOUGH_MEMORY;
- package->files[index].File = load_dynamic_stringW(row, 1); + file->File = load_dynamic_stringW( row, 1 );
- component = MSI_RecordGetString(row, 2); - package->files[index].ComponentIndex = get_loaded_component(package, - component); + component = MSI_RecordGetString( row, 2 ); + file->Component = get_loaded_component( package, component );
- if (package->files[index].ComponentIndex == -1) + if (!file->Component) ERR("Unfound Component %s\n",debugstr_w(component));
- package->files[index].FileName = load_dynamic_stringW(row,3); - reduce_to_longfilename(package->files[index].FileName); + file->FileName = load_dynamic_stringW( row, 3 ); + reduce_to_longfilename( file->FileName );
- package->files[index].ShortName = load_dynamic_stringW(row,3); - reduce_to_shortfilename(package->files[index].ShortName); + file->ShortName = load_dynamic_stringW( row, 3 ); + reduce_to_shortfilename( file->ShortName );
- package->files[index].FileSize = MSI_RecordGetInteger(row,4); - package->files[index].Version = load_dynamic_stringW(row, 5); - package->files[index].Language = load_dynamic_stringW(row, 6); - package->files[index].Attributes= MSI_RecordGetInteger(row,7); - package->files[index].Sequence= MSI_RecordGetInteger(row,8); + file->FileSize = MSI_RecordGetInteger( row, 4 ); + file->Version = load_dynamic_stringW( row, 5 ); + file->Language = load_dynamic_stringW( row, 6 ); + file->Attributes = MSI_RecordGetInteger( row, 7 ); + file->Sequence = MSI_RecordGetInteger( row, 8 );
- package->files[index].Temporary = FALSE; - package->files[index].State = 0; + file->Temporary = FALSE; + file->State = 0;
- TRACE("File Loaded (%s)\n",debugstr_w(package->files[index].File)); + TRACE("File Loaded (%s)\n",debugstr_w(file->File)); + + list_add_tail( &package->files, &file->entry );
return ERROR_SUCCESS; } @@ -1292,7 +1294,7 @@ }
-static INT load_folder(MSIPACKAGE *package, const WCHAR* dir) +static MSIFOLDER *load_folder( MSIPACKAGE *package, LPCWSTR dir ) { static const WCHAR Query[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', @@ -1304,38 +1306,25 @@ LPCWSTR parent; LPWSTR shortname = NULL; MSIRECORD * row = 0; - INT index = -1; - DWORD i; + MSIFOLDER *folder;
TRACE("Looking for dir %s\n",debugstr_w(dir));
- for (i = 0; i < package->loaded_folders; i++) - { - if (strcmpW(package->folders[i].Directory,dir)==0) - { - TRACE(" %s retuning on index %lu\n",debugstr_w(dir),i); - return i; - } - } + folder = get_loaded_folder( package, dir ); + if (folder) + return folder;
TRACE("Working to load %s\n",debugstr_w(dir));
- index = package->loaded_folders++; - if (package->loaded_folders==1) - package->folders = HeapAlloc(GetProcessHeap(),0, - sizeof(MSIFOLDER)); - else - package->folders= HeapReAlloc(GetProcessHeap(),0, - package->folders, package->loaded_folders* - sizeof(MSIFOLDER)); + folder = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (MSIFOLDER) ); + if (!folder) + return NULL;
- memset(&package->folders[index],0,sizeof(MSIFOLDER)); + folder->Directory = strdupW(dir);
- package->folders[index].Directory = strdupW(dir); - row = MSI_QueryGetRecord(package->db, Query, dir); if (!row) - return -1; + return NULL;
ptargetdir = targetdir = load_dynamic_stringW(row,3);
@@ -1371,73 +1360,78 @@ if (targetdir) { TRACE(" TargetDefault = %s\n",debugstr_w(targetdir)); - HeapFree(GetProcessHeap(),0, package->folders[index].TargetDefault); - package->folders[index].TargetDefault = strdupW(targetdir); + HeapFree(GetProcessHeap(),0, folder->TargetDefault); + folder->TargetDefault = strdupW(targetdir); }
if (srcdir) - package->folders[index].SourceDefault = strdupW(srcdir); + folder->SourceDefault = strdupW(srcdir); else if (shortname) - package->folders[index].SourceDefault = strdupW(shortname); + folder->SourceDefault = strdupW(shortname); else if (targetdir) - package->folders[index].SourceDefault = strdupW(targetdir); + folder->SourceDefault = strdupW(targetdir); HeapFree(GetProcessHeap(), 0, ptargetdir); - TRACE(" SourceDefault = %s\n",debugstr_w(package->folders[index].SourceDefault)); + TRACE(" SourceDefault = %s\n", debugstr_w( folder->SourceDefault ));
parent = MSI_RecordGetString(row,2); if (parent) { - i = load_folder(package,parent); - package->folders[index].ParentIndex = i; - TRACE("Parent is index %i... %s %s\n", - package->folders[index].ParentIndex, - debugstr_w(package->folders[package->folders[index].ParentIndex].Directo ry), - debugstr_w(parent)); + folder->Parent = load_folder( package, parent ); + if ( folder->Parent ) + TRACE("loaded parent %p %s\n", folder->Parent, + debugstr_w(folder->Parent->Directory)); + else + ERR("failed to load parent folder %s\n", debugstr_w(parent)); } - else - package->folders[index].ParentIndex = -2;
- package->folders[index].Property = load_dynamic_property(package, dir,NULL); + folder->Property = load_dynamic_property( package, dir, NULL );
msiobj_release(&row->hdr); - TRACE(" %s retuning on index %i\n",debugstr_w(dir),index); - return index; + + list_add_tail( &package->folders, &folder->entry ); + + TRACE("%s returning %p\n",debugstr_w(dir),folder); + + return folder; }
/* scan for and update current install states */ static void ACTION_UpdateInstallStates(MSIPACKAGE *package) { - int i; + MSICOMPONENT *comp; + MSIFEATURE *feature;
- for (i = 0; i < package->loaded_components; i++) + LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) { INSTALLSTATE res; - res = MsiGetComponentPathW(package->ProductCode, - package->components[i].ComponentId , NULL, NULL); + res = MsiGetComponentPathW( package->ProductCode, + comp->ComponentId, NULL, NULL); if (res < 0) res = INSTALLSTATE_ABSENT; - package->components[i].Installed = res; + comp->Installed = res; }
- for (i = 0; i < package->loaded_features; i++) + LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { + ComponentList *cl; INSTALLSTATE res = -10; - int j; - for (j = 0; j < package->features[i].ComponentCount; j++) + + LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry ) { - MSICOMPONENT* component = &package->components[package->features[i]. - Components[j]]; + comp= cl->component; + if (res == -10) - res = component->Installed; + res = comp->Installed; else { - if (res == component->Installed) + if (res == comp->Installed) continue;
- if (res != component->Installed) + if (res != comp->Installed) res = INSTALLSTATE_INCOMPLETE; } } + feature->Installed = res; } }
@@ -1446,19 +1440,19 @@ { static const WCHAR all[]={'A','L','L',0}; LPWSTR override = NULL; - INT i; BOOL rc = FALSE; + MSIFEATURE *feature;
override = load_dynamic_property(package, property, NULL); if (override) { rc = TRUE; - for(i = 0; i < package->loaded_features; i++) + LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { if (strcmpiW(override,all)==0) { - package->features[i].ActionRequest= state; - package->features[i].Action = state; + feature->ActionRequest= state; + feature->Action = state; } else { @@ -1468,12 +1462,11 @@ while (ptr) { if ((ptr2 && - strncmpW(ptr,package->features[i].Feature, ptr2-ptr)==0) - || (!ptr2 && - strcmpW(ptr,package->features[i].Feature)==0)) + strncmpW(ptr,feature->Feature, ptr2-ptr)==0) + || (!ptr2 && strcmpW(ptr,feature->Feature)==0)) { - package->features[i].ActionRequest= state; - package->features[i].Action = state; + feature->ActionRequest= state; + feature->Action = state; break; } if (ptr2) @@ -1496,8 +1489,6 @@ { 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[] = @@ -1505,7 +1496,10 @@ static const WCHAR szRemove[] = {'R','E','M','O','V','E',0}; BOOL override = FALSE; + MSICOMPONENT* component; + MSIFEATURE *feature;
+ /* I do not know if this is where it should happen.. but */
TRACE("Checking Install Level\n"); @@ -1546,30 +1540,27 @@
if (!override) { - for(i = 0; i < package->loaded_features; i++) + LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - BOOL feature_state = ((package->features[i].Level > 0) && - (package->features[i].Level <= install_level)); + BOOL feature_state = ((feature->Level > 0) && + (feature->Level <= install_level));
- if ((feature_state) && - (package->features[i].Action == INSTALLSTATE_UNKNOWN)) + if ((feature_state) && (feature->Action == INSTALLSTATE_UNKNOWN)) { - if (package->features[i].Attributes & - msidbFeatureAttributesFavorSource) + if (feature->Attributes & msidbFeatureAttributesFavorSource) { - package->features[i].ActionRequest = INSTALLSTATE_SOURCE; - package->features[i].Action = INSTALLSTATE_SOURCE; + feature->ActionRequest = INSTALLSTATE_SOURCE; + feature->Action = INSTALLSTATE_SOURCE; } - else if (package->features[i].Attributes & - msidbFeatureAttributesFavorAdvertise) + else if (feature->Attributes & msidbFeatureAttributesFavorAdvertise) { - package->features[i].ActionRequest =INSTALLSTATE_ADVERTISED; - package->features[i].Action =INSTALLSTATE_ADVERTISED; + feature->ActionRequest = INSTALLSTATE_ADVERTISED; + feature->Action = INSTALLSTATE_ADVERTISED; } else { - package->features[i].ActionRequest = INSTALLSTATE_LOCAL; - package->features[i].Action = INSTALLSTATE_LOCAL; + feature->ActionRequest = INSTALLSTATE_LOCAL; + feature->Action = INSTALLSTATE_LOCAL; } } } @@ -1587,17 +1578,17 @@ * now we want to enable or disable components base on feature */
- for(i = 0; i < package->loaded_features; i++) + LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - 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]]; + component = cl->component;
if (!component->Enabled) { @@ -1644,10 +1635,8 @@ } }
- for(i = 0; i < package->loaded_components; i++) + LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry ) { - MSICOMPONENT* component= &package->components[i]; - TRACE("Result: Component %s (Installed %i, Action %i, Request %i)\n", debugstr_w(component->Component), component->Installed, component->Action, component->ActionRequest); @@ -1678,14 +1667,14 @@ static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param) { MSIPACKAGE *package = (MSIPACKAGE*)param; - LPCWSTR Feature; - int feature_index; + LPCWSTR name; + MSIFEATURE *feature;
- Feature = MSI_RecordGetString(row,1); + name = MSI_RecordGetString( row, 1 );
- feature_index = get_loaded_feature(package,Feature); - if (feature_index < 0) - ERR("FAILED to find loaded feature %s\n",debugstr_w(Feature)); + feature = get_loaded_feature( package, name ); + if (!feature) + ERR("FAILED to find loaded feature %s\n",debugstr_w(name)); else { LPCWSTR Condition; @@ -1694,9 +1683,8 @@ if (MSI_EvaluateConditionW(package,Condition) == MSICONDITION_TRUE) { int level = MSI_RecordGetInteger(row,2); - TRACE("Reseting feature %s to level %i\n", debugstr_w(Feature), - level); - package->features[feature_index].Level = level; + TRACE("Reseting feature %s to level %i\n", debugstr_w(name), level); + feature->Level = level; } } return ERROR_SUCCESS; @@ -1722,9 +1710,10 @@ static const WCHAR szlevel[] = {'I','N','S','T','A','L','L','L','E','V','E','L',0}; static const WCHAR szOne[] = { '1', 0 }; + MSICOMPONENT *comp; + MSIFILE *file; UINT rc; MSIQUERY * view; - DWORD i; LPWSTR level; DWORD sz = 3; WCHAR buffer[3]; @@ -1743,16 +1732,13 @@ msiobj_release(&view->hdr); }
- TRACE("File calculations %i files\n",package->loaded_files); + TRACE("File calculations\n");
- for (i = 0; i < package->loaded_files; i++) + LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { MSICOMPONENT* comp = NULL; - MSIFILE* file= NULL;
- file = &package->files[i]; - if (file->ComponentIndex >= 0) - comp = &package->components[file->ComponentIndex]; + comp = file->Component;
if (file->Temporary == TRUE) continue; @@ -1838,16 +1824,15 @@ }
TRACE("Enabling or Disabling Components\n"); - for (i = 0; i < package->loaded_components; i++) + LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) { - if (package->components[i].Condition[0]) + if (comp->Condition[0]) { if (MSI_EvaluateConditionW(package, - package->components[i].Condition) == MSICONDITION_FALSE) + comp->Condition) == MSICONDITION_FALSE) { - TRACE("Disabling component %s\n", - debugstr_w(package->components[i].Component)); - package->components[i].Enabled = FALSE; + TRACE("Disabling component %s\n", debugstr_w(comp->Component)); + comp->Enabled = FALSE; } } } @@ -1995,7 +1980,7 @@ DWORD type,size; LPWSTR deformated; LPCWSTR szRoot, component, name, key, value; - INT component_index; + MSICOMPONENT *comp; MSIRECORD * uirow; LPWSTR uikey; INT root; @@ -2010,21 +1995,21 @@ name = NULL;
component = MSI_RecordGetString(row, 6); - component_index = get_loaded_component(package,component); + comp = get_loaded_component(package,component); + if (!comp) + return ERROR_SUCCESS;
- if (!ACTION_VerifyComponentForAction(package, component_index, - INSTALLSTATE_LOCAL)) + if (!ACTION_VerifyComponentForAction(package, comp, INSTALLSTATE_LOCAL)) { TRACE("Skipping write due to disabled component %s\n", debugstr_w(component));
- package->components[component_index].Action = - package->components[component_index].Installed; + comp->Action = comp->Installed;
return ERROR_SUCCESS; }
- package->components[component_index].Action = INSTALLSTATE_LOCAL; + comp->Action = INSTALLSTATE_LOCAL;
name = MSI_RecordGetString(row, 4); if( MSI_RecordIsNull(row,5) && name ) @@ -2192,6 +2177,7 @@
static UINT ACTION_InstallValidate(MSIPACKAGE *package) { + MSICOMPONENT *comp; DWORD progress = 0; DWORD total = 0; static const WCHAR q1[]= @@ -2200,7 +2186,8 @@ UINT rc; MSIQUERY * view; MSIRECORD * row = 0; - int i; + MSIFEATURE *feature; + MSIFILE *file;
TRACE(" InstallValidate \n");
@@ -2231,14 +2218,18 @@ msiobj_release(&view->hdr);
total = total + progress * REG_PROGRESS_VALUE; - total = total + package->loaded_components * COMPONENT_PROGRESS_VALUE; - for (i=0; i < package->loaded_files; i++) - total += package->files[i].FileSize; + LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) + { + total += COMPONENT_PROGRESS_VALUE; + } + LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) + { + total += file->FileSize; + } ui_progress(package,0,total,0,0);
- for(i = 0; i < package->loaded_features; i++) + LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - MSIFEATURE* feature = &package->features[i]; TRACE("Feature: %s; Installed: %i; Action %i; Request %i\n", debugstr_w(feature->Feature), feature->Installed, feature->Action, feature->ActionRequest); @@ -2290,10 +2281,8 @@ return rc; }
-static LPWSTR resolve_keypath( MSIPACKAGE* package, INT - component_index) +static LPWSTR resolve_keypath( MSIPACKAGE* package, MSICOMPONENT *cmp ) { - MSICOMPONENT* cmp = &package->components[component_index];
if (cmp->KeyPath[0]==0) { @@ -2349,14 +2338,10 @@ } else { - int j; - j = get_loaded_file(package,cmp->KeyPath); + MSIFILE *file = get_loaded_file( package, cmp->KeyPath );
- if (j>=0) - { - LPWSTR p = strdupW(package->files[j].TargetPath); - return p; - } + if (file) + return strdupW( file->TargetPath ); } return NULL; } @@ -2408,78 +2393,78 @@ /* * Return TRUE if the count should be written out and FALSE if not */ -static void ACTION_RefCountComponent( MSIPACKAGE* package, UINT index) +static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp ) { + MSIFEATURE *feature; INT count = 0; BOOL write = FALSE; - INT j;
/* only refcount DLLs */ - if (package->components[index].KeyPath[0]==0 || - package->components[index].Attributes & - msidbComponentAttributesRegistryKeyPath || - package->components[index].Attributes & - msidbComponentAttributesODBCDataSource) + if (comp->KeyPath[0]==0 || + comp->Attributes & msidbComponentAttributesRegistryKeyPath || + comp->Attributes & msidbComponentAttributesODBCDataSource) write = FALSE; else { - count = ACTION_GetSharedDLLsCount(package->components[index]. - FullKeypath); + count = ACTION_GetSharedDLLsCount( comp->FullKeypath); write = (count > 0);
- if (package->components[index].Attributes & - msidbComponentAttributesSharedDllRefCount) + if (comp->Attributes & msidbComponentAttributesSharedDllRefCount) write = TRUE; }
/* increment counts */ - for (j = 0; j < package->loaded_features; j++) + LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - int i; + ComponentList *cl;
- if (!ACTION_VerifyFeatureForAction(package,j,INSTALLSTATE_LOCAL)) + if (!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_LOCAL )) continue;
- for (i = 0; i < package->features[j].ComponentCount; i++) + LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry ) { - if (package->features[j].Components[i] == index) + if ( cl->component == comp ) count++; } } + /* decrement counts */ - for (j = 0; j < package->loaded_features; j++) + LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - int i; - if (!ACTION_VerifyFeatureForAction(package,j,INSTALLSTATE_ABSENT)) + ComponentList *cl; + + if (!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ABSENT )) continue;
- for (i = 0; i < package->features[j].ComponentCount; i++) + LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry ) { - if (package->features[j].Components[i] == index) + if ( cl->component == comp ) count--; } }
/* ref count all the files in the component */ if (write) - for (j = 0; j < package->loaded_files; j++) + { + MSIFILE *file; + + LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { - if (package->files[j].Temporary) + if (file->Temporary) continue; - if (package->files[j].ComponentIndex == index) - ACTION_WriteSharedDLLsCount(package->files[j].TargetPath,count); + if (file->Component == comp) + ACTION_WriteSharedDLLsCount( file->TargetPath, count ); } + }
/* add a count for permenent */ - if (package->components[index].Attributes & - msidbComponentAttributesPermanent) + if (comp->Attributes & msidbComponentAttributesPermanent) count ++;
- package->components[index].RefCount = count; + comp->RefCount = count;
if (write) - ACTION_WriteSharedDLLsCount(package->components[index].FullKeypath, - package->components[index].RefCount); + ACTION_WriteSharedDLLsCount( comp->FullKeypath, comp->RefCount ); }
/* @@ -2494,7 +2479,7 @@ WCHAR squished_pc[GUID_SIZE]; WCHAR squished_cc[GUID_SIZE]; UINT rc; - DWORD i; + MSICOMPONENT *comp; HKEY hkey=0,hkey2=0;
if (!package) @@ -2508,32 +2493,33 @@
squash_guid(package->ProductCode,squished_pc); ui_progress(package,1,COMPONENT_PROGRESS_VALUE,1,0); - for (i = 0; i < package->loaded_components; i++) + + LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) { ui_progress(package,2,0,0,0); - if (package->components[i].ComponentId[0]!=0) + if (comp->ComponentId[0]!=0) { WCHAR *keypath = NULL; MSIRECORD * uirow;
- squash_guid(package->components[i].ComponentId,squished_cc); + squash_guid(comp->ComponentId,squished_cc);
- keypath = resolve_keypath(package,i); - package->components[i].FullKeypath = keypath; + keypath = resolve_keypath( package, comp ); + comp->FullKeypath = keypath;
/* do the refcounting */ - ACTION_RefCountComponent( package, i); + ACTION_RefCountComponent( package, comp ); [truncated at 1000 lines; 4574 more skipped]