[RAPPS]
authorAlexander Shaposhnikov <sanchaez@reactos.org>
Tue, 27 Jun 2017 23:21:58 +0000 (23:21 +0000)
committerAlexander Shaposhnikov <sanchaez@reactos.org>
Tue, 27 Jun 2017 23:21:58 +0000 (23:21 +0000)
* Separated available and installed version.
  If the app is installed it's DisplayVersion is shown.
* Reduced registry key access checks
* Version parser WIP

svn path=/branches/GSoC_2017/rapps/; revision=75219

reactos/base/applications/rapps/available.cpp
reactos/base/applications/rapps/installed.cpp
reactos/base/applications/rapps/lang/en-US.rc
reactos/base/applications/rapps/lang/ru-RU.rc
reactos/base/applications/rapps/lang/uk-UA.rc
reactos/base/applications/rapps/misc.cpp
reactos/base/applications/rapps/rapps.h
reactos/base/applications/rapps/resource.h

index 279029c..cd70bd7 100644 (file)
@@ -9,20 +9,19 @@
 
 #include "rapps.h"
 
-
-template<typename T, size_t N, size_t N2>
-inline void _AddText(T (&szText)[N], UINT a, T (&b)[N2], DWORD c, DWORD d) {
+inline void _AddText(UINT a, LPCWSTR b, DWORD c, DWORD d) {
   if (b[0] != '\0') 
   {
-      LoadStringW(hInst, a, szText, N); 
+      WCHAR szText[MAX_STR_LEN];
+      LoadStringW(hInst, a, szText, _countof(szText));
       InsertRichEditText(szText, c); 
       InsertRichEditText(b, d); 
   }
 }
 
-template<typename T, size_t N>
-inline void _AddTextNewl(T (&szText)[N], UINT a, DWORD b) {
-    LoadStringW(hInst, a, szText, N);
+inline void _AddTextNewl(UINT a, DWORD b) {
+    WCHAR szText[MAX_STR_LEN];
+    LoadStringW(hInst, a, szText, _countof(szText));
     InsertRichEditText(L"\n", 0);
     InsertRichEditText(szText, b);
     InsertRichEditText(L"\n", 0);
@@ -41,7 +40,7 @@ inline void _GetStringNullFailure(LPCWSTR a, T(&b)[N], T (&cFileName)[N2]) {
 }
 
 //App is "installed" if the RegName or Name is in the registry
-inline bool _AppInstallCheckKey(PAPPLICATION_INFO Info, REGSAM key)
+inline BOOL _AppInstallCheckWithKey(PAPPLICATION_INFO Info, REGSAM key)
 {
     return (*Info->szRegName
         && (IsInstalledApplication(Info->szRegName, TRUE, key)
@@ -53,11 +52,27 @@ inline bool _AppInstallCheckKey(PAPPLICATION_INFO Info, REGSAM key)
 
 //Check both registry keys in 64bit system
 //TODO: check system type beforehand to avoid double checks?
-inline bool _AppInstallCheck(PAPPLICATION_INFO Info) {
-  return  _AppInstallCheckKey(Info, KEY_WOW64_32KEY) 
-    || _AppInstallCheckKey(Info, KEY_WOW64_64KEY);
+inline BOOL _AppInstallCheck(PAPPLICATION_INFO Info) {
+  return  _AppInstallCheckWithKey(Info, KEY_WOW64_32KEY) 
+    || _AppInstallCheckWithKey(Info, KEY_WOW64_64KEY);
+}
+
+//App is "installed" if the RegName or Name is in the registry
+inline BOOL _GetInstalledVersionWithKey(PAPPLICATION_INFO Info, LPWSTR szVersion, UINT iVersionSize, REGSAM key)
+{
+    return (*Info->szRegName
+        && (InstalledVersion(szVersion, iVersionSize, Info->szRegName, TRUE, key)
+        || InstalledVersion(szVersion, iVersionSize, Info->szRegName, FALSE, key)))
+        || (*Info->szName && (InstalledVersion(szVersion, iVersionSize, Info->szName, TRUE, key)
+            || InstalledVersion(szVersion, iVersionSize, Info->szName, FALSE, key)));
 }
 
+//App is "installed" if the RegName or Name is in the registry
+inline BOOL _GetInstalledVersion(PAPPLICATION_INFO Info, LPWSTR szVersion, UINT iVersionSize)
+{
+    return  _GetInstalledVersionWithKey(Info, szVersion, iVersionSize, KEY_WOW64_32KEY)
+        || _GetInstalledVersionWithKey(Info, szVersion, iVersionSize, KEY_WOW64_64KEY);
+}
 
 LIST_ENTRY CachedEntriesHead = { &CachedEntriesHead, &CachedEntriesHead };
 PLIST_ENTRY pCachedEntry = &CachedEntriesHead;
@@ -66,25 +81,30 @@ BOOL
 ShowAvailableAppInfo(INT Index)
 {
     PAPPLICATION_INFO Info = (PAPPLICATION_INFO) ListViewGetlParam(Index);
-    WCHAR szText[MAX_STR_LEN];
+    BOOL bIsInstalled = _AppInstallCheck(Info);
+    WCHAR szVersion[MAX_PATH];
 
     if (!Info) return FALSE;
 
     NewRichEditText(Info->szName, CFE_BOLD);
-    if (_AppInstallCheck(Info))
+    if (bIsInstalled)
     {
-      _AddTextNewl(szText, IDS_STATUS_INSTALLED, CFE_ITALIC);
+      _AddTextNewl(IDS_STATUS_INSTALLED, CFE_ITALIC);
+      if (_GetInstalledVersion(Info, szVersion, _countof(szVersion)))
+      {
+          _AddText(IDS_AINFO_VERSION, szVersion, CFE_BOLD, 0);
+      }
     } else 
     {
-      _AddTextNewl(szText, IDS_STATUS_NOTINSTALLED, CFE_ITALIC);
+      _AddTextNewl(IDS_STATUS_NOTINSTALLED, CFE_ITALIC);
     }
 
-    _AddText(szText, IDS_AINFO_VERSION,     Info->szVersion, CFE_BOLD, 0);
-    _AddText(szText, IDS_AINFO_LICENSE,     Info->szLicense, CFE_BOLD, 0);
-    _AddText(szText, IDS_AINFO_SIZE,        Info->szSize,    CFE_BOLD, 0);
-    _AddText(szText, IDS_AINFO_URLSITE,     Info->szUrlSite, CFE_BOLD, CFE_LINK);
-    _AddText(szText, IDS_AINFO_DESCRIPTION, Info->szDesc,    CFE_BOLD, 0);
-    _AddText(szText, IDS_AINFO_URLDOWNLOAD, Info->szUrlDownload, CFE_BOLD, CFE_LINK);
+    _AddText(IDS_AINFO_AVAILABLEVERSION, Info->szVersion, CFE_BOLD, 0);
+    _AddText(IDS_AINFO_LICENSE, Info->szLicense, CFE_BOLD, 0);
+    _AddText(IDS_AINFO_SIZE, Info->szSize, CFE_BOLD, 0);
+    _AddText(IDS_AINFO_URLSITE, Info->szUrlSite, CFE_BOLD, CFE_LINK);
+    _AddText(IDS_AINFO_DESCRIPTION, Info->szDesc, CFE_BOLD, 0);
+    _AddText(IDS_AINFO_URLDOWNLOAD, Info->szUrlDownload, CFE_BOLD, CFE_LINK);
 
     return TRUE;
 }
index 9f07a92..a5d7888 100644 (file)
@@ -35,11 +35,12 @@ IsInstalledApplication(LPCWSTR lpRegName, BOOL IsUserKey, REGSAM keyWow)
 {
     HKEY hKey = NULL;
     BOOL IsInstalled = FALSE;
+    WCHAR szPath[MAX_PATH] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+    StringCbPrintfW(szPath, _countof(szPath), L"%ls\\%ls", szPath, lpRegName);
 
-    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))
+    if (RegOpenKeyExW(IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
+        szPath, 0, keyWow | KEY_READ,
+                    &hKey) == ERROR_SUCCESS)
     {
         IsInstalled = TRUE;
     }
@@ -52,35 +53,31 @@ InstalledVersion(LPWSTR szVersionResult, UINT iVersionResultSize, LPCWSTR lpRegN
 {
     DWORD dwSize = MAX_PATH;
     DWORD dwType = REG_SZ;
-    WCHAR szVersion[MAX_PATH];
-    HKEY hKey, hSubKey;
-    BOOL HasVersion = FALSE;
+    WCHAR szVersion[MAX_PATH] = L"";
+    HKEY hKey;
+    BOOL bHasVersion = FALSE;
     iVersionResultSize = 0;
+    WCHAR szPath[MAX_PATH] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+    StringCbPrintfW(szPath, _countof(szPath), L"%ls\\%ls", szPath, lpRegName);
 
     if (RegOpenKeyExW(IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
-        L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, keyWow | KEY_ENUMERATE_SUB_KEYS,
+        szPath, 0, keyWow | KEY_READ,
         &hKey) == ERROR_SUCCESS)
     {
-        if (FindRegistryKeyByName(hKey, keyWow, lpRegName, &hSubKey))
+        dwSize = MAX_PATH;
+        if (RegQueryValueExW(hKey,
+            L"DisplayVersion",
+            NULL,
+            &dwType,
+            (LPBYTE) szVersion,
+            &dwSize) == ERROR_SUCCESS)
         {
-            dwSize = sizeof(szVersion);
-            if (RegQueryValueExW(hSubKey,
-                L"DisplayVersion",
-                NULL,
-                &dwType,
-                (LPBYTE) szVersion,
-                &dwSize) == ERROR_SUCCESS)
-            {
-                szVersionResult = szVersion;
-                iVersionResultSize = dwSize;
-                HasVersion = TRUE;
-            }
+            StringCbCopyW(szVersionResult, dwSize, szVersion);
+            bHasVersion = TRUE;
         }
-        RegCloseKey(hSubKey);
     }
-
     RegCloseKey(hKey);
-    return HasVersion;
+    return bHasVersion;
 }
 
 
index f89edbd..2c31109 100644 (file)
@@ -152,6 +152,7 @@ END
 STRINGTABLE
 BEGIN
     IDS_AINFO_VERSION "\nVersion: "
+    IDS_AINFO_AVAILABLEVERSION "\nAvailable Version: "
     IDS_AINFO_DESCRIPTION "\nDescription: "
     IDS_AINFO_SIZE "\nSize: "
     IDS_AINFO_URLSITE "\nHome Page: "
index cf77d67..f31acb4 100644 (file)
@@ -152,6 +152,7 @@ END
 STRINGTABLE
 BEGIN
     IDS_AINFO_VERSION "\nВерсия: "
+    IDS_AINFO_AVAILABLEVERSION "\nДоступная версия: "
     IDS_AINFO_DESCRIPTION "\nОписание: "
     IDS_AINFO_SIZE "\nРазмер: "
     IDS_AINFO_URLSITE "\nДомашняя страница: "
index e106024..f823c10 100644 (file)
@@ -160,6 +160,7 @@ END
 STRINGTABLE
 BEGIN
     IDS_AINFO_VERSION "\nВерсія: "
+    IDS_AINFO_AVAILABLEVERSION "\nДоступна версія: "
     IDS_AINFO_DESCRIPTION "\nОпис: "
     IDS_AINFO_SIZE "\nРозмір: "
     IDS_AINFO_URLSITE "\nДомашня сторінка: "
index 499f74e..0bd0e9a 100644 (file)
@@ -8,6 +8,8 @@
  */
 
 #include "rapps.h"
+#include <atlsimpcoll.h>
+#include <atlstr.h> 
 
 /* SESSION Operation */
 #define EXTRACT_FILLFILELIST  0x00000001
@@ -495,29 +497,70 @@ UINT ParserGetInt(LPCWSTR lpKeyName, LPCWSTR lpFileName)
     RtlInitUnicodeString(&BufferW, Buffer);
     RtlUnicodeStringToInteger(&BufferW, 0, &Result);
 
-    return Result;
+    return (UINT)Result;
 }
 
-
+//Parses version string that can be formatted as 1.2.3.4-5
+//Returns int buffer and it's size
 BOOL
-ParseVersion(LPWSTR szVersion, INT* version)
+ParseVersion(_In_z_ LPCWSTR szVersion, _Outptr_ INT* parrVersion, _Out_opt_ UINT iVersionSize)
 {
-    return TRUE;
+    ATL::CSimpleArray<int> arrVersionResult;
+    ATL::CStringW szVersionSingleInt = L"";
+    ATL::CStringW sDelimiters = L".-";
+    BOOL bHasParsed = TRUE;
+    INT iVersionCharCount = 0;
+    //INT iVersionSingleCharCount = 0;
+    INT iIntResult;
+    iVersionSize = 0;
+    while(szVersion[iVersionCharCount] != L'\0')
+    {
+        for (;!sDelimiters.Find(szVersion[iVersionCharCount]); ++iVersionCharCount)
+        {
+            szVersionSingleInt += szVersion[iVersionCharCount];
+        }
+        szVersionSingleInt += L'\0';
+        iIntResult = StrToIntW(szVersionSingleInt.GetBuffer());
+        if (iIntResult)
+        {
+            arrVersionResult.Add(iIntResult);
+            iVersionSize++;
+        }
+        else
+        {
+            bHasParsed = FALSE;
+        }
+        ++iVersionCharCount;
+    }
+    parrVersion = arrVersionResult.GetData();
+    return bHasParsed;
 }
 
-
-//Finds subkey in key by name or path and returns it
+//Compares versions 
+//In:   Zero terminated strings of versions
+//Out:  TRUE if first is bigger than second, FALSE if else
 BOOL
-FindRegistryKeyByName(_In_ HKEY hKeyBase, _In_ REGSAM keyWow, _In_ LPCWSTR lpcKey, _Out_opt_ PHKEY hKeyResult)
+CompareVersionsBigger(_In_z_ LPCWSTR sczVersion1, _In_z_ LPCWSTR sczVersion2, _Out_ BOOL bResult)
 {
-    HKEY hSubKey;
-    if (RegOpenKeyExW(hKeyBase, lpcKey, 0, keyWow | KEY_READ, &hSubKey) == ERROR_SUCCESS)
+    UINT iVersionSize1 = 0;
+    UINT iVersionSize2 = 0;
+    INT *parrVersion1 = NULL, *parrVersion2 = NULL;
+    bResult = FALSE;
+
+    if (!ParseVersion(sczVersion1, parrVersion1, iVersionSize1)
+        || !ParseVersion(sczVersion2, parrVersion2, iVersionSize2))
     {
-        hKeyResult = &hSubKey;
-        return TRUE;
+        return FALSE;
     }
-    hKeyResult = NULL;
-    RegCloseKey(hSubKey);
-    return FALSE;
-}
 
+    for (INT i = 0; i < iVersionSize1 && i < iVersionSize2; ++i)
+    {
+        if (parrVersion1[i] > parrVersion2[i])
+        {
+            bResult = TRUE;
+            return TRUE;
+        }
+    }
+
+    return TRUE;
+}
\ No newline at end of file
index 1ed84b2..61868ff 100644 (file)
@@ -181,7 +181,9 @@ BOOL WriteLogMessage(WORD wType, DWORD dwEventID, LPWSTR lpMsg);
 UINT ParserGetString(LPCWSTR lpKeyName, LPWSTR lpReturnedString, UINT nSize, LPCWSTR lpFileName);
 UINT ParserGetInt(LPCWSTR lpKeyName, LPCWSTR lpFileName);
 
+BOOL ParseVersion(_In_z_ LPCWSTR szVersion, _Outptr_ INT* parrVersion, _Out_opt_ UINT iVersionSize);
 BOOL FindRegistryKeyByName(_In_ HKEY hKeyBase, _In_ REGSAM keyWow, _In_ LPCWSTR lpcKey, _Out_opt_ PHKEY hKeyResult);
+BOOL CompareVersionsBigger(_In_z_ LPCWSTR sczVersion1, _In_z_ LPCWSTR sczVersion2, _Out_ BOOL bResult = FALSE);
 
 /* settingsdlg.c */
 VOID CreateSettingsDlg(HWND hwnd);
index fe6b509..de3f21a 100644 (file)
 #define IDS_APP_DESCRIPTION      252
 
 /* Apps info */
-#define IDS_INFO_VERSION         280
-#define IDS_INFO_DESCRIPTION     281
-#define IDS_INFO_PUBLISHER       282
-#define IDS_INFO_HELPLINK        283
-#define IDS_INFO_HELPPHONE       284
-#define IDS_INFO_README          285
-#define IDS_INFO_REGOWNER        286
-#define IDS_INFO_PRODUCTID       287
-#define IDS_INFO_CONTACT         288
-#define IDS_INFO_UPDATEINFO      289
-#define IDS_INFO_INFOABOUT       290
-#define IDS_INFO_COMMENTS        291
-#define IDS_INFO_INSTLOCATION    292
-#define IDS_INFO_INSTALLSRC      293
-#define IDS_INFO_UNINSTALLSTR    294
-#define IDS_INFO_MODIFYPATH      295
-#define IDS_INFO_INSTALLDATE     296
+#define IDS_INFO_VERSION          280
+#define IDS_INFO_DESCRIPTION      281
+#define IDS_INFO_PUBLISHER        282
+#define IDS_INFO_HELPLINK         283
+#define IDS_INFO_HELPPHONE        284
+#define IDS_INFO_README           285
+#define IDS_INFO_REGOWNER         286
+#define IDS_INFO_PRODUCTID        287
+#define IDS_INFO_CONTACT          288
+#define IDS_INFO_UPDATEINFO       289
+#define IDS_INFO_INFOABOUT        290
+#define IDS_INFO_COMMENTS         291
+#define IDS_INFO_INSTLOCATION     292
+#define IDS_INFO_INSTALLSRC       293
+#define IDS_INFO_UNINSTALLSTR     294
+#define IDS_INFO_MODIFYPATH       295
+#define IDS_INFO_INSTALLDATE      296
 
 /* Info for available apps */
-#define IDS_AINFO_VERSION        350
-#define IDS_AINFO_DESCRIPTION    351
-#define IDS_AINFO_SIZE           352
-#define IDS_AINFO_URLSITE        353
-#define IDS_AINFO_LICENSE        354
-#define IDS_AINFO_URLDOWNLOAD    355
+#define IDS_AINFO_VERSION            350
+#define IDS_AINFO_DESCRIPTION        351
+#define IDS_AINFO_SIZE               352
+#define IDS_AINFO_URLSITE            353
+#define IDS_AINFO_LICENSE            354
+#define IDS_AINFO_URLDOWNLOAD        355
+#define IDS_AINFO_AVAILABLEVERSION   356
+
 
 /* Names of categories */
 #define IDS_CAT_AUDIO            700