--- programs/uninstaller/main.c.orig	2007-04-24 14:50:13.000000000 -0500
+++ programs/uninstaller/main.c	2007-04-25 12:06:43.000000000 -0500
@@ -35,6 +35,7 @@
     WCHAR *key;
     WCHAR *descr;
     WCHAR *command;
+    HKEY rootkey;
     int active;
 } uninst_entry;
 static uninst_entry *entries = NULL;
@@ -64,6 +65,7 @@
         'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
         'U','n','i','n','s','t','a','l','l',0 };
 static const WCHAR UninstallCommandlineW[] = {'U','n','i','n','s','t','a','l','l','S','t','r','i','n','g',0};
+static const DWORD MAXSUBKEYNAMELEN = 255;
 
 
 /**
@@ -185,48 +187,58 @@
 static int FetchUninstallInformation(void)
 {
     HKEY hkeyUninst, hkeyApp;
-    int i;
+    int i, x;
     DWORD sizeOfSubKeyName, displen, uninstlen;
-    WCHAR subKeyName[256];
+    WCHAR subKeyName[MAXSUBKEYNAMELEN+1];
     WCHAR key_app[1024];
     WCHAR *p;
+    uninst_entry *entry;
+    HKEY hkeyroot[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
   
     numentries = 0;
     oldsel = -1;
-    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, PathUninstallW, 0, KEY_READ, &hkeyUninst) != ERROR_SUCCESS)
-        return 0;
 
     if (!entries)
         entries = HeapAlloc(GetProcessHeap(), 0, sizeof(uninst_entry));
 
-    lstrcpyW(key_app, PathUninstallW);
-    lstrcatW(key_app, BackSlashW);
-    p = key_app+lstrlenW(PathUninstallW)+1;
-
-    sizeOfSubKeyName = 255;
-    for (i=0; RegEnumKeyExW( hkeyUninst, i, subKeyName, &sizeOfSubKeyName, NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS; ++i)
+    /* Loop thru HKCU first, then thru HKLM  */
+    for (x=0; x<sizeof(hkeyroot) / sizeof(hkeyroot[0]); ++x)
     {
-        lstrcpyW(p, subKeyName);
-        RegOpenKeyExW(HKEY_LOCAL_MACHINE, key_app, 0, KEY_READ, &hkeyApp);
-        if ((RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, NULL, &displen) == ERROR_SUCCESS)
-         && (RegQueryValueExW(hkeyApp, UninstallCommandlineW, 0, 0, NULL, &uninstlen) == ERROR_SUCCESS))
+        /* If there is no uninstall info in a specific root key, finish this run and go to the next */
+        if (RegOpenKeyExW(hkeyroot[x], PathUninstallW, 0, KEY_READ, &hkeyUninst) != ERROR_SUCCESS)
+            continue;
+
+        lstrcpyW(key_app, PathUninstallW);
+        lstrcatW(key_app, BackSlashW);
+        p = key_app+lstrlenW(PathUninstallW)+1;
+
+        sizeOfSubKeyName = MAXSUBKEYNAMELEN;
+        for (i=0; RegEnumKeyExW( hkeyUninst, i, subKeyName, &sizeOfSubKeyName, NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS; ++i)
         {
-            numentries++;
-            entries = HeapReAlloc(GetProcessHeap(), 0, entries, numentries*sizeof(uninst_entry));
-            entries[numentries-1].key = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(subKeyName)+1)*sizeof(WCHAR));
-            lstrcpyW(entries[numentries-1].key, subKeyName);
-            entries[numentries-1].descr = HeapAlloc(GetProcessHeap(), 0, displen);
-            RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, (LPBYTE)entries[numentries-1].descr, &displen);
-            entries[numentries-1].command = HeapAlloc(GetProcessHeap(), 0, uninstlen);
-            entries[numentries-1].active = 0;
-            RegQueryValueExW(hkeyApp, UninstallCommandlineW, 0, 0, (LPBYTE)entries[numentries-1].command, &uninstlen);
-            WINE_TRACE("allocated entry #%d: %s (%s), %s\n",
-            numentries, wine_dbgstr_w(entries[numentries-1].key), wine_dbgstr_w(entries[numentries-1].descr), wine_dbgstr_w(entries[numentries-1].command));
-            if(sFilter != NULL && StrStrIW(entries[numentries-1].descr,sFilter)==NULL)
-                numentries--;
+            lstrcpyW(p, subKeyName);
+            RegOpenKeyExW(hkeyroot[x], key_app, 0, KEY_READ, &hkeyApp);
+            if ((RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, NULL, &displen) == ERROR_SUCCESS)
+             && (RegQueryValueExW(hkeyApp, UninstallCommandlineW, 0, 0, NULL, &uninstlen) == ERROR_SUCCESS))
+            {
+                numentries++;
+                entries = HeapReAlloc(GetProcessHeap(), 0, entries, numentries*sizeof(uninst_entry));
+                entry = &entries[numentries-1];
+                entry->key = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(subKeyName)+1)*sizeof(WCHAR));
+                lstrcpyW(entry->key, subKeyName);
+                entry->descr = HeapAlloc(GetProcessHeap(), 0, displen);
+                RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, (LPBYTE)entry->descr, &displen);
+                entry->command = HeapAlloc(GetProcessHeap(), 0, uninstlen);
+                entry->active = 0;
+                RegQueryValueExW(hkeyApp, UninstallCommandlineW, 0, 0, (LPBYTE)entry->command, &uninstlen);
+                entry->rootkey = hkeyroot[x];
+                WINE_TRACE("allocated entry #%d: %s (%s), %s\n", numentries, wine_dbgstr_w(entry->key),
+                           wine_dbgstr_w(entry->descr), wine_dbgstr_w(entry->command));
+                if(sFilter != NULL && StrStrIW(entry->descr,sFilter)==NULL)
+                    numentries--;
+            }
+            RegCloseKey(hkeyApp);
+            sizeOfSubKeyName = MAXSUBKEYNAMELEN;
         }
-        RegCloseKey(hkeyApp);
-        sizeOfSubKeyName = 255;
     }
     qsort(entries, numentries, sizeof(uninst_entry), cmp_by_name);
     RegCloseKey(hkeyUninst);
@@ -242,7 +254,7 @@
     STARTUPINFOW si;
     PROCESS_INFORMATION info;
     DWORD exit_code;
-    HKEY hkey;
+    HKEY hkeyUninst;
     for (i=0; i < numentries; i++)
     {
         if (!(entries[i].active)) /* don't uninstall this one */
@@ -264,9 +276,9 @@
             if(MessageBoxW(0, errormsg, sAppName, MB_YESNO | MB_ICONQUESTION)==IDYES)
             {
                 /* delete the application's uninstall entry */
-                RegOpenKeyExW(HKEY_LOCAL_MACHINE, PathUninstallW, 0, KEY_READ, &hkey);
-                RegDeleteKeyW(hkey, entries[i].key);
-                RegCloseKey(hkey);
+                RegOpenKeyExW(entries[i].rootkey, PathUninstallW, 0, KEY_READ, &hkeyUninst);
+                RegDeleteKeyW(hkeyUninst, entries[i].key);
+                RegCloseKey(hkeyUninst);
             }
         }
     }
