[RAPPS] License header unification and minor style changes
[reactos.git] / reactos / base / applications / rapps / installed.cpp
1 /*
2 * PROJECT: ReactOS Applications Manager
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * FILE: base/applications/rapps/installed.cpp
5 * PURPOSE: Functions for working with installed applications
6 * COPYRIGHT: Copyright 2009 Dmitry Chapyshev (dmitry@reactos.org)
7 * Copyright 2017 Alexander Shaposhnikov (chaez.san@gmail.com)
8 */
9 #include "defines.h"
10
11 #include "installed.h"
12
13 #include "gui.h"
14 #include "misc.h"
15
16 BOOL GetApplicationString(HKEY hKey, LPCWSTR lpKeyName, ATL::CStringW& String)
17 {
18 BOOL result = GetApplicationString(hKey, lpKeyName, String.GetBuffer(MAX_PATH));
19 String.ReleaseBuffer();
20 return result;
21 }
22
23 BOOL GetApplicationString(HKEY hKey, LPCWSTR lpKeyName, LPWSTR szString)
24 {
25 DWORD dwSize = MAX_PATH * sizeof(WCHAR);
26
27 if (RegQueryValueExW(hKey,
28 lpKeyName,
29 NULL,
30 NULL,
31 (LPBYTE) szString,
32 &dwSize) == ERROR_SUCCESS)
33 {
34 return TRUE;
35 }
36
37 StringCchCopyW(szString, MAX_PATH, L"---");
38 return FALSE;
39 }
40
41 BOOL UninstallApplication(INT Index, BOOL bModify)
42 {
43 LPCWSTR szModify = L"ModifyPath";
44 LPCWSTR szUninstall = L"UninstallString";
45 WCHAR szPath[MAX_PATH];
46 WCHAR szAppName[MAX_STR_LEN];
47 DWORD dwType, dwSize;
48 INT ItemIndex;
49 LVITEMW Item;
50 HKEY hKey;
51 PINSTALLED_INFO ItemInfo;
52
53 if (!IsInstalledEnum(SelectedEnumType))
54 return FALSE;
55
56 if (Index == -1)
57 {
58 ItemIndex = (INT) SendMessageW(hListView, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
59 if (ItemIndex == -1)
60 return FALSE;
61 }
62 else
63 {
64 ItemIndex = Index;
65 }
66
67 ListView_GetItemText(hListView, ItemIndex, 0, szAppName, _countof(szAppName));
68 WriteLogMessage(EVENTLOG_SUCCESS, MSG_SUCCESS_REMOVE, szAppName);
69
70 ZeroMemory(&Item, sizeof(Item));
71
72 Item.mask = LVIF_PARAM;
73 Item.iItem = ItemIndex;
74 if (!ListView_GetItem(hListView, &Item))
75 return FALSE;
76
77 ItemInfo = (PINSTALLED_INFO) Item.lParam;
78 hKey = ItemInfo->hSubKey;
79
80 dwType = REG_SZ;
81 dwSize = MAX_PATH * sizeof(WCHAR);
82 if (RegQueryValueExW(hKey,
83 bModify ? szModify : szUninstall,
84 NULL,
85 &dwType,
86 (LPBYTE) szPath,
87 &dwSize) != ERROR_SUCCESS)
88 {
89 return FALSE;
90 }
91
92 return StartProcess(szPath, TRUE);
93 }
94
95 BOOL ShowInstalledAppInfo(INT Index)
96 {
97 ATL::CStringW szText;
98 ATL::CStringW szInfo;
99 PINSTALLED_INFO Info = (PINSTALLED_INFO) ListViewGetlParam(Index);
100
101 if (!Info || !Info->hSubKey) return FALSE;
102
103 GetApplicationString(Info->hSubKey, L"DisplayName", szText);
104 NewRichEditText(szText, CFE_BOLD);
105 InsertRichEditText(L"\n", 0);
106
107 #define GET_INFO(a, b, c, d) \
108 if (GetApplicationString(Info->hSubKey, a, szInfo)) \
109 { \
110 szText.LoadStringW(b); \
111 InsertRichEditText(szText, c); \
112 InsertRichEditText(szInfo, d); \
113 } \
114
115 GET_INFO(L"DisplayVersion", IDS_INFO_VERSION, CFE_BOLD, 0);
116 GET_INFO(L"Publisher", IDS_INFO_PUBLISHER, CFE_BOLD, 0);
117 GET_INFO(L"RegOwner", IDS_INFO_REGOWNER, CFE_BOLD, 0);
118 GET_INFO(L"ProductID", IDS_INFO_PRODUCTID, CFE_BOLD, 0);
119 GET_INFO(L"HelpLink", IDS_INFO_HELPLINK, CFE_BOLD, CFM_LINK);
120 GET_INFO(L"HelpTelephone", IDS_INFO_HELPPHONE, CFE_BOLD, 0);
121 GET_INFO(L"Readme", IDS_INFO_README, CFE_BOLD, 0);
122 GET_INFO(L"Contact", IDS_INFO_CONTACT, CFE_BOLD, 0);
123 GET_INFO(L"URLUpdateInfo", IDS_INFO_UPDATEINFO, CFE_BOLD, CFM_LINK);
124 GET_INFO(L"URLInfoAbout", IDS_INFO_INFOABOUT, CFE_BOLD, CFM_LINK);
125 GET_INFO(L"Comments", IDS_INFO_COMMENTS, CFE_BOLD, 0);
126 GET_INFO(L"InstallDate", IDS_INFO_INSTALLDATE, CFE_BOLD, 0);
127 GET_INFO(L"InstallLocation", IDS_INFO_INSTLOCATION, CFE_BOLD, 0);
128 GET_INFO(L"InstallSource", IDS_INFO_INSTALLSRC, CFE_BOLD, 0);
129 GET_INFO(L"UninstallString", IDS_INFO_UNINSTALLSTR, CFE_BOLD, 0);
130 GET_INFO(L"InstallSource", IDS_INFO_INSTALLSRC, CFE_BOLD, 0);
131 GET_INFO(L"ModifyPath", IDS_INFO_MODIFYPATH, CFE_BOLD, 0);
132
133 return TRUE;
134 }
135
136 VOID RemoveAppFromRegistry(INT Index)
137 {
138 PINSTALLED_INFO Info;
139 WCHAR szFullName[MAX_PATH] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\";
140 ATL::CStringW szMsgText, szMsgTitle;
141 INT ItemIndex = SendMessageW(hListView, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
142
143 if (!IsInstalledEnum(SelectedEnumType))
144 return;
145
146 Info = (PINSTALLED_INFO) ListViewGetlParam(Index);
147 if (!Info || !Info->hSubKey || (ItemIndex == -1)) return;
148
149 if (!szMsgText.LoadStringW(IDS_APP_REG_REMOVE) ||
150 !szMsgTitle.LoadStringW(IDS_INFORMATION))
151 return;
152
153 if (MessageBoxW(hMainWnd, szMsgText, szMsgTitle, MB_YESNO | MB_ICONQUESTION) == IDYES)
154 {
155 ATL::CStringW::CopyChars(szFullName,
156 MAX_PATH,
157 Info->szKeyName.GetString(),
158 MAX_PATH - wcslen(szFullName));
159
160 if (RegDeleteKeyW(Info->hRootKey, szFullName) == ERROR_SUCCESS)
161 {
162 ListView_DeleteItem(hListView, ItemIndex);
163 return;
164 }
165
166 if (!szMsgText.LoadStringW(IDS_UNABLE_TO_REMOVE))
167 return;
168
169 MessageBoxW(hMainWnd, szMsgText.GetString(), NULL, MB_OK | MB_ICONERROR);
170 }
171 }
172
173 BOOL EnumInstalledApplications(INT EnumType, BOOL IsUserKey, APPENUMPROC lpEnumProc)
174 {
175 DWORD dwSize = MAX_PATH, dwType, dwValue;
176 BOOL bIsSystemComponent, bIsUpdate;
177 ATL::CStringW szParentKeyName;
178 ATL::CStringW szDisplayName;
179 INSTALLED_INFO Info;
180 HKEY hKey;
181 LONG ItemIndex = 0;
182
183 Info.hRootKey = IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
184
185 if (RegOpenKeyW(Info.hRootKey,
186 L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
187 &hKey) != ERROR_SUCCESS)
188 {
189 return FALSE;
190 }
191
192 while (RegEnumKeyExW(hKey, ItemIndex, Info.szKeyName.GetBuffer(MAX_PATH), &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
193 {
194 Info.szKeyName.ReleaseBuffer();
195 if (RegOpenKeyW(hKey, Info.szKeyName.GetString(), &Info.hSubKey) == ERROR_SUCCESS)
196 {
197 dwType = REG_DWORD;
198 dwSize = sizeof(DWORD);
199
200 if (RegQueryValueExW(Info.hSubKey,
201 L"SystemComponent",
202 NULL,
203 &dwType,
204 (LPBYTE) &dwValue,
205 &dwSize) == ERROR_SUCCESS)
206 {
207 bIsSystemComponent = (dwValue == 0x1);
208 }
209 else
210 {
211 bIsSystemComponent = FALSE;
212 }
213
214 dwType = REG_SZ;
215 dwSize = MAX_PATH * sizeof(WCHAR);
216 bIsUpdate = (RegQueryValueExW(Info.hSubKey,
217 L"ParentKeyName",
218 NULL,
219 &dwType,
220 (LPBYTE) szParentKeyName.GetBuffer(MAX_PATH),
221 &dwSize) == ERROR_SUCCESS);
222 szParentKeyName.ReleaseBuffer();
223
224 dwType = REG_SZ;
225 dwSize = MAX_PATH * sizeof(WCHAR);
226 if (RegQueryValueExW(Info.hSubKey,
227 L"DisplayName",
228 NULL,
229 &dwType,
230 (LPBYTE) szDisplayName.GetBuffer(MAX_PATH),
231 &dwSize) == ERROR_SUCCESS)
232 {
233 szDisplayName.ReleaseBuffer();
234 if (EnumType < ENUM_ALL_INSTALLED || EnumType > ENUM_UPDATES)
235 EnumType = ENUM_ALL_INSTALLED;
236
237 if (!bIsSystemComponent)
238 {
239 if ((EnumType == ENUM_ALL_INSTALLED) || /* All components */
240 ((EnumType == ENUM_INSTALLED_APPLICATIONS) && (!bIsUpdate)) || /* Applications only */
241 ((EnumType == ENUM_UPDATES) && (bIsUpdate))) /* Updates only */
242 {
243 if (!lpEnumProc(ItemIndex, szDisplayName, &Info))
244 break;
245 }
246 else
247 {
248 RegCloseKey(Info.hSubKey);
249 }
250 }
251 else
252 {
253 RegCloseKey(Info.hSubKey);
254 }
255 }
256 else
257 {
258 szDisplayName.ReleaseBuffer();
259 RegCloseKey(Info.hSubKey);
260 }
261 }
262
263 dwSize = MAX_PATH;
264 ItemIndex++;
265 }
266
267 Info.szKeyName.ReleaseBuffer();
268 RegCloseKey(hKey);
269
270 return TRUE;
271 }