fb0bf03219f50b5fec3c4d103c82911c347b9b94
[reactos.git] / base / applications / rapps / installed.cpp
1 /*
2 * PROJECT: ReactOS Applications Manager
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * FILE: base/applications/rapps/installed.cpp
5 * PURPOSE: Functions for working with installed applications
6 * COPYRIGHT: Copyright 2009 Dmitry Chapyshev (dmitry@reactos.org)
7 * Copyright 2017 Alexander Shaposhnikov (sanchaez@reactos.org)
8 */
9 #include "rapps.h"
10
11 #include "installed.h"
12
13 #include "gui.h"
14 #include "misc.h"
15
16 BOOL INSTALLED_INFO::GetApplicationString(LPCWSTR lpKeyName, ATL::CStringW& String)
17 {
18 BOOL result = ::GetApplicationString(hSubKey, lpKeyName, String.GetBuffer(MAX_PATH));
19 String.ReleaseBuffer();
20 return result;
21 }
22
23 BOOL GetApplicationString(HKEY hKey, LPCWSTR lpKeyName, LPWSTR szString)
24 {
25 DWORD dwSize = MAX_PATH * sizeof(WCHAR);
26
27 if (RegQueryValueExW(hKey,
28 lpKeyName,
29 NULL,
30 NULL,
31 (LPBYTE) szString,
32 &dwSize) == ERROR_SUCCESS)
33 {
34 return TRUE;
35 }
36
37 StringCchCopyW(szString, MAX_PATH, L"---");
38 return FALSE;
39 }
40
41 BOOL UninstallApplication(INT Index, BOOL bModify)
42 {
43 LPCWSTR szModify = L"ModifyPath";
44 LPCWSTR szUninstall = L"UninstallString";
45 WCHAR szPath[MAX_PATH];
46 WCHAR szAppName[MAX_STR_LEN];
47 DWORD dwType, dwSize;
48 INT ItemIndex;
49 LVITEMW Item;
50 HKEY hKey;
51 PINSTALLED_INFO ItemInfo;
52
53 if (!IsInstalledEnum(SelectedEnumType))
54 return FALSE;
55
56 if (Index == -1)
57 {
58 ItemIndex = (INT) SendMessageW(hListView, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
59 if (ItemIndex == -1)
60 return FALSE;
61 }
62 else
63 {
64 ItemIndex = Index;
65 }
66
67 ListView_GetItemText(hListView, ItemIndex, 0, szAppName, _countof(szAppName));
68 WriteLogMessage(EVENTLOG_SUCCESS, MSG_SUCCESS_REMOVE, szAppName);
69
70 ZeroMemory(&Item, sizeof(Item));
71
72 Item.mask = LVIF_PARAM;
73 Item.iItem = ItemIndex;
74 if (!ListView_GetItem(hListView, &Item))
75 return FALSE;
76
77 ItemInfo = (PINSTALLED_INFO) Item.lParam;
78 hKey = ItemInfo->hSubKey;
79
80 dwType = REG_SZ;
81 dwSize = MAX_PATH * sizeof(WCHAR);
82 if (RegQueryValueExW(hKey,
83 bModify ? szModify : szUninstall,
84 NULL,
85 &dwType,
86 (LPBYTE) szPath,
87 &dwSize) != ERROR_SUCCESS)
88 {
89 return FALSE;
90 }
91
92 return StartProcess(szPath, TRUE);
93 }
94
95 VOID RemoveAppFromRegistry(INT Index)
96 {
97 PINSTALLED_INFO Info;
98 WCHAR szFullName[MAX_PATH] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\";
99 ATL::CStringW szMsgText, szMsgTitle;
100 INT ItemIndex = SendMessageW(hListView, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
101
102 if (!IsInstalledEnum(SelectedEnumType))
103 return;
104
105 Info = (PINSTALLED_INFO) ListViewGetlParam(Index);
106 if (!Info || !Info->hSubKey || (ItemIndex == -1)) return;
107
108 if (!szMsgText.LoadStringW(IDS_APP_REG_REMOVE) ||
109 !szMsgTitle.LoadStringW(IDS_INFORMATION))
110 return;
111
112 if (MessageBoxW(hMainWnd, szMsgText, szMsgTitle, MB_YESNO | MB_ICONQUESTION) == IDYES)
113 {
114 ATL::CStringW::CopyChars(szFullName,
115 MAX_PATH,
116 Info->szKeyName.GetString(),
117 MAX_PATH - wcslen(szFullName));
118
119 if (RegDeleteKeyW(Info->hRootKey, szFullName) == ERROR_SUCCESS)
120 {
121 ListView_DeleteItem(hListView, ItemIndex);
122 return;
123 }
124
125 if (!szMsgText.LoadStringW(IDS_UNABLE_TO_REMOVE))
126 return;
127
128 MessageBoxW(hMainWnd, szMsgText.GetString(), NULL, MB_OK | MB_ICONERROR);
129 }
130 }
131
132 BOOL EnumInstalledApplications(INT EnumType, BOOL IsUserKey, APPENUMPROC lpEnumProc, PVOID param)
133 {
134 DWORD dwSize = MAX_PATH, dwType, dwValue;
135 BOOL bIsSystemComponent, bIsUpdate;
136 ATL::CStringW szParentKeyName;
137 ATL::CStringW szDisplayName;
138 INSTALLED_INFO Info;
139 HKEY hKey;
140 LONG ItemIndex = 0;
141
142 Info.hRootKey = IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
143
144 if (RegOpenKeyW(Info.hRootKey,
145 L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
146 &hKey) != ERROR_SUCCESS)
147 {
148 return FALSE;
149 }
150
151 while (RegEnumKeyExW(hKey, ItemIndex, Info.szKeyName.GetBuffer(MAX_PATH), &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
152 {
153 Info.szKeyName.ReleaseBuffer();
154 if (RegOpenKeyW(hKey, Info.szKeyName.GetString(), &Info.hSubKey) == ERROR_SUCCESS)
155 {
156 dwType = REG_DWORD;
157 dwSize = sizeof(DWORD);
158
159 if (RegQueryValueExW(Info.hSubKey,
160 L"SystemComponent",
161 NULL,
162 &dwType,
163 (LPBYTE) &dwValue,
164 &dwSize) == ERROR_SUCCESS)
165 {
166 bIsSystemComponent = (dwValue == 0x1);
167 }
168 else
169 {
170 bIsSystemComponent = FALSE;
171 }
172
173 dwType = REG_SZ;
174 dwSize = MAX_PATH * sizeof(WCHAR);
175 bIsUpdate = (RegQueryValueExW(Info.hSubKey,
176 L"ParentKeyName",
177 NULL,
178 &dwType,
179 (LPBYTE) szParentKeyName.GetBuffer(MAX_PATH),
180 &dwSize) == ERROR_SUCCESS);
181 szParentKeyName.ReleaseBuffer();
182
183 dwType = REG_SZ;
184 dwSize = MAX_PATH * sizeof(WCHAR);
185 if (RegQueryValueExW(Info.hSubKey,
186 L"DisplayName",
187 NULL,
188 &dwType,
189 (LPBYTE) szDisplayName.GetBuffer(MAX_PATH),
190 &dwSize) == ERROR_SUCCESS)
191 {
192 szDisplayName.ReleaseBuffer();
193 if (EnumType < ENUM_ALL_INSTALLED || EnumType > ENUM_UPDATES)
194 EnumType = ENUM_ALL_INSTALLED;
195
196 if (!bIsSystemComponent)
197 {
198 if ((EnumType == ENUM_ALL_INSTALLED) || /* All components */
199 ((EnumType == ENUM_INSTALLED_APPLICATIONS) && (!bIsUpdate)) || /* Applications only */
200 ((EnumType == ENUM_UPDATES) && (bIsUpdate))) /* Updates only */
201 {
202 if (!lpEnumProc(ItemIndex, szDisplayName, &Info, param))
203 break;
204 }
205 else
206 {
207 RegCloseKey(Info.hSubKey);
208 }
209 }
210 else
211 {
212 RegCloseKey(Info.hSubKey);
213 }
214 }
215 else
216 {
217 szDisplayName.ReleaseBuffer();
218 RegCloseKey(Info.hSubKey);
219 }
220 }
221
222 dwSize = MAX_PATH;
223 ItemIndex++;
224 }
225
226 Info.szKeyName.ReleaseBuffer();
227 RegCloseKey(hKey);
228
229 return TRUE;
230 }