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