Owen Rudge : appwiz.cpl: Read installed application information from registry.

Alexandre Julliard julliard at winehq.org
Fri Jul 25 08:13:52 CDT 2008


Module: wine
Branch: master
Commit: c16aeaf8e560dae85c7d7bb649ecf6bd197b7c82
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c16aeaf8e560dae85c7d7bb649ecf6bd197b7c82

Author: Owen Rudge <owen at owenrudge.net>
Date:   Mon Jul 21 19:42:25 2008 +0100

appwiz.cpl: Read installed application information from registry.

---

 dlls/appwiz.cpl/appwiz.c |  244 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 244 insertions(+), 0 deletions(-)

diff --git a/dlls/appwiz.cpl/appwiz.c b/dlls/appwiz.cpl/appwiz.c
index 4bf86a9..4cbcf79 100644
--- a/dlls/appwiz.cpl/appwiz.c
+++ b/dlls/appwiz.cpl/appwiz.c
@@ -48,8 +48,44 @@ WINE_DEFAULT_DEBUG_CHANNEL(appwizcpl);
 /* define a maximum length for various buffers we use */
 #define MAX_STRING_LEN    1024
 
+typedef struct APPINFO {
+    int id;
+
+    LPWSTR title;
+    LPWSTR path;
+
+    LPWSTR icon;
+    int iconIdx;
+
+    LPWSTR publisher;
+    LPWSTR version;
+
+    HKEY regroot;
+    WCHAR regkey[MAX_STRING_LEN];
+
+    struct APPINFO *next;
+} APPINFO;
+
+static struct APPINFO *AppInfo = NULL;
 static HINSTANCE hInst;
 
