- build a standard Wine list of components instead of using an array
- use component pointers instead of array indexes

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 1140577..be12ed5 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -965,52 +965,44 @@
     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 {
@@ -1018,28 +1010,33 @@
     INT index;
 } _ilfs;
 
-static UINT add_feature_component( MSIFEATURE *feature, int index )
+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 = index;
+    cl->component = comp;
     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;
-    INT c_indx;
+    MSIPACKAGE *package = ilfs->package;
+    MSICOMPONENT *comp;
 
-    c_indx = load_component(ilfs->package,row);
-    add_feature_component( &ilfs->package->features[ilfs->index], c_indx );
+    comp = load_component( row );
+    if (!comp)
+        return ERROR_FUNCTION_FAILED;
 
-    TRACE("Loaded new component to index %i\n",c_indx);
+    list_add_tail( &package->components, &comp->entry );
+    add_feature_component( &package->features[ilfs->index], comp );
+
+    TRACE("Loaded new component %p\n", comp);
 
     return ERROR_SUCCESS;
 }
@@ -1049,7 +1046,7 @@
     _ilfs* ilfs= (_ilfs*)param;
     LPCWSTR component;
     DWORD rc;
-    INT c_indx;
+    MSICOMPONENT *comp;
     MSIQUERY * view;
     static const WCHAR Query[] = 
         {'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ', 
@@ -1061,12 +1058,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);
-        add_feature_component( &ilfs->package->features[ilfs->index], c_indx );
+        TRACE("Component %s already loaded\n", debugstr_w(component) );
+        add_feature_component( &ilfs->package->features[ilfs->index], comp );
         return ERROR_SUCCESS;
     }
 
@@ -1183,10 +1179,10 @@
     package->files[index].File = load_dynamic_stringW(row, 1);
 
     component = MSI_RecordGetString(row, 2);
-    package->files[index].ComponentIndex = get_loaded_component(package,
+    package->files[index].Component = get_loaded_component(package,
                     component);
 
-    if (package->files[index].ComponentIndex == -1)
+    if (!package->files[index].Component)
         ERR("Unfound Component %s\n",debugstr_w(component));
 
     package->files[index].FileName = load_dynamic_stringW(row,3);
@@ -1423,16 +1419,17 @@
 /* scan for and update current install states */
 static void ACTION_UpdateInstallStates(MSIPACKAGE *package)
 {
+    MSICOMPONENT *comp;
     int i;
 
-    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++)
@@ -1443,16 +1440,16 @@
         LIST_FOR_EACH_ENTRY( cl, package->features[i].Components,
                              ComponentList, entry )
         {
-            MSICOMPONENT* component = &package->components[cl->component];
+            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;
             }
         }
@@ -1522,6 +1519,7 @@
     static const WCHAR szRemove[] =
         {'R','E','M','O','V','E',0};
     BOOL override = FALSE;
+    MSICOMPONENT* component;
 
     /* I do not know if this is where it should happen.. but */
 
@@ -1615,7 +1613,7 @@
 
         LIST_FOR_EACH_ENTRY( cl, feature->Components, ComponentList, entry )
         {
-            MSICOMPONENT* component = &package->components[cl->component];
+            component = cl->component;
 
             if (!component->Enabled)
             {
@@ -1662,10 +1660,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);
@@ -1740,6 +1736,7 @@
     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;
     UINT rc;
     MSIQUERY * view;
     DWORD i;
@@ -1769,8 +1766,7 @@
         MSIFILE* file= NULL;
 
         file = &package->files[i];
-        if (file->ComponentIndex >= 0)
-            comp = &package->components[file->ComponentIndex];
+        comp = file->Component;
 
         if (file->Temporary == TRUE)
             continue;
@@ -1856,16 +1852,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;
             }
         }
     }
@@ -2013,7 +2008,7 @@
     DWORD type,size;
     LPWSTR  deformated;
     LPCWSTR szRoot, component, name, key, value;
-    INT component_index;
+    MSICOMPONENT *comp;
     MSIRECORD * uirow;
     LPWSTR uikey;
     INT   root;
