1 /*
2 *
3 * PROJECT: Add or Remove Programs (Console Version)
4 * FILE: rosapps/applications/cmdutils/appwiz/appwiz.c
5 * PURPOSE: ReactOS Software Control Panel
6 * PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
7 * UPDATE HISTORY:
8 * 07-28-2008 Created
9 */
10
11 #define SHOW_ALL 1
12 #define APP_ONLY 2
13 #define UPD_ONLY 3
14
15 #include <windows.h>
16 #include <stdio.h>
17 #include <conio.h>
18 #include <tchar.h>
19
20
PrintHelp()21 void PrintHelp()
22 {
23 printf(_T("Add or Remove Programs\n\
24 APPWIZ [/? /l] [/all /app /upd]\n\
25 /?\t Help\n\
26 /l\t Show list\n\
27 /all\t Show programs and updates\n\
28 /app\t Show programs only\n\
29 /upd\t Show updates only\n"));
30 _getch();
31 }
32
33
RunGUIAppWiz()34 void RunGUIAppWiz()
35 {
36 SHELLEXECUTEINFO shInputDll;
37
38 memset(&shInputDll, 0x0, sizeof(SHELLEXECUTEINFO));
39 shInputDll.cbSize = sizeof(shInputDll);
40 shInputDll.hwnd = NULL;
41 shInputDll.lpVerb = _T("open");
42 shInputDll.lpFile = _T("RunDll32.exe");
43 shInputDll.lpParameters = _T("shell32.dll,Control_RunDLL appwiz.cpl");
44
45 if (ShellExecuteEx(&shInputDll) == 0)
46 {
47 MessageBox(NULL, _T("Can not start appwiz.cpl"), NULL, MB_OK | MB_ICONERROR);
48 }
49 }
50
CallUninstall(LPTSTR szUninstallString)51 void CallUninstall(LPTSTR szUninstallString)
52 {
53 STARTUPINFO si;
54 PROCESS_INFORMATION pi;
55 DWORD dwRet;
56 MSG msg;
57
58 ZeroMemory(&si, sizeof(si));
59 si.cb = sizeof(si);
60 si.wShowWindow = SW_SHOW;
61
62 if (CreateProcess(NULL, szUninstallString, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
63 {
64 CloseHandle(pi.hThread);
65
66 for (;;)
67 {
68 dwRet = MsgWaitForMultipleObjects(1, &pi.hProcess, FALSE, INFINITE, QS_ALLEVENTS);
69 if (dwRet == WAIT_OBJECT_0 + 1)
70 {
71 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
72 {
73 TranslateMessage(&msg);
74 DispatchMessage(&msg);
75 }
76 }
77 else if (dwRet == WAIT_OBJECT_0 || dwRet == WAIT_FAILED)
78 break;
79 }
80 CloseHandle(pi.hProcess);
81 }
82 }
83
84
85 /*
86 dwMode:
87 SHOW_ALL - Applications & Updates
88 APP_ONLY - Applications only
89 UPD_ONLY - Updates only
90 */
ShowAppList(DWORD dwMode,INT iItem)91 int ShowAppList(DWORD dwMode, INT iItem)
92 {
93 HKEY hKey, hSubKey;
94 DWORD dwSize, dwType, dwValue;
95 TCHAR szName[MAX_PATH];
96 TCHAR szParentKeyName[MAX_PATH];
97 TCHAR szDisplayName[MAX_PATH];
98 TCHAR szOutBuf[MAX_PATH];
99 FILETIME FileTime;
100 BOOL bIsUpdate = FALSE;
101 BOOL bIsSystemComponent = FALSE;
102 INT iIndex = 0, iColor = 0, iCount = 1;
103 HANDLE hOutput;
104
105 if (RegOpenKey(HKEY_LOCAL_MACHINE,
106 _T("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"),
107 &hKey) != ERROR_SUCCESS)
108 {
109 printf(_T("ERROR: Can not open Uninstall key. Press any key for continue...\n"));
110 _getch();
111 return 0;
112 }
113
114 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
115 SetConsoleTextAttribute(hOutput, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
116
117 dwSize = MAX_PATH;
118 while (RegEnumKeyEx(hKey, iIndex, szName, &dwSize, NULL, NULL, NULL, &FileTime) == ERROR_SUCCESS)
119 {
120 if (RegOpenKey(hKey, szName, &hSubKey) == ERROR_SUCCESS)
121 {
122 dwType = REG_DWORD;
123 dwSize = sizeof(DWORD);
124
125 if (RegQueryValueEx(hSubKey, _T("SystemComponent"),
126 NULL, &dwType,
127 (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS)
128 {
129 bIsSystemComponent = (dwValue == 0x1);
130 }
131 else
132 {
133 bIsSystemComponent = FALSE;
134 }
135
136 dwType = REG_SZ;
137 dwSize = MAX_PATH;
138
139 bIsUpdate = (RegQueryValueEx(hSubKey, _T("ParentKeyName"),
140 NULL, &dwType,
141 (LPBYTE) szParentKeyName,
142 &dwSize) == ERROR_SUCCESS);
143 dwSize = MAX_PATH;
144 if (RegQueryValueEx(hSubKey, _T("DisplayName"),
145 NULL, &dwType,
146 (LPBYTE) szDisplayName,
147 &dwSize) == ERROR_SUCCESS)
148 {
149 if (!bIsSystemComponent)
150 {
151 if ((dwMode == SHOW_ALL) || ((dwMode == APP_ONLY) && (!bIsUpdate)) || ((dwMode == UPD_ONLY) && (bIsUpdate)))
152 {
153 if (iItem == -1)
154 {
155 wsprintf(szOutBuf, _T(" %d \t %s\n"), iCount, szDisplayName);
156 CharToOem(szOutBuf, szOutBuf);
157 printf("%s", szOutBuf);
158 }
159 else
160 {
161 dwType = REG_SZ;
162 dwSize = MAX_PATH;
163
164 if ((RegQueryValueEx(hSubKey, _T("UninstallString"), NULL, &dwType,
165 (LPBYTE) szOutBuf, &dwSize) == ERROR_SUCCESS) && (iItem == iCount))
166 {
167 CallUninstall(szOutBuf);
168 }
169 }
170 iCount++;
171 iColor++;
172 }
173 }
174 }
175 }
176
177 if (iColor <= 5)
178 {
179 SetConsoleTextAttribute(hOutput, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
180 }
181 else
182 {
183 SetConsoleTextAttribute(hOutput, FOREGROUND_GREEN | FOREGROUND_INTENSITY | FOREGROUND_RED);
184 if (iColor >= 10) iColor = 0;
185 }
186
187 dwSize = MAX_PATH;
188 iIndex++;
189 }
190
191 RegCloseKey(hSubKey);
192 RegCloseKey(hKey);
193
194 SetConsoleTextAttribute(hOutput, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
195 printf("\n\nPlease enter application/update number and press ENTER for uninstall\nor press any key for Exit...\n");
196
197 return 1;
198 }
199
200
_tmain(int argc,_TCHAR * argv[])201 int _tmain(int argc, _TCHAR* argv[])
202 {
203 INT iNumber;
204 TCHAR Char[4 + 1];
205
206 SetConsoleTitle(_T("Application Wizard"));
207
208 if (argc < 2)
209 {
210 RunGUIAppWiz();
211 return 0;
212 }
213
214 if (_tcsncmp(argv[1], _T("/?"), 2) == 0)
215 {
216 PrintHelp();
217 return 0;
218 }
219
220 if (_tcsncmp(argv[1], _T("/l"), 2) == 0)
221 {
222 if (argc < 3) goto ShowAll;
223 if (_tcsncmp(argv[2], _T("/all"), 4) == 0)
224 {
225 ShowAll:
226 if (ShowAppList(SHOW_ALL, -1) == 0) return 0;
227 scanf(_T("%s"), Char);
228
229 iNumber = atoi(Char);
230
231 if (iNumber == 0) return 0;
232 ShowAppList(SHOW_ALL, iNumber);
233 }
234 else if (_tcsncmp(argv[2], _T("/app"), 4) == 0)
235 {
236 if (ShowAppList(APP_ONLY, -1) == 0) return 0;
237
238 scanf(_T("%s"), Char);
239
240 iNumber = atoi(Char);
241
242 if (iNumber == 0) return 0;
243 ShowAppList(APP_ONLY, iNumber);
244 }
245 else if (_tcsncmp(argv[2], _T("/upd"), 4) == 0)
246 {
247 if (ShowAppList(UPD_ONLY, -1) == 0) return 0;
248
249 scanf(_T("%s"), Char);
250
251 iNumber = atoi(Char);
252
253 if (iNumber == 0) return 0;
254 ShowAppList(UPD_ONLY, iNumber);
255 }
256
257 return 0;
258 }
259
260 return 0;
261 }
262