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