ReactOS  0.4.15-dev-3720-g4cf9b79
installed.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 installed applications
5  * COPYRIGHT: Copyright 2009 Dmitry Chapyshev <dmitry@reactos.org>
6  * Copyright 2017 Alexander Shaposhnikov <sanchaez@reactos.org>
7  * Copyright 2020 He Yang <1160386205@qq.com>
8  * Copyright 2021 Mark Jansen <mark.jansen@reactos.org>
9  */
10 
11 #include "rapps.h"
12 #include "installed.h"
13 #include "misc.h"
14 
16  : m_IsUserKey(bIsUserKey)
17  , m_WowKey(RegWowKey)
18  , m_hSubKey(hKey)
19  , m_szKeyName(szKeyName)
20 {
21  DWORD dwSize = 0;
22  bIsUpdate = (RegQueryValueExW(m_hSubKey, L"ParentKeyName", NULL, NULL, NULL, &dwSize) == ERROR_SUCCESS);
23 }
24 
26 {
27  if (m_hSubKey)
28  {
30  m_hSubKey = NULL;
31  }
32 }
33 
35 {
36  // Key not closed, so we have not loaded details yet
37  if (m_hSubKey)
38  {
43  GetApplicationRegString(L"HelpTelephone", szHelpTelephone);
46  GetApplicationRegString(L"URLUpdateInfo", szURLUpdateInfo);
48  if (GetApplicationRegString(L"InstallDate", szInstallDate) == FALSE)
49  {
50  // It might be a DWORD (Unix timestamp). try again.
51  DWORD dwInstallTimeStamp;
52  if (GetApplicationRegDword(L"InstallDate", &dwInstallTimeStamp))
53  {
54  FILETIME InstallFileTime;
55  SYSTEMTIME InstallSystemTime, InstallLocalTime;
56 
57  UnixTimeToFileTime(dwInstallTimeStamp, &InstallFileTime);
58  FileTimeToSystemTime(&InstallFileTime, &InstallSystemTime);
59 
60  // convert to localtime
61  SystemTimeToTzSpecificLocalTime(NULL, &InstallSystemTime, &InstallLocalTime);
62 
63  // convert to readable date string
64  int cchTimeStrLen = GetDateFormatW(LOCALE_USER_DEFAULT, 0, &InstallLocalTime, NULL, 0, 0);
65 
67  LOCALE_USER_DEFAULT, // use default locale for current user
68  0, &InstallLocalTime, NULL, szInstallDate.GetBuffer(cchTimeStrLen), cchTimeStrLen);
70  }
71  }
72  GetApplicationRegString(L"InstallLocation", szInstallLocation);
73  GetApplicationRegString(L"InstallSource", szInstallSource);
74  GetApplicationRegString(L"UninstallString", szUninstallString);
76 
78  m_hSubKey = NULL;
79  }
80 }
81 
83 {
84  DWORD dwAllocated = 0, dwSize, dwType;
85 
86  // retrieve the size of value first.
87  if (RegQueryValueExW(m_hSubKey, lpKeyName, NULL, &dwType, NULL, &dwAllocated) != ERROR_SUCCESS ||
88  dwType != REG_SZ)
89  {
90  String.Empty();
91  return FALSE;
92  }
93 
94  // query the value
95  dwSize = dwAllocated;
96  LSTATUS Result =
97  RegQueryValueExW(m_hSubKey, lpKeyName, NULL, NULL, (LPBYTE)String.GetBuffer(dwAllocated / sizeof(WCHAR)), &dwSize);
98 
99  dwSize = min(dwAllocated, dwSize);
100  // CString takes care of zero-terminating it
101  String.ReleaseBuffer(dwSize / sizeof(WCHAR));
102 
103  if (Result != ERROR_SUCCESS)
104  {
105  String.Empty();
106  return FALSE;
107  }
108 
109  return TRUE;
110 }
111 
113 {
114  DWORD dwSize = sizeof(DWORD), dwType;
116  lpKeyName,
117  NULL,
118  &dwType,
119  (LPBYTE)lpValue,
120  &dwSize) != ERROR_SUCCESS || dwType != REG_DWORD)
121  {
122  return FALSE;
123  }
124 
125  return TRUE;
126 }
127 
129 {
130  if (szDisplayIcon.IsEmpty())
131  {
132  return FALSE;
133  }
135  return TRUE;
136 }
137 
139 {
140  if (!bModify)
141  WriteLogMessage(EVENTLOG_SUCCESS, MSG_SUCCESS_REMOVE, szDisplayName);
142 
143  return StartProcess(bModify ? szModifyPath : szUninstallString, TRUE);
144 }
145 
147 
149 {
150  ATL::CStringW szFullName = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + m_szKeyName;
151  HMODULE hMod = GetModuleHandleW(L"advapi32.dll");
152  RegDeleteKeyExWProc pRegDeleteKeyExW;
153 
154  // TODO: if there are subkeys inside, simply RegDeleteKeyExW
155  // (or RegDeleteKeyW on Server 2003 SP0 and earlier) will fail
156  // we don't have RegDeleteTree for ReactOS now. (It's a WinVista API)
157  // write a function to delete all subkeys recursively to solve this
158  // or consider letting ReactOS having this API
159 
160  /* Load RegDeleteKeyExW from advapi32.dll if available */
161  if (hMod)
162  {
163  pRegDeleteKeyExW = (RegDeleteKeyExWProc)GetProcAddress(hMod, "RegDeleteKeyExW");
164 
165  if (pRegDeleteKeyExW)
166  {
167  /* Return it */
168  return pRegDeleteKeyExW(m_IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, szFullName, m_WowKey, 0);
169  }
170  }
171 
172  /* Otherwise, return non-Ex function */
174 }
175 
177 {
179 
182 
183  int LoopTime;
184 
185  // test if the OS is 64 bit.
186  if (IsSystem64Bit())
187  {
188  // loop for all 3 combination.
189  // note that HKEY_CURRENT_USER\Software don't have a redirect
190  // https://docs.microsoft.com/en-us/windows/win32/winprog64/shared-registry-keys#redirected-shared-and-reflected-keys-under-wow64
191  LoopTime = 3;
192  }
193  else
194  {
195  // loop for 2 combination for KEY_WOW64_32KEY only
196  LoopTime = 2;
197  }
198 
199  // loop for all combination
200  for (int i = 0; i < LoopTime; i++)
201  {
203  HKEY hKey, hSubKey;
204  LONG ItemIndex = 0;
205  ATL::CStringW szKeyName;
206 
207  if (RegOpenKeyExW(RootKeyEnum[i],
208  L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
209  NULL,
210  KEY_READ | RegSamEnum[i],
211  &hKey) != ERROR_SUCCESS)
212  {
213  return FALSE;
214  }
215 
216  while (1)
217  {
218  dwSize = MAX_PATH;
219  if (RegEnumKeyExW(hKey, ItemIndex, szKeyName.GetBuffer(MAX_PATH), &dwSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
220  {
221  break;
222  }
223 
224  ItemIndex++;
225 
226  szKeyName.ReleaseBuffer();
227  if (RegOpenKeyW(hKey, szKeyName, &hSubKey) == ERROR_SUCCESS)
228  {
229  DWORD dwValue = 0;
230  BOOL bIsSystemComponent = FALSE;
231 
232  dwSize = sizeof(DWORD);
233  if (RegQueryValueExW(hSubKey, L"SystemComponent", NULL, NULL, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS)
234  {
235  bIsSystemComponent = (dwValue == 0x1);
236  }
237  // Ignore system components
238  if (bIsSystemComponent)
239  {
240  RegCloseKey(hSubKey);
241  continue;
242  }
243 
244  BOOL bSuccess = FALSE;
245  CInstalledApplicationInfo *Info = new CInstalledApplicationInfo(RootKeyEnum[i] == HKEY_CURRENT_USER, RegSamEnum[i], hSubKey, szKeyName);
246 
247  // items without display name are ignored
248  if (Info->GetApplicationRegString(L"DisplayName", Info->szDisplayName))
249  {
250  Info->GetApplicationRegString(L"DisplayIcon", Info->szDisplayIcon);
251  Info->GetApplicationRegString(L"DisplayVersion", Info->szDisplayVersion);
252  Info->GetApplicationRegString(L"Comments", Info->szComments);
253 
254  bSuccess = TRUE;
255  }
256 
257  if (bSuccess)
258  {
259  // add to InfoList.
261 
262  // invoke callback
263  if (lpEnumProc)
264  {
265  if ((EnumType == ENUM_ALL_INSTALLED) || /* All components */
266  ((EnumType == ENUM_INSTALLED_APPLICATIONS) && (!Info->bIsUpdate)) || /* Applications only */
267  ((EnumType == ENUM_UPDATES) && (Info->bIsUpdate))) /* Updates only */
268  {
269  lpEnumProc(Info, param);
270  }
271  }
272  }
273  else
274  {
275  // destory object
276  delete Info;
277  }
278  }
279  }
280 
281  szKeyName.ReleaseBuffer();
282  RegCloseKey(hKey);
283  }
284 
285  return TRUE;
286 }
287 
289 {
290  POSITION InfoListPosition = m_InfoList.GetHeadPosition();
291 
292  /* loop and deallocate all the cached app infos in the list */
293  while (InfoListPosition)
294  {
295  CInstalledApplicationInfo *Info = m_InfoList.GetNext(InfoListPosition);
296  delete Info;
297  }
298 
300 }
CInstalledApplicationInfo(BOOL bIsUserKey, REGSAM RegWowKey, HKEY hKey, const CStringW &szKeyName)
Definition: installed.cpp:15
POSITION GetHeadPosition() const
Definition: atlcoll.h:549
#define CloseHandle
Definition: compat.h:598
#define ERROR_SUCCESS
Definition: deptool.c:10
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define LOCALE_USER_DEFAULT
#define HKEY_CURRENT_USER
Definition: winreg.h:11
BOOL IsSystem64Bit()
Definition: misc.cpp:339
BOOL(CALLBACK * APPENUMPROC)(CInstalledApplicationInfo *Info, PVOID param)
Definition: installed.h:52
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1237
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:58
static BOOLEAN bSuccess
Definition: drive.cpp:432
VOID FreeCachedEntries()
Definition: installed.cpp:288
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
BOOL WINAPI SystemTimeToTzSpecificLocalTime(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation, CONST SYSTEMTIME *lpUniversalTime, LPSYSTEMTIME lpLocalTime)
Definition: timezone.c:377
#define L(x)
Definition: ntvdm.h:50
unsigned char * LPBYTE
Definition: typedefs.h:53
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
void ReleaseBuffer(_In_ int nNewLength=-1)
Definition: atlsimpstr.h:372
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3291
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
LSTATUS(WINAPI * RegDeleteKeyExWProc)(HKEY, LPCWSTR, REGSAM, DWORD)
Definition: installed.cpp:146
ATL::CAtlList< CInstalledApplicationInfo * > m_InfoList
Definition: installed.h:56
BOOL Enum(INT EnumType, APPENUMPROC lpEnumProc, PVOID param)
Definition: installed.cpp:176
BOOL UninstallApplication(BOOL bModify)
Definition: installed.cpp:138
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
E & GetNext(_Inout_ POSITION &pos)
Definition: atlcoll.h:561
#define EVENTLOG_SUCCESS
Definition: winnt_old.h:2898
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
BOOL WriteLogMessage(WORD wType, DWORD dwEventID, LPCWSTR lpMsg)
Definition: misc.cpp:226
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4120
__wchar_t WCHAR
Definition: xmlstorage.h:180
GLfloat param
Definition: glext.h:5796
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL RetrieveIcon(ATL::CStringW &IconLocation)
Definition: installed.cpp:128
void RemoveAll()
Definition: atlcoll.h:725
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
INT WINAPI GetDateFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpDateStr, INT cchOut)
Definition: lcformat.c:979
bool IsEmpty() const
Definition: atlsimpstr.h:379
POSITION AddTail(INARGTYPE element)
Definition: atlcoll.h:624
BOOL StartProcess(const ATL::CStringW &Path, BOOL Wait)
Definition: misc.cpp:83
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FxAutoRegKey hKey
ACCESS_MASK REGSAM
Definition: winreg.h:69
BOOL GetApplicationRegString(LPCWSTR lpKeyName, ATL::CStringW &String)
Definition: installed.cpp:82
#define min(a, b)
Definition: monoChain.cc:55
void UnixTimeToFileTime(DWORD dwUnixTime, LPFILETIME pFileTime)
Definition: misc.cpp:394
#define NULL
Definition: types.h:112
BOOL GetApplicationRegDword(LPCWSTR lpKeyName, DWORD *lpValue)
Definition: installed.cpp:112
HANDLE HKEY
Definition: registry.h:24
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
#define GetProcAddress(x, y)
Definition: compat.h:612
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2527
#define REG_DWORD
Definition: sdbapi.c:596
#define RegCloseKey(hKey)
Definition: registry.h:40
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22