[RAPPS] Bulk install!
[reactos.git] / reactos / base / applications / rapps / installed.cpp
index 9f07a92..57e6909 100644 (file)
@@ -3,13 +3,22 @@
  * LICENSE:         GPL - See COPYING in the top level directory
  * FILE:            base/applications/rapps/installed.cpp
  * PURPOSE:         Functions for working with installed applications
- * PROGRAMMERS:     Dmitry Chapyshev (dmitry@reactos.org)
+ * PROGRAMMERS:     Dmitry Chapyshev            (dmitry@reactos.org)
+ *                  Alexander Shaposhnikov      (chaez.san@gmail.com)
  */
 
 #include "rapps.h"
 
 BOOL
-GetApplicationString(HKEY hKey, LPCWSTR lpKeyName, LPWSTR lpString)
+GetApplicationString(HKEY hKey, LPCWSTR lpKeyName, ATL::CStringW& String)
+{
+    BOOL result = GetApplicationString(hKey, lpKeyName, String.GetBuffer(MAX_PATH));
+    String.ReleaseBuffer();
+    return result;
+}
+
+BOOL
+GetApplicationString(HKEY hKey, LPCWSTR lpKeyName, LPWSTR szString)
 {
     DWORD dwSize = MAX_PATH * sizeof(WCHAR);
 
@@ -17,83 +26,82 @@ GetApplicationString(HKEY hKey, LPCWSTR lpKeyName, LPWSTR lpString)
                          lpKeyName,
                          NULL,
                          NULL,
-                         (LPBYTE)lpString,
+                         (LPBYTE) szString,
                          &dwSize) == ERROR_SUCCESS)
     {
         return TRUE;
     }
 
-    (VOID)StringCchCopyW(lpString, MAX_PATH, L"---");
-
+    StringCchCopyW(szString, MAX_PATH, L"---");
     return FALSE;
 }
 
-
-
-BOOL
-IsInstalledApplication(LPCWSTR lpRegName, BOOL IsUserKey, REGSAM keyWow)
-{
-    HKEY hKey = NULL;
-    BOOL IsInstalled = FALSE;
-
-    if ((RegOpenKeyExW(IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
-                    L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, keyWow | KEY_ENUMERATE_SUB_KEYS,
-                    &hKey) == ERROR_SUCCESS) \
-        && FindRegistryKeyByName(hKey, keyWow, lpRegName, NULL))
-    {
-        IsInstalled = TRUE;
-    }
-    RegCloseKey(hKey);
-    return IsInstalled;
-}
-
 BOOL
-InstalledVersion(LPWSTR szVersionResult, UINT iVersionResultSize, LPCWSTR lpRegName, BOOL IsUserKey, REGSAM keyWow)
+GetInstalledVersion_WowUser(_Out_opt_ ATL::CStringW* szVersionResult, 
+                            _In_z_ const ATL::CStringW& RegName, 
+                            _In_ BOOL IsUserKey, 
+                            _In_ REGSAM keyWow)
 {
-    DWORD dwSize = MAX_PATH;
-    DWORD dwType = REG_SZ;
-    WCHAR szVersion[MAX_PATH];
-    HKEY hKey, hSubKey;
-    BOOL HasVersion = FALSE;
-    iVersionResultSize = 0;
+    HKEY hKey;
+    BOOL bHasSucceded = FALSE;
+    ATL::CStringW szVersion;
+    ATL::CStringW szPath = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + RegName;
 
     if (RegOpenKeyExW(IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
-        L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, keyWow | KEY_ENUMERATE_SUB_KEYS,
-        &hKey) == ERROR_SUCCESS)
+                      szPath.GetString(), 0, keyWow | KEY_READ,
+                      &hKey) == ERROR_SUCCESS)
     {
-        if (FindRegistryKeyByName(hKey, keyWow, lpRegName, &hSubKey))
+        if (szVersionResult != NULL)
         {
-            dwSize = sizeof(szVersion);
-            if (RegQueryValueExW(hSubKey,
-                L"DisplayVersion",
-                NULL,
-                &dwType,
-                (LPBYTE) szVersion,
-                &dwSize) == ERROR_SUCCESS)
+            DWORD dwSize = MAX_PATH * sizeof(WCHAR);
+            DWORD dwType = REG_SZ;
+            if (RegQueryValueExW(hKey,
+                                 L"DisplayVersion",
+                                 NULL,
+                                 &dwType,
+                                 (LPBYTE) szVersion.GetBuffer(MAX_PATH),
+                                 &dwSize) == ERROR_SUCCESS)
+            {
+                szVersion.ReleaseBuffer();
+                *szVersionResult = szVersion;
+                bHasSucceded = TRUE;
+            }
+            else
             {
-                szVersionResult = szVersion;
-                iVersionResultSize = dwSize;
-                HasVersion = TRUE;
+                szVersion.ReleaseBuffer();
             }
         }
-        RegCloseKey(hSubKey);
+        else
+        {
+            bHasSucceded = TRUE;
+            szVersion.ReleaseBuffer();
+        }
+        
     }
 
     RegCloseKey(hKey);
-    return HasVersion;
+    return bHasSucceded;
 }
 
+BOOL GetInstalledVersion(ATL::CStringW* pszVersion, const ATL::CStringW& szRegName)
+{
+    return (!szRegName.IsEmpty()
+            && (::GetInstalledVersion_WowUser(pszVersion, szRegName, TRUE, KEY_WOW64_32KEY)
+                || ::GetInstalledVersion_WowUser(pszVersion, szRegName, FALSE, KEY_WOW64_32KEY)
+                || ::GetInstalledVersion_WowUser(pszVersion, szRegName, TRUE, KEY_WOW64_64KEY)
+                || ::GetInstalledVersion_WowUser(pszVersion, szRegName, FALSE, KEY_WOW64_64KEY)));
+}
 
 BOOL
 UninstallApplication(INT Index, BOOL bModify)
 {
-    WCHAR szModify[] = L"ModifyPath";
-    WCHAR szUninstall[] = L"UninstallString";
+    LPCWSTR szModify = L"ModifyPath";
+    LPCWSTR szUninstall = L"UninstallString";
     WCHAR szPath[MAX_PATH];
     WCHAR szAppName[MAX_STR_LEN];
     DWORD dwType, dwSize;
     INT ItemIndex;
-    LVITEM Item;
+    LVITEMW Item;
     HKEY hKey;
     PINSTALLED_INFO ItemInfo;
 
@@ -121,16 +129,16 @@ UninstallApplication(INT Index, BOOL bModify)
     if (!ListView_GetItem(hListView, &Item))
         return FALSE;
 
-    ItemInfo = (PINSTALLED_INFO)Item.lParam;
+    ItemInfo = (PINSTALLED_INFO) Item.lParam;
     hKey = ItemInfo->hSubKey;
 
     dwType = REG_SZ;
-    dwSize = sizeof(szPath);
+    dwSize = MAX_PATH * sizeof(WCHAR);
     if (RegQueryValueExW(hKey,
                          bModify ? szModify : szUninstall,
                          NULL,
                          &dwType,
-                         (LPBYTE)szPath,
+                         (LPBYTE) szPath,
                          &dwSize) != ERROR_SUCCESS)
     {
         return FALSE;
@@ -143,20 +151,20 @@ UninstallApplication(INT Index, BOOL bModify)
 BOOL
 ShowInstalledAppInfo(INT Index)
 {
-    WCHAR szText[MAX_PATH], szInfo[MAX_PATH];
+    ATL::CStringW szText;
+    ATL::CStringW szInfo;
     PINSTALLED_INFO Info = (PINSTALLED_INFO) ListViewGetlParam(Index);
 
     if (!Info || !Info->hSubKey) return FALSE;
 
     GetApplicationString(Info->hSubKey, L"DisplayName", szText);
     NewRichEditText(szText, CFE_BOLD);
-
     InsertRichEditText(L"\n", 0);
 
 #define GET_INFO(a, b, c, d) \
     if (GetApplicationString(Info->hSubKey, a, szInfo)) \
     { \
-        LoadStringW(hInst, b, szText, _countof(szText)); \
+        szText.LoadStringW(hInst, b); \
         InsertRichEditText(szText, c); \
         InsertRichEditText(szInfo, d); \
     } \
@@ -188,8 +196,8 @@ RemoveAppFromRegistry(INT Index)
 {
     PINSTALLED_INFO Info;
     WCHAR szFullName[MAX_PATH] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\";
-    WCHAR szMsgText[MAX_STR_LEN], szMsgTitle[MAX_STR_LEN];
-    INT ItemIndex = SendMessage(hListView, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
+    ATL::CStringW szMsgText, szMsgTitle;
+    INT ItemIndex = SendMessageW(hListView, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
 
     if (!IS_INSTALLED_ENUM(SelectedEnumType))
         return;
@@ -197,24 +205,27 @@ RemoveAppFromRegistry(INT Index)
     Info = (PINSTALLED_INFO) ListViewGetlParam(Index);
     if (!Info || !Info->hSubKey || (ItemIndex == -1)) return;
 
-    if (!LoadStringW(hInst, IDS_APP_REG_REMOVE, szMsgText, _countof(szMsgText)) ||
-        !LoadStringW(hInst, IDS_INFORMATION, szMsgTitle, _countof(szMsgTitle)))
+    if (!szMsgText.LoadStringW(hInst, IDS_APP_REG_REMOVE) ||
+        !szMsgTitle.LoadStringW(hInst, IDS_INFORMATION))
         return;
 
     if (MessageBoxW(hMainWnd, szMsgText, szMsgTitle, MB_YESNO | MB_ICONQUESTION) == IDYES)
     {
-        wcsncat(szFullName, Info->szKeyName, MAX_PATH - wcslen(szFullName));
+        ATL::CStringW::CopyChars(szFullName, 
+                                 MAX_PATH, 
+                                 Info->szKeyName.GetString(), 
+                                 MAX_PATH - wcslen(szFullName));
 
         if (RegDeleteKeyW(Info->hRootKey, szFullName) == ERROR_SUCCESS)
         {
-            (VOID) ListView_DeleteItem(hListView, ItemIndex);
+            ListView_DeleteItem(hListView, ItemIndex);
             return;
         }
 
-        if (!LoadStringW(hInst, IDS_UNABLE_TO_REMOVE, szMsgText, _countof(szMsgText)))
+        if (!szMsgText.LoadStringW(hInst, IDS_UNABLE_TO_REMOVE))
             return;
 
-        MessageBoxW(hMainWnd, szMsgText, NULL, MB_OK | MB_ICONERROR);
+        MessageBoxW(hMainWnd, szMsgText.GetString(), NULL, MB_OK | MB_ICONERROR);
     }
 }
 
@@ -224,8 +235,8 @@ EnumInstalledApplications(INT EnumType, BOOL IsUserKey, APPENUMPROC lpEnumProc)
 {
     DWORD dwSize = MAX_PATH, dwType, dwValue;
     BOOL bIsSystemComponent, bIsUpdate;
-    WCHAR pszParentKeyName[MAX_PATH];
-    WCHAR pszDisplayName[MAX_PATH];
+    ATL::CStringW szParentKeyName;
+    ATL::CStringW szDisplayName;
     INSTALLED_INFO Info;
     HKEY hKey;
     LONG ItemIndex = 0;
@@ -239,9 +250,10 @@ EnumInstalledApplications(INT EnumType, BOOL IsUserKey, APPENUMPROC lpEnumProc)
         return FALSE;
     }
 
-    while (RegEnumKeyExW(hKey, ItemIndex, Info.szKeyName, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+    while (RegEnumKeyExW(hKey, ItemIndex, Info.szKeyName.GetBuffer(MAX_PATH), &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
     {
-        if (RegOpenKeyW(hKey, Info.szKeyName, &Info.hSubKey) == ERROR_SUCCESS)
+        Info.szKeyName.ReleaseBuffer();
+        if (RegOpenKeyW(hKey, Info.szKeyName.GetString(), &Info.hSubKey) == ERROR_SUCCESS)
         {
             dwType = REG_DWORD;
             dwSize = sizeof(DWORD);
@@ -250,7 +262,7 @@ EnumInstalledApplications(INT EnumType, BOOL IsUserKey, APPENUMPROC lpEnumProc)
                                  L"SystemComponent",
                                  NULL,
                                  &dwType,
-                                 (LPBYTE)&dwValue,
+                                 (LPBYTE) &dwValue,
                                  &dwSize) == ERROR_SUCCESS)
             {
                 bIsSystemComponent = (dwValue == 0x1);
@@ -261,22 +273,25 @@ EnumInstalledApplications(INT EnumType, BOOL IsUserKey, APPENUMPROC lpEnumProc)
             }
 
             dwType = REG_SZ;
-            dwSize = sizeof(pszParentKeyName);
+            dwSize = MAX_PATH * sizeof(WCHAR);
             bIsUpdate = (RegQueryValueExW(Info.hSubKey,
                                           L"ParentKeyName",
                                           NULL,
                                           &dwType,
-                                          (LPBYTE)pszParentKeyName,
+                                          (LPBYTE) szParentKeyName.GetBuffer(MAX_PATH),
                                           &dwSize) == ERROR_SUCCESS);
+            szParentKeyName.ReleaseBuffer();
 
-            dwSize = sizeof(pszDisplayName);
+            dwType = REG_SZ;
+            dwSize = MAX_PATH * sizeof(WCHAR);
             if (RegQueryValueExW(Info.hSubKey,
                                  L"DisplayName",
                                  NULL,
                                  &dwType,
-                                 (LPBYTE)pszDisplayName,
+                                 (LPBYTE) szDisplayName.GetBuffer(MAX_PATH),
                                  &dwSize) == ERROR_SUCCESS)
             {
+                szDisplayName.ReleaseBuffer();
                 if (EnumType < ENUM_ALL_COMPONENTS || EnumType > ENUM_UPDATES)
                     EnumType = ENUM_ALL_COMPONENTS;
 
@@ -286,7 +301,7 @@ EnumInstalledApplications(INT EnumType, BOOL IsUserKey, APPENUMPROC lpEnumProc)
                         ((EnumType == ENUM_APPLICATIONS) && (!bIsUpdate)) || /* Applications only */
                         ((EnumType == ENUM_UPDATES) && (bIsUpdate))) /* Updates only */
                     {
-                        if (!lpEnumProc(ItemIndex, pszDisplayName, &Info))
+                        if (!lpEnumProc(ItemIndex, szDisplayName, &Info))
                             break;
                     }
                     else
@@ -301,6 +316,7 @@ EnumInstalledApplications(INT EnumType, BOOL IsUserKey, APPENUMPROC lpEnumProc)
             }
             else
             {
+                szDisplayName.ReleaseBuffer();
                 RegCloseKey(Info.hSubKey);
             }
         }
@@ -309,6 +325,7 @@ EnumInstalledApplications(INT EnumType, BOOL IsUserKey, APPENUMPROC lpEnumProc)
         ItemIndex++;
     }
 
+    Info.szKeyName.ReleaseBuffer();
     RegCloseKey(hKey);
 
     return TRUE;