[RAPPS] Update check, license type

* 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
This commit is contained in:
Alexander Shaposhnikov 2017-06-29 14:17:16 +00:00
parent de725c5391
commit 82f11f1d0b
7 changed files with 195 additions and 54 deletions

View 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);
//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
{
_AddTextNewl(IDS_STATUS_NOTINSTALLED, CFE_ITALIC);
_AddText(IDS_AINFO_LICENSE, Info->szLicense, CFE_BOLD, 0);
}
_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);
@ -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);
}

View 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

View 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

View 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

View 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)
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)
{
szVersionSingleInt += szVersion[iVersionCharCount];
szVersionSingleInt += szVersion[VersionCharCount];
}
szVersionSingleInt += L'\0';
iIntResult = StrToIntW(szVersionSingleInt.GetBuffer());
if (iIntResult)
{
arrVersionResult.Add(iIntResult);
iVersionSize++;
}
else
if (szVersionSingleInt.IsEmpty())
{
bHasParsed = FALSE;
continue;
}
++iVersionCharCount;
INT IntResult = StrToIntW(szVersionSingleInt.GetBuffer());
Version->arrVersion[Version->VersionSize] = IntResult;
++Version->VersionSize;
szVersionSingleInt.Empty();
++VersionCharCount;
}
parrVersion = arrVersionResult.GetData();
if (IsCharAlphaW(szVersion[VersionCharCount]))
{
Version->cVersionSuffix = szVersion[VersionCharCount];
}
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;
}

View 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
@ -73,14 +73,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)
typedef enum
{
None,
OpenSource,
Freeware,
Trial,
Max = Trial,
Min = None
} LICENSE_TYPE, *PLICENSE_TYPE;
/* aboutdlg.c */
/* 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 */

View file

@ -172,6 +172,10 @@
#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