ReactOS 0.4.17-dev-243-g1369312
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#include "misc.h"
15
16
19#define UNINSTALL_SUBKEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
20#define MANIFEST_DOTEXT L".txt"
21
22static inline HKEY
24{
27 {
28 RegSam = g_RegSamEnum[Index];
29 return g_RootKeyEnum[Index];
30 }
31 return NULL;
32}
33
35{
36 // HKCU + HKLM (Native) + HKLM (WoW64)
37 // Note that HKEY_CURRENT_USER\Software does not have a redirect
38 // https://learn.microsoft.com/en-us/windows/win32/winprog64/shared-registry-keys#redirected-shared-and-reflected-keys-under-wow64
39
42
43public:
45 {
46 // We don't want to display duplicate entries on systems without WoW64 keys support.
47 // When ROS starts supporting the WOW REGSAM flags,
48 // this code can be changed back to IsSystem64Bit() ? 3 : 2.
51 }
52
53 HKEY Get(REGSAM &RegSam)
54 {
55 return m_Index < m_Count ? GetRootKeyInfo(m_Index, RegSam) : NULL;
56 }
57
58 void Next()
59 {
60 m_Index++;
61 }
62
64 {
65 return m_Index;
66 }
67};
68
69static VOID
71{
72 POSITION InfoListPosition = list.GetHeadPosition();
73 while (InfoListPosition)
74 {
75 CAppInfo *Info = list.GetNext(InfoListPosition);
76 delete Info;
77 }
78 list.RemoveAll();
79}
80
81CAppDB::CAppDB(const CStringW &path) : m_BasePath(path)
82{
84}
85
88{
91 return path;
92}
93
96{
97 POSITION CurrentListPosition = m_Available.GetHeadPosition();
98 while (CurrentListPosition)
99 {
100 CAppInfo *Info = m_Available.GetNext(CurrentListPosition);
101 if (Info->szIdentifier == name)
102 {
103 return static_cast<CAvailableApplicationInfo *>(Info);
104 }
105 }
106 return NULL;
107}
108
111{
113 CPathW AppsPath = DBPath ? CPathW(DBPath) : (CPathW(GetDefaultPath()) += RAPPS_DATABASE_SUBDIR);
114 CPathW ManifestPath = CPathW(AppsPath) += PkgName + MANIFEST_DOTEXT;
115 CConfigParser *Parser = new CConfigParser(ManifestPath);
116 int Cat;
117 if (!Parser->GetInt(DB_CATEGORY, Cat))
118 Cat = ENUM_INVALID;
119
120 pAppInfo = new CAvailableApplicationInfo(Parser, PkgName, static_cast<AppsCategories>(Cat), AppsPath);
121 if (pAppInfo->Valid())
122 return pAppInfo;
123 delete pAppInfo;
124 return NULL;
125}
126
127void
129{
130 const BOOL UseInstalled = IsInstalledEnum(Type);
131 const CAtlList<CAppInfo *> &list = UseInstalled ? m_Installed : m_Available;
132 const BOOL IncludeAll = UseInstalled ? (Type == ENUM_ALL_INSTALLED) : (Type == ENUM_ALL_AVAILABLE);
133
134 POSITION CurrentListPosition = list.GetHeadPosition();
135 while (CurrentListPosition)
136 {
137 CAppInfo *Info = list.GetNext(CurrentListPosition);
138
139 if (IncludeAll || Type == Info->iCategory)
140 {
141 List.AddTail(Info);
142 }
143 }
144}
145
146BOOL
148{
150
151 CPathW AppsPath = m_BasePath;
152 AppsPath += RAPPS_DATABASE_SUBDIR;
153 CPathW WildcardPath = AppsPath;
154 WildcardPath += L"*" MANIFEST_DOTEXT;
155
156 WIN32_FIND_DATAW FindFileData;
157 HANDLE hFind = FindFirstFileW(WildcardPath, &FindFileData);
158 if (hFind == INVALID_HANDLE_VALUE)
159 {
160 return FALSE;
161 }
162
163 do
164 {
165 CStringW szPkgName = FindFileData.cFileName;
167 szPkgName.ReleaseBuffer();
168
170 ATLASSERT(Info == NULL);
171 if (!Info)
172 {
173 Info = CreateAvailableAppInstance(szPkgName, AppsPath);
174 if (Info)
176 }
177
178 } while (FindNextFileW(hFind, &FindFileData));
179
180 FindClose(hFind);
181 return TRUE;
182}
183
184VOID
186{
188 return;
189
190 if (EnumerateFiles())
191 return;
192
195
196 CPathW AppsPath = m_BasePath;
197 AppsPath += RAPPS_DATABASE_SUBDIR;
199 return;
200
201 CPathW CabFile = m_BasePath;
202 CabFile += APPLICATION_DATABASE_NAME;
203 DeleteFileW(CabFile);
204
206}
207
210{
211 CRegKey hSubKey;
212 if (hSubKey.Open(hKeyParent, KeyName, KEY_READ) != ERROR_SUCCESS)
213 return NULL;
215
216 size = sizeof(DWORD);
217 if (!RegQueryValueExW(hSubKey, L"SystemComponent", NULL, NULL, (LPBYTE)&value, &size) && value == 1)
218 {
219 // Ignore system components
220 return NULL;
221 }
222
223 size = 0;
224 BOOL bIsUpdate = !RegQueryValueExW(hSubKey, L"ParentKeyName", NULL, NULL, NULL, &size);
225
228 pInfo = new CInstalledApplicationInfo(hSubKey.Detach(), KeyName, cat, KeyIndex);
229 if (pInfo && pInfo->Valid())
230 {
231 return pInfo;
232 }
233 delete pInfo;
234 return NULL;
235}
236
239{
240 ATLASSERT(List || SearchOnly);
241 REGSAM wowsam;
242 HKEY hRootKey;
243 for (CEnumInstalledRootKey RootEnum; (hRootKey = RootEnum.Get(wowsam)) != NULL; RootEnum.Next())
244 {
246 if (hKey.Open(hRootKey, UNINSTALL_SUBKEY, KEY_READ | wowsam) != ERROR_SUCCESS)
247 {
248 continue;
249 }
250 for (DWORD Index = 0;; ++Index)
251 {
252 WCHAR szKeyName[MAX_PATH];
253 DWORD dwSize = _countof(szKeyName);
254 if (hKey.EnumKey(Index, szKeyName, &dwSize) != ERROR_SUCCESS)
255 {
256 break;
257 }
258 if (List || !StrCmpIW(SearchOnly, szKeyName))
259 {
261 Info = CreateInstalledAppByRegistryKey(szKeyName, hKey, RootEnum.GetKeyIndex());
262 if (Info)
263 {
264 if (List)
265 List->AddTail(Info);
266 else
267 return Info;
268 }
269 }
270 }
271 }
272 return NULL;
273}
274
275VOID
277{
278 // Remove all old entries
280
282}
283
286{
287 return EnumerateRegistry(NULL, Name);
288}
289
292{
294 UINT KeyIndex = User ? (0) : ((WowSam & KEY_WOW64_64KEY) ? 2 : 1);
296 if (hKey.Open(hRootKey, UNINSTALL_SUBKEY, KEY_READ | WowSam) == ERROR_SUCCESS)
297 {
299 }
300 return NULL;
301}
302
303static void
305{
307 WIN32_FIND_DATAW FindFileData;
308
309 CPathW DirWithFilter = Dir;
310 DirWithFilter += Filter;
311
312 hFind = FindFirstFileW(DirWithFilter, &FindFileData);
313
314 if (hFind == INVALID_HANDLE_VALUE)
315 return;
316
317 do
318 {
319 CPathW szTmp = Dir;
320 szTmp += FindFileData.cFileName;
321
322 if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
323 {
325 }
326 } while (FindNextFileW(hFind, &FindFileData) != 0);
327 FindClose(hFind);
328}
329
330VOID
332{
333 // Delete icons
334 CPathW AppsPath = m_BasePath;
335 AppsPath += RAPPS_DATABASE_SUBDIR;
336 CPathW IconPath = AppsPath;
337 IconPath += L"icons";
339
340 // Delete leftover screenshots
341 CPathW ScrnshotFolder = AppsPath;
342 ScrnshotFolder += L"screenshots";
343 DeleteWithWildcard(ScrnshotFolder, L"*.tmp");
344
345 // Delete data base files (*.txt)
347
349 RemoveDirectoryW(ScrnshotFolder);
350 RemoveDirectoryW(AppsPath);
352}
353
354DWORD
356{
357 // Validate that this is actually an installed app / update
358 ATLASSERT(Info->iCategory == ENUM_INSTALLED_APPLICATIONS || Info->iCategory == ENUM_UPDATES);
359 if (Info->iCategory != ENUM_INSTALLED_APPLICATIONS && Info->iCategory != ENUM_UPDATES)
361
362 const CInstalledApplicationInfo *InstalledInfo = static_cast<const CInstalledApplicationInfo *>(Info);
363
364 CStringW Name = InstalledInfo->szIdentifier;
365 REGSAM wowsam;
366 HKEY hRoot = GetRootKeyInfo(InstalledInfo->m_KeyInfo, wowsam);
368 if (!hRoot)
369 return ERROR_OPEN_FAILED;
370
371 CRegKey Uninstall;
372 LSTATUS err = Uninstall.Open(hRoot, UNINSTALL_SUBKEY, KEY_READ | KEY_WRITE | wowsam);
373 if (err == ERROR_SUCCESS)
374 {
375 err = Uninstall.RecurseDeleteKey(Name);
376 }
377 return err;
378}
#define ATLASSERT(x)
Definition: CComVariant.cpp:10
char szTmp[518]
Type
Definition: Type.h:7
static VOID ClearList(CAtlList< CAppInfo * > &list)
Definition: appdb.cpp:70
#define UNINSTALL_SUBKEY
Definition: appdb.cpp:19
#define MANIFEST_DOTEXT
Definition: appdb.cpp:20
static void DeleteWithWildcard(const CPathW &Dir, const CStringW &Filter)
Definition: appdb.cpp:304
static HKEY g_RootKeyEnum[3]
Definition: appdb.cpp:17
static REGSAM g_RegSamEnum[3]
Definition: appdb.cpp:18
static HKEY GetRootKeyInfo(UINT Index, REGSAM &RegSam)
Definition: appdb.cpp:23
BOOL IsInstalledEnum(INT x)
Definition: appinfo.h:67
#define DB_CATEGORY
Definition: appinfo.h:92
AppsCategories
Definition: appinfo.h:24
@ ENUM_UPDATES
Definition: appinfo.h:46
@ ENUM_ALL_AVAILABLE
Definition: appinfo.h:25
@ 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 GetStorageDirectory(CStringW &lpDirectory)
Definition: misc.cpp:241
BOOL IsSameRegKey(HKEY hRoot, LPCWSTR Path1, REGSAM Sam1, LPCWSTR Path2, REGSAM Sam2)
Definition: misc.cpp:476
SETTINGS_INFO SettingsInfo
Definition: winmain.cpp:21
BOOL ExtractFilesFromCab(const CStringW &szCabName, const CStringW &szCabDir, const CStringW &szOutputDir, EXTRACTCALLBACK Callback, void *Cookie)
Definition: cabinet.cpp:250
POSITION AddTail(INARGTYPE element)
Definition: atlcoll.h:629
POSITION GetHeadPosition() const
Definition: atlcoll.h:554
E & GetNext(_Inout_ POSITION &pos)
Definition: atlcoll.h:566
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
static DWORD RemoveInstalledAppFromRegistry(const CAppInfo *Info)
Definition: appdb.cpp:355
VOID UpdateAvailable()
Definition: appdb.cpp:185
static CInstalledApplicationInfo * CreateInstalledAppByRegistryKey(LPCWSTR KeyName, HKEY hKeyParent, UINT KeyIndex)
Definition: appdb.cpp:209
CAvailableApplicationInfo * FindAvailableByPackageName(const CStringW &name)
Definition: appdb.cpp:95
CAtlList< CAppInfo * > m_Available
Definition: appdb.h:12
CAppDB(const CStringW &path)
Definition: appdb.cpp:81
BOOL EnumerateFiles()
Definition: appdb.cpp:147
CPathW m_BasePath
Definition: appdb.h:11
static CStringW GetDefaultPath()
Definition: appdb.cpp:87
static CInstalledApplicationInfo * EnumerateRegistry(CAtlList< CAppInfo * > *List, LPCWSTR Name)
Definition: appdb.cpp:238
VOID UpdateInstalled()
Definition: appdb.cpp:276
VOID GetApps(CAtlList< CAppInfo * > &List, AppsCategories Type) const
Definition: appdb.cpp:128
static CAvailableApplicationInfo * CreateAvailableAppInstance(const CStringW &PkgName, PCWSTR DBPath=NULL)
Definition: appdb.cpp:110
CAtlList< CAppInfo * > m_Installed
Definition: appdb.h:13
VOID RemoveCached()
Definition: appdb.cpp:331
static CInstalledApplicationInfo * CreateInstalledAppInstance(LPCWSTR KeyName, BOOL User, REGSAM WowSam)
Definition: appdb.cpp:291
const CStringW szIdentifier
Definition: appinfo.h:119
virtual BOOL Valid() const override
Definition: appinfo.cpp:342
BOOL GetInt(const CStringW &KeyName, INT &iResult)
UINT GetKeyIndex() const
Definition: appdb.cpp:63
HKEY Get(REGSAM &RegSam)
Definition: appdb.cpp:53
virtual BOOL Valid() const override
Definition: appinfo.cpp:618
Definition: list.h:37
#define ERROR_SUCCESS
Definition: deptool.c:10
LPWSTR Name
Definition: desk.c:124
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#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 ERROR_INVALID_PARAMETER
Definition: compat.h:101
#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:58
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:700
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
void WINAPI PathRemoveExtensionW(WCHAR *path)
Definition: path.c:1946
int WINAPI StrCmpIW(const WCHAR *str, const WCHAR *comp)
Definition: string.c:456
static const WCHAR IconPath[]
Definition: install.c:51
#define L(x)
Definition: resources.c:13
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
GLsizeiptr size
Definition: glext.h:5919
#define C_ASSERT(e)
Definition: intsafe.h:73
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static HTREEITEM hRoot
Definition: treeview.c:383
CPathT< CStringW > CPathW
Definition: atlpath.h:395
unsigned int UINT
Definition: ndis.h:50
#define KEY_READ
Definition: nt_native.h:1026
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define KEY_WRITE
Definition: nt_native.h:1034
#define DWORD
Definition: nt_native.h:44
short WCHAR
Definition: pedump.c:58
VOID DownloadApplicationsDB(LPCWSTR lpUrl, BOOL IsOfficial)
Definition: loaddlg.cpp:1250
#define err(...)
#define _countof(array)
Definition: sndvol32.h:70
BOOL bUseSource
Definition: settings.h:24
WCHAR szSourceURL[INTERNET_MAX_URL_LENGTH]
Definition: settings.h:25
_Field_z_ WCHAR cFileName[MAX_PATH]
Definition: minwinbase.h:291
DWORD dwFileAttributes
Definition: minwinbase.h:283
Definition: name.c:39
const uint16_t * PCWSTR
Definition: typedefs.h:57
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
Definition: pdh_main.c:96
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2705
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_OPEN_FAILED
Definition: winerror.h:306
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
ACCESS_MASK REGSAM
Definition: winreg.h:76
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46