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