@@ -2028,21 +2023,19 @@
     name = NULL;
 
     component = MSI_RecordGetString(row, 6);
-    component_index = get_loaded_component(package,component);
+    comp = get_loaded_component(package,component);
 
-    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 )
@@ -2210,6 +2203,7 @@
 
 static UINT ACTION_InstallValidate(MSIPACKAGE *package)
 {
+    MSICOMPONENT *comp;
     DWORD progress = 0;
     DWORD total = 0;
     static const WCHAR q1[]=
@@ -2249,7 +2243,10 @@
     msiobj_release(&view->hdr);
 
     total = total + progress * REG_PROGRESS_VALUE;
-    total = total + package->loaded_components * COMPONENT_PROGRESS_VALUE;
+    LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
+    {
+        total += COMPONENT_PROGRESS_VALUE;
+    }
     for (i=0; i < package->loaded_files; i++)
         total += package->files[i].FileSize;
     ui_progress(package,0,total,0,0);
@@ -2308,10 +2305,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)
     {
@@ -2426,27 +2421,23 @@
 /*
  * 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 )
 {
     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;
     }
 
@@ -2461,7 +2452,7 @@
         LIST_FOR_EACH_ENTRY( cl, package->features[j].Components,
                              ComponentList, entry )
         {
-            if ( cl->component == index )
+            if ( cl->component == comp )
                 count++;
         }
     }
@@ -2476,7 +2467,7 @@
         LIST_FOR_EACH_ENTRY( cl, package->features[j].Components,
                              ComponentList, entry )
         {
-            if ( cl->component == index )
+            if ( cl->component == comp )
                 count--;
         }
     }
@@ -2487,20 +2478,18 @@
         {
             if (package->files[j].Temporary)
                 continue;
-            if (package->files[j].ComponentIndex == index)
+            if (package->files[j].Component == comp)
                 ACTION_WriteSharedDLLsCount(package->files[j].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 );
 }
 
 /*
@@ -2515,7 +2504,7 @@
     WCHAR squished_pc[GUID_SIZE];
     WCHAR squished_cc[GUID_SIZE];
     UINT rc;
-    DWORD i;
+    MSICOMPONENT *comp;
     HKEY hkey=0,hkey2=0;
 
     if (!package)
@@ -2529,32 +2518,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 );
 
             TRACE("Component %s (%s), Keypath=%s, RefCount=%i\n", 
-                            debugstr_w(package->components[i].Component),
+                            debugstr_w(comp->Component),
                             debugstr_w(squished_cc),
-                            debugstr_w(package->components[i].FullKeypath), 
-                            package->components[i].RefCount);
+                            debugstr_w(comp->FullKeypath), 
+                            comp->RefCount);
             /*
             * Write the keypath out if the component is to be registered
             * and delete the key if the component is to be deregistered
             */
-            if (ACTION_VerifyComponentForAction(package, i,
+            if (ACTION_VerifyComponentForAction(package, comp,
                                     INSTALLSTATE_LOCAL))
             {
                 rc = RegCreateKeyW(hkey,squished_cc,&hkey2);
@@ -2566,8 +2556,7 @@
                     RegSetValueExW(hkey2,squished_pc,0,REG_SZ,(LPBYTE)keypath,
                                 (strlenW(keypath)+1)*sizeof(WCHAR));
 
-                    if (package->components[i].Attributes & 
-                                msidbComponentAttributesPermanent)
+                    if (comp->Attributes & msidbComponentAttributesPermanent)
                     {
                         static const WCHAR szPermKey[] =
                             { '0','0','0','0','0','0','0','0','0','0','0','0',
@@ -2584,14 +2573,13 @@
                     /* UI stuff */
                     uirow = MSI_CreateRecord(3);
                     MSI_RecordSetStringW(uirow,1,package->ProductCode);
-                    MSI_RecordSetStringW(uirow,2,package->components[i].
-                                                            ComponentId);
+                    MSI_RecordSetStringW(uirow,2,comp->ComponentId);
                     MSI_RecordSetStringW(uirow,3,keypath);
                     ui_actiondata(package,szProcessComponents,uirow);
                     msiobj_release( &uirow->hdr );
                }
             }
-            else if (ACTION_VerifyComponentForAction(package, i,
+            else if (ACTION_VerifyComponentForAction(package, comp,
                                     INSTALLSTATE_ABSENT))
             {
                 DWORD res;
@@ -2611,8 +2599,7 @@
                 /* UI stuff */
                 uirow = MSI_CreateRecord(2);
                 MSI_RecordSetStringW(uirow,1,package->ProductCode);
-                MSI_RecordSetStringW(uirow,2,package->components[i].
-                                ComponentId);
+                MSI_RecordSetStringW(uirow,2,comp->ComponentId);
                 ui_actiondata(package,szProcessComponents,uirow);
                 msiobj_release( &uirow->hdr );
             }
@@ -2688,28 +2675,28 @@
     MSIPACKAGE* package = (MSIPACKAGE*)param;
     LPCWSTR component;
     INT index;
+    MSICOMPONENT *comp;
     typelib_struct tl_struct;
     HMODULE module;
     static const WCHAR szTYPELIB[] = {'T','Y','P','E','L','I','B',0};
 
     component = MSI_RecordGetString(row,3);
-    index = get_loaded_component(package,component);
-    if (index < 0)
+    comp = get_loaded_component(package,component);
+    if (!comp)
         return ERROR_SUCCESS;
 
-    if (!ACTION_VerifyComponentForAction(package, index, INSTALLSTATE_LOCAL))
+    if (!ACTION_VerifyComponentForAction(package, comp, INSTALLSTATE_LOCAL))
     {
         TRACE("Skipping typelib reg due to disabled component\n");
 
-        package->components[index].Action =
-            package->components[index].Installed;
+        comp->Action = comp->Installed;
 
         return ERROR_SUCCESS;
     }
 
-    package->components[index].Action = INSTALLSTATE_LOCAL;
+    comp->Action = INSTALLSTATE_LOCAL;
 
-    index = get_loaded_file(package,package->components[index].KeyPath); 
+    index = get_loaded_file(package,comp->KeyPath); 
 
     if (index < 0)
         return ERROR_SUCCESS;
@@ -2801,29 +2788,27 @@
     LPCWSTR buffer;
     WCHAR filename[0x100];
     DWORD sz;
-    DWORD index;
+    MSICOMPONENT *comp;
     static const WCHAR szlnk[]={'.','l','n','k',0};
     IShellLinkW *sl;
     IPersistFile *pf;
     HRESULT res;
 
     buffer = MSI_RecordGetString(row,4);
-    index = get_loaded_component(package,buffer);
-
-    if (index < 0)
+    comp = get_loaded_component(package,buffer);
+    if (!comp)
         return ERROR_SUCCESS;
 
-    if (!ACTION_VerifyComponentForAction(package, index, INSTALLSTATE_LOCAL))
+    if (!ACTION_VerifyComponentForAction(package, comp, INSTALLSTATE_LOCAL))
     {
         TRACE("Skipping shortcut creation due to disabled component\n");
 
-        package->components[index].Action =
-                package->components[index].Installed;
+        comp->Action = comp->Installed;
 
         return ERROR_SUCCESS;
     }
 
-    package->components[index].Action = INSTALLSTATE_LOCAL;
+    comp->Action = INSTALLSTATE_LOCAL;
 
     ui_actiondata(package,szCreateShortcuts,row);
 
@@ -2869,7 +2854,7 @@
     {
         LPWSTR keypath;
         FIXME("poorly handled shortcut format, advertised shortcut\n");
-        keypath = strdupW(package->components[index].FullKeypath);
+        keypath = strdupW( comp->FullKeypath );
         IShellLinkW_SetPath(sl,keypath);
         HeapFree(GetProcessHeap(),0,keypath);
     }
@@ -3146,26 +3131,25 @@
     LPWSTR deformated_section, deformated_key, deformated_value;
     LPWSTR folder, fullname = NULL;
     MSIRECORD * uirow;
-    INT component_index,action;
+    INT action;
+    MSICOMPONENT *comp;
     static const WCHAR szWindowsFolder[] =
           {'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
 
     component = MSI_RecordGetString(row, 8);
-    component_index = get_loaded_component(package,component);
+    comp = get_loaded_component(package,component);
 
-    if (!ACTION_VerifyComponentForAction(package, component_index,
-                            INSTALLSTATE_LOCAL))
+    if (!ACTION_VerifyComponentForAction(package, comp, INSTALLSTATE_LOCAL))
     {
         TRACE("Skipping ini file 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;
 
     identifier = MSI_RecordGetString(row,1); 
     filename = MSI_RecordGetString(row,2);
@@ -3371,7 +3355,7 @@
         LIST_FOR_EACH_ENTRY( cl, package->features[i].Components,
                              ComponentList, entry )
         {
-            MSICOMPONENT* component = &package->components[cl->component];
+            MSICOMPONENT* component = cl->component;
             WCHAR buf[21];
 
             memset(buf,0,sizeof(buf));
@@ -4000,7 +3984,7 @@
 
     /* check to make sure that component is installed */
     if (!ACTION_VerifyComponentForAction(package, 
-                package->files[index].ComponentIndex, INSTALLSTATE_LOCAL))
+                package->files[index].Component, INSTALLSTATE_LOCAL))
     {
         TRACE("Skipping: Component not scheduled for install\n");
         return ERROR_SUCCESS;
@@ -4062,18 +4046,15 @@
     LPWSTR output = NULL;
     HKEY hkey;
     UINT rc = ERROR_SUCCESS;
-    UINT index;
+    MSICOMPONENT *comp;
     DWORD sz = 0;
 
     component = MSI_RecordGetString(rec,3);
-    index = get_loaded_component(package,component);
+    comp = get_loaded_component(package,component);
 
-    if (!ACTION_VerifyComponentForAction(package, index,
-                            INSTALLSTATE_LOCAL) && 
-       !ACTION_VerifyComponentForAction(package, index,
-                            INSTALLSTATE_SOURCE) &&
-       !ACTION_VerifyComponentForAction(package, index,
-                            INSTALLSTATE_ADVERTISED))
+    if (!ACTION_VerifyComponentForAction(package, comp, INSTALLSTATE_LOCAL) && 
+       !ACTION_VerifyComponentForAction(package, comp, INSTALLSTATE_SOURCE) &&
+       !ACTION_VerifyComponentForAction(package, comp, INSTALLSTATE_ADVERTISED))
     {
         TRACE("Skipping: Component %s not scheduled for install\n",
                         debugstr_w(component));
@@ -4091,8 +4072,7 @@
     qualifier = MSI_RecordGetString(rec,2);
     feature = MSI_RecordGetString(rec,5);
   
-    advertise = create_component_advertise_string(package, 
-                    &package->components[index], feature);
+    advertise = create_component_advertise_string(package, comp, feature);
 
     sz = strlenW(advertise);
 
diff --git a/dlls/msi/action.h b/dlls/msi/action.h
index 47ba17b..babdcce 100644
--- a/dlls/msi/action.h
+++ b/dlls/msi/action.h
@@ -44,6 +44,8 @@
 
 typedef struct tagMSICOMPONENT
 {
+    struct list entry;
+    DWORD magic;
     WCHAR Component[IDENTIFIER_SIZE];
     WCHAR ComponentId[IDENTIFIER_SIZE];
     WCHAR Directory[IDENTIFIER_SIZE];
@@ -66,7 +68,7 @@
 typedef struct tagComponentList
 {
     struct list entry;
-    int component;
+    MSICOMPONENT *component;
 } ComponentList;
 
 typedef struct tagMSIFOLDER
@@ -91,7 +93,7 @@
 typedef struct tagMSIFILE
 {
     LPWSTR File;
-    INT ComponentIndex;
+    MSICOMPONENT *Component;
     LPWSTR FileName;
     LPWSTR ShortName;
     INT FileSize;
@@ -115,7 +117,7 @@
 {
     WCHAR CLSID[IDENTIFIER_SIZE];     /* Primary Key */
     WCHAR Context[IDENTIFIER_SIZE];   /* Primary Key */
-    INT ComponentIndex;               /* Primary Key */
+    MSICOMPONENT *Component;
     INT ProgIDIndex;
     LPWSTR ProgIDText;
     LPWSTR Description;
@@ -134,7 +136,7 @@
 typedef struct tagMSIEXTENSION
 {
     WCHAR Extension[256];  /* Primary Key */
-    INT ComponentIndex;    /* Primary Key */
+    MSICOMPONENT *Component;
     INT ProgIDIndex;
     LPWSTR ProgIDText;
     INT MIMEIndex;
@@ -233,7 +235,7 @@
 LPWSTR load_dynamic_property(MSIPACKAGE *package, LPCWSTR prop, UINT* rc);
 LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, 
                       BOOL set_prop, MSIFOLDER **folder);
-int get_loaded_component(MSIPACKAGE* package, LPCWSTR Component );
+MSICOMPONENT *get_loaded_component( MSIPACKAGE* package, LPCWSTR Component );
 int get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature );
 int get_loaded_file(MSIPACKAGE* package, LPCWSTR file);
 int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path);
@@ -242,7 +244,7 @@
 DWORD build_version_dword(LPCWSTR);
 LPWSTR build_directory_name(DWORD , ...);
 BOOL create_full_pathW(const WCHAR *path);
-BOOL ACTION_VerifyComponentForAction(MSIPACKAGE*, INT, INSTALLSTATE);
+BOOL ACTION_VerifyComponentForAction(MSIPACKAGE*, MSICOMPONENT*, INSTALLSTATE);
 BOOL ACTION_VerifyFeatureForAction(MSIPACKAGE*, INT, INSTALLSTATE);
 void reduce_to_longfilename(WCHAR*);
 void reduce_to_shortfilename(WCHAR*);
diff --git a/dlls/msi/classes.c b/dlls/msi/classes.c
index ed0f550..d453818 100644
--- a/dlls/msi/classes.c
+++ b/dlls/msi/classes.c
@@ -253,8 +253,7 @@
     sz = IDENTIFIER_SIZE;
     MSI_RecordGetStringW(row, 2, package->classes[index].Context, &sz);
     buffer = MSI_RecordGetString(row,3);
-    package->classes[index].ComponentIndex = get_loaded_component(package, 
-                    buffer);
+    package->classes[index].Component = get_loaded_component(package, buffer);
 
     package->classes[index].ProgIDText = load_dynamic_stringW(row,4);
     package->classes[index].ProgIDIndex = 
@@ -466,8 +465,7 @@
                     debugstr_w(package->extensions[index].Extension));
 
     buffer = MSI_RecordGetString(row,2);
-    package->extensions[index].ComponentIndex = 
-            get_loaded_component(package,buffer);
+    package->extensions[index].Component = get_loaded_component(package,buffer);
 
     package->extensions[index].ProgIDText = load_dynamic_stringW(row,3);
     package->extensions[index].ProgIDIndex = load_given_progid(package,
@@ -574,10 +572,10 @@
 
 static UINT iterate_all_classes(MSIRECORD *rec, LPVOID param)
 {
+    MSICOMPONENT *comp;
     LPCWSTR clsid;
     LPCWSTR context;
     LPCWSTR buffer;
-    INT    component_index;
     MSIPACKAGE* package =(MSIPACKAGE*)param;
     INT i;
     BOOL match = FALSE;
@@ -585,7 +583,7 @@
     clsid = MSI_RecordGetString(rec,1);
     context = MSI_RecordGetString(rec,2);
     buffer = MSI_RecordGetString(rec,3);
-    component_index = get_loaded_component(package,buffer);
+    comp = get_loaded_component(package,buffer);
 
     for (i = 0; i < package->loaded_classes; i++)
     {
@@ -593,7 +591,7 @@
             continue;
         if (strcmpW(context,package->classes[i].Context))
             continue;
-        if (component_index == package->classes[i].ComponentIndex)
+        if (comp == package->classes[i].Component)
         {
             match = TRUE;
             break;
@@ -625,22 +623,22 @@
 
 static UINT iterate_all_extensions(MSIRECORD *rec, LPVOID param)
 {
+    MSICOMPONENT *comp;
     LPCWSTR buffer;
     LPCWSTR extension;
-    INT    component_index;
     MSIPACKAGE* package =(MSIPACKAGE*)param;
     BOOL match = FALSE;
     INT i;
 
     extension = MSI_RecordGetString(rec,1);
     buffer = MSI_RecordGetString(rec,2);
-    component_index = get_loaded_component(package,buffer);
+    comp = get_loaded_component(package,buffer);
 
     for (i = 0; i < package->loaded_extensions; i++)
     {
         if (strcmpiW(extension,package->extensions[i].Extension))
             continue;
-        if (component_index == package->extensions[i].ComponentIndex)
+        if (comp == package->extensions[i].Component)
         {
             match = TRUE;
             break;
@@ -920,16 +918,15 @@
     
     for (i = 0; i < package->loaded_classes; i++)
     {
-        INT index,f_index;
+        MSICOMPONENT *comp;
+        INT index, f_index;
         DWORD size, sz;
         LPWSTR argument;
 
-        if (package->classes[i].ComponentIndex < 0)
-        {
+        comp = package->classes[i].Component;
+        if ( !comp )
             continue;
-        }
 
-        index = package->classes[i].ComponentIndex;
         f_index = package->classes[i].FeatureIndex;
 
         /* 
@@ -963,7 +960,7 @@
                                      Description)+1)*sizeof(WCHAR));
 
         RegCreateKeyW(hkey2,package->classes[i].Context,&hkey3);
-        index = get_loaded_file(package,package->components[index].KeyPath);
+        index = get_loaded_file( package, comp->KeyPath );
 
 
         /* the context server is a short path name 
@@ -1425,14 +1422,13 @@
     for (i = 0; i < package->loaded_extensions; i++)
     {
         WCHAR extension[257];
-        INT index,f_index;
+        INT f_index;
      
-        index = package->extensions[i].ComponentIndex;
-        f_index = package->extensions[i].FeatureIndex;
-
-        if (index < 0)
+        if (!package->extensions[i].Component)
             continue;
 
+        f_index = package->extensions[i].FeatureIndex;
+
         /* 
          * yes. MSDN says that these are based on _Feature_ not on
          * Component.  So verify the feature is to be installed
@@ -1512,7 +1508,7 @@
             /* do all the verbs */
             for (v = 0; v < package->extensions[i].VerbCount; v++)
                 register_verb(package, progid, 
-                              &package->components[index],
+                              package->extensions[i].Component,
                               &package->extensions[i],
                               &package->verbs[package->extensions[i].Verbs[v]], 
                               &Sequence);
diff --git a/dlls/msi/files.c b/dlls/msi/files.c
index c7f0862..9cc79c0 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -56,14 +56,13 @@
 
 static const WCHAR cszTempFolder[]= {'T','e','m','p','F','o','l','d','e','r',0};
 
-inline static UINT create_component_directory ( MSIPACKAGE* package, INT component)
+static UINT create_component_directory( MSIPACKAGE* package, MSICOMPONENT *comp )
 {
     UINT rc = ERROR_SUCCESS;
     MSIFOLDER *folder;
     LPWSTR install_path;
 
-    install_path = resolve_folder(package, package->components[component].Directory,
-                        FALSE, FALSE, &folder);
+    install_path = resolve_folder(package, comp->Directory, FALSE, FALSE, &folder);
     if (!install_path)
         return ERROR_FUNCTION_FAILED; 
 
@@ -683,7 +682,7 @@
         if (file->Temporary)
             continue;
 
-        if (!ACTION_VerifyComponentForAction(package, file->ComponentIndex, 
+        if (!ACTION_VerifyComponentForAction(package, file->Component, 
                                        INSTALLSTATE_LOCAL))
         {
             ui_progress(package,2,file->FileSize,0,0);
@@ -700,13 +699,12 @@
 
             TRACE("Pass 1: %s\n",debugstr_w(file->File));
 
-            create_component_directory( package, file->ComponentIndex);
+            create_component_directory( package, file->Component );
 
             /* recalculate file paths because things may have changed */
 
-            if (file->ComponentIndex >= 0)
-                comp = &package->components[file->ComponentIndex];
-            else
+            comp = file->Component;
+            if (!comp)
             {
                 ERR("No Component for file\n");
                 continue;
@@ -724,7 +722,6 @@
     for (index = 0; index < package->loaded_files; index++)
     {
         MSIFILE *file;
-        MSICOMPONENT* comp = NULL;
 
         file = &package->files[index];
 
@@ -735,10 +732,7 @@
         {
             TRACE("Pass 2: %s\n",debugstr_w(file->File));
 
-            if (file->ComponentIndex >= 0)
-                comp = &package->components[file->ComponentIndex];
-
-            rc = ready_media_for_file(package, index, comp);
+            rc = ready_media_for_file( package, index, file->Component );
             if (rc != ERROR_SUCCESS)
             {
                 ERR("Unable to ready media\n");
@@ -808,27 +802,25 @@
     WCHAR dest_name[0x100];
     LPWSTR dest_path, dest;
     LPCWSTR file_key, component;
-    INT component_index;
     DWORD sz;
     DWORD rc;
+    MSICOMPONENT *comp;
 
     component = MSI_RecordGetString(row,2);
-    component_index = get_loaded_component(package,component);
+    comp = get_loaded_component(package,component);
 
-    if (!ACTION_VerifyComponentForAction(package, component_index,
-                            INSTALLSTATE_LOCAL))
+    if (!ACTION_VerifyComponentForAction(package, comp, INSTALLSTATE_LOCAL))
     {
         TRACE("Skipping copy due to disabled component %s\n",
                         debugstr_w(component));
 
         /* the action taken was the same as the current install state */        
-        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;
 
     file_key = MSI_RecordGetString(row,3);
     if (!file_key)
diff --git a/dlls/msi/format.c b/dlls/msi/format.c
index 4bd8f98..373e425 100644
--- a/dlls/msi/format.c
+++ b/dlls/msi/format.c
@@ -79,18 +79,17 @@
 static LPWSTR deformat_component(MSIPACKAGE* package, LPCWSTR key, DWORD* sz)
 {
     LPWSTR value = NULL;
-    INT index;
+    MSICOMPONENT *comp;
 
     *sz = 0;
     if (!package)
         return NULL;
 
     ERR("POORLY HANDLED DEFORMAT.. [$componentkey] \n");
-    index = get_loaded_component(package,key);
-    if (index >= 0)
+    comp = get_loaded_component(package,key);
+    if (comp)
     {
-        value = resolve_folder(package, package->components[index].Directory, 
-                                       FALSE, FALSE, NULL);
+        value = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL);
         *sz = (strlenW(value)) * sizeof(WCHAR);
     }
 
diff --git a/dlls/msi/helpers.c b/dlls/msi/helpers.c
index 10056ff..51a5184 100644
--- a/dlls/msi/helpers.c
+++ b/dlls/msi/helpers.c
@@ -167,20 +167,16 @@
     return str;
 }
 
-int get_loaded_component(MSIPACKAGE* package, LPCWSTR Component )
+MSICOMPONENT* get_loaded_component( MSIPACKAGE* package, LPCWSTR Component )
 {
-    int rc = -1;
-    DWORD i;
+    MSICOMPONENT *comp = NULL;
 
-    for (i = 0; i < package->loaded_components; i++)
+    LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
     {
-        if (strcmpW(Component,package->components[i].Component)==0)
-        {
-            rc = i;
-            break;
-        }
+        if (lstrcmpW(Component,comp->Component)==0)
+            return comp;
     }
-    return rc;
+    return NULL;
 }
 
 int get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature )
@@ -487,11 +483,14 @@
     if (package->folders && package->loaded_folders > 0)
         HeapFree(GetProcessHeap(),0,package->folders);
 
-    for (i = 0; i < package->loaded_components; i++)
-        HeapFree(GetProcessHeap(),0,package->components[i].FullKeypath);
-
-    if (package->components && package->loaded_components > 0)
-        HeapFree(GetProcessHeap(),0,package->components);
+    LIST_FOR_EACH_SAFE( item, cursor, &package->components )
+    {
+        MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );
+        
+        list_remove( &comp->entry );
+        HeapFree( GetProcessHeap(), 0, comp->FullKeypath );
+        HeapFree( GetProcessHeap(), 0, comp );
+    }
 
     for (i = 0; i < package->loaded_files; i++)
     {
@@ -762,13 +761,13 @@
     msiobj_release(&row->hdr);
 }
 
-BOOL ACTION_VerifyComponentForAction(MSIPACKAGE* package, INT index, 
+BOOL ACTION_VerifyComponentForAction(MSIPACKAGE* package, MSICOMPONENT* comp,
                                             INSTALLSTATE check )
 {
-    if (package->components[index].Installed == check)
+    if (comp->Installed == check)
         return FALSE;
 
-    if (package->components[index].ActionRequest == check)
+    if (comp->ActionRequest == check)
         return TRUE;
     else
         return FALSE;
@@ -867,8 +866,8 @@
 
     LIST_FOR_EACH_ENTRY( cl, feature->Components, ComponentList, entry )
     {
-        MSICOMPONENT* component = &package->components[cl->component];
-
+        MSICOMPONENT* component = cl->component;
+    
         TRACE("MODIFYING(%i): Component %s (Installed %i, Action %i, Request %i)\n",
             newstate, debugstr_w(component->Component), component->Installed, 
             component->Action, component->ActionRequest);
diff --git a/dlls/msi/install.c b/dlls/msi/install.c
index 78f02d0..25c5de3 100644
--- a/dlls/msi/install.c
+++ b/dlls/msi/install.c
@@ -545,20 +545,20 @@
 UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPWSTR szComponent,
                   INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
 {
-    INT index;
+    MSICOMPONENT *comp;
 
     TRACE("%p %s %p %p\n", package, debugstr_w(szComponent), piInstalled,
 piAction);
 
-    index = get_loaded_component(package,szComponent);
-    if (index < 0)
+    comp = get_loaded_component(package,szComponent);
+    if (!comp)
         return ERROR_UNKNOWN_COMPONENT;
 
     if (piInstalled)
-        *piInstalled = package->components[index].Installed;
+        *piInstalled = comp->Installed;
 
     if (piAction)
-        *piAction = package->components[index].Action;
+        *piAction = comp->Action;
 
     TRACE("states (%i, %i)\n",
 (piInstalled)?*piInstalled:-1,(piAction)?*piAction:-1);
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 6731010..28d16ef 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -190,8 +190,7 @@
     UINT loaded_features;
     struct tagMSIFOLDER  *folders;
     UINT loaded_folders;
-    struct tagMSICOMPONENT *components;
-    UINT loaded_components;
+    struct list components;
     struct tagMSIFILE *files;
     UINT loaded_files;
     LPWSTR ActionFormat;
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index d3114df..2b910f9 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -379,11 +379,10 @@
         package->db = db;
         package->features = NULL;
         package->folders = NULL;
-        package->components = NULL;
+        list_init( &package->components );
         package->files = NULL;
         package->loaded_features = 0;
         package->loaded_folders = 0;
-        package->loaded_components= 0;
         package->loaded_files = 0;
         package->ActionFormat = NULL;
         package->LastAction = NULL;