mirror of
https://github.com/reactos/reactos.git
synced 2024-11-19 05:22:59 +00:00
4b03981846
Tries now to map the "License" text set to "Freeware" to the LICENSE_FREEWARE "LicenseType" so it is translated correctly (LoadString). Fixes the following: - If only the "License" field is set in the DB, nothing will change (this applies to 99% of the current entries in the DB). - If both "LicenseType" and "License" are set, both will be used (no observable change in behavior): "Open Source (GPL v2)" etc. - If only "LicenseType" is set, it will now display just the type "Freeware" instead of "Freeware ()". This is done only for "Freeware", because the others (the open source ones) have many variations. "OpenSource", "Open Source", "Open Source (GPL)" etc.
637 lines
17 KiB
C++
637 lines
17 KiB
C++
/*
|
|
* PROJECT: ReactOS Applications Manager
|
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
|
* PURPOSE: Classes for working with available applications
|
|
* COPYRIGHT: Copyright 2017 Alexander Shaposhnikov (sanchaez@reactos.org)
|
|
* Copyright 2020 He Yang (1160386205@qq.com)
|
|
* Copyright 2021-2023 Mark Jansen <mark.jansen@reactos.org>
|
|
*/
|
|
|
|
#include "rapps.h"
|
|
#include "appview.h"
|
|
|
|
CAppInfo::CAppInfo(const CStringW &Identifier, AppsCategories Category)
|
|
: szIdentifier(Identifier), iCategory(Category)
|
|
{
|
|
}
|
|
|
|
CAppInfo::~CAppInfo()
|
|
{
|
|
}
|
|
|
|
CAvailableApplicationInfo::CAvailableApplicationInfo(
|
|
CConfigParser *Parser,
|
|
const CStringW &PkgName,
|
|
AppsCategories Category,
|
|
const CPathW &BasePath)
|
|
: CAppInfo(PkgName, Category), m_Parser(Parser), m_ScrnshotRetrieved(false), m_LanguagesLoaded(false)
|
|
{
|
|
m_Parser->GetString(L"Name", szDisplayName);
|
|
m_Parser->GetString(L"Version", szDisplayVersion);
|
|
m_Parser->GetString(L"URLDownload", m_szUrlDownload);
|
|
m_Parser->GetString(L"Description", szComments);
|
|
|
|
CPathW IconPath = BasePath;
|
|
IconPath += L"icons";
|
|
|
|
CStringW IconName;
|
|
if (m_Parser->GetString(L"Icon", IconName))
|
|
{
|
|
IconPath += IconName;
|
|
}
|
|
else
|
|
{
|
|
// inifile.ico
|
|
IconPath += (szIdentifier + L".ico");
|
|
}
|
|
|
|
if (PathFileExistsW(IconPath))
|
|
{
|
|
szDisplayIcon = (LPCWSTR)IconPath;
|
|
}
|
|
|
|
INT iSizeBytes;
|
|
|
|
if (m_Parser->GetInt(L"SizeBytes", iSizeBytes))
|
|
{
|
|
StrFormatByteSizeW(iSizeBytes, m_szSize.GetBuffer(MAX_PATH), MAX_PATH);
|
|
m_szSize.ReleaseBuffer();
|
|
}
|
|
|
|
m_Parser->GetString(L"URLSite", m_szUrlSite);
|
|
}
|
|
|
|
CAvailableApplicationInfo::~CAvailableApplicationInfo()
|
|
{
|
|
delete m_Parser;
|
|
}
|
|
|
|
VOID
|
|
CAvailableApplicationInfo::ShowAppInfo(CAppRichEdit *RichEdit)
|
|
{
|
|
RichEdit->SetText(szDisplayName, CFE_BOLD);
|
|
InsertVersionInfo(RichEdit);
|
|
RichEdit->LoadAndInsertText(IDS_AINFO_LICENSE, LicenseString(), 0);
|
|
InsertLanguageInfo(RichEdit);
|
|
|
|
RichEdit->LoadAndInsertText(IDS_AINFO_SIZE, m_szSize, 0);
|
|
RichEdit->LoadAndInsertText(IDS_AINFO_URLSITE, m_szUrlSite, CFE_LINK);
|
|
RichEdit->LoadAndInsertText(IDS_AINFO_DESCRIPTION, szComments, 0);
|
|
RichEdit->LoadAndInsertText(IDS_AINFO_URLDOWNLOAD, m_szUrlDownload, CFE_LINK);
|
|
RichEdit->LoadAndInsertText(IDS_AINFO_PACKAGE_NAME, szIdentifier, 0);
|
|
}
|
|
|
|
int
|
|
CompareVersion(const CStringW &left, const CStringW &right)
|
|
{
|
|
int nLeft = 0, nRight = 0;
|
|
|
|
while (true)
|
|
{
|
|
CStringW leftPart = left.Tokenize(L".", nLeft);
|
|
CStringW rightPart = right.Tokenize(L".", nRight);
|
|
|
|
if (leftPart.IsEmpty() && rightPart.IsEmpty())
|
|
return 0;
|
|
if (leftPart.IsEmpty())
|
|
return -1;
|
|
if (rightPart.IsEmpty())
|
|
return 1;
|
|
|
|
int leftVal, rightVal;
|
|
|
|
if (!StrToIntExW(leftPart, STIF_DEFAULT, &leftVal))
|
|
leftVal = 0;
|
|
if (!StrToIntExW(rightPart, STIF_DEFAULT, &rightVal))
|
|
rightVal = 0;
|
|
|
|
if (leftVal > rightVal)
|
|
return 1;
|
|
if (rightVal < leftVal)
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
CAvailableApplicationInfo::InsertVersionInfo(CAppRichEdit *RichEdit)
|
|
{
|
|
CStringW szRegName;
|
|
m_Parser->GetString(L"RegName", szRegName);
|
|
|
|
BOOL bIsInstalled = ::GetInstalledVersion(NULL, szRegName) || ::GetInstalledVersion(NULL, szDisplayName);
|
|
if (bIsInstalled)
|
|
{
|
|
CStringW szInstalledVersion;
|
|
CStringW szNameVersion = szDisplayName + L" " + szDisplayVersion;
|
|
BOOL bHasInstalledVersion = ::GetInstalledVersion(&szInstalledVersion, szRegName) ||
|
|
::GetInstalledVersion(&szInstalledVersion, szDisplayName) ||
|
|
::GetInstalledVersion(&szInstalledVersion, szNameVersion);
|
|
|
|
if (bHasInstalledVersion)
|
|
{
|
|
BOOL bHasUpdate = CompareVersion(szInstalledVersion, szDisplayVersion) < 0;
|
|
if (bHasUpdate)
|
|
RichEdit->LoadAndInsertText(IDS_STATUS_UPDATE_AVAILABLE, CFE_ITALIC);
|
|
else
|
|
RichEdit->LoadAndInsertText(IDS_STATUS_INSTALLED, CFE_ITALIC);
|
|
|
|
RichEdit->LoadAndInsertText(IDS_AINFO_VERSION, szInstalledVersion, 0);
|
|
}
|
|
else
|
|
{
|
|
RichEdit->LoadAndInsertText(IDS_STATUS_INSTALLED, CFE_ITALIC);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RichEdit->LoadAndInsertText(IDS_STATUS_NOTINSTALLED, CFE_ITALIC);
|
|
}
|
|
|
|
RichEdit->LoadAndInsertText(IDS_AINFO_AVAILABLEVERSION, szDisplayVersion, 0);
|
|
}
|
|
|
|
CStringW
|
|
CAvailableApplicationInfo::LicenseString()
|
|
{
|
|
INT IntBuffer;
|
|
m_Parser->GetInt(L"LicenseType", IntBuffer);
|
|
CStringW szLicenseString;
|
|
m_Parser->GetString(L"License", szLicenseString);
|
|
LicenseType licenseType;
|
|
|
|
if (IsKnownLicenseType(IntBuffer))
|
|
{
|
|
licenseType = static_cast<LicenseType>(IntBuffer);
|
|
}
|
|
else
|
|
{
|
|
licenseType = LICENSE_NONE;
|
|
if (szLicenseString.CompareNoCase(L"Freeware") == 0)
|
|
{
|
|
licenseType = LICENSE_FREEWARE;
|
|
szLicenseString = L"";
|
|
}
|
|
}
|
|
|
|
CStringW szLicense;
|
|
switch (licenseType)
|
|
{
|
|
case LICENSE_OPENSOURCE:
|
|
szLicense.LoadStringW(IDS_LICENSE_OPENSOURCE);
|
|
break;
|
|
case LICENSE_FREEWARE:
|
|
szLicense.LoadStringW(IDS_LICENSE_FREEWARE);
|
|
break;
|
|
case LICENSE_TRIAL:
|
|
szLicense.LoadStringW(IDS_LICENSE_TRIAL);
|
|
break;
|
|
default:
|
|
return szLicenseString;
|
|
}
|
|
|
|
if (!szLicenseString.IsEmpty())
|
|
szLicense += L" (" + szLicenseString + L")";
|
|
return szLicense;
|
|
}
|
|
|
|
VOID
|
|
CAvailableApplicationInfo::InsertLanguageInfo(CAppRichEdit *RichEdit)
|
|
{
|
|
if (!m_LanguagesLoaded)
|
|
{
|
|
RetrieveLanguages();
|
|
}
|
|
|
|
if (m_LanguageLCIDs.GetSize() == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const INT nTranslations = m_LanguageLCIDs.GetSize();
|
|
CStringW szLangInfo;
|
|
CStringW szLoadedTextAvailability;
|
|
CStringW szLoadedAInfoText;
|
|
|
|
szLoadedAInfoText.LoadStringW(IDS_AINFO_LANGUAGES);
|
|
|
|
const LCID lcEnglish = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT);
|
|
if (m_LanguageLCIDs.Find(GetUserDefaultLCID()) >= 0)
|
|
{
|
|
szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_AVAILABLE_TRANSLATION);
|
|
if (nTranslations > 1)
|
|
{
|
|
CStringW buf;
|
|
buf.LoadStringW(IDS_LANGUAGE_MORE_PLACEHOLDER);
|
|
szLangInfo.Format(buf, nTranslations - 1);
|
|
}
|
|
else
|
|
{
|
|
szLangInfo.LoadStringW(IDS_LANGUAGE_SINGLE);
|
|
szLangInfo = L" (" + szLangInfo + L")";
|
|
}
|
|
}
|
|
else if (m_LanguageLCIDs.Find(lcEnglish) >= 0)
|
|
{
|
|
szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_ENGLISH_TRANSLATION);
|
|
if (nTranslations > 1)
|
|
{
|
|
CStringW buf;
|
|
buf.LoadStringW(IDS_LANGUAGE_AVAILABLE_PLACEHOLDER);
|
|
szLangInfo.Format(buf, nTranslations - 1);
|
|
}
|
|
else
|
|
{
|
|
szLangInfo.LoadStringW(IDS_LANGUAGE_SINGLE);
|
|
szLangInfo = L" (" + szLangInfo + L")";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_NO_TRANSLATION);
|
|
}
|
|
|
|
RichEdit->InsertText(szLoadedAInfoText, CFE_BOLD);
|
|
RichEdit->InsertText(szLoadedTextAvailability, NULL);
|
|
RichEdit->InsertText(szLangInfo, CFE_ITALIC);
|
|
}
|
|
|
|
VOID
|
|
CAvailableApplicationInfo::RetrieveLanguages()
|
|
{
|
|
m_LanguagesLoaded = true;
|
|
|
|
CStringW szBuffer;
|
|
if (!m_Parser->GetString(L"Languages", szBuffer))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Parse parameter string
|
|
int iIndex = 0;
|
|
while (true)
|
|
{
|
|
CStringW szLocale = szBuffer.Tokenize(L"|", iIndex);
|
|
if (szLocale.IsEmpty())
|
|
break;
|
|
|
|
szLocale = L"0x" + szLocale;
|
|
|
|
INT iLCID;
|
|
if (StrToIntExW(szLocale, STIF_SUPPORT_HEX, &iLCID))
|
|
{
|
|
m_LanguageLCIDs.Add(static_cast<LCID>(iLCID));
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
CAvailableApplicationInfo::Valid() const
|
|
{
|
|
return !szDisplayName.IsEmpty() && !m_szUrlDownload.IsEmpty();
|
|
}
|
|
|
|
BOOL
|
|
CAvailableApplicationInfo::CanModify()
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
CAvailableApplicationInfo::RetrieveIcon(CStringW &Path) const
|
|
{
|
|
Path = szDisplayIcon;
|
|
return !Path.IsEmpty();
|
|
}
|
|
|
|
#define MAX_SCRNSHOT_NUM 16
|
|
BOOL
|
|
CAvailableApplicationInfo::RetrieveScreenshot(CStringW &Path)
|
|
{
|
|
if (!m_ScrnshotRetrieved)
|
|
{
|
|
static_assert(MAX_SCRNSHOT_NUM < 10000, "MAX_SCRNSHOT_NUM is too big");
|
|
for (int i = 0; i < MAX_SCRNSHOT_NUM; i++)
|
|
{
|
|
CStringW ScrnshotField;
|
|
ScrnshotField.Format(L"Screenshot%d", i + 1);
|
|
CStringW ScrnshotLocation;
|
|
if (!m_Parser->GetString(ScrnshotField, ScrnshotLocation))
|
|
{
|
|
// We stop at the first screenshot not found,
|
|
// so screenshots _have_ to be consecutive
|
|
break;
|
|
}
|
|
|
|
if (PathIsURLW(ScrnshotLocation.GetString()))
|
|
{
|
|
m_szScrnshotLocation.Add(ScrnshotLocation);
|
|
}
|
|
}
|
|
m_ScrnshotRetrieved = true;
|
|
}
|
|
|
|
if (m_szScrnshotLocation.GetSize() > 0)
|
|
{
|
|
Path = m_szScrnshotLocation[0];
|
|
}
|
|
|
|
return !Path.IsEmpty();
|
|
}
|
|
|
|
VOID
|
|
CAvailableApplicationInfo::GetDownloadInfo(CStringW &Url, CStringW &Sha1, ULONG &SizeInBytes) const
|
|
{
|
|
Url = m_szUrlDownload;
|
|
m_Parser->GetString(L"SHA1", Sha1);
|
|
INT iSizeBytes;
|
|
|
|
if (m_Parser->GetInt(L"SizeBytes", iSizeBytes))
|
|
{
|
|
SizeInBytes = (ULONG)iSizeBytes;
|
|
}
|
|
else
|
|
{
|
|
SizeInBytes = 0;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
CAvailableApplicationInfo::GetDisplayInfo(CStringW &License, CStringW &Size, CStringW &UrlSite, CStringW &UrlDownload)
|
|
{
|
|
License = LicenseString();
|
|
Size = m_szSize;
|
|
UrlSite = m_szUrlSite;
|
|
UrlDownload = m_szUrlDownload;
|
|
}
|
|
|
|
BOOL
|
|
CAvailableApplicationInfo::UninstallApplication(BOOL bModify)
|
|
{
|
|
ATLASSERT(FALSE && "Should not be called");
|
|
return FALSE;
|
|
}
|
|
|
|
CInstalledApplicationInfo::CInstalledApplicationInfo(
|
|
HKEY Key,
|
|
const CStringW &KeyName,
|
|
AppsCategories Category,
|
|
int KeyIndex)
|
|
: CAppInfo(KeyName, Category), m_hKey(Key), iKeyIndex(KeyIndex)
|
|
{
|
|
if (GetApplicationRegString(L"DisplayName", szDisplayName))
|
|
{
|
|
GetApplicationRegString(L"DisplayIcon", szDisplayIcon);
|
|
GetApplicationRegString(L"DisplayVersion", szDisplayVersion);
|
|
GetApplicationRegString(L"Comments", szComments);
|
|
}
|
|
}
|
|
|
|
CInstalledApplicationInfo::~CInstalledApplicationInfo()
|
|
{
|
|
}
|
|
|
|
VOID
|
|
CInstalledApplicationInfo::AddApplicationRegString(
|
|
CAppRichEdit *RichEdit,
|
|
UINT StringID,
|
|
const CStringW &String,
|
|
DWORD TextFlags)
|
|
{
|
|
CStringW Tmp;
|
|
if (GetApplicationRegString(String, Tmp))
|
|
{
|
|
RichEdit->InsertTextWithString(StringID, Tmp, TextFlags);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
CInstalledApplicationInfo::ShowAppInfo(CAppRichEdit *RichEdit)
|
|
{
|
|
RichEdit->SetText(szDisplayName, CFE_BOLD);
|
|
RichEdit->InsertText(L"\n", 0);
|
|
|
|
RichEdit->InsertTextWithString(IDS_INFO_VERSION, szDisplayVersion, 0);
|
|
AddApplicationRegString(RichEdit, IDS_INFO_PUBLISHER, L"Publisher", 0);
|
|
AddApplicationRegString(RichEdit, IDS_INFO_REGOWNER, L"RegOwner", 0);
|
|
AddApplicationRegString(RichEdit, IDS_INFO_PRODUCTID, L"ProductID", 0);
|
|
AddApplicationRegString(RichEdit, IDS_INFO_HELPLINK, L"HelpLink", CFM_LINK);
|
|
AddApplicationRegString(RichEdit, IDS_INFO_HELPPHONE, L"HelpTelephone", 0);
|
|
AddApplicationRegString(RichEdit, IDS_INFO_README, L"Readme", 0);
|
|
AddApplicationRegString(RichEdit, IDS_INFO_CONTACT, L"Contact", 0);
|
|
AddApplicationRegString(RichEdit, IDS_INFO_UPDATEINFO, L"URLUpdateInfo", CFM_LINK);
|
|
AddApplicationRegString(RichEdit, IDS_INFO_INFOABOUT, L"URLInfoAbout", CFM_LINK);
|
|
RichEdit->InsertTextWithString(IDS_INFO_COMMENTS, szComments, 0);
|
|
|
|
if (m_szInstallDate.IsEmpty())
|
|
{
|
|
RetrieveInstallDate();
|
|
}
|
|
|
|
RichEdit->InsertTextWithString(IDS_INFO_INSTALLDATE, m_szInstallDate, 0);
|
|
AddApplicationRegString(RichEdit, IDS_INFO_INSTLOCATION, L"InstallLocation", 0);
|
|
AddApplicationRegString(RichEdit, IDS_INFO_INSTALLSRC, L"InstallSource", 0);
|
|
|
|
if (m_szUninstallString.IsEmpty())
|
|
{
|
|
RetrieveUninstallStrings();
|
|
}
|
|
|
|
RichEdit->InsertTextWithString(IDS_INFO_UNINSTALLSTR, m_szUninstallString, 0);
|
|
RichEdit->InsertTextWithString(IDS_INFO_MODIFYPATH, m_szModifyString, 0);
|
|
}
|
|
|
|
VOID
|
|
CInstalledApplicationInfo::RetrieveInstallDate()
|
|
{
|
|
DWORD dwInstallTimeStamp;
|
|
SYSTEMTIME InstallLocalTime;
|
|
if (GetApplicationRegString(L"InstallDate", m_szInstallDate))
|
|
{
|
|
ZeroMemory(&InstallLocalTime, sizeof(InstallLocalTime));
|
|
// Check if we have 8 characters to parse the datetime.
|
|
// Maybe other formats exist as well?
|
|
m_szInstallDate = m_szInstallDate.Trim();
|
|
if (m_szInstallDate.GetLength() == 8)
|
|
{
|
|
InstallLocalTime.wYear = wcstol(m_szInstallDate.Left(4).GetString(), NULL, 10);
|
|
InstallLocalTime.wMonth = wcstol(m_szInstallDate.Mid(4, 2).GetString(), NULL, 10);
|
|
InstallLocalTime.wDay = wcstol(m_szInstallDate.Mid(6, 2).GetString(), NULL, 10);
|
|
}
|
|
}
|
|
// It might be a DWORD (Unix timestamp). try again.
|
|
else if (GetApplicationRegDword(L"InstallDate", &dwInstallTimeStamp))
|
|
{
|
|
FILETIME InstallFileTime;
|
|
SYSTEMTIME InstallSystemTime;
|
|
|
|
UnixTimeToFileTime(dwInstallTimeStamp, &InstallFileTime);
|
|
FileTimeToSystemTime(&InstallFileTime, &InstallSystemTime);
|
|
|
|
// convert to localtime
|
|
SystemTimeToTzSpecificLocalTime(NULL, &InstallSystemTime, &InstallLocalTime);
|
|
}
|
|
|
|
// convert to readable date string
|
|
int cchTimeStrLen = GetDateFormatW(LOCALE_USER_DEFAULT, 0, &InstallLocalTime, NULL, 0, 0);
|
|
|
|
GetDateFormatW(
|
|
LOCALE_USER_DEFAULT, // use default locale for current user
|
|
0, &InstallLocalTime, NULL, m_szInstallDate.GetBuffer(cchTimeStrLen), cchTimeStrLen);
|
|
m_szInstallDate.ReleaseBuffer();
|
|
}
|
|
|
|
VOID
|
|
CInstalledApplicationInfo::RetrieveUninstallStrings()
|
|
{
|
|
DWORD dwWindowsInstaller = 0;
|
|
if (GetApplicationRegDword(L"WindowsInstaller", &dwWindowsInstaller) && dwWindowsInstaller)
|
|
{
|
|
// MSI has the same info in Uninstall / modify, so manually build it
|
|
m_szUninstallString.Format(L"msiexec /x%s", szIdentifier.GetString());
|
|
}
|
|
else
|
|
{
|
|
GetApplicationRegString(L"UninstallString", m_szUninstallString);
|
|
}
|
|
DWORD dwNoModify = 0;
|
|
if (!GetApplicationRegDword(L"NoModify", &dwNoModify))
|
|
{
|
|
CStringW Tmp;
|
|
if (GetApplicationRegString(L"NoModify", Tmp))
|
|
{
|
|
dwNoModify = Tmp.GetLength() > 0 ? (Tmp[0] == '1') : 0;
|
|
}
|
|
else
|
|
{
|
|
dwNoModify = 0;
|
|
}
|
|
}
|
|
if (!dwNoModify)
|
|
{
|
|
if (dwWindowsInstaller)
|
|
{
|
|
m_szModifyString.Format(L"msiexec /i%s", szIdentifier.GetString());
|
|
}
|
|
else
|
|
{
|
|
GetApplicationRegString(L"ModifyPath", m_szModifyString);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
CInstalledApplicationInfo::Valid() const
|
|
{
|
|
return !szDisplayName.IsEmpty();
|
|
}
|
|
|
|
BOOL
|
|
CInstalledApplicationInfo::CanModify()
|
|
{
|
|
if (m_szUninstallString.IsEmpty())
|
|
{
|
|
RetrieveUninstallStrings();
|
|
}
|
|
|
|
return !m_szModifyString.IsEmpty();
|
|
}
|
|
|
|
BOOL
|
|
CInstalledApplicationInfo::RetrieveIcon(CStringW &Path) const
|
|
{
|
|
Path = szDisplayIcon;
|
|
return !Path.IsEmpty();
|
|
}
|
|
|
|
BOOL
|
|
CInstalledApplicationInfo::RetrieveScreenshot(CStringW & /*Path*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
VOID
|
|
CInstalledApplicationInfo::GetDownloadInfo(CStringW &Url, CStringW &Sha1, ULONG &SizeInBytes) const
|
|
{
|
|
ATLASSERT(FALSE && "Should not be called");
|
|
}
|
|
|
|
VOID
|
|
CInstalledApplicationInfo::GetDisplayInfo(CStringW &License, CStringW &Size, CStringW &UrlSite, CStringW &UrlDownload)
|
|
{
|
|
ATLASSERT(FALSE && "Should not be called");
|
|
}
|
|
|
|
BOOL
|
|
CInstalledApplicationInfo::UninstallApplication(BOOL bModify)
|
|
{
|
|
if (m_szUninstallString.IsEmpty())
|
|
{
|
|
RetrieveUninstallStrings();
|
|
}
|
|
|
|
BOOL bSuccess = StartProcess(bModify ? m_szModifyString : m_szUninstallString, TRUE);
|
|
|
|
if (bSuccess && !bModify)
|
|
WriteLogMessage(EVENTLOG_SUCCESS, MSG_SUCCESS_REMOVE, szDisplayName);
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
BOOL
|
|
CInstalledApplicationInfo::GetApplicationRegString(LPCWSTR lpKeyName, CStringW &String)
|
|
{
|
|
ULONG nChars = 0;
|
|
// Get the size
|
|
if (m_hKey.QueryStringValue(lpKeyName, NULL, &nChars) != ERROR_SUCCESS)
|
|
{
|
|
String.Empty();
|
|
return FALSE;
|
|
}
|
|
|
|
LPWSTR Buffer = String.GetBuffer(nChars);
|
|
LONG lResult = m_hKey.QueryStringValue(lpKeyName, Buffer, &nChars);
|
|
if (nChars > 0 && Buffer[nChars - 1] == UNICODE_NULL)
|
|
nChars--;
|
|
String.ReleaseBuffer(nChars);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
{
|
|
String.Empty();
|
|
return FALSE;
|
|
}
|
|
|
|
if (String.Find('%') >= 0)
|
|
{
|
|
CStringW Tmp;
|
|
DWORD dwLen = ExpandEnvironmentStringsW(String, NULL, 0);
|
|
if (dwLen > 0)
|
|
{
|
|
BOOL bSuccess = ExpandEnvironmentStringsW(String, Tmp.GetBuffer(dwLen), dwLen) == dwLen;
|
|
Tmp.ReleaseBuffer(dwLen - 1);
|
|
if (bSuccess)
|
|
{
|
|
String = Tmp;
|
|
}
|
|
else
|
|
{
|
|
String.Empty();
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CInstalledApplicationInfo::GetApplicationRegDword(LPCWSTR lpKeyName, DWORD *lpValue)
|
|
{
|
|
DWORD dwSize = sizeof(DWORD), dwType;
|
|
if (RegQueryValueExW(m_hKey, lpKeyName, NULL, &dwType, (LPBYTE)lpValue, &dwSize) != ERROR_SUCCESS ||
|
|
dwType != REG_DWORD)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|