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