- start implementing create shortcut wizard
[reactos.git] / reactos / dll / cpl / appwiz / appwiz.c
1 /*
2 * ReactOS
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$
20 *
21 * PROJECT: ReactOS Software Control Panel
22 * FILE: dll/cpl/appwiz/appwiz.c
23 * PURPOSE: ReactOS Software Control Panel
24 * PROGRAMMER: Gero Kuehn (reactos.filter@gkware.com)
25 * UPDATE HISTORY:
26 * 06-17-2004 Created
27 */
28
29 #include <windows.h>
30 #include <commctrl.h>
31 #include <cpl.h>
32 #include <prsht.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <stdarg.h>
36 #include <tchar.h>
37 #include <process.h>
38
39 #include "resource.h"
40 #include "appwiz.h"
41
42 #define NUM_APPLETS (1)
43
44 LONG CALLBACK SystemApplet(VOID);
45 INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
46 INT_PTR CALLBACK ComputerPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
47 HINSTANCE hApplet = 0;
48
49 /* Applets */
50 APPLET Applets[NUM_APPLETS] =
51 {
52 {IDI_CPLSYSTEM, IDS_CPLSYSTEMNAME, IDS_CPLSYSTEMDESCRIPTION, SystemApplet}
53 };
54
55
56 static VOID
57 CallUninstall(HWND hwndDlg)
58 {
59 STARTUPINFO si;
60 PROCESS_INFORMATION pi;
61 INT nIndex;
62 HKEY hKey;
63 DWORD dwType;
64 TCHAR pszUninstallString[MAX_PATH];
65 DWORD dwSize;
66
67 nIndex = (INT)SendDlgItemMessage(hwndDlg, IDC_SOFTWARELIST, LB_GETCURSEL, 0, 0);
68 if (nIndex == -1)
69 {
70 MessageBox(hwndDlg,
71 _TEXT("No item selected"),
72 _TEXT("Error"),
73 MB_ICONSTOP);
74 }
75 else
76 {
77 hKey = (HKEY)SendDlgItemMessage(hwndDlg, IDC_SOFTWARELIST, LB_GETITEMDATA, (WPARAM)nIndex, 0);
78
79 dwType = REG_SZ;
80 dwSize = MAX_PATH;
81 if (RegQueryValueEx(hKey,
82 _TEXT("UninstallString"),
83 NULL,
84 &dwType,
85 (LPBYTE)pszUninstallString,
86 &dwSize) == ERROR_SUCCESS)
87 {
88 ZeroMemory(&si, sizeof(si));
89 si.cb = sizeof(si);
90 si.wShowWindow = SW_SHOW;
91 if (CreateProcess(NULL,pszUninstallString,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
92 {
93 CloseHandle(pi.hProcess);
94 CloseHandle(pi.hThread);
95 }
96 }
97 else
98 {
99 MessageBox(hwndDlg,
100 _TEXT("Unable to read UninstallString. This entry is invalid or has been created by an MSI installer."),
101 _TEXT("Error"),
102 MB_ICONSTOP);
103 }
104 }
105 }
106
107
108 static VOID
109 FillSoftwareList(HWND hwndDlg)
110 {
111 TCHAR pszName[MAX_PATH];
112 TCHAR pszDisplayName[MAX_PATH];
113 TCHAR pszParentKeyName[MAX_PATH];
114 FILETIME FileTime;
115 HKEY hKey;
116 HKEY hSubKey;
117 DWORD dwType;
118 DWORD dwSize;
119 DWORD dwValue = 0;
120 BOOL bIsUpdate = FALSE;
121 BOOL bIsSystemComponent = FALSE;
122 BOOL bShowUpdates = FALSE;
123 INT i;
124 ULONG ulIndex;
125
126 bShowUpdates = (SendMessage(GetDlgItem(hwndDlg, IDC_SHOWUPDATES), BM_GETCHECK, 0, 0) == BST_CHECKED);
127
128 if (RegOpenKey(HKEY_LOCAL_MACHINE,
129 _TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"),
130 &hKey) != ERROR_SUCCESS)
131 {
132 MessageBox(hwndDlg,
133 _TEXT("Unable to open Uninstall Key"),
134 _TEXT("Error"),
135 MB_ICONSTOP);
136 return;
137 }
138
139 i = 0;
140 dwSize = MAX_PATH;
141 while (RegEnumKeyEx (hKey, i, pszName, &dwSize, NULL, NULL, NULL, &FileTime) == ERROR_SUCCESS)
142 {
143 if (RegOpenKey(hKey,pszName,&hSubKey) == ERROR_SUCCESS)
144 {
145 dwType = REG_DWORD;
146 dwSize = sizeof(DWORD);
147 if (RegQueryValueEx(hSubKey,
148 _TEXT("SystemComponent"),
149 NULL,
150 &dwType,
151 (LPBYTE)&dwValue,
152 &dwSize) == ERROR_SUCCESS)
153 {
154 bIsSystemComponent = (dwValue == 0x1);
155 }
156 else
157 {
158 bIsSystemComponent = FALSE;
159 }
160
161 dwType = REG_SZ;
162 dwSize = MAX_PATH;
163 bIsUpdate = (RegQueryValueEx(hSubKey,
164 _TEXT("ParentKeyName"),
165 NULL,
166 &dwType,
167 (LPBYTE)pszParentKeyName,
168 &dwSize) == ERROR_SUCCESS);
169 dwSize = MAX_PATH;
170 if (RegQueryValueEx(hSubKey,
171 _TEXT("DisplayName"),
172 NULL,
173 &dwType,
174 (LPBYTE)pszDisplayName,
175 &dwSize) == ERROR_SUCCESS)
176 {
177 if ((!bIsUpdate) && (!bIsSystemComponent))
178 {
179 ulIndex = (ULONG)SendDlgItemMessage(hwndDlg,IDC_SOFTWARELIST,LB_ADDSTRING,0,(LPARAM)pszDisplayName);
180 SendDlgItemMessage(hwndDlg,IDC_SOFTWARELIST,LB_SETITEMDATA,ulIndex,(LPARAM)hSubKey);
181 }
182 else if (bIsUpdate && bShowUpdates)
183 {
184 ulIndex = (ULONG)SendDlgItemMessage(hwndDlg,IDC_SOFTWARELIST,LB_ADDSTRING,0,(LPARAM)pszDisplayName);
185 SendDlgItemMessage(hwndDlg,IDC_SOFTWARELIST,LB_SETITEMDATA,ulIndex,(LPARAM)hSubKey);
186 }
187 }
188 }
189
190 dwSize = MAX_PATH;
191 i++;
192 }
193
194 RegCloseKey(hKey);
195 }
196
197
198 /* Property page dialog callback */
199 static INT_PTR CALLBACK
200 InstallPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
201 {
202 UNREFERENCED_PARAMETER(lParam);
203
204 switch (uMsg)
205 {
206 case WM_INITDIALOG:
207 EnableWindow(GetDlgItem(hwndDlg, IDC_INSTALL), FALSE);
208 FillSoftwareList(hwndDlg);
209 break;
210
211 case WM_COMMAND:
212 switch (LOWORD(wParam))
213 {
214 case IDC_SHOWUPDATES:
215 if (HIWORD(wParam) == BN_CLICKED)
216 {
217 SendDlgItemMessage(hwndDlg, IDC_SOFTWARELIST, LB_RESETCONTENT, 0, 0);
218 FillSoftwareList(hwndDlg);
219 }
220 break;
221
222 case IDC_SOFTWARELIST:
223 if (HIWORD(wParam) == LBN_DBLCLK)
224 {
225 CallUninstall(hwndDlg);
226 }
227 break;
228
229 case IDC_ADDREMOVE:
230 CallUninstall(hwndDlg);
231 break;
232 }
233 break;
234 }
235
236 return FALSE;
237 }
238
239
240 /* Property page dialog callback */
241 static INT_PTR CALLBACK
242 RosPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
243 {
244 UNREFERENCED_PARAMETER(lParam);
245 UNREFERENCED_PARAMETER(wParam);
246 UNREFERENCED_PARAMETER(hwndDlg);
247
248 switch (uMsg)
249 {
250 case WM_INITDIALOG:
251 break;
252 }
253
254 return FALSE;
255 }
256
257
258 static VOID
259 InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc)
260 {
261 ZeroMemory(psp, sizeof(PROPSHEETPAGE));
262 psp->dwSize = sizeof(PROPSHEETPAGE);
263 psp->dwFlags = PSP_DEFAULT;
264 psp->hInstance = hApplet;
265 psp->pszTemplate = MAKEINTRESOURCE(idDlg);
266 psp->pfnDlgProc = DlgProc;
267 }
268
269
270 /* First Applet */
271
272 LONG CALLBACK
273 SystemApplet(VOID)
274 {
275 PROPSHEETPAGE psp[2];
276 PROPSHEETHEADER psh;
277 TCHAR Caption[1024];
278
279 LoadString(hApplet, IDS_CPLSYSTEMNAME, Caption, sizeof(Caption) / sizeof(TCHAR));
280
281 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
282 psh.dwSize = sizeof(PROPSHEETHEADER);
283 psh.dwFlags = PSH_PROPSHEETPAGE;
284 psh.hwndParent = NULL;
285 psh.hInstance = hApplet;
286 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDI_CPLSYSTEM));
287 psh.pszCaption = Caption;
288 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
289 psh.nStartPage = 0;
290 psh.ppsp = psp;
291 psh.pfnCallback = NULL;
292
293 InitPropSheetPage(&psp[0], IDD_PROPPAGEINSTALL, (DLGPROC) InstallPageProc);
294 InitPropSheetPage(&psp[1], IDD_PROPPAGEROSSETUP, (DLGPROC) RosPageProc);
295
296 return (LONG)(PropertySheet(&psh) != -1);
297 }
298
299
300 /* Control Panel Callback */
301 LONG CALLBACK
302 CPlApplet(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
303 {
304 CPLINFO *CPlInfo;
305 DWORD i;
306
307 UNREFERENCED_PARAMETER(hwndCPl);
308
309 i = (DWORD)lParam1;
310 switch (uMsg)
311 {
312 case CPL_INIT:
313 return TRUE;
314
315 case CPL_GETCOUNT:
316 return NUM_APPLETS;
317
318 case CPL_INQUIRE:
319 CPlInfo = (CPLINFO*)lParam2;
320 CPlInfo->lData = 0;
321 CPlInfo->idIcon = Applets[i].idIcon;
322 CPlInfo->idName = Applets[i].idName;
323 CPlInfo->idInfo = Applets[i].idDescription;
324 break;
325
326 case CPL_DBLCLK:
327 Applets[i].AppletProc();
328 break;
329 }
330
331 return FALSE;
332 }
333
334
335 BOOL WINAPI
336 DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
337 {
338 UNREFERENCED_PARAMETER(lpvReserved);
339
340 switch (dwReason)
341 {
342 case DLL_PROCESS_ATTACH:
343 case DLL_THREAD_ATTACH:
344 hApplet = hinstDLL;
345 break;
346 }
347
348 return TRUE;
349 }
350
351 INT_PTR
352 CALLBACK
353 WelcomeDlgProc(HWND hwndDlg,
354 UINT uMsg,
355 WPARAM wParam,
356 LPARAM lParam)
357 {
358 switch(uMsg)
359 {
360 case WM_INITDIALOG:
361 PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
362 break;
363 case WM_COMMAND:
364 switch(HIWORD(wParam))
365 {
366 case EN_CHANGE:
367 if (SendDlgItemMessage(hwndDlg, IDC_SHORTCUT_LOCATION, WM_GETTEXTLENGTH, 0, 0))
368 {
369 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
370 }
371 else
372 {
373 PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
374 }
375 }
376
377 }
378 return FALSE;
379 }
380
381 INT_PTR
382 CALLBACK
383 FinishDlgProc(HWND hwndDlg,
384 UINT uMsg,
385 WPARAM wParam,
386 LPARAM lParam)
387 {
388 switch(uMsg)
389 {
390 case WM_INITDIALOG:
391 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH);
392 break;
393 }
394 return FALSE;
395 }
396
397
398 LONG CALLBACK
399 NewLinkHere(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
400 {
401 PROPSHEETHEADERW psh;
402 HPROPSHEETPAGE ahpsp[2];
403 PROPSHEETPAGE psp;
404 UINT nPages = 0;
405
406 /* Create the Welcome page */
407 psp.dwSize = sizeof(PROPSHEETPAGE);
408 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
409 psp.hInstance = hApplet;
410 psp.pfnDlgProc = WelcomeDlgProc;
411 psp.pszTemplate = MAKEINTRESOURCE(IDD_SHORTCUT_LOCATION);
412 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
413
414 /* Create the Finish page */
415 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
416 psp.pfnDlgProc = FinishDlgProc;
417 psp.pszTemplate = MAKEINTRESOURCE(IDD_SHORTCUT_FINISH);
418 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
419
420
421 /* Create the property sheet */
422 psh.dwSize = sizeof(PROPSHEETHEADER);
423 psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK;
424 psh.hInstance = hApplet;
425 psh.hwndParent = NULL;
426 psh.nPages = nPages;
427 psh.nStartPage = 0;
428 psh.phpage = ahpsp;
429 psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
430
431 /* Display the wizard */
432 PropertySheet(&psh);
433
434 return TRUE;
435
436
437
438
439
440
441
442 return FALSE;
443 }