2015-04-22 16:53:55 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Applications Manager
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
2017-04-02 14:46:54 +00:00
|
|
|
* FILE: base/applications/rapps/available.cpp
|
2017-07-18 22:52:51 +00:00
|
|
|
* PURPOSE: Classes for working with available applications
|
2015-04-22 16:53:55 +00:00
|
|
|
* PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
|
|
|
|
* Ismael Ferreras Morezuelas (swyterzone+ros@gmail.com)
|
2017-07-10 21:02:24 +00:00
|
|
|
* Alexander Shaposhnikov (chaez.san@gmail.com)
|
2015-04-22 16:53:55 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "rapps.h"
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
// CAvailableApplicationInfo
|
2017-07-10 21:02:24 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
CAvailableApplicationInfo::CAvailableApplicationInfo(const ATL::CStringW& sFileNameParam)
|
2017-06-27 23:33:15 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
LicenseType = LICENSE_TYPE::None;
|
|
|
|
sFileName = sFileNameParam;
|
|
|
|
RetrieveCategory();
|
2017-06-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
VOID CAvailableApplicationInfo::RefreshAppInfo()
|
2017-06-27 23:33:15 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
if (RetrieveGeneralInfo())
|
2017-07-10 21:02:24 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
RetrieveLicenseType();
|
|
|
|
RetrieveLanguages();
|
|
|
|
RetrieveInstalledStatus();
|
|
|
|
if (m_IsInstalled)
|
|
|
|
{
|
|
|
|
RetrieveInstalledVersion();
|
|
|
|
}
|
2017-07-10 21:02:24 +00:00
|
|
|
}
|
2017-06-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
BOOL CAvailableApplicationInfo::RetrieveGeneralInfo()
|
2017-06-27 23:33:15 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
if (szUrlDownload.IsEmpty())
|
2017-06-27 23:33:15 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
if (!GetString(L"Name", szName)
|
|
|
|
|| !GetString(L"URLDownload", szUrlDownload))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2017-07-13 15:29:53 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
GetString(L"RegName", szRegName);
|
|
|
|
GetString(L"Version", szVersion);
|
|
|
|
GetString(L"License", szLicense);
|
|
|
|
GetString(L"Description", szDesc);
|
|
|
|
GetString(L"Size", szSize);
|
|
|
|
GetString(L"URLSite", szUrlSite);
|
|
|
|
GetString(L"CDPath", szCDPath);
|
|
|
|
GetString(L"Language", szRegName);
|
|
|
|
GetString(L"SHA1", szSHA1);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
2017-06-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
VOID CAvailableApplicationInfo::RetrieveInstalledStatus()
|
2017-06-27 23:33:15 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
m_IsInstalled = ::GetInstalledVersion(NULL, szRegName)
|
|
|
|
|| ::GetInstalledVersion(NULL, szName);
|
2017-06-27 23:21:58 +00:00
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
VOID CAvailableApplicationInfo::RetrieveInstalledVersion()
|
2017-06-27 23:21:58 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
m_HasInstalledVersion = ::GetInstalledVersion(&szInstalledVersion, szRegName)
|
|
|
|
|| ::GetInstalledVersion(&szInstalledVersion, szName);
|
2017-06-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
BOOL CAvailableApplicationInfo::RetrieveLanguages()
|
2017-07-13 15:29:53 +00:00
|
|
|
{
|
|
|
|
const WCHAR cDelimiter = L'|';
|
|
|
|
ATL::CStringW szBuffer;
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
// TODO: Get multiline parameter
|
|
|
|
if (!ParserGetString(L"Languages", sFileName, szBuffer))
|
|
|
|
return FALSE;
|
2017-07-13 15:29:53 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
// Parse parameter string
|
2017-07-13 15:29:53 +00:00
|
|
|
ATL::CStringW szLocale;
|
|
|
|
for (INT i = 0; szBuffer[i] != UNICODE_NULL; ++i)
|
|
|
|
{
|
|
|
|
if (szBuffer[i] != cDelimiter)
|
|
|
|
{
|
|
|
|
szLocale += szBuffer[i];
|
2017-07-18 22:52:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Languages.Add(szLocale);
|
2017-07-13 15:29:53 +00:00
|
|
|
szLocale.Empty();
|
|
|
|
}
|
|
|
|
}
|
2017-07-18 22:52:51 +00:00
|
|
|
|
2017-07-13 15:29:53 +00:00
|
|
|
// For the text after delimiter
|
|
|
|
if (!szLocale.IsEmpty())
|
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
Languages.Add(szLocale);
|
2017-07-13 15:29:53 +00:00
|
|
|
}
|
2017-07-18 22:52:51 +00:00
|
|
|
|
|
|
|
return TRUE;
|
2017-07-13 15:29:53 +00:00
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
VOID CAvailableApplicationInfo::RetrieveLicenseType()
|
2017-07-13 15:29:53 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
INT IntBuffer = ParserGetInt(L"LicenseType", sFileName);
|
|
|
|
|
|
|
|
if (IntBuffer < 0 || IntBuffer > LICENSE_TYPE::Max)
|
2017-07-13 15:29:53 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
LicenseType = LICENSE_TYPE::None;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LicenseType = (LICENSE_TYPE) IntBuffer;
|
2017-07-13 15:29:53 +00:00
|
|
|
}
|
|
|
|
}
|
2017-07-18 22:52:51 +00:00
|
|
|
|
|
|
|
VOID CAvailableApplicationInfo::RetrieveCategory()
|
2017-07-13 22:01:02 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
Category = ParserGetInt(L"Category", sFileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL CAvailableApplicationInfo::HasLanguageInfo() const
|
|
|
|
{
|
|
|
|
return m_HasLanguageInfo;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL CAvailableApplicationInfo::HasNativeLanguage() const
|
|
|
|
{
|
|
|
|
if (!m_HasLanguageInfo)
|
2017-07-13 22:01:02 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2017-07-18 22:52:51 +00:00
|
|
|
|
2017-07-13 22:01:02 +00:00
|
|
|
//TODO: make the actual check
|
|
|
|
return TRUE;
|
|
|
|
}
|
2017-07-13 15:29:53 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
BOOL CAvailableApplicationInfo::HasEnglishLanguage() const
|
2017-07-13 15:29:53 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
if (!m_HasLanguageInfo)
|
2017-07-13 15:29:53 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
return FALSE;
|
2017-07-13 15:29:53 +00:00
|
|
|
}
|
2017-06-04 21:36:14 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
//TODO: make the actual check
|
|
|
|
return TRUE;
|
|
|
|
}
|
2015-04-22 16:53:55 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
BOOL CAvailableApplicationInfo::IsInstalled() const
|
2015-04-22 16:53:55 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
return m_IsInstalled;
|
2017-07-13 15:29:53 +00:00
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
BOOL CAvailableApplicationInfo::HasInstalledVersion() const
|
2017-07-13 15:29:53 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
return m_HasInstalledVersion;
|
|
|
|
}
|
2017-07-10 21:02:24 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
BOOL CAvailableApplicationInfo::HasUpdate() const
|
|
|
|
{
|
|
|
|
return (szInstalledVersion.Compare(szVersion) < 0) ? TRUE : FALSE;
|
2017-07-13 15:29:53 +00:00
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
VOID CAvailableApplicationInfo::SetLastWriteTime(FILETIME* ftTime)
|
2017-07-13 22:01:02 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
RtlCopyMemory(&ftCacheStamp, ftTime, sizeof(FILETIME));
|
|
|
|
}
|
2017-07-13 22:01:02 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
inline BOOL CAvailableApplicationInfo::GetString(LPCWSTR lpKeyName, ATL::CStringW& ReturnedString)
|
|
|
|
{
|
|
|
|
if (!ParserGetString(lpKeyName, sFileName, ReturnedString))
|
2017-07-13 22:01:02 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
ReturnedString.Empty();
|
|
|
|
return FALSE;
|
2017-07-13 22:01:02 +00:00
|
|
|
}
|
2017-07-18 22:52:51 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
2017-07-13 22:01:02 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
// CAvailableApps
|
|
|
|
CAvailableApps::CAvailableApps()
|
|
|
|
{
|
|
|
|
//set all paths
|
|
|
|
if (GetStorageDirectory(m_szPath))
|
2017-07-13 22:01:02 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
m_szAppsPath = m_szPath + L"\\rapps\\";
|
|
|
|
m_szCabPath = m_szPath + L"\\rappmgr.cab";
|
|
|
|
m_szSearchPath = m_szAppsPath + L"*.txt";
|
2017-07-13 22:01:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
VOID CAvailableApps::FreeCachedEntries()
|
2017-07-13 15:29:53 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
POSITION InfoListPosition = m_InfoList.GetHeadPosition();
|
2017-07-13 15:29:53 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
/* loop and deallocate all the cached app infos in the list */
|
|
|
|
while (InfoListPosition)
|
|
|
|
{
|
|
|
|
CAvailableApplicationInfo* Info = m_InfoList.GetAt(InfoListPosition);
|
|
|
|
m_InfoList.RemoveHead();
|
|
|
|
delete Info;
|
2015-04-22 16:53:55 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
InfoListPosition = m_InfoList.GetHeadPosition();
|
|
|
|
}
|
2015-04-22 16:53:55 +00:00
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
BOOL CAvailableApps::DeleteCurrentAppsDB()
|
2015-04-22 16:53:55 +00:00
|
|
|
{
|
|
|
|
HANDLE hFind = INVALID_HANDLE_VALUE;
|
|
|
|
WIN32_FIND_DATAW FindFileData;
|
|
|
|
BOOL result = TRUE;
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
if (m_szPath.IsEmpty())
|
2015-04-22 16:53:55 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
result = result && DeleteFileW(m_szCabPath.GetString());
|
|
|
|
hFind = FindFirstFileW(m_szSearchPath.GetString(), &FindFileData);
|
2015-04-22 16:53:55 +00:00
|
|
|
|
|
|
|
if (hFind == INVALID_HANDLE_VALUE)
|
|
|
|
return result;
|
|
|
|
|
2017-07-10 21:02:24 +00:00
|
|
|
ATL::CStringW szTmp;
|
2015-04-22 16:53:55 +00:00
|
|
|
do
|
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
szTmp = m_szPath + FindFileData.cFileName;
|
2017-07-10 21:02:24 +00:00
|
|
|
result = result && DeleteFileW(szTmp.GetString());
|
|
|
|
} while (FindNextFileW(hFind, &FindFileData) != 0);
|
2015-04-22 16:53:55 +00:00
|
|
|
|
|
|
|
FindClose(hFind);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
BOOL CAvailableApps::UpdateAppsDB()
|
2015-04-22 16:53:55 +00:00
|
|
|
{
|
|
|
|
if (!DeleteCurrentAppsDB())
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
DownloadApplicationsDB(APPLICATION_DATABASE_URL);
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
if (m_szPath.IsEmpty())
|
2015-04-22 16:53:55 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
if (!ExtractFilesFromCab(m_szCabPath, m_szAppsPath))
|
2015-04-22 16:53:55 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
BOOL CAvailableApps::EnumAvailableApplications(INT EnumType, AVAILENUMPROC lpEnumProc)
|
2015-04-22 16:53:55 +00:00
|
|
|
{
|
|
|
|
HANDLE hFind = INVALID_HANDLE_VALUE;
|
|
|
|
WIN32_FIND_DATAW FindFileData;
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
if (!CreateDirectoryW(m_szPath.GetString(), NULL) &&
|
2015-04-22 16:53:55 +00:00
|
|
|
GetLastError() != ERROR_ALREADY_EXISTS)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
hFind = FindFirstFileW(m_szSearchPath.GetString(), &FindFileData);
|
2015-04-22 16:53:55 +00:00
|
|
|
|
|
|
|
if (hFind == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
if (GetFileAttributesW(m_szCabPath) == INVALID_FILE_ATTRIBUTES)
|
2015-04-22 16:53:55 +00:00
|
|
|
DownloadApplicationsDB(APPLICATION_DATABASE_URL);
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
ExtractFilesFromCab(m_szCabPath, m_szAppsPath);
|
|
|
|
hFind = FindFirstFileW(m_szSearchPath.GetString(), &FindFileData);
|
2015-04-22 16:53:55 +00:00
|
|
|
|
|
|
|
if (hFind == INVALID_HANDLE_VALUE)
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/* loop for all the cached entries */
|
2017-07-18 22:52:51 +00:00
|
|
|
POSITION CurrentListPosition = m_InfoList.GetHeadPosition();
|
|
|
|
CAvailableApplicationInfo* Info = NULL;
|
2017-07-10 21:02:24 +00:00
|
|
|
|
|
|
|
while (CurrentListPosition != NULL)
|
2015-04-22 16:53:55 +00:00
|
|
|
{
|
2017-07-10 21:02:24 +00:00
|
|
|
POSITION LastListPosition = CurrentListPosition;
|
2017-07-18 22:52:51 +00:00
|
|
|
Info = m_InfoList.GetNext(CurrentListPosition);
|
2015-04-22 16:53:55 +00:00
|
|
|
|
|
|
|
/* do we already have this entry in cache? */
|
2017-07-18 22:52:51 +00:00
|
|
|
if (Info->sFileName == FindFileData.cFileName)
|
2015-04-22 16:53:55 +00:00
|
|
|
{
|
|
|
|
/* is it current enough, or the file has been modified since our last time here? */
|
|
|
|
if (CompareFileTime(&FindFileData.ftLastWriteTime, &Info->ftCacheStamp) == 1)
|
|
|
|
{
|
|
|
|
/* recreate our cache, this is the slow path */
|
2017-07-18 22:52:51 +00:00
|
|
|
m_InfoList.RemoveAt(LastListPosition);
|
|
|
|
|
2017-07-10 21:02:24 +00:00
|
|
|
delete Info;
|
2017-07-18 22:52:51 +00:00
|
|
|
Info = nullptr;
|
2017-07-10 21:02:24 +00:00
|
|
|
break;
|
2015-04-22 16:53:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* speedy path, compare directly, we already have the data */
|
|
|
|
goto skip_if_cached;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create a new entry */
|
2017-07-18 22:52:51 +00:00
|
|
|
Info = new CAvailableApplicationInfo(FindFileData.cFileName);
|
2015-04-22 16:53:55 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
/* set a timestamp for the next time */
|
|
|
|
Info->SetLastWriteTime(&FindFileData.ftLastWriteTime);
|
|
|
|
m_InfoList.AddTail(Info);
|
2015-04-22 16:53:55 +00:00
|
|
|
|
2017-07-10 21:02:24 +00:00
|
|
|
skip_if_cached:
|
2015-04-22 16:53:55 +00:00
|
|
|
if (Info->Category == FALSE)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (EnumType != Info->Category && EnumType != ENUM_ALL_AVAILABLE)
|
|
|
|
continue;
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
Info->RefreshAppInfo();
|
2015-04-22 16:53:55 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
if (!lpEnumProc(static_cast<PAPPLICATION_INFO>(Info), m_szAppsPath.GetString()))
|
2015-04-22 16:53:55 +00:00
|
|
|
break;
|
|
|
|
|
2017-07-10 21:02:24 +00:00
|
|
|
} while (FindNextFileW(hFind, &FindFileData) != 0);
|
2015-04-22 16:53:55 +00:00
|
|
|
|
|
|
|
FindClose(hFind);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
const ATL::CStringW & CAvailableApps::GetFolderPath()
|
2015-04-22 16:53:55 +00:00
|
|
|
{
|
2017-07-18 22:52:51 +00:00
|
|
|
return m_szPath;
|
|
|
|
}
|
2017-07-13 15:29:53 +00:00
|
|
|
|
2017-07-18 22:52:51 +00:00
|
|
|
const ATL::CStringW & CAvailableApps::GetAppPath()
|
|
|
|
{
|
|
|
|
return m_szAppsPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
const ATL::CStringW & CAvailableApps::GetCabPath()
|
|
|
|
{
|
|
|
|
return m_szCabPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
const LPCWSTR CAvailableApps::GetFolderPathString()
|
|
|
|
{
|
|
|
|
return m_szPath.GetString();
|
|
|
|
}
|
|
|
|
|
|
|
|
const LPCWSTR CAvailableApps::GetAppPathString()
|
|
|
|
{
|
|
|
|
return m_szPath.GetString();
|
|
|
|
}
|
|
|
|
|
|
|
|
const LPCWSTR CAvailableApps::GetCabPathString()
|
|
|
|
{
|
|
|
|
return m_szPath.GetString();
|
|
|
|
}
|