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