+/* names of registry keys */
+static const WCHAR BackSlashW[] = { '\\', 0 };
+static const WCHAR DisplayNameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
+static const WCHAR DisplayIconW[] = {'D','i','s','p','l','a','y','I','c','o','n',0};
+static const WCHAR DisplayVersionW[] = {'D','i','s','p','l','a','y','V','e','r',
+    's','i','o','n',0};
+static const WCHAR PublisherW[] = {'P','u','b','l','i','s','h','e','r',0};
+static const WCHAR UninstallCommandlineW[] = {'U','n','i','n','s','t','a','l','l',
+    'S','t','r','i','n','g',0};
+
+static const WCHAR PathUninstallW[] = {
+        'S','o','f','t','w','a','r','e','\\',
+        'M','i','c','r','o','s','o','f','t','\\',
+        'W','i','n','d','o','w','s','\\',
+        'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+        'U','n','i','n','s','t','a','l','l',0 };
+
 /******************************************************************************
  * Name       : DllMain
  * Description: Entry point for DLL file
@@ -69,6 +105,205 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
 }
 
 /******************************************************************************
+ * Name       : FreeAppInfo
+ * Description: Frees memory used by an AppInfo structure, and any children.
+ */
+static void FreeAppInfo(APPINFO *info)
+{
+    APPINFO *iter = info;
+
+    while (iter)
+    {
+        if (iter->title)
+            HeapFree(GetProcessHeap(), 0, iter->title);
+
+        if (iter->path)
+            HeapFree(GetProcessHeap(), 0, iter->path);
+
+        if (iter->icon)
+            HeapFree(GetProcessHeap(), 0, iter->icon);
+
+        if (iter->publisher)
+            HeapFree(GetProcessHeap(), 0, iter->publisher);
+
+        if (iter->version)
+            HeapFree(GetProcessHeap(), 0, iter->version);
+
+        iter = iter->next;
+        HeapFree(GetProcessHeap(), 0, iter);
+    }
+}
+
+/******************************************************************************
+ * Name       : ReadApplicationsFromRegistry
+ * Description: Creates a linked list of uninstallable applications from the
+ *              registry.
+ * Parameters : root    - Which registry root to read from (HKCU/HKLM)
+ * Returns    : TRUE if successful, FALSE otherwise
+ */
+static BOOL ReadApplicationsFromRegistry(HKEY root)
+{
+    HKEY hkeyUninst, hkeyApp;
+    int i, id = 0;
+    DWORD sizeOfSubKeyName, displen, uninstlen;
+    WCHAR subKeyName[256];
+    WCHAR key_app[MAX_STRING_LEN];
+    WCHAR *p;
+    APPINFO *iter = AppInfo;
+    LPWSTR iconPtr;
+    BOOL ret = FALSE;
+
+    if (RegOpenKeyExW(root, PathUninstallW, 0, KEY_READ, &hkeyUninst) !=
+      ERROR_SUCCESS)
+        return FALSE;
+
+    lstrcpyW(key_app, PathUninstallW);
+    lstrcatW(key_app, BackSlashW);
+    p = key_app+lstrlenW(PathUninstallW)+1;
+
+    sizeOfSubKeyName = sizeof(subKeyName) / sizeof(subKeyName[0]);
+
+    if (iter)
+    {
+        /* find the end of the list */
+        for (iter = AppInfo; iter->next; iter = iter->next);
+    }
+
+    for (i = 0; RegEnumKeyExW(hkeyUninst, i, subKeyName, &sizeOfSubKeyName, NULL,
+        NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS; ++i)
+    {
+        lstrcpyW(p, subKeyName);
+        RegOpenKeyExW(root, key_app, 0, KEY_READ, &hkeyApp);
+
+        displen = 0;
+        uninstlen = 0;
+
+        if ((RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, NULL, &displen) ==
+            ERROR_SUCCESS) && (RegQueryValueExW(hkeyApp, UninstallCommandlineW,
+            0, 0, NULL, &uninstlen) == ERROR_SUCCESS))
+        {
+            /* if we already have iter, allocate the next entry */
+            if (iter)
+            {
+                iter->next = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                    sizeof(struct APPINFO));
+
+                if (!iter->next)
+                    goto err;
+
+                iter = iter->next;
+            }
+            else
+            {
+                /* if not, start the list */
+                iter = AppInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                    sizeof(struct APPINFO));
+
+                if (!iter)
+                    goto err;
+            }
+
+            iter->title = HeapAlloc(GetProcessHeap(), 0, displen);
+
+            if (!iter->title)
+                goto err;
+
+            RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, (LPBYTE)iter->title,
+                &displen);
+
+            /* now get DisplayIcon */
+            displen = 0;
+            RegQueryValueExW(hkeyApp, DisplayIconW, 0, 0, NULL, &displen);
+
+            if (displen == 0)
+                iter->icon = 0;
+            else
+            {
+                iter->icon = HeapAlloc(GetProcessHeap(), 0, displen);
+
+                if (!iter->icon)
+                    goto err;
+
+                RegQueryValueExW(hkeyApp, DisplayIconW, 0, 0, (LPBYTE)iter->icon,
+                    &displen);
+
+                /* separate the index from the icon name, if supplied */
+                iconPtr = strchrW(iter->icon, ',');
+
+                if (iconPtr)
+                {
+                    *iconPtr++ = 0;
+                    iter->iconIdx = atoiW(iconPtr);
+                }
+            }
+
+            iter->path = HeapAlloc(GetProcessHeap(), 0, uninstlen);
+
+            if (!iter->path)
+                goto err;
+
+            RegQueryValueExW(hkeyApp, UninstallCommandlineW, 0, 0,
+                (LPBYTE)iter->path, &uninstlen);
+
+            /* publisher, version */
+            if (RegQueryValueExW(hkeyApp, PublisherW, 0, 0, NULL, &displen) ==
+                ERROR_SUCCESS)
+            {
+                iter->publisher = HeapAlloc(GetProcessHeap(), 0, displen);
+
+                if (!iter->publisher)
+                    goto err;
+
+                RegQueryValueExW(hkeyApp, PublisherW, 0, 0, (LPBYTE)iter->publisher,
+                    &displen);
+            }
+
+            if (RegQueryValueExW(hkeyApp, DisplayVersionW, 0, 0, NULL, &displen) ==
+                ERROR_SUCCESS)
+            {
+                iter->version = HeapAlloc(GetProcessHeap(), 0, displen);
+
+                if (!iter->version)
+                    goto err;
+
+                RegQueryValueExW(hkeyApp, DisplayVersionW, 0, 0, (LPBYTE)iter->version,
+                    &displen);
+            }
+
+            /* registry key */
+            iter->regroot = root;
+            lstrcpyW(iter->regkey, subKeyName);
+
+            iter->id = id++;
+        }
+
+        RegCloseKey(hkeyApp);
+        sizeOfSubKeyName = sizeof(subKeyName) / sizeof(subKeyName[0]);
+    }
+
+    ret = TRUE;
+    goto end;
+
+err:
+    RegCloseKey(hkeyApp);
+    FreeAppInfo(iter);
+
+end:
+    RegCloseKey(hkeyUninst);
+    return ret;
+}
+
+/******************************************************************************
+ * Name       : EmptyList
+ * Description: Frees memory used by the application linked list.
+ */
+static inline void EmptyList(void)
+{
+    FreeAppInfo(AppInfo);
+    AppInfo = NULL;
+}
+
+/******************************************************************************
  * Name       : UpdateButtons
  * Description: Enables/disables the Add/Remove button depending on current
  *              selection in list box.
@@ -175,11 +410,18 @@ static HIMAGELIST ResetApplicationList(BOOL bFirstRun, HWND hWnd, HIMAGELIST hIm
     else /* we need to remove the existing things first */
     {
         ImageList_Destroy(hImageList);
+
+        /* reset the list, since it's probably changed if the uninstallation was
+           successful */
+        EmptyList();
     }
 
     /* now create the image list and add the applications to the listview */
     hImageList = AddListViewImageList(hWndListView);
 
+    ReadApplicationsFromRegistry(HKEY_LOCAL_MACHINE);
+    ReadApplicationsFromRegistry(HKEY_CURRENT_USER);
+
     UpdateButtons(hWnd);
 
     return(hImageList);
@@ -211,6 +453,8 @@ static BOOL CALLBACK MainDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
         case WM_DESTROY:
             ImageList_Destroy(hImageList);
 
+            EmptyList();
+
             return 0;
     }
 




More information about the wine-cvs mailing list