xref: /reactos/base/applications/rapps/appinfo.cpp (revision 57b775ef)
1a9b1e059SJoachim Henze /*
2a9b1e059SJoachim Henze  * PROJECT:     ReactOS Applications Manager
3a9b1e059SJoachim Henze  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4a9b1e059SJoachim Henze  * PURPOSE:     Classes for working with available applications
5a9b1e059SJoachim Henze  * COPYRIGHT:   Copyright 2017 Alexander Shaposhnikov (sanchaez@reactos.org)
6a9b1e059SJoachim Henze  *              Copyright 2020 He Yang (1160386205@qq.com)
7a9b1e059SJoachim Henze  *              Copyright 2021-2023 Mark Jansen <mark.jansen@reactos.org>
8a9b1e059SJoachim Henze  */
9a9b1e059SJoachim Henze 
10a9b1e059SJoachim Henze #include "rapps.h"
11a9b1e059SJoachim Henze #include "appview.h"
12a9b1e059SJoachim Henze 
CAppInfo(const CStringW & Identifier,AppsCategories Category)13a9b1e059SJoachim Henze CAppInfo::CAppInfo(const CStringW &Identifier, AppsCategories Category)
14a9b1e059SJoachim Henze     : szIdentifier(Identifier), iCategory(Category)
15a9b1e059SJoachim Henze {
16a9b1e059SJoachim Henze }
17a9b1e059SJoachim Henze 
~CAppInfo()18a9b1e059SJoachim Henze CAppInfo::~CAppInfo()
19a9b1e059SJoachim Henze {
20a9b1e059SJoachim Henze }
21a9b1e059SJoachim Henze 
CAvailableApplicationInfo(CConfigParser * Parser,const CStringW & PkgName,AppsCategories Category,const CPathW & BasePath)22a9b1e059SJoachim Henze CAvailableApplicationInfo::CAvailableApplicationInfo(
23a9b1e059SJoachim Henze     CConfigParser *Parser,
24a9b1e059SJoachim Henze     const CStringW &PkgName,
25a9b1e059SJoachim Henze     AppsCategories Category,
26a9b1e059SJoachim Henze     const CPathW &BasePath)
27a9b1e059SJoachim Henze     : CAppInfo(PkgName, Category), m_Parser(Parser), m_ScrnshotRetrieved(false), m_LanguagesLoaded(false)
28a9b1e059SJoachim Henze {
29a9b1e059SJoachim Henze     m_Parser->GetString(L"Name", szDisplayName);
30a9b1e059SJoachim Henze     m_Parser->GetString(L"Version", szDisplayVersion);
31a9b1e059SJoachim Henze     m_Parser->GetString(L"URLDownload", m_szUrlDownload);
32a9b1e059SJoachim Henze     m_Parser->GetString(L"Description", szComments);
33a9b1e059SJoachim Henze 
34a9b1e059SJoachim Henze     CPathW IconPath = BasePath;
35a9b1e059SJoachim Henze     IconPath += L"icons";
36a9b1e059SJoachim Henze 
37a9b1e059SJoachim Henze     CStringW IconName;
38a9b1e059SJoachim Henze     if (m_Parser->GetString(L"Icon", IconName))
39a9b1e059SJoachim Henze     {
40a9b1e059SJoachim Henze         IconPath += IconName;
41a9b1e059SJoachim Henze     }
42a9b1e059SJoachim Henze     else
43a9b1e059SJoachim Henze     {
44a9b1e059SJoachim Henze         // inifile.ico
45a9b1e059SJoachim Henze         IconPath += (szIdentifier + L".ico");
46a9b1e059SJoachim Henze     }
47a9b1e059SJoachim Henze 
48a9b1e059SJoachim Henze     if (PathFileExistsW(IconPath))
49a9b1e059SJoachim Henze     {
50a9b1e059SJoachim Henze         szDisplayIcon = (LPCWSTR)IconPath;
51a9b1e059SJoachim Henze     }
52a9b1e059SJoachim Henze 
53a9b1e059SJoachim Henze     INT iSizeBytes;
54a9b1e059SJoachim Henze 
55a9b1e059SJoachim Henze     if (m_Parser->GetInt(L"SizeBytes", iSizeBytes))
56a9b1e059SJoachim Henze     {
57a9b1e059SJoachim Henze         StrFormatByteSizeW(iSizeBytes, m_szSize.GetBuffer(MAX_PATH), MAX_PATH);
58a9b1e059SJoachim Henze         m_szSize.ReleaseBuffer();
59a9b1e059SJoachim Henze     }
60a9b1e059SJoachim Henze 
61a9b1e059SJoachim Henze     m_Parser->GetString(L"URLSite", m_szUrlSite);
62a9b1e059SJoachim Henze }
63a9b1e059SJoachim Henze 
~CAvailableApplicationInfo()64a9b1e059SJoachim Henze CAvailableApplicationInfo::~CAvailableApplicationInfo()
65a9b1e059SJoachim Henze {
66a9b1e059SJoachim Henze     delete m_Parser;
67a9b1e059SJoachim Henze }
68a9b1e059SJoachim Henze 
69a9b1e059SJoachim Henze VOID
ShowAppInfo(CAppRichEdit * RichEdit)70a9b1e059SJoachim Henze CAvailableApplicationInfo::ShowAppInfo(CAppRichEdit *RichEdit)
71a9b1e059SJoachim Henze {
72a9b1e059SJoachim Henze     RichEdit->SetText(szDisplayName, CFE_BOLD);
73a9b1e059SJoachim Henze     InsertVersionInfo(RichEdit);
74a9b1e059SJoachim Henze     RichEdit->LoadAndInsertText(IDS_AINFO_LICENSE, LicenseString(), 0);
75a9b1e059SJoachim Henze     InsertLanguageInfo(RichEdit);
76a9b1e059SJoachim Henze 
77a9b1e059SJoachim Henze     RichEdit->LoadAndInsertText(IDS_AINFO_SIZE, m_szSize, 0);
78a9b1e059SJoachim Henze     RichEdit->LoadAndInsertText(IDS_AINFO_URLSITE, m_szUrlSite, CFE_LINK);
79a9b1e059SJoachim Henze     RichEdit->LoadAndInsertText(IDS_AINFO_DESCRIPTION, szComments, 0);
80a9b1e059SJoachim Henze     RichEdit->LoadAndInsertText(IDS_AINFO_URLDOWNLOAD, m_szUrlDownload, CFE_LINK);
81a9b1e059SJoachim Henze     RichEdit->LoadAndInsertText(IDS_AINFO_PACKAGE_NAME, szIdentifier, 0);
82a9b1e059SJoachim Henze }
83a9b1e059SJoachim Henze 
84a9b1e059SJoachim Henze int
CompareVersion(const CStringW & left,const CStringW & right)85a9b1e059SJoachim Henze CompareVersion(const CStringW &left, const CStringW &right)
86a9b1e059SJoachim Henze {
87a9b1e059SJoachim Henze     int nLeft = 0, nRight = 0;
88a9b1e059SJoachim Henze 
89a9b1e059SJoachim Henze     while (true)
90a9b1e059SJoachim Henze     {
91a9b1e059SJoachim Henze         CStringW leftPart = left.Tokenize(L".", nLeft);
92a9b1e059SJoachim Henze         CStringW rightPart = right.Tokenize(L".", nRight);
93a9b1e059SJoachim Henze 
94a9b1e059SJoachim Henze         if (leftPart.IsEmpty() && rightPart.IsEmpty())
95a9b1e059SJoachim Henze             return 0;
96a9b1e059SJoachim Henze         if (leftPart.IsEmpty())
97a9b1e059SJoachim Henze             return -1;
98a9b1e059SJoachim Henze         if (rightPart.IsEmpty())
99a9b1e059SJoachim Henze             return 1;
100a9b1e059SJoachim Henze 
101a9b1e059SJoachim Henze         int leftVal, rightVal;
102a9b1e059SJoachim Henze 
103a9b1e059SJoachim Henze         if (!StrToIntExW(leftPart, STIF_DEFAULT, &leftVal))
104a9b1e059SJoachim Henze             leftVal = 0;
105a9b1e059SJoachim Henze         if (!StrToIntExW(rightPart, STIF_DEFAULT, &rightVal))
106a9b1e059SJoachim Henze             rightVal = 0;
107a9b1e059SJoachim Henze 
108a9b1e059SJoachim Henze         if (leftVal > rightVal)
109a9b1e059SJoachim Henze             return 1;
110a9b1e059SJoachim Henze         if (rightVal < leftVal)
111a9b1e059SJoachim Henze             return -1;
112a9b1e059SJoachim Henze     }
113a9b1e059SJoachim Henze }
114a9b1e059SJoachim Henze 
115a9b1e059SJoachim Henze VOID
InsertVersionInfo(CAppRichEdit * RichEdit)116a9b1e059SJoachim Henze CAvailableApplicationInfo::InsertVersionInfo(CAppRichEdit *RichEdit)
117a9b1e059SJoachim Henze {
118a9b1e059SJoachim Henze     CStringW szRegName;
119*57b775efSWhindmar Saksit     m_Parser->GetString(DB_REGNAME, szRegName);
120a9b1e059SJoachim Henze 
121a9b1e059SJoachim Henze     BOOL bIsInstalled = ::GetInstalledVersion(NULL, szRegName) || ::GetInstalledVersion(NULL, szDisplayName);
122a9b1e059SJoachim Henze     if (bIsInstalled)
123a9b1e059SJoachim Henze     {
124a9b1e059SJoachim Henze         CStringW szInstalledVersion;
125a9b1e059SJoachim Henze         CStringW szNameVersion = szDisplayName + L" " + szDisplayVersion;
126a9b1e059SJoachim Henze         BOOL bHasInstalledVersion = ::GetInstalledVersion(&szInstalledVersion, szRegName) ||
127a9b1e059SJoachim Henze                                     ::GetInstalledVersion(&szInstalledVersion, szDisplayName) ||
128a9b1e059SJoachim Henze                                     ::GetInstalledVersion(&szInstalledVersion, szNameVersion);
129a9b1e059SJoachim Henze 
130a9b1e059SJoachim Henze         if (bHasInstalledVersion)
131a9b1e059SJoachim Henze         {
132a9b1e059SJoachim Henze             BOOL bHasUpdate = CompareVersion(szInstalledVersion, szDisplayVersion) < 0;
133a9b1e059SJoachim Henze             if (bHasUpdate)
134*57b775efSWhindmar Saksit             {
135a9b1e059SJoachim Henze                 RichEdit->LoadAndInsertText(IDS_STATUS_UPDATE_AVAILABLE, CFE_ITALIC);
136a9b1e059SJoachim Henze                 RichEdit->LoadAndInsertText(IDS_AINFO_VERSION, szInstalledVersion, 0);
137a9b1e059SJoachim Henze             }
138a9b1e059SJoachim Henze             else
139a9b1e059SJoachim Henze             {
140a9b1e059SJoachim Henze                 RichEdit->LoadAndInsertText(IDS_STATUS_INSTALLED, CFE_ITALIC);
141a9b1e059SJoachim Henze             }
142a9b1e059SJoachim Henze         }
143a9b1e059SJoachim Henze         else
144a9b1e059SJoachim Henze         {
145*57b775efSWhindmar Saksit             RichEdit->LoadAndInsertText(IDS_STATUS_INSTALLED, CFE_ITALIC);
146*57b775efSWhindmar Saksit         }
147*57b775efSWhindmar Saksit     }
148*57b775efSWhindmar Saksit     else
149*57b775efSWhindmar Saksit     {
150a9b1e059SJoachim Henze         RichEdit->LoadAndInsertText(IDS_STATUS_NOTINSTALLED, CFE_ITALIC);
151a9b1e059SJoachim Henze     }
152a9b1e059SJoachim Henze 
153a9b1e059SJoachim Henze     RichEdit->LoadAndInsertText(IDS_AINFO_AVAILABLEVERSION, szDisplayVersion, 0);
154a9b1e059SJoachim Henze }
155a9b1e059SJoachim Henze 
156a9b1e059SJoachim Henze CStringW
LicenseString()157a9b1e059SJoachim Henze CAvailableApplicationInfo::LicenseString()
158a9b1e059SJoachim Henze {
159a9b1e059SJoachim Henze     INT IntBuffer;
160a9b1e059SJoachim Henze     m_Parser->GetInt(L"LicenseType", IntBuffer);
161a9b1e059SJoachim Henze     CStringW szLicenseString;
162a9b1e059SJoachim Henze     m_Parser->GetString(L"License", szLicenseString);
163a9b1e059SJoachim Henze     LicenseType licenseType;
164a9b1e059SJoachim Henze 
1654b039818SWhindmar Saksit     if (IsKnownLicenseType(IntBuffer))
166a9b1e059SJoachim Henze     {
167a9b1e059SJoachim Henze         licenseType = static_cast<LicenseType>(IntBuffer);
168a9b1e059SJoachim Henze     }
169a9b1e059SJoachim Henze     else
170a9b1e059SJoachim Henze     {
171a9b1e059SJoachim Henze         licenseType = LICENSE_NONE;
1724b039818SWhindmar Saksit         if (szLicenseString.CompareNoCase(L"Freeware") == 0)
1734b039818SWhindmar Saksit         {
1744b039818SWhindmar Saksit             licenseType = LICENSE_FREEWARE;
1754b039818SWhindmar Saksit             szLicenseString = L"";
1764b039818SWhindmar Saksit         }
177a9b1e059SJoachim Henze     }
178a9b1e059SJoachim Henze 
179a9b1e059SJoachim Henze     CStringW szLicense;
180a9b1e059SJoachim Henze     switch (licenseType)
181a9b1e059SJoachim Henze     {
182a9b1e059SJoachim Henze         case LICENSE_OPENSOURCE:
183a9b1e059SJoachim Henze             szLicense.LoadStringW(IDS_LICENSE_OPENSOURCE);
184a9b1e059SJoachim Henze             break;
185a9b1e059SJoachim Henze         case LICENSE_FREEWARE:
186a9b1e059SJoachim Henze             szLicense.LoadStringW(IDS_LICENSE_FREEWARE);
187a9b1e059SJoachim Henze             break;
188a9b1e059SJoachim Henze         case LICENSE_TRIAL:
189a9b1e059SJoachim Henze             szLicense.LoadStringW(IDS_LICENSE_TRIAL);
190a9b1e059SJoachim Henze             break;
191a9b1e059SJoachim Henze         default:
192a9b1e059SJoachim Henze             return szLicenseString;
193a9b1e059SJoachim Henze     }
194a9b1e059SJoachim Henze 
1954b039818SWhindmar Saksit     if (!szLicenseString.IsEmpty())
1964b039818SWhindmar Saksit         szLicense += L" (" + szLicenseString + L")";
1974b039818SWhindmar Saksit     return szLicense;
198a9b1e059SJoachim Henze }
199a9b1e059SJoachim Henze 
200a9b1e059SJoachim Henze VOID
InsertLanguageInfo(CAppRichEdit * RichEdit)201a9b1e059SJoachim Henze CAvailableApplicationInfo::InsertLanguageInfo(CAppRichEdit *RichEdit)
202a9b1e059SJoachim Henze {
203a9b1e059SJoachim Henze     if (!m_LanguagesLoaded)
204a9b1e059SJoachim Henze     {
205a9b1e059SJoachim Henze         RetrieveLanguages();
206a9b1e059SJoachim Henze     }
207a9b1e059SJoachim Henze 
208a9b1e059SJoachim Henze     if (m_LanguageLCIDs.GetSize() == 0)
209a9b1e059SJoachim Henze     {
210a9b1e059SJoachim Henze         return;
211a9b1e059SJoachim Henze     }
212a9b1e059SJoachim Henze 
213a9b1e059SJoachim Henze     const INT nTranslations = m_LanguageLCIDs.GetSize();
214a9b1e059SJoachim Henze     CStringW szLangInfo;
215a9b1e059SJoachim Henze     CStringW szLoadedTextAvailability;
216a9b1e059SJoachim Henze     CStringW szLoadedAInfoText;
217a9b1e059SJoachim Henze 
218a9b1e059SJoachim Henze     szLoadedAInfoText.LoadStringW(IDS_AINFO_LANGUAGES);
219a9b1e059SJoachim Henze 
220a9b1e059SJoachim Henze     const LCID lcEnglish = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT);
221a9b1e059SJoachim Henze     if (m_LanguageLCIDs.Find(GetUserDefaultLCID()) >= 0)
222a9b1e059SJoachim Henze     {
223a9b1e059SJoachim Henze         szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_AVAILABLE_TRANSLATION);
224a9b1e059SJoachim Henze         if (nTranslations > 1)
225a9b1e059SJoachim Henze         {
226a9b1e059SJoachim Henze             CStringW buf;
227a9b1e059SJoachim Henze             buf.LoadStringW(IDS_LANGUAGE_MORE_PLACEHOLDER);
228a9b1e059SJoachim Henze             szLangInfo.Format(buf, nTranslations - 1);
229a9b1e059SJoachim Henze         }
230a9b1e059SJoachim Henze         else
231a9b1e059SJoachim Henze         {
232a9b1e059SJoachim Henze             szLangInfo.LoadStringW(IDS_LANGUAGE_SINGLE);
233a9b1e059SJoachim Henze             szLangInfo = L" (" + szLangInfo + L")";
234a9b1e059SJoachim Henze         }
235a9b1e059SJoachim Henze     }
236a9b1e059SJoachim Henze     else if (m_LanguageLCIDs.Find(lcEnglish) >= 0)
237a9b1e059SJoachim Henze     {
238a9b1e059SJoachim Henze         szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_ENGLISH_TRANSLATION);
239a9b1e059SJoachim Henze         if (nTranslations > 1)
240a9b1e059SJoachim Henze         {
241a9b1e059SJoachim Henze             CStringW buf;
242a9b1e059SJoachim Henze             buf.LoadStringW(IDS_LANGUAGE_AVAILABLE_PLACEHOLDER);
243a9b1e059SJoachim Henze             szLangInfo.Format(buf, nTranslations - 1);
244a9b1e059SJoachim Henze         }
245a9b1e059SJoachim Henze         else
246a9b1e059SJoachim Henze         {
247a9b1e059SJoachim Henze             szLangInfo.LoadStringW(IDS_LANGUAGE_SINGLE);
248a9b1e059SJoachim Henze             szLangInfo = L" (" + szLangInfo + L")";
249a9b1e059SJoachim Henze         }
250a9b1e059SJoachim Henze     }
251a9b1e059SJoachim Henze     else
252a9b1e059SJoachim Henze     {
253a9b1e059SJoachim Henze         szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_NO_TRANSLATION);
254a9b1e059SJoachim Henze     }
255a9b1e059SJoachim Henze 
256a9b1e059SJoachim Henze     RichEdit->InsertText(szLoadedAInfoText, CFE_BOLD);
257a9b1e059SJoachim Henze     RichEdit->InsertText(szLoadedTextAvailability, NULL);
258a9b1e059SJoachim Henze     RichEdit->InsertText(szLangInfo, CFE_ITALIC);
259a9b1e059SJoachim Henze }
260a9b1e059SJoachim Henze 
261a9b1e059SJoachim Henze VOID
RetrieveLanguages()262a9b1e059SJoachim Henze CAvailableApplicationInfo::RetrieveLanguages()
263a9b1e059SJoachim Henze {
264a9b1e059SJoachim Henze     m_LanguagesLoaded = true;
265a9b1e059SJoachim Henze 
266a9b1e059SJoachim Henze     CStringW szBuffer;
267a9b1e059SJoachim Henze     if (!m_Parser->GetString(L"Languages", szBuffer))
268a9b1e059SJoachim Henze     {
269a9b1e059SJoachim Henze         return;
270a9b1e059SJoachim Henze     }
271a9b1e059SJoachim Henze 
272a9b1e059SJoachim Henze     // Parse parameter string
273a9b1e059SJoachim Henze     int iIndex = 0;
274a9b1e059SJoachim Henze     while (true)
275a9b1e059SJoachim Henze     {
276a9b1e059SJoachim Henze         CStringW szLocale = szBuffer.Tokenize(L"|", iIndex);
277a9b1e059SJoachim Henze         if (szLocale.IsEmpty())
278a9b1e059SJoachim Henze             break;
279a9b1e059SJoachim Henze 
280a9b1e059SJoachim Henze         szLocale = L"0x" + szLocale;
281a9b1e059SJoachim Henze 
282a9b1e059SJoachim Henze         INT iLCID;
283a9b1e059SJoachim Henze         if (StrToIntExW(szLocale, STIF_SUPPORT_HEX, &iLCID))
284a9b1e059SJoachim Henze         {
285a9b1e059SJoachim Henze             m_LanguageLCIDs.Add(static_cast<LCID>(iLCID));
286a9b1e059SJoachim Henze         }
287a9b1e059SJoachim Henze     }
288a9b1e059SJoachim Henze }
289a9b1e059SJoachim Henze 
290a9b1e059SJoachim Henze BOOL
Valid() const291a9b1e059SJoachim Henze CAvailableApplicationInfo::Valid() const
292a9b1e059SJoachim Henze {
293a9b1e059SJoachim Henze     return !szDisplayName.IsEmpty() && !m_szUrlDownload.IsEmpty();
294a9b1e059SJoachim Henze }
295a9b1e059SJoachim Henze 
296a9b1e059SJoachim Henze BOOL
CanModify()297a9b1e059SJoachim Henze CAvailableApplicationInfo::CanModify()
298a9b1e059SJoachim Henze {
299a9b1e059SJoachim Henze     return FALSE;
300a9b1e059SJoachim Henze }
301a9b1e059SJoachim Henze 
302a9b1e059SJoachim Henze BOOL
RetrieveIcon(CStringW & Path) const303a9b1e059SJoachim Henze CAvailableApplicationInfo::RetrieveIcon(CStringW &Path) const
304a9b1e059SJoachim Henze {
305a9b1e059SJoachim Henze     Path = szDisplayIcon;
306a9b1e059SJoachim Henze     return !Path.IsEmpty();
307a9b1e059SJoachim Henze }
308a9b1e059SJoachim Henze 
309a9b1e059SJoachim Henze #define MAX_SCRNSHOT_NUM 16
310a9b1e059SJoachim Henze BOOL
RetrieveScreenshot(CStringW & Path)311a9b1e059SJoachim Henze CAvailableApplicationInfo::RetrieveScreenshot(CStringW &Path)
312a9b1e059SJoachim Henze {
313a9b1e059SJoachim Henze     if (!m_ScrnshotRetrieved)
314a9b1e059SJoachim Henze     {
315a9b1e059SJoachim Henze         static_assert(MAX_SCRNSHOT_NUM < 10000, "MAX_SCRNSHOT_NUM is too big");
316a9b1e059SJoachim Henze         for (int i = 0; i < MAX_SCRNSHOT_NUM; i++)
317a9b1e059SJoachim Henze         {
318a9b1e059SJoachim Henze             CStringW ScrnshotField;
319a9b1e059SJoachim Henze             ScrnshotField.Format(L"Screenshot%d", i + 1);
320a9b1e059SJoachim Henze             CStringW ScrnshotLocation;
321a9b1e059SJoachim Henze             if (!m_Parser->GetString(ScrnshotField, ScrnshotLocation))
322a9b1e059SJoachim Henze             {
323a9b1e059SJoachim Henze                 // We stop at the first screenshot not found,
324a9b1e059SJoachim Henze                 // so screenshots _have_ to be consecutive
325a9b1e059SJoachim Henze                 break;
326a9b1e059SJoachim Henze             }
327a9b1e059SJoachim Henze 
328a9b1e059SJoachim Henze             if (PathIsURLW(ScrnshotLocation.GetString()))
329a9b1e059SJoachim Henze             {
330a9b1e059SJoachim Henze                 m_szScrnshotLocation.Add(ScrnshotLocation);
331a9b1e059SJoachim Henze             }
332a9b1e059SJoachim Henze         }
333a9b1e059SJoachim Henze         m_ScrnshotRetrieved = true;
334a9b1e059SJoachim Henze     }
335a9b1e059SJoachim Henze 
336a9b1e059SJoachim Henze     if (m_szScrnshotLocation.GetSize() > 0)
337a9b1e059SJoachim Henze     {
338a9b1e059SJoachim Henze         Path = m_szScrnshotLocation[0];
339a9b1e059SJoachim Henze     }
340a9b1e059SJoachim Henze 
341a9b1e059SJoachim Henze     return !Path.IsEmpty();
342a9b1e059SJoachim Henze }
343a9b1e059SJoachim Henze 
344a9b1e059SJoachim Henze VOID
GetDownloadInfo(CStringW & Url,CStringW & Sha1,ULONG & SizeInBytes) const345a9b1e059SJoachim Henze CAvailableApplicationInfo::GetDownloadInfo(CStringW &Url, CStringW &Sha1, ULONG &SizeInBytes) const
346a9b1e059SJoachim Henze {
347a9b1e059SJoachim Henze     Url = m_szUrlDownload;
348a9b1e059SJoachim Henze     m_Parser->GetString(L"SHA1", Sha1);
349a9b1e059SJoachim Henze     INT iSizeBytes;
350a9b1e059SJoachim Henze 
351a9b1e059SJoachim Henze     if (m_Parser->GetInt(L"SizeBytes", iSizeBytes))
352a9b1e059SJoachim Henze     {
353a9b1e059SJoachim Henze         SizeInBytes = (ULONG)iSizeBytes;
354a9b1e059SJoachim Henze     }
355a9b1e059SJoachim Henze     else
356a9b1e059SJoachim Henze     {
357a9b1e059SJoachim Henze         SizeInBytes = 0;
358a9b1e059SJoachim Henze     }
359a9b1e059SJoachim Henze }
360a9b1e059SJoachim Henze 
361a9b1e059SJoachim Henze VOID
GetDisplayInfo(CStringW & License,CStringW & Size,CStringW & UrlSite,CStringW & UrlDownload)362a9b1e059SJoachim Henze CAvailableApplicationInfo::GetDisplayInfo(CStringW &License, CStringW &Size, CStringW &UrlSite, CStringW &UrlDownload)
363a9b1e059SJoachim Henze {
364a9b1e059SJoachim Henze     License = LicenseString();
365a9b1e059SJoachim Henze     Size = m_szSize;
366a9b1e059SJoachim Henze     UrlSite = m_szUrlSite;
367a9b1e059SJoachim Henze     UrlDownload = m_szUrlDownload;
368a9b1e059SJoachim Henze }
369a9b1e059SJoachim Henze 
370*57b775efSWhindmar Saksit InstallerType
GetInstallerType() const371*57b775efSWhindmar Saksit CAvailableApplicationInfo::GetInstallerType() const
372*57b775efSWhindmar Saksit {
373*57b775efSWhindmar Saksit     CStringW str;
374*57b775efSWhindmar Saksit     m_Parser->GetString(DB_INSTALLER, str);
375*57b775efSWhindmar Saksit     if (str.CompareNoCase(DB_GENINSTSECTION) == 0)
376*57b775efSWhindmar Saksit         return INSTALLER_GENERATE;
377*57b775efSWhindmar Saksit     else
378*57b775efSWhindmar Saksit         return INSTALLER_UNKNOWN;
379*57b775efSWhindmar Saksit }
380*57b775efSWhindmar Saksit 
381a9b1e059SJoachim Henze BOOL
UninstallApplication(UninstallCommandFlags Flags)382*57b775efSWhindmar Saksit CAvailableApplicationInfo::UninstallApplication(UninstallCommandFlags Flags)
383a9b1e059SJoachim Henze {
384a9b1e059SJoachim Henze     ATLASSERT(FALSE && "Should not be called");
385a9b1e059SJoachim Henze     return FALSE;
386a9b1e059SJoachim Henze }
387a9b1e059SJoachim Henze 
CInstalledApplicationInfo(HKEY Key,const CStringW & KeyName,AppsCategories Category,UINT KeyInfo)388a9b1e059SJoachim Henze CInstalledApplicationInfo::CInstalledApplicationInfo(
389a9b1e059SJoachim Henze     HKEY Key,
390a9b1e059SJoachim Henze     const CStringW &KeyName,
391*57b775efSWhindmar Saksit     AppsCategories Category, UINT KeyInfo)
392*57b775efSWhindmar Saksit     : CAppInfo(KeyName, Category), m_hKey(Key), m_KeyInfo(KeyInfo)
393a9b1e059SJoachim Henze {
394a9b1e059SJoachim Henze     if (GetApplicationRegString(L"DisplayName", szDisplayName))
395a9b1e059SJoachim Henze     {
396a9b1e059SJoachim Henze         GetApplicationRegString(L"DisplayIcon", szDisplayIcon);
397a9b1e059SJoachim Henze         GetApplicationRegString(L"DisplayVersion", szDisplayVersion);
398a9b1e059SJoachim Henze         GetApplicationRegString(L"Comments", szComments);
399a9b1e059SJoachim Henze     }
400a9b1e059SJoachim Henze }
401a9b1e059SJoachim Henze 
~CInstalledApplicationInfo()402a9b1e059SJoachim Henze CInstalledApplicationInfo::~CInstalledApplicationInfo()
403a9b1e059SJoachim Henze {
404a9b1e059SJoachim Henze }
405a9b1e059SJoachim Henze 
406a9b1e059SJoachim Henze VOID
AddApplicationRegString(CAppRichEdit * RichEdit,UINT StringID,const CStringW & String,DWORD TextFlags)407a9b1e059SJoachim Henze CInstalledApplicationInfo::AddApplicationRegString(
408a9b1e059SJoachim Henze     CAppRichEdit *RichEdit,
409a9b1e059SJoachim Henze     UINT StringID,
410a9b1e059SJoachim Henze     const CStringW &String,
411a9b1e059SJoachim Henze     DWORD TextFlags)
412a9b1e059SJoachim Henze {
413a9b1e059SJoachim Henze     CStringW Tmp;
414a9b1e059SJoachim Henze     if (GetApplicationRegString(String, Tmp))
415a9b1e059SJoachim Henze     {
416a9b1e059SJoachim Henze         RichEdit->InsertTextWithString(StringID, Tmp, TextFlags);
417a9b1e059SJoachim Henze     }
418a9b1e059SJoachim Henze }
419a9b1e059SJoachim Henze 
420a9b1e059SJoachim Henze VOID
ShowAppInfo(CAppRichEdit * RichEdit)421a9b1e059SJoachim Henze CInstalledApplicationInfo::ShowAppInfo(CAppRichEdit *RichEdit)
422a9b1e059SJoachim Henze {
423a9b1e059SJoachim Henze     RichEdit->SetText(szDisplayName, CFE_BOLD);
424a9b1e059SJoachim Henze     RichEdit->InsertText(L"\n", 0);
425a9b1e059SJoachim Henze 
426a9b1e059SJoachim Henze     RichEdit->InsertTextWithString(IDS_INFO_VERSION, szDisplayVersion, 0);
427a9b1e059SJoachim Henze     AddApplicationRegString(RichEdit, IDS_INFO_PUBLISHER, L"Publisher", 0);
428a9b1e059SJoachim Henze     AddApplicationRegString(RichEdit, IDS_INFO_REGOWNER, L"RegOwner", 0);
429a9b1e059SJoachim Henze     AddApplicationRegString(RichEdit, IDS_INFO_PRODUCTID, L"ProductID", 0);
430a9b1e059SJoachim Henze     AddApplicationRegString(RichEdit, IDS_INFO_HELPLINK, L"HelpLink", CFM_LINK);
431a9b1e059SJoachim Henze     AddApplicationRegString(RichEdit, IDS_INFO_HELPPHONE, L"HelpTelephone", 0);
432a9b1e059SJoachim Henze     AddApplicationRegString(RichEdit, IDS_INFO_README, L"Readme", 0);
433a9b1e059SJoachim Henze     AddApplicationRegString(RichEdit, IDS_INFO_CONTACT, L"Contact", 0);
434a9b1e059SJoachim Henze     AddApplicationRegString(RichEdit, IDS_INFO_UPDATEINFO, L"URLUpdateInfo", CFM_LINK);
435a9b1e059SJoachim Henze     AddApplicationRegString(RichEdit, IDS_INFO_INFOABOUT, L"URLInfoAbout", CFM_LINK);
436a9b1e059SJoachim Henze     RichEdit->InsertTextWithString(IDS_INFO_COMMENTS, szComments, 0);
437a9b1e059SJoachim Henze 
438a9b1e059SJoachim Henze     if (m_szInstallDate.IsEmpty())
439a9b1e059SJoachim Henze     {
440a9b1e059SJoachim Henze         RetrieveInstallDate();
441a9b1e059SJoachim Henze     }
442a9b1e059SJoachim Henze 
443a9b1e059SJoachim Henze     RichEdit->InsertTextWithString(IDS_INFO_INSTALLDATE, m_szInstallDate, 0);
444a9b1e059SJoachim Henze     AddApplicationRegString(RichEdit, IDS_INFO_INSTLOCATION, L"InstallLocation", 0);
445a9b1e059SJoachim Henze     AddApplicationRegString(RichEdit, IDS_INFO_INSTALLSRC, L"InstallSource", 0);
446a9b1e059SJoachim Henze 
447a9b1e059SJoachim Henze     if (m_szUninstallString.IsEmpty())
448a9b1e059SJoachim Henze     {
449a9b1e059SJoachim Henze         RetrieveUninstallStrings();
450a9b1e059SJoachim Henze     }
451a9b1e059SJoachim Henze 
452a9b1e059SJoachim Henze     RichEdit->InsertTextWithString(IDS_INFO_UNINSTALLSTR, m_szUninstallString, 0);
453a9b1e059SJoachim Henze     RichEdit->InsertTextWithString(IDS_INFO_MODIFYPATH, m_szModifyString, 0);
454a9b1e059SJoachim Henze }
455a9b1e059SJoachim Henze 
456a9b1e059SJoachim Henze VOID
RetrieveInstallDate()457a9b1e059SJoachim Henze CInstalledApplicationInfo::RetrieveInstallDate()
458a9b1e059SJoachim Henze {
459a9b1e059SJoachim Henze     DWORD dwInstallTimeStamp;
460a9b1e059SJoachim Henze     SYSTEMTIME InstallLocalTime;
461a9b1e059SJoachim Henze     if (GetApplicationRegString(L"InstallDate", m_szInstallDate))
462a9b1e059SJoachim Henze     {
463a9b1e059SJoachim Henze         ZeroMemory(&InstallLocalTime, sizeof(InstallLocalTime));
464a9b1e059SJoachim Henze         // Check if we have 8 characters to parse the datetime.
465a9b1e059SJoachim Henze         // Maybe other formats exist as well?
466a9b1e059SJoachim Henze         m_szInstallDate = m_szInstallDate.Trim();
467a9b1e059SJoachim Henze         if (m_szInstallDate.GetLength() == 8)
468a9b1e059SJoachim Henze         {
469a9b1e059SJoachim Henze             InstallLocalTime.wYear = wcstol(m_szInstallDate.Left(4).GetString(), NULL, 10);
470a9b1e059SJoachim Henze             InstallLocalTime.wMonth = wcstol(m_szInstallDate.Mid(4, 2).GetString(), NULL, 10);
471a9b1e059SJoachim Henze             InstallLocalTime.wDay = wcstol(m_szInstallDate.Mid(6, 2).GetString(), NULL, 10);
472a9b1e059SJoachim Henze         }
473a9b1e059SJoachim Henze     }
474a9b1e059SJoachim Henze     // It might be a DWORD (Unix timestamp). try again.
475a9b1e059SJoachim Henze     else if (GetApplicationRegDword(L"InstallDate", &dwInstallTimeStamp))
476a9b1e059SJoachim Henze     {
477a9b1e059SJoachim Henze         FILETIME InstallFileTime;
478a9b1e059SJoachim Henze         SYSTEMTIME InstallSystemTime;
479a9b1e059SJoachim Henze 
480a9b1e059SJoachim Henze         UnixTimeToFileTime(dwInstallTimeStamp, &InstallFileTime);
481a9b1e059SJoachim Henze         FileTimeToSystemTime(&InstallFileTime, &InstallSystemTime);
482a9b1e059SJoachim Henze 
483a9b1e059SJoachim Henze         // convert to localtime
484a9b1e059SJoachim Henze         SystemTimeToTzSpecificLocalTime(NULL, &InstallSystemTime, &InstallLocalTime);
485a9b1e059SJoachim Henze     }
486a9b1e059SJoachim Henze 
487a9b1e059SJoachim Henze     // convert to readable date string
488a9b1e059SJoachim Henze     int cchTimeStrLen = GetDateFormatW(LOCALE_USER_DEFAULT, 0, &InstallLocalTime, NULL, 0, 0);
489a9b1e059SJoachim Henze 
490a9b1e059SJoachim Henze     GetDateFormatW(
491a9b1e059SJoachim Henze         LOCALE_USER_DEFAULT, // use default locale for current user
492a9b1e059SJoachim Henze         0, &InstallLocalTime, NULL, m_szInstallDate.GetBuffer(cchTimeStrLen), cchTimeStrLen);
493a9b1e059SJoachim Henze     m_szInstallDate.ReleaseBuffer();
494a9b1e059SJoachim Henze }
495a9b1e059SJoachim Henze 
496a9b1e059SJoachim Henze VOID
RetrieveUninstallStrings()497a9b1e059SJoachim Henze CInstalledApplicationInfo::RetrieveUninstallStrings()
498a9b1e059SJoachim Henze {
499a9b1e059SJoachim Henze     DWORD dwWindowsInstaller = 0;
500a9b1e059SJoachim Henze     if (GetApplicationRegDword(L"WindowsInstaller", &dwWindowsInstaller) && dwWindowsInstaller)
501a9b1e059SJoachim Henze     {
502a9b1e059SJoachim Henze         // MSI has the same info in Uninstall / modify, so manually build it
503a9b1e059SJoachim Henze         m_szUninstallString.Format(L"msiexec /x%s", szIdentifier.GetString());
504a9b1e059SJoachim Henze     }
505a9b1e059SJoachim Henze     else
506a9b1e059SJoachim Henze     {
507a9b1e059SJoachim Henze         GetApplicationRegString(L"UninstallString", m_szUninstallString);
508a9b1e059SJoachim Henze     }
509a9b1e059SJoachim Henze     DWORD dwNoModify = 0;
510a9b1e059SJoachim Henze     if (!GetApplicationRegDword(L"NoModify", &dwNoModify))
511a9b1e059SJoachim Henze     {
512a9b1e059SJoachim Henze         CStringW Tmp;
513a9b1e059SJoachim Henze         if (GetApplicationRegString(L"NoModify", Tmp))
514a9b1e059SJoachim Henze         {
515a9b1e059SJoachim Henze             dwNoModify = Tmp.GetLength() > 0 ? (Tmp[0] == '1') : 0;
516a9b1e059SJoachim Henze         }
517a9b1e059SJoachim Henze         else
518a9b1e059SJoachim Henze         {
519a9b1e059SJoachim Henze             dwNoModify = 0;
520a9b1e059SJoachim Henze         }
521a9b1e059SJoachim Henze     }
522a9b1e059SJoachim Henze     if (!dwNoModify)
523a9b1e059SJoachim Henze     {
524a9b1e059SJoachim Henze         if (dwWindowsInstaller)
525a9b1e059SJoachim Henze         {
526a9b1e059SJoachim Henze             m_szModifyString.Format(L"msiexec /i%s", szIdentifier.GetString());
527a9b1e059SJoachim Henze         }
528a9b1e059SJoachim Henze         else
529a9b1e059SJoachim Henze         {
530a9b1e059SJoachim Henze             GetApplicationRegString(L"ModifyPath", m_szModifyString);
531a9b1e059SJoachim Henze         }
532a9b1e059SJoachim Henze     }
533a9b1e059SJoachim Henze }
534a9b1e059SJoachim Henze 
535a9b1e059SJoachim Henze BOOL
Valid() const536a9b1e059SJoachim Henze CInstalledApplicationInfo::Valid() const
537a9b1e059SJoachim Henze {
538a9b1e059SJoachim Henze     return !szDisplayName.IsEmpty();
539a9b1e059SJoachim Henze }
540a9b1e059SJoachim Henze 
541a9b1e059SJoachim Henze BOOL
CanModify()542a9b1e059SJoachim Henze CInstalledApplicationInfo::CanModify()
543a9b1e059SJoachim Henze {
544a9b1e059SJoachim Henze     if (m_szUninstallString.IsEmpty())
545a9b1e059SJoachim Henze     {
546a9b1e059SJoachim Henze         RetrieveUninstallStrings();
547a9b1e059SJoachim Henze     }
548a9b1e059SJoachim Henze 
549a9b1e059SJoachim Henze     return !m_szModifyString.IsEmpty();
550a9b1e059SJoachim Henze }
551a9b1e059SJoachim Henze 
552a9b1e059SJoachim Henze BOOL
RetrieveIcon(CStringW & Path) const553a9b1e059SJoachim Henze CInstalledApplicationInfo::RetrieveIcon(CStringW &Path) const
554a9b1e059SJoachim Henze {
555a9b1e059SJoachim Henze     Path = szDisplayIcon;
556a9b1e059SJoachim Henze     return !Path.IsEmpty();
557a9b1e059SJoachim Henze }
558a9b1e059SJoachim Henze 
559a9b1e059SJoachim Henze BOOL
RetrieveScreenshot(CStringW &)560a9b1e059SJoachim Henze CInstalledApplicationInfo::RetrieveScreenshot(CStringW & /*Path*/)
561a9b1e059SJoachim Henze {
562a9b1e059SJoachim Henze     return FALSE;
563a9b1e059SJoachim Henze }
564a9b1e059SJoachim Henze 
565a9b1e059SJoachim Henze VOID
GetDownloadInfo(CStringW & Url,CStringW & Sha1,ULONG & SizeInBytes) const566a9b1e059SJoachim Henze CInstalledApplicationInfo::GetDownloadInfo(CStringW &Url, CStringW &Sha1, ULONG &SizeInBytes) const
567a9b1e059SJoachim Henze {
568a9b1e059SJoachim Henze     ATLASSERT(FALSE && "Should not be called");
569a9b1e059SJoachim Henze }
570a9b1e059SJoachim Henze 
571a9b1e059SJoachim Henze VOID
GetDisplayInfo(CStringW & License,CStringW & Size,CStringW & UrlSite,CStringW & UrlDownload)572a9b1e059SJoachim Henze CInstalledApplicationInfo::GetDisplayInfo(CStringW &License, CStringW &Size, CStringW &UrlSite, CStringW &UrlDownload)
573a9b1e059SJoachim Henze {
574a9b1e059SJoachim Henze     ATLASSERT(FALSE && "Should not be called");
575a9b1e059SJoachim Henze }
576a9b1e059SJoachim Henze 
577*57b775efSWhindmar Saksit InstallerType
GetInstallerType() const578*57b775efSWhindmar Saksit CInstalledApplicationInfo::GetInstallerType() const
579a9b1e059SJoachim Henze {
580*57b775efSWhindmar Saksit     CRegKey reg;
581*57b775efSWhindmar Saksit     if (reg.Open(m_hKey, GENERATE_ARPSUBKEY, KEY_READ) == ERROR_SUCCESS)
582*57b775efSWhindmar Saksit     {
583*57b775efSWhindmar Saksit         return INSTALLER_GENERATE;
584*57b775efSWhindmar Saksit     }
585*57b775efSWhindmar Saksit     return INSTALLER_UNKNOWN;
586*57b775efSWhindmar Saksit }
587*57b775efSWhindmar Saksit 
588*57b775efSWhindmar Saksit BOOL
UninstallApplication(UninstallCommandFlags Flags)589*57b775efSWhindmar Saksit CInstalledApplicationInfo::UninstallApplication(UninstallCommandFlags Flags)
590*57b775efSWhindmar Saksit {
591*57b775efSWhindmar Saksit     if (GetInstallerType() == INSTALLER_GENERATE)
592*57b775efSWhindmar Saksit     {
593*57b775efSWhindmar Saksit         return UninstallGenerated(*this, Flags);
594*57b775efSWhindmar Saksit     }
595*57b775efSWhindmar Saksit 
596*57b775efSWhindmar Saksit     BOOL bModify = Flags & UCF_MODIFY;
597a9b1e059SJoachim Henze     if (m_szUninstallString.IsEmpty())
598a9b1e059SJoachim Henze     {
599a9b1e059SJoachim Henze         RetrieveUninstallStrings();
600a9b1e059SJoachim Henze     }
601a9b1e059SJoachim Henze 
602*57b775efSWhindmar Saksit     CStringW cmd = bModify ? m_szModifyString : m_szUninstallString;
603*57b775efSWhindmar Saksit     if ((Flags & (UCF_MODIFY | UCF_SILENT)) == UCF_SILENT)
604*57b775efSWhindmar Saksit     {
605*57b775efSWhindmar Saksit         DWORD msi = 0;
606*57b775efSWhindmar Saksit         msi = GetApplicationRegDword(L"WindowsInstaller", &msi) && msi;
607*57b775efSWhindmar Saksit         if (msi)
608*57b775efSWhindmar Saksit         {
609*57b775efSWhindmar Saksit             cmd += L" /qn";
610*57b775efSWhindmar Saksit         }
611*57b775efSWhindmar Saksit         else
612*57b775efSWhindmar Saksit         {
613*57b775efSWhindmar Saksit             CStringW silentcmd;
614*57b775efSWhindmar Saksit             if (GetApplicationRegString(L"QuietUninstallString", silentcmd) && !silentcmd.IsEmpty())
615*57b775efSWhindmar Saksit             {
616*57b775efSWhindmar Saksit                 cmd = silentcmd;
617*57b775efSWhindmar Saksit             }
618*57b775efSWhindmar Saksit         }
619*57b775efSWhindmar Saksit     }
620*57b775efSWhindmar Saksit 
621*57b775efSWhindmar Saksit     BOOL bSuccess = StartProcess(cmd, TRUE);
622a9b1e059SJoachim Henze 
623a9b1e059SJoachim Henze     if (bSuccess && !bModify)
624a9b1e059SJoachim Henze         WriteLogMessage(EVENTLOG_SUCCESS, MSG_SUCCESS_REMOVE, szDisplayName);
625a9b1e059SJoachim Henze 
626a9b1e059SJoachim Henze     return bSuccess;
627a9b1e059SJoachim Henze }
628a9b1e059SJoachim Henze 
629a9b1e059SJoachim Henze BOOL
GetApplicationRegString(LPCWSTR lpKeyName,CStringW & String)630a9b1e059SJoachim Henze CInstalledApplicationInfo::GetApplicationRegString(LPCWSTR lpKeyName, CStringW &String)
631a9b1e059SJoachim Henze {
632a9b1e059SJoachim Henze     ULONG nChars = 0;
633a9b1e059SJoachim Henze     // Get the size
634a9b1e059SJoachim Henze     if (m_hKey.QueryStringValue(lpKeyName, NULL, &nChars) != ERROR_SUCCESS)
635a9b1e059SJoachim Henze     {
636a9b1e059SJoachim Henze         String.Empty();
637a9b1e059SJoachim Henze         return FALSE;
638a9b1e059SJoachim Henze     }
639a9b1e059SJoachim Henze 
640a9b1e059SJoachim Henze     LPWSTR Buffer = String.GetBuffer(nChars);
641a9b1e059SJoachim Henze     LONG lResult = m_hKey.QueryStringValue(lpKeyName, Buffer, &nChars);
642a9b1e059SJoachim Henze     if (nChars > 0 && Buffer[nChars - 1] == UNICODE_NULL)
643a9b1e059SJoachim Henze         nChars--;
644a9b1e059SJoachim Henze     String.ReleaseBuffer(nChars);
645a9b1e059SJoachim Henze 
646a9b1e059SJoachim Henze     if (lResult != ERROR_SUCCESS)
647a9b1e059SJoachim Henze     {
648a9b1e059SJoachim Henze         String.Empty();
649a9b1e059SJoachim Henze         return FALSE;
650a9b1e059SJoachim Henze     }
651a9b1e059SJoachim Henze 
652a9b1e059SJoachim Henze     if (String.Find('%') >= 0)
653a9b1e059SJoachim Henze     {
654a9b1e059SJoachim Henze         CStringW Tmp;
655a9b1e059SJoachim Henze         DWORD dwLen = ExpandEnvironmentStringsW(String, NULL, 0);
656a9b1e059SJoachim Henze         if (dwLen > 0)
657a9b1e059SJoachim Henze         {
658a9b1e059SJoachim Henze             BOOL bSuccess = ExpandEnvironmentStringsW(String, Tmp.GetBuffer(dwLen), dwLen) == dwLen;
659a9b1e059SJoachim Henze             Tmp.ReleaseBuffer(dwLen - 1);
660a9b1e059SJoachim Henze             if (bSuccess)
661a9b1e059SJoachim Henze             {
662a9b1e059SJoachim Henze                 String = Tmp;
663a9b1e059SJoachim Henze             }
664a9b1e059SJoachim Henze             else
665a9b1e059SJoachim Henze             {
666a9b1e059SJoachim Henze                 String.Empty();
667a9b1e059SJoachim Henze                 return FALSE;
668a9b1e059SJoachim Henze             }
669a9b1e059SJoachim Henze         }
670a9b1e059SJoachim Henze     }
671a9b1e059SJoachim Henze 
672a9b1e059SJoachim Henze     return TRUE;
673a9b1e059SJoachim Henze }
674a9b1e059SJoachim Henze 
675a9b1e059SJoachim Henze BOOL
GetApplicationRegDword(LPCWSTR lpKeyName,DWORD * lpValue)676a9b1e059SJoachim Henze CInstalledApplicationInfo::GetApplicationRegDword(LPCWSTR lpKeyName, DWORD *lpValue)
677a9b1e059SJoachim Henze {
678a9b1e059SJoachim Henze     DWORD dwSize = sizeof(DWORD), dwType;
679a9b1e059SJoachim Henze     if (RegQueryValueExW(m_hKey, lpKeyName, NULL, &dwType, (LPBYTE)lpValue, &dwSize) != ERROR_SUCCESS ||
680a9b1e059SJoachim Henze         dwType != REG_DWORD)
681a9b1e059SJoachim Henze     {
682a9b1e059SJoachim Henze         return FALSE;
683a9b1e059SJoachim Henze     }
684a9b1e059SJoachim Henze 
685a9b1e059SJoachim Henze     return TRUE;
686a9b1e059SJoachim Henze }
687