- convert verbs into a standard list
- remove limitation of 100 verbs
- use pointers to verbs rather than indexes

diff --git a/dlls/msi/action.h b/dlls/msi/action.h
index b01036c..e422327 100644
--- a/dlls/msi/action.h
+++ b/dlls/msi/action.h
@@ -165,8 +165,7 @@
     MSIFEATURE *Feature;
     /* not in the table, set during installation */
     BOOL Installed;
-    INT VerbCount;
-    INT Verbs[100]; /* yes hard coded limit, but realistically 100 verbs??? */
+    struct list verbs;
 } MSIEXTENSION;
 
 typedef struct tagMSIPROGID
@@ -184,7 +183,7 @@
 
 typedef struct tagMSIVERB
 {
-    MSIEXTENSION *Extension;
+    struct list entry;
     LPWSTR Verb;
     INT Sequence;
     LPWSTR Command;
diff --git a/dlls/msi/classes.c b/dlls/msi/classes.c
index b94e1f6..7499d9d 100644
--- a/dlls/msi/classes.c
+++ b/dlls/msi/classes.c
@@ -440,6 +440,8 @@
     if (!ext)
         return NULL;
 
+    list_init( &ext->verbs );
+
     list_add_tail( &package->extensions, &ext->entry );
 
     sz = 256;
@@ -502,49 +504,36 @@
 static UINT iterate_load_verb(MSIRECORD *row, LPVOID param)
 {
     MSIPACKAGE* package = (MSIPACKAGE*)param;
-    DWORD index = package->loaded_verbs;
+    MSIVERB *verb;
     LPCWSTR buffer;
+    MSIEXTENSION *extension;
+
+    buffer = MSI_RecordGetString(row,1);
+    extension = load_given_extension( package, buffer );
+    if (!extension)
+    {
+        ERR("Verb unable to find loaded extension %s\n", debugstr_w(buffer));
+        return ERROR_SUCCESS;
+    }
 
     /* fill in the data */
 
-    package->loaded_verbs++;
-    if (package->loaded_verbs == 1)
-        package->verbs = HeapAlloc(GetProcessHeap(),0,sizeof(MSIVERB));
-    else
-        package->verbs = HeapReAlloc(GetProcessHeap(),0,
-            package->verbs , package->loaded_verbs * sizeof(MSIVERB));
+    verb = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSIVERB) );
+    if (!verb)
+        return ERROR_OUTOFMEMORY;
 
-    memset(&package->verbs[index],0,sizeof(MSIVERB));
-
-    buffer = MSI_RecordGetString(row,1);
-    package->verbs[index].Extension = load_given_extension(package,buffer);
-    if (package->verbs[index].Extension == NULL && buffer)
-        ERR("Verb unable to find loaded extension %s\n", debugstr_w(buffer));
-
-    package->verbs[index].Verb = load_dynamic_stringW(row,2);
-    TRACE("loading verb %s\n",debugstr_w(package->verbs[index].Verb));
-    package->verbs[index].Sequence = MSI_RecordGetInteger(row,3);
+    verb->Verb = load_dynamic_stringW(row,2);
+    TRACE("loading verb %s\n",debugstr_w(verb->Verb));
+    verb->Sequence = MSI_RecordGetInteger(row,3);
 
     buffer = MSI_RecordGetString(row,4);
-    deformat_string(package,buffer,&package->verbs[index].Command);
+    deformat_string(package,buffer,&verb->Command);
 
     buffer = MSI_RecordGetString(row,5);
-    deformat_string(package,buffer,&package->verbs[index].Argument);
+    deformat_string(package,buffer,&verb->Argument);
 
     /* assosiate the verb with the correct extension */
-    if (package->verbs[index].Extension)
-    {
-        MSIEXTENSION* extension = package->verbs[index].Extension;
-        int count = extension->VerbCount;
-
-        if (count >= 99)
-            FIXME("Exceeding max verb count! Increase that limit!!!\n");
-        else
-        {
-            extension->VerbCount++;
-            extension->Verbs[count] = index;
-        }
-    }
+    list_add_tail( &extension->verbs, &verb->entry );
     
     return ERROR_SUCCESS;
 }
@@ -728,7 +717,7 @@
     if (!list_empty( &package->classes ) ||
         !list_empty( &package->mimes ) ||
         !list_empty( &package->extensions ) ||
-        package->progids || package->verbs )
+        package->progids )
         return;
 
     load_all_classes(package);
@@ -1136,7 +1125,7 @@
     }
     else
     {
-        FIXME("UNHANDLED case, Parent progid but classid is NULL\n");
+        FIXME("progid (%s) with null classid\n", debugstr_w(progid->ProgID));
     }
 
     if (progid->IconPath)
@@ -1398,8 +1387,8 @@
         /* this is only registered if the extension has at least 1 verb
          * according to MSDN
          */
-        if (ext->ProgIDIndex >= 0 && ext->VerbCount > 0)
-           mark_progid_for_install(package, ext->ProgIDIndex);
+        if (ext->ProgIDIndex >= 0 && !list_empty( &ext->verbs ) )
+            mark_progid_for_install(package, ext->ProgIDIndex);
 
         mark_mime_for_install(ext->Mime);
 
@@ -1423,7 +1412,7 @@
             HKEY hkey2;
             LPWSTR newkey;
             LPCWSTR progid;
-            INT v;
+            MSIVERB *verb;
             INT Sequence = MSI_NULL_INTEGER;
             
             if (ext->ProgIDIndex >= 0)
@@ -1445,9 +1434,11 @@
             HeapFree(GetProcessHeap(),0,newkey);
 
             /* do all the verbs */
-            for (v = 0; v < ext->VerbCount; v++)
+            LIST_FOR_EACH_ENTRY( verb, &ext->verbs, MSIVERB, entry )
+            {
                 register_verb( package, progid, ext->Component,
-                               ext, &package->verbs[ext->Verbs[v]], &Sequence);
+                               ext, verb, &Sequence);
+            }
         }
         
         RegCloseKey(hkey);
diff --git a/dlls/msi/helpers.c b/dlls/msi/helpers.c
index 21432e2..3d49591 100644
--- a/dlls/msi/helpers.c
+++ b/dlls/msi/helpers.c
@@ -430,6 +430,25 @@
     HeapFree( GetProcessHeap(), 0, feature );
 }
 
+void free_extension( MSIEXTENSION *ext )
+{
+    struct list *item, *cursor;
+
+    LIST_FOR_EACH_SAFE( item, cursor, &ext->verbs )
+    {
+        MSIVERB *verb = LIST_ENTRY( item, MSIVERB, entry );
+
+        list_remove( &verb->entry );
+        HeapFree( GetProcessHeap(), 0, verb->Verb );
+        HeapFree( GetProcessHeap(), 0, verb->Command );
+        HeapFree( GetProcessHeap(), 0, verb->Argument );
+        HeapFree( GetProcessHeap(), 0, verb );
+    }
+
+    HeapFree( GetProcessHeap(), 0, ext->ProgIDText );
+    HeapFree( GetProcessHeap(), 0, ext );
+}
+
 
 /* Called when the package is being closed */
 void ACTION_free_package_structures( MSIPACKAGE* package)
@@ -506,8 +525,7 @@
         MSIEXTENSION *ext = LIST_ENTRY( item, MSIEXTENSION, entry );
 
         list_remove( &ext->entry );
-        HeapFree( GetProcessHeap(), 0, ext->ProgIDText );
-        HeapFree( GetProcessHeap(), 0, ext );
+        free_extension( ext );
     }
 
     for (i = 0; i < package->loaded_progids; i++)
@@ -520,16 +538,6 @@
     if (package->progids && package->loaded_progids > 0)
         HeapFree(GetProcessHeap(),0,package->progids);
 
-    for (i = 0; i < package->loaded_verbs; i++)
-    {
-        HeapFree(GetProcessHeap(),0,package->verbs[i].Verb);
-        HeapFree(GetProcessHeap(),0,package->verbs[i].Command);
-        HeapFree(GetProcessHeap(),0,package->verbs[i].Argument);
-    }
-
-    if (package->verbs && package->loaded_verbs > 0)
-        HeapFree(GetProcessHeap(),0,package->verbs);
-
     LIST_FOR_EACH_SAFE( item, cursor, &package->mimes )
     {
         MSIMIME *mt = LIST_ENTRY( item, MSIMIME, entry );
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index ce235fe..919d178 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -196,8 +196,6 @@
     struct list extensions;
     struct tagMSIPROGID *progids;
     UINT loaded_progids;
-    struct tagMSIVERB *verbs;
-    UINT loaded_verbs;
     struct list mimes;
     struct list appids;