[RAPPS] Update check, license type
authorAlexander Shaposhnikov <sanchaez@reactos.org>
Thu, 29 Jun 2017 14:17:16 +0000 (14:17 +0000)
committerAlexander Shaposhnikov <sanchaez@reactos.org>
Thu, 29 Jun 2017 14:17:16 +0000 (14:17 +0000)
* Added LicenseType numeric field in the RAPPS DB files.
  Values mean: 1 - open source, 2 - freeware, 3 - trial/demo
  The existing License field will be used to contain the license name itself.
* Finished version parser and update check.
  Now RAPPS can suggest an update.
* Added new strings to lang/en-US.rc, lang/ru-RU.rc, lang/uk-UA.rc

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

reactos/base/applications/rapps/available.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 fd26eea..66277d2 100644 (file)
@@ -87,27 +87,59 @@ BOOL
 ShowAvailableAppInfo(INT Index)
 {
     PAPPLICATION_INFO Info = (PAPPLICATION_INFO) ListViewGetlParam(Index);
-    BOOL bIsInstalled = _AppInstallCheck(Info);
-    WCHAR szVersion[MAX_PATH];
+    WCHAR szVersion[MAX_PATH] = L"\0";
+    WCHAR szLicense[MAX_PATH] = L"\0";
+    BOOL bIsInstalled = _AppInstallCheck(Info), 
+        bHasVersion = _GetInstalledVersion(Info, szVersion, _countof(szVersion));
 
     if (!Info) return FALSE;
 
     NewRichEditText(Info->szName, CFE_BOLD);
+    //installed status
     if (bIsInstalled)
     {
-        _AddTextNewl(IDS_STATUS_INSTALLED, CFE_ITALIC);
-        if (_GetInstalledVersion(Info, szVersion, _countof(szVersion)))
+        if (bHasVersion)
         {
+            if (CompareVersionsStrings(Info->szVersion, szVersion))
+                _AddTextNewl(IDS_STATUS_UPDATE_AVAILABLE, CFE_ITALIC);
+            else
+                _AddTextNewl(IDS_STATUS_INSTALLED, CFE_ITALIC);
+
             _AddText(IDS_AINFO_VERSION, szVersion, CFE_BOLD, 0);
-        }
+        } 
+        else
+            _AddTextNewl(IDS_STATUS_INSTALLED, CFE_ITALIC);
+
     }
     else
-    {
         _AddTextNewl(IDS_STATUS_NOTINSTALLED, CFE_ITALIC);
-    }
+
 
     _AddText(IDS_AINFO_AVAILABLEVERSION, Info->szVersion, CFE_BOLD, 0);
-    _AddText(IDS_AINFO_LICENSE, Info->szLicense, CFE_BOLD, 0);
+    //license
+    switch (Info->LicenseType)
+    {
+        case LICENSE_TYPE::OpenSource:
+            LoadStringW(hInst, IDS_LICENSE_OPENSOURCE, szLicense, _countof(szLicense));
+            break;
+        case LICENSE_TYPE::Freeware:
+            LoadStringW(hInst, IDS_LICENSE_FREEWARE, szLicense, _countof(szLicense));
+            break;
+        case LICENSE_TYPE::Trial:
+            LoadStringW(hInst, IDS_LICENSE_TRIAL, szLicense, _countof(szLicense));
+            break;
+        default:
+            break;
+    }
+    if (szLicense[0] != '\0')
+    {
+        StringCbPrintfW(szLicense, _countof(szLicense), L"%ls (%ls)", szLicense, Info->szLicense);
+        _AddText(IDS_AINFO_LICENSE, szLicense, CFE_BOLD, 0);
+    }
+    else
+    {
+        _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);
@@ -297,6 +329,11 @@ EnumAvailableApplications(INT EnumType, AVAILENUMPROC lpEnumProc)
             break;
 
         Info->Category = ParserGetInt(L"Category", FindFileData.cFileName);
+        INT IntBuffer = ParserGetInt(L"LicenseType", FindFileData.cFileName);
+        if (IntBuffer < LICENSE_TYPE::Max)
+        {
+            Info->LicenseType = (LICENSE_TYPE) IntBuffer;
+        }
 
         /* copy the cache-related fields for the next time */
         RtlCopyMemory(&Info->cFileName, &FindFileData.cFileName, MAX_PATH);
@@ -331,6 +368,7 @@ EnumAvailableApplications(INT EnumType, AVAILENUMPROC lpEnumProc)
             _GetStringNullFailure(L"Size", Info->szSize, FindFileData.cFileName);
             _GetStringNullFailure(L"URLSite", Info->szUrlSite, FindFileData.cFileName);
             _GetStringNullFailure(L"CDPath", Info->szCDPath, FindFileData.cFileName);
+            _GetStringNullFailure(L"Language", Info->szRegName, FindFileData.cFileName);
             _GetStringNullFailure(L"SHA1", Info->szSHA1, FindFileData.cFileName);
         }
 
index 2c31109..f3431cd 100644 (file)
@@ -217,3 +217,10 @@ BEGIN
     IDS_STATUS_DOWNLOADING "Downloading…"
     IDS_STATUS_INSTALLING "Installing…"
 END
+
+STRINGTABLE
+BEGIN
+    IDS_LICENSE_OPENSOURCE "Open Source"
+    IDS_LICENSE_FREEWARE "Freeware"
+    IDS_LICENSE_TRIAL "Trial/Demo"
+END
index f31acb4..7f95c9b 100644 (file)
@@ -216,4 +216,11 @@ BEGIN
     IDS_STATUS_UPDATE_AVAILABLE "Есть обновления"
     IDS_STATUS_DOWNLOADING "Загружается…"
     IDS_STATUS_INSTALLING "Установка…"
+END
+
+STRINGTABLE
+BEGIN
+    IDS_LICENSE_OPENSOURCE "Свободное ПО"
+    IDS_LICENSE_FREEWARE "Бесплатное ПО"
+    IDS_LICENSE_TRIAL "Пробная версия"
 END
\ No newline at end of file
index f823c10..4f28b3e 100644 (file)
@@ -215,3 +215,20 @@ BEGIN
     IDS_INTERRUPTED_DOWNLOAD "The download was interrupted. Check connection to Internet."
     IDS_UNABLE_TO_WRITE "Unable to write to disk. Disk may be at capacity."
 END
+
+STRINGTABLE
+BEGIN
+    IDS_STATUS_INSTALLED "Встановлено"
+    IDS_STATUS_NOTINSTALLED "Не встановлено"
+    IDS_STATUS_DOWNLOADED "Завантажено"
+    IDS_STATUS_UPDATE_AVAILABLE "Є оновлення"
+    IDS_STATUS_DOWNLOADING "Завантажується…"
+    IDS_STATUS_INSTALLING "Встановлюється…"
+END
+
+STRINGTABLE
+BEGIN
+    IDS_LICENSE_OPENSOURCE "Вільне ПЗ"
+    IDS_LICENSE_FREEWARE "Безкоштовне ПЗ"
+    IDS_LICENSE_TRIAL "Пробна версія"
+END
\ No newline at end of file
index 0bd0e9a..159c739 100644 (file)
@@ -20,6 +20,8 @@ WCHAR szCachedINISectionLocale[MAX_PATH] = L"Section.";
 WCHAR szCachedINISectionLocaleNeutral[MAX_PATH] = {0};
 BYTE bCachedSectionStatus = FALSE;
 
+#define STR_VERSION_CURRENT L"CURRENT"
+
 typedef struct
 {
     int erfOper;
@@ -500,39 +502,58 @@ UINT ParserGetInt(LPCWSTR lpKeyName, LPCWSTR lpFileName)
     return (UINT)Result;
 }
 
-//Parses version string that can be formatted as 1.2.3.4-5
+template<typename XCHAR>
+inline BOOL IsCharNumeric(XCHAR ch)
+{
+    return IsCharAlphaNumeric(ch) && !IsCharAlpha(ch);
+}
+
+
+//Parses version string that can be formatted as 1.2.3-4b (or CURRENT)
 //Returns int buffer and it's size
 BOOL
-ParseVersion(_In_z_ LPCWSTR szVersion, _Outptr_ INT* parrVersion, _Out_opt_ UINT iVersionSize)
+ParseVersion(_In_z_ LPCWSTR szVersion, _Outptr_ PVERSION_INFO Version)
 {
-    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')
+    INT VersionCharCount = 0;
+    INT VersionLength = lstrlenW(szVersion);
+    StringCbCopyW(Version->szVersion, VersionLength * sizeof(szVersion), szVersion);
+    //CURRENT
+    if (!StrCmpW(szVersion, STR_VERSION_CURRENT))
     {
-        for (;!sDelimiters.Find(szVersion[iVersionCharCount]); ++iVersionCharCount)
-        {
-            szVersionSingleInt += szVersion[iVersionCharCount];
-        }
-        szVersionSingleInt += L'\0';
-        iIntResult = StrToIntW(szVersionSingleInt.GetBuffer());
-        if (iIntResult)
+        Version->VersionSize = NULL;
+        return bHasParsed;
+    }
+
+    Version->VersionSize = 0;
+    //int expected every iteration, quit the loop if its not a number
+    while (Version->VersionSize < MAX_VERSION 
+        && IsCharNumeric(szVersion[VersionCharCount]) 
+        && VersionCharCount < VersionLength)
+    {
+        for (; IsCharNumeric(szVersion[VersionCharCount]) && VersionCharCount < VersionLength; ++VersionCharCount)
         {
-            arrVersionResult.Add(iIntResult);
-            iVersionSize++;
+            szVersionSingleInt += szVersion[VersionCharCount];
         }
-        else
+        if (szVersionSingleInt.IsEmpty())
         {
             bHasParsed = FALSE;
+            continue;
         }
-        ++iVersionCharCount;
+        INT IntResult = StrToIntW(szVersionSingleInt.GetBuffer());
+        Version->arrVersion[Version->VersionSize] = IntResult;
+        ++Version->VersionSize;
+        szVersionSingleInt.Empty();
+        ++VersionCharCount;
+    }
+
+    if (IsCharAlphaW(szVersion[VersionCharCount]))
+    {
+        Version->cVersionSuffix = szVersion[VersionCharCount];
     }
-    parrVersion = arrVersionResult.GetData();
+    else
+        Version->cVersionSuffix = NULL;
     return bHasParsed;
 }
 
@@ -540,27 +561,54 @@ ParseVersion(_In_z_ LPCWSTR szVersion, _Outptr_ INT* parrVersion, _Out_opt_ UINT
 //In:   Zero terminated strings of versions
 //Out:  TRUE if first is bigger than second, FALSE if else
 BOOL
-CompareVersionsBigger(_In_z_ LPCWSTR sczVersion1, _In_z_ LPCWSTR sczVersion2, _Out_ BOOL bResult)
+CompareVersionsStrings(_In_z_ LPCWSTR sczVersionLeft, _In_z_ LPCWSTR sczVersionRight)
 {
-    UINT iVersionSize1 = 0;
-    UINT iVersionSize2 = 0;
-    INT *parrVersion1 = NULL, *parrVersion2 = NULL;
-    bResult = FALSE;
+    VERSION_INFO LeftVersion, RightVersion;
 
-    if (!ParseVersion(sczVersion1, parrVersion1, iVersionSize1)
-        || !ParseVersion(sczVersion2, parrVersion2, iVersionSize2))
+    if (!ParseVersion(sczVersionLeft, &LeftVersion)
+        || !ParseVersion(sczVersionRight, &RightVersion))
     {
         return FALSE;
     }
 
-    for (INT i = 0; i < iVersionSize1 && i < iVersionSize2; ++i)
+    return CompareVersions(&LeftVersion, &RightVersion);  
+}
+
+BOOL
+CompareVersions(_In_ PVERSION_INFO LeftVersion, _In_ PVERSION_INFO RightVersion)
+{
+    //CURRENT 
+    if (!LeftVersion->VersionSize || !RightVersion->VersionSize)
     {
-        if (parrVersion1[i] > parrVersion2[i])
+        return FALSE;
+    }
+    //1.2.3 > 1.2
+    INT SizeDiff = LeftVersion->VersionSize - RightVersion->VersionSize;
+    if (SizeDiff > 0)
+    {
+        return TRUE;
+    }
+    if (SizeDiff < 0)
+    {
+        return FALSE;
+    }
+    //2.0.0 > 1.9.9
+    for (INT i = 0; i < LeftVersion->VersionSize && i < RightVersion->VersionSize && i < MAX_VERSION; ++i)
+    {
+        if (LeftVersion->arrVersion[i] > RightVersion->arrVersion[i])
         {
-            bResult = TRUE;
             return TRUE;
         }
+        if (LeftVersion->arrVersion[i] < RightVersion->arrVersion[i])
+        {
+            return FALSE;
+        }
+    }
+    //1.2.3b > 1.2.3
+    if (LeftVersion->cVersionSuffix > RightVersion->cVersionSuffix)
+    {
+        return TRUE;
     }
 
-    return TRUE;
+    return FALSE;
 }
\ No newline at end of file
index 61868ff..837ef60 100644 (file)
@@ -39,7 +39,7 @@
 
 #define SPLIT_WIDTH 4
 #define MAX_STR_LEN 256
-
+#define MAX_VERSION 10
 #define LISTVIEW_ICON_SIZE 24
 #define TREEVIEW_ICON_SIZE 24
 
 #define IS_INSTALLED_ENUM(a) (a >= ENUM_INSTALLED_MIN && a <= ENUM_INSTALLED_MAX)
 #define IS_AVAILABLE_ENUM(a) (a >= ENUM_AVAILABLE_MIN && a <= ENUM_AVAILABLE_MAX)
 
-
-/* aboutdlg.c */
+typedef enum
+{
+    None,
+    OpenSource,
+    Freeware,
+    Trial,
+    Max = Trial,
+    Min = None
+} LICENSE_TYPE, *PLICENSE_TYPE;
+
+/* aboutdlg.cpp */
 VOID ShowAboutDialog(VOID);
 
-/* available.c */
+/* available.cpp */
 typedef struct
 {
     INT Category;
+    LICENSE_TYPE LicenseType;
     WCHAR szName[MAX_PATH];
     WCHAR szRegName[MAX_PATH];
     WCHAR szVersion[MAX_PATH];
@@ -90,6 +100,7 @@ typedef struct
     WCHAR szUrlSite[MAX_PATH];
     WCHAR szUrlDownload[MAX_PATH];
     WCHAR szCDPath[MAX_PATH];
+    WCHAR szLanguages[MAX_PATH];
 
     /* caching mechanism related entries */
     WCHAR cFileName[MAX_PATH];
@@ -129,17 +140,26 @@ typedef struct
 
 } SETTINGS_INFO, *PSETTINGS_INFO;
 
-/* available.c */
+typedef struct
+{
+    INT arrVersion[MAX_VERSION];
+    UINT VersionSize;
+    WCHAR cVersionSuffix = (WCHAR) NULL;
+    WCHAR szVersion[MAX_PATH];
+} VERSION_INFO, *PVERSION_INFO;
+
+/* available.cpp */
 typedef BOOL (CALLBACK *AVAILENUMPROC)(PAPPLICATION_INFO Info);
 BOOL EnumAvailableApplications(INT EnumType, AVAILENUMPROC lpEnumProc);
 BOOL ShowAvailableAppInfo(INT Index);
 BOOL UpdateAppsDB(VOID);
 VOID FreeCachedAvailableEntries(VOID);
 
-/* installdlg.c */
+
+/* installdlg.cpp */
 BOOL InstallApplication(INT Index);
 
-/* installed.c */
+/* installed.cpp */
 typedef BOOL (CALLBACK *APPENUMPROC)(INT ItemIndex, LPWSTR lpName, PINSTALLED_INFO Info);
 BOOL EnumInstalledApplications(INT EnumType, BOOL IsUserKey, APPENUMPROC lpEnumProc);
 BOOL GetApplicationString(HKEY hKey, LPCWSTR lpKeyName, LPWSTR lpString);
@@ -150,7 +170,7 @@ VOID RemoveAppFromRegistry(INT Index);
 
 BOOL InstalledVersion(LPWSTR szVersionResult, UINT iVersionResultSize, LPCWSTR lpRegName, BOOL IsUserKey, REGSAM keyWow);
 
-/* winmain.c */
+/* winmain.cpp */
 extern HWND hMainWnd;
 extern HINSTANCE hInst;
 extern INT SelectedEnumType;
@@ -158,11 +178,11 @@ extern SETTINGS_INFO SettingsInfo;
 VOID SaveSettings(HWND hwnd);
 VOID FillDefaultSettings(PSETTINGS_INFO pSettingsInfo);
 
-/* loaddlg.c */
+/* loaddlg.cpp */
 BOOL DownloadApplication(INT Index);
 VOID DownloadApplicationsDB(LPCWSTR lpUrl);
 
-/* misc.c */
+/* misc.cpp */
 INT GetSystemColorDepth(VOID);
 int GetWindowWidth(HWND hwnd);
 int GetWindowHeight(HWND hwnd);
@@ -181,11 +201,11 @@ 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);
+BOOL ParseVersion(_In_z_ LPCWSTR szVersion, _Outptr_ PVERSION_INFO parrVersion);
+BOOL CompareVersionsStrings(_In_z_ LPCWSTR sczVersionLeft, _In_z_ LPCWSTR sczVersionRight);
+BOOL CompareVersions(_In_ PVERSION_INFO LeftVersion, _In_ PVERSION_INFO RightVersion);
 
-/* settingsdlg.c */
+/* settingsdlg.cpp */
 VOID CreateSettingsDlg(HWND hwnd);
 
 /* gui.cpp */
index de3f21a..a89b8cb 100644 (file)
 #define IDS_STATUS_DOWNLOADING        804
 #define IDS_STATUS_INSTALLING         805
 
+/* App license names */
+#define IDS_LICENSE_OPENSOURCE  900
+#define IDS_LICENSE_FREEWARE 901
+#define IDS_LICENSE_TRIAL 902
 
 /* Accelerators */
 #define HOTKEYS                  715