ReactOS 0.4.15-dev-7918-g2a2556c
appdb.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Applications Manager
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Classes for working with available applications
5 * COPYRIGHT: Copyright 2017 Alexander Shaposhnikov (sanchaez@reactos.org)
6 * Copyright 2020 He Yang (1160386205@qq.com)
7 * Copyright 2021-2023 Mark Jansen <mark.jansen@reactos.org>
8 */
9
10#include "rapps.h"
11#include "appdb.h"
12#include "configparser.h"
13#include "settings.h"
14
15
18#define UNINSTALL_SUBKEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
19
20static VOID
22{
23 POSITION InfoListPosition = list.GetHeadPosition();
24 while (InfoListPosition)
25 {
26 CAppInfo *Info = list.GetNext(InfoListPosition);
27 delete Info;
28 }
29 list.RemoveAll();
30}
31
32CAppDB::CAppDB(const CStringW &path) : m_BasePath(path)
33{
35}
36
39{
40 POSITION CurrentListPosition = m_Available.GetHeadPosition();
41 while (CurrentListPosition)
42 {
43 CAppInfo *Info = m_Available.GetNext(CurrentListPosition);
44 if (Info->szIdentifier == name)
45 {
46 return Info;
47 }
48 }
49 return NULL;
50}
51
52void
54{
55 const BOOL UseInstalled = IsInstalledEnum(Type);
56 const CAtlList<CAppInfo *> &list = UseInstalled ? m_Installed : m_Available;
57 const BOOL IncludeAll = UseInstalled ? (Type == ENUM_ALL_INSTALLED) : (Type == ENUM_ALL_AVAILABLE);
58
59 POSITION CurrentListPosition = list.GetHeadPosition();
60 while (CurrentListPosition)
61 {
62 CAppInfo *Info = list.GetNext(CurrentListPosition);
63
64 if (IncludeAll || Type == Info->iCategory)
65 {
66 List.AddTail(Info);
67 }
68 }
69}
70
71BOOL
73{
75
76 CPathW AppsPath = m_BasePath;
77 AppsPath += RAPPS_DATABASE_SUBDIR;
78 CPathW WildcardPath = AppsPath;
79 WildcardPath += L"*.txt";
80
81 WIN32_FIND_DATAW FindFileData;
82 HANDLE hFind = FindFirstFileW(WildcardPath, &FindFileData);
83 if (hFind == INVALID_HANDLE_VALUE)
84 {
85 return FALSE;
86 }
87
88 do
89 {
90 CStringW szPkgName = FindFileData.cFileName;
92 szPkgName.ReleaseBuffer();
93
94 CAppInfo *Info = FindByPackageName(szPkgName);
96 if (!Info)
97 {
98 CConfigParser *Parser = new CConfigParser(CPathW(AppsPath) += FindFileData.cFileName);
99 int Cat;
100 if (!Parser->GetInt(L"Category", Cat))
101 Cat = ENUM_INVALID;
102
103 Info = new CAvailableApplicationInfo(Parser, szPkgName, static_cast<AppsCategories>(Cat), AppsPath);
104 if (Info->Valid())
105 {
107 }
108 else
109 {
110 delete Info;
111 }
112 }
113
114 } while (FindNextFileW(hFind, &FindFileData));
115
116 FindClose(hFind);
117 return TRUE;
118}
119
120VOID
122{
124 return;
125
126 if (EnumerateFiles())
127 return;
128
131
132 CPathW AppsPath = m_BasePath;
133 AppsPath += RAPPS_DATABASE_SUBDIR;
135 return;
136
137 CPathW CabFile = m_BasePath;
138 CabFile += APPLICATION_DATABASE_NAME;
139 DeleteFileW(CabFile);
140
142}
143
144VOID
146{
147 // Remove all old entries
149
150 int LoopKeys = 2;
151
152 if (IsSystem64Bit())
153 {
154 // loop for all 3 combination.
155 // note that HKEY_CURRENT_USER\Software don't have a redirect
156 // https://docs.microsoft.com/en-us/windows/win32/winprog64/shared-registry-keys#redirected-shared-and-reflected-keys-under-wow64
157 LoopKeys = 3;
158 }
159
160 for (int keyIndex = 0; keyIndex < LoopKeys; keyIndex++)
161 {
162 LONG ItemIndex = 0;
163 WCHAR szKeyName[MAX_PATH];
164
166 if (hKey.Open(g_RootKeyEnum[keyIndex], UNINSTALL_SUBKEY, KEY_READ | g_RegSamEnum[keyIndex]) != ERROR_SUCCESS)
167 {
168 continue;
169 }
170
171 while (1)
172 {
173 DWORD dwSize = _countof(szKeyName);
174 if (hKey.EnumKey(ItemIndex, szKeyName, &dwSize) != ERROR_SUCCESS)
175 {
176 break;
177 }
178
179 ItemIndex++;
180
181 CRegKey hSubKey;
182 if (hSubKey.Open(hKey, szKeyName, KEY_READ) == ERROR_SUCCESS)
183 {
184 DWORD dwValue = 0;
185
186 dwSize = sizeof(DWORD);
187 if (RegQueryValueExW(hSubKey, L"SystemComponent", NULL, NULL, (LPBYTE)&dwValue, &dwSize) ==
189 dwValue == 1)
190 {
191 // Ignore system components
192 continue;
193 }
194
195 BOOL bIsUpdate =
196 (RegQueryValueExW(hSubKey, L"ParentKeyName", NULL, NULL, NULL, &dwSize) == ERROR_SUCCESS);
197
199 hSubKey.Detach(), szKeyName, bIsUpdate ? ENUM_UPDATES : ENUM_INSTALLED_APPLICATIONS, keyIndex);
200
201 if (Info->Valid())
202 {
204 }
205 else
206 {
207 delete Info;
208 }
209 }
210 }
211 }
212}
213
214static void
216{
218 WIN32_FIND_DATAW FindFileData;
219
220 CPathW DirWithFilter = Dir;
221 DirWithFilter += Filter;
222
223 hFind = FindFirstFileW(DirWithFilter, &FindFileData);
224
225 if (hFind == INVALID_HANDLE_VALUE)
226 return;
227
228 do
229 {
230 CPathW szTmp = Dir;
231 szTmp += FindFileData.cFileName;
232
233 if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
234 {
236 }
237 } while (FindNextFileW(hFind, &FindFileData) != 0);
238 FindClose(hFind);
239}
240
241VOID
243{
244 // Delete icons
245 CPathW AppsPath = m_BasePath;
246 AppsPath += RAPPS_DATABASE_SUBDIR;
247 CPathW IconPath = AppsPath;
248 IconPath += L"icons";
250
251 // Delete leftover screenshots
252 CPathW ScrnshotFolder = AppsPath;
253 ScrnshotFolder += L"screenshots";
254 DeleteWithWildcard(ScrnshotFolder, L"*.tmp");
255
256 // Delete data base files (*.txt)
257 DeleteWithWildcard(AppsPath, L"*.txt");
258
260 RemoveDirectoryW(ScrnshotFolder);
261 RemoveDirectoryW(AppsPath);
263}
264
265BOOL
267{
268 // Validate that this is actually an installed app / update
269 ATLASSERT(Info->iCategory == ENUM_INSTALLED_APPLICATIONS || Info->iCategory == ENUM_UPDATES);
270 if (Info->iCategory != ENUM_INSTALLED_APPLICATIONS && Info->iCategory != ENUM_UPDATES)
271 return FALSE;
272
273 // Grab the index in the registry keys
274 const CInstalledApplicationInfo *InstalledInfo = static_cast<const CInstalledApplicationInfo *>(Info);
275 ATLASSERT(InstalledInfo->iKeyIndex >= 0 && InstalledInfo->iKeyIndex < (int)_countof(g_RootKeyEnum));
276 if (InstalledInfo->iKeyIndex < 0 && InstalledInfo->iKeyIndex >= (int)_countof(g_RootKeyEnum))
277 return FALSE;
278
279 int keyIndex = InstalledInfo->iKeyIndex;
280
281 // Grab the registry key name
282 CStringW Name = InstalledInfo->szIdentifier;
283
284 // Recursively delete this key
285 CRegKey Uninstall;
286 if (Uninstall.Open(g_RootKeyEnum[keyIndex], UNINSTALL_SUBKEY, KEY_READ | KEY_WRITE | g_RegSamEnum[keyIndex]) !=
288 return FALSE;
289
290 return Uninstall.RecurseDeleteKey(Name) == ERROR_SUCCESS;
291}
#define ATLASSERT(x)
Definition: CComVariant.cpp:10
char szTmp[518]
Type
Definition: Type.h:7
static VOID ClearList(CAtlList< CAppInfo * > &list)
Definition: appdb.cpp:21
#define UNINSTALL_SUBKEY
Definition: appdb.cpp:18
static void DeleteWithWildcard(const CPathW &Dir, const CStringW &Filter)
Definition: appdb.cpp:215
static HKEY g_RootKeyEnum[3]
Definition: appdb.cpp:16
static REGSAM g_RegSamEnum[3]
Definition: appdb.cpp:17
BOOL IsInstalledEnum(INT x)
Definition: appinfo.h:61
AppsCategories
Definition: appinfo.h:25
@ ENUM_UPDATES
Definition: appinfo.h:46
@ ENUM_ALL_AVAILABLE
Definition: appinfo.h:26
@ ENUM_INSTALLED_APPLICATIONS
Definition: appinfo.h:45
@ ENUM_INVALID
Definition: appinfo.h:47
@ ENUM_ALL_INSTALLED
Definition: appinfo.h:44
#define RAPPS_DATABASE_SUBDIR
Definition: defines.h:37
#define APPLICATION_DATABASE_URL
Definition: defines.h:40
#define APPLICATION_DATABASE_NAME
Definition: defines.h:41
BOOL IsSystem64Bit()
Definition: misc.cpp:290
SETTINGS_INFO SettingsInfo
Definition: winmain.cpp:20
BOOL ExtractFilesFromCab(const CStringW &szCabName, const CStringW &szCabDir, const CStringW &szOutputDir)
Definition: cabinet.cpp:236
POSITION AddTail(INARGTYPE element)
Definition: atlcoll.h:626
POSITION GetHeadPosition() const
Definition: atlcoll.h:551
E & GetNext(_Inout_ POSITION &pos)
Definition: atlcoll.h:563
void Canonicalize()
Definition: atlpath.h:149
LONG Open(HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired=KEY_READ|KEY_WRITE) noexcept
Definition: atlbase.h:1173
HKEY Detach() noexcept
Definition: atlbase.h:1166
LONG RecurseDeleteKey(LPCTSTR lpszKey) noexcept
Definition: atlbase.h:1414
void ReleaseBuffer(_In_ int nNewLength=-1)
Definition: atlsimpstr.h:387
VOID UpdateAvailable()
Definition: appdb.cpp:121
CAppInfo * FindByPackageName(const CStringW &name)
Definition: appdb.cpp:38
CAtlList< CAppInfo * > m_Available
Definition: appdb.h:12
CAppDB(const CStringW &path)
Definition: appdb.cpp:32
BOOL EnumerateFiles()
Definition: appdb.cpp:72
CPathW m_BasePath
Definition: appdb.h:11
VOID UpdateInstalled()
Definition: appdb.cpp:145
VOID GetApps(CAtlList< CAppInfo * > &List, AppsCategories Type) const
Definition: appdb.cpp:53
BOOL RemoveInstalledAppFromRegistry(const CAppInfo *Info)
Definition: appdb.cpp:266
CAtlList< CAppInfo * > m_Installed
Definition: appdb.h:13
VOID RemoveCached()
Definition: appdb.cpp:242
const CStringW szIdentifier
Definition: appinfo.h:74
BOOL GetInt(const CStringW &KeyName, INT &iResult)
Definition: list.h:37
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
static const WCHAR IconPath[]
Definition: install.c:51
void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
Definition: path.c:823
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
FxAutoRegKey hKey
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
CPathT< CStringW > CPathW
Definition: atlpath.h:395
#define KEY_READ
Definition: nt_native.h:1023
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define KEY_WRITE
Definition: nt_native.h:1031
#define DWORD
Definition: nt_native.h:44
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
VOID DownloadApplicationsDB(LPCWSTR lpUrl, BOOL IsOfficial)
Definition: loaddlg.cpp:1118
#define _countof(array)
Definition: sndvol32.h:68
BOOL bUseSource
Definition: settings.h:23
WCHAR szSourceURL[INTERNET_MAX_URL_LENGTH]
Definition: settings.h:24
Definition: name.c:39
unsigned char * LPBYTE
Definition: typedefs.h:53
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
ACCESS_MASK REGSAM
Definition: winreg.h:69
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
__wchar_t WCHAR
Definition: xmlstorage.h:180