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