--- programs/uninstaller/main.c.old	2007-04-13 10:47:52.000000000 -0500
+++ programs/uninstaller/main.c	2007-04-23 17:19:40.000000000 -0500
@@ -35,12 +35,14 @@
     WCHAR *key;
     WCHAR *descr;
     WCHAR *command;
+    HKEY rootkey;
     int active;
 } uninst_entry;
 static uninst_entry *entries = NULL;
 static unsigned int numentries = 0;
 static int list_need_update = 1;
 static int oldsel = -1;
+const int numrootkeys = 2;
 static WCHAR *sFilter;
 static WCHAR sAppName[MAX_STRING_LEN];
 static WCHAR sAboutTitle[MAX_STRING_LEN];
@@ -54,7 +56,6 @@
 static int cmp_by_name(const void *a, const void *b);
 static INT_PTR CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
 
-
 static const WCHAR BackSlashW[] = { '\\', 0 };
 static const WCHAR DisplayNameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
 static const WCHAR PathUninstallW[] = {
@@ -64,7 +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;
 
 /**
  * Used to output program list when used with --list
@@ -148,7 +149,6 @@
                 WINE_ERR( "The remove option requires a parameter.\n");
                 return 1;
             }
-
             RemoveSpecificProgram( argv[i++] );
             return 0;
         }
@@ -178,55 +178,61 @@
     return lstrcmpiW(((const uninst_entry *)a)->descr, ((const uninst_entry *)b)->descr);
 }
 
-
 /**
  * Fetch information from the uninstall key.
  */
 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;
-  
+    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));
+    /* Loop thru HKCU first, then thru HKLM  */
+    for (x=0; x<sizeof(hkeyroot[0]); ++x)
+    {
+        /* 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;
+	if (!entries)
+            entries = HeapAlloc(GetProcessHeap(), 0, sizeof(uninst_entry));
 
-    sizeOfSubKeyName = 255;
-    for (i=0; RegEnumKeyExW( hkeyUninst, i, subKeyName, &sizeOfSubKeyName, NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS; ++i)
-    {
-        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))
+        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));
+                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);
+                entries[numentries-1].rootkey = hkeyroot[x];
+		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--;
+            }
+            RegCloseKey(hkeyApp);
+            sizeOfSubKeyName = maxSubkeyNameLen;
         }
-        RegCloseKey(hkeyApp);
-        sizeOfSubKeyName = 255;
     }
     qsort(entries, numentries, sizeof(uninst_entry), cmp_by_name);
     RegCloseKey(hkeyUninst);
@@ -242,7 +248,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 +270,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);
             }
         }
     }
@@ -310,7 +316,7 @@
                 case IDC_UNINSTALL:
                 {
                     int count = SendMessageW(hList, LB_GETSELCOUNT, 0, 0);
-                    if(count != 0)
+                    if (count != 0)
                     {
                         UninstallProgram();
                         UpdateList(hList);
@@ -329,9 +335,9 @@
                        }
                        entries[sel].active ^= 1; /* toggle */
                        WINE_TRACE("toggling %d %s\n", entries[sel].active,
-                       wine_dbgstr_w(entries[oldsel].descr));
+                       wine_dbgstr_w(entries[sel].descr));
                        oldsel = sel;
-                   }
+                    }
                     break;
                 case IDC_ABOUT:
                     MessageBoxW(0, sAbout, sAboutTitle, MB_OK);
@@ -356,6 +362,9 @@
     {
         int prevsel;
         prevsel = SendMessageW(hList, LB_GETCURSEL, 0, 0);
+        /* If no uninstall information can be found, then display a dialog to let the user know.
+         * Windows doesn't do this, why do we?  We should just catch the error and silently return..
+         */
         if (!(FetchUninstallInformation()))
         {
             MessageBoxW(0, sRegistryKeyNotAvailable, sAppName, MB_OK);
