- build a standard Wine list of folders instead of using an array
- use folder pointers instead of array indexes

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 76bb0cb..f0f4bc9 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -1291,7 +1291,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',' ',
@@ -1303,38 +1303,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));
-
-    package->folders[index].Directory = strdupW(dir);
+    folder->Directory = strdupW(dir);
 
     row = MSI_QueryGetRecord(package->db, Query, dir);
     if (!row)
-        return -1;
+        return NULL;
 
     ptargetdir = targetdir = load_dynamic_stringW(row,3);
 
@@ -1370,37 +1357,39 @@
     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].Directory),
-                    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 */
diff --git a/dlls/msi/action.h b/dlls/msi/action.h
index abdadec..77ae48a 100644
--- a/dlls/msi/action.h
+++ b/dlls/msi/action.h
@@ -74,6 +74,7 @@
 
 typedef struct tagMSIFOLDER
 {
+    struct list entry;
     LPWSTR Directory;
     LPWSTR TargetDefault;
     LPWSTR SourceDefault;
@@ -81,7 +82,7 @@
     LPWSTR ResolvedTarget;
     LPWSTR ResolvedSource;
     LPWSTR Property;   /* initially set property */
-    INT   ParentIndex;
+    struct tagMSIFOLDER *Parent;
     INT   State;
         /* 0 = uninitialized */
         /* 1 = existing */
@@ -89,7 +90,7 @@
         /* 3 = created persist if empty */
     INT   Cost;
     INT   Space;
-}MSIFOLDER;
+} MSIFOLDER;
 
 typedef struct tagMSIFILE
 {
@@ -240,6 +241,7 @@
 MSICOMPONENT *get_loaded_component( MSIPACKAGE* package, LPCWSTR Component );
 MSIFEATURE *get_loaded_feature( MSIPACKAGE* package, LPCWSTR Feature );
 MSIFILE *get_loaded_file( MSIPACKAGE* package, LPCWSTR file );
+MSIFOLDER *get_loaded_folder( MSIPACKAGE *package, LPCWSTR dir );
 int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path);
 UINT schedule_action(MSIPACKAGE *package, UINT script, LPCWSTR action);
 UINT build_icon_path(MSIPACKAGE *, LPCWSTR, LPWSTR *);
diff --git a/dlls/msi/helpers.c b/dlls/msi/helpers.c
index 54797bf..aba1b52 100644
--- a/dlls/msi/helpers.c
+++ b/dlls/msi/helpers.c
@@ -225,10 +225,22 @@
     return 0;
 }
 
+MSIFOLDER *get_loaded_folder( MSIPACKAGE *package, LPCWSTR dir )
+{
+    MSIFOLDER *folder;
+    
+    LIST_FOR_EACH_ENTRY( folder, &package->folders, MSIFOLDER, entry )
+    {
+        if (lstrcmpW( dir, folder->Directory )==0)
+            return folder;
+    }
+    return NULL;
+}
+
 LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, 
                       BOOL set_prop, MSIFOLDER **folder)
 {
-    DWORD i;
+    MSIFOLDER *f;
     LPWSTR p, path = NULL;
 
     TRACE("Working to resolve %s\n",debugstr_w(name));
@@ -254,17 +266,6 @@
             path = build_directory_name(2, check_path, NULL);
             if (strcmpiW(path,check_path)!=0)
                 MSI_SetPropertyW(package,cszTargetDir,path);
-
-            if (folder)
-            {
-                for (i = 0; i < package->loaded_folders; i++)
-                {
-                    if (strcmpW(package->folders[i].Directory,name)==0)
-                        break;
-                }
-                *folder = &(package->folders[i]);
-            }
-            return path;
         }
         else
         {
@@ -279,81 +280,66 @@
                         *(p+1) = 0;
                 }
             }
-            if (folder)
-            {
-                for (i = 0; i < package->loaded_folders; i++)
-                {
-                    if (strcmpW(package->folders[i].Directory,name)==0)
-                        break;
-                }
-                *folder = &(package->folders[i]);
-            }
-            return path;
         }
+        if (folder)
+            *folder = get_loaded_folder( package, name );
+        return path;
     }
 
-    for (i = 0; i < package->loaded_folders; i++)
-    {
-        if (strcmpW(package->folders[i].Directory,name)==0)
-            break;
-    }
-
-    if (i >= package->loaded_folders)
+    f = get_loaded_folder( package, name );
+    if (!f)
         return NULL;
 
     if (folder)
-        *folder = &(package->folders[i]);
+        *folder = f;
 
-    if (!source && package->folders[i].ResolvedTarget)
+    if (!source && f->ResolvedTarget)
     {
-        path = strdupW(package->folders[i].ResolvedTarget);
+        path = strdupW( f->ResolvedTarget );
         TRACE("   already resolved to %s\n",debugstr_w(path));
         return path;
     }
-    else if (source && package->folders[i].ResolvedSource)
+    else if (source && f->ResolvedSource)
     {
-        path = strdupW(package->folders[i].ResolvedSource);
+        path = strdupW( f->ResolvedSource );
         TRACE("   (source)already resolved to %s\n",debugstr_w(path));
         return path;
     }
-    else if (!source && package->folders[i].Property)
+    else if (!source && f->Property)
     {
-        path = build_directory_name(2, package->folders[i].Property, NULL);
+        path = build_directory_name( 2, f->Property, NULL );
                     
         TRACE("   internally set to %s\n",debugstr_w(path));
         if (set_prop)
-            MSI_SetPropertyW(package,name,path);
+            MSI_SetPropertyW( package, name, path );
         return path;
     }
 
-    if (package->folders[i].ParentIndex >= 0)
+    if (f->Parent)
     {
-        LPWSTR parent = package->folders[package->folders[i].ParentIndex].Directory;
+        LPWSTR parent = f->Parent->Directory;
 
         TRACE(" ! Parent is %s\n", debugstr_w(parent));
 
         p = resolve_folder(package, parent, source, set_prop, NULL);
         if (!source)
         {
-            TRACE("   TargetDefault = %s\n",
-                    debugstr_w(package->folders[i].TargetDefault));
+            TRACE("   TargetDefault = %s\n", debugstr_w(f->TargetDefault));
 
-            path = build_directory_name(3, p, 
-                            package->folders[i].TargetDefault, NULL);
-            package->folders[i].ResolvedTarget = strdupW(path);
+            path = build_directory_name( 3, p, f->TargetDefault, NULL );
+            f->ResolvedTarget = strdupW( path );
             TRACE("   resolved into %s\n",debugstr_w(path));
             if (set_prop)
                 MSI_SetPropertyW(package,name,path);
         }
         else 
         {
-            if (package->folders[i].SourceDefault && 
-                package->folders[i].SourceDefault[0]!='.')
-                path = build_directory_name(3, p, package->folders[i].SourceDefault, NULL);
+            if (f->SourceDefault && f->SourceDefault[0]!='.')
+                path = build_directory_name( 3, p, f->SourceDefault, NULL );
             else
                 path = strdupW(p);
             TRACE("   (source)resolved into %s\n",debugstr_w(path));
-            package->folders[i].ResolvedSource = strdupW(path);
+            f->ResolvedSource = strdupW( path );
         }
         HeapFree(GetProcessHeap(),0,p);
     }
@@ -462,17 +448,18 @@
         free_feature( feature );
     }
 
-    for (i = 0; i < package->loaded_folders; i++)
+    LIST_FOR_EACH_SAFE( item, cursor, &package->folders )
     {
-        HeapFree(GetProcessHeap(),0,package->folders[i].Directory);
-        HeapFree(GetProcessHeap(),0,package->folders[i].TargetDefault);
-        HeapFree(GetProcessHeap(),0,package->folders[i].SourceDefault);
-        HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedTarget);
-        HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedSource);
-        HeapFree(GetProcessHeap(),0,package->folders[i].Property);
+        MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry );
+
+        list_remove( &folder->entry );
+        HeapFree( GetProcessHeap(), 0, folder->Directory );
+        HeapFree( GetProcessHeap(), 0, folder->TargetDefault );
+        HeapFree( GetProcessHeap(), 0, folder->SourceDefault );
+        HeapFree( GetProcessHeap(), 0, folder->ResolvedTarget );
+        HeapFree( GetProcessHeap(), 0, folder->ResolvedSource );
+        HeapFree( GetProcessHeap(), 0, folder->Property );
     }
-    if (package->folders && package->loaded_folders > 0)
-        HeapFree(GetProcessHeap(),0,package->folders);
 
     LIST_FOR_EACH_SAFE( item, cursor, &package->components )
     {
diff --git a/dlls/msi/install.c b/dlls/msi/install.c
index c2e5b88..698fdae 100644
--- a/dlls/msi/install.c
+++ b/dlls/msi/install.c
@@ -263,7 +263,6 @@
 UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, 
                              LPCWSTR szFolderPath)
 {
-    DWORD i;
     DWORD attrib;
     LPWSTR path = NULL;
     LPWSTR path2 = NULL;
@@ -312,16 +311,17 @@
     }
     else
     {
-        for (i = 0; i < package->loaded_folders; i++)
+        MSIFOLDER *f;
+
+        LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
         {
-            HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedTarget);
-            package->folders[i].ResolvedTarget=NULL;
+            HeapFree( GetProcessHeap(),0,f->ResolvedTarget);
+            f->ResolvedTarget=NULL;
         }
 
-        for (i = 0; i < package->loaded_folders; i++)
+        LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
         {
-            path2=resolve_folder(package, package->folders[i].Directory, FALSE,
-                       TRUE, NULL);
+            path2 = resolve_folder(package, f->Directory, FALSE, TRUE, NULL);
             HeapFree(GetProcessHeap(),0,path2);
         }
     }
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index cae5dbd..4e6a84a 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -186,11 +186,10 @@
 {
     MSIOBJECTHDR hdr;
     MSIDATABASE *db;
-    struct tagMSIFOLDER  *folders;
-    UINT loaded_folders;
     struct list components;
     struct list features;
     struct list files;
+    struct list folders;
     LPWSTR ActionFormat;
     LPWSTR LastAction;
 
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index ff3823e..36b336a 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -377,11 +377,10 @@
         msiobj_addref( &db->hdr );
 
         package->db = db;
-        list_init( &package->features );
-        package->folders = NULL;
         list_init( &package->components );
+        list_init( &package->features );
         list_init( &package->files );
-        package->loaded_folders = 0;
+        list_init( &package->folders );
         package->ActionFormat = NULL;
         package->LastAction = NULL;
         package->dialog = NULL;