[CMAKE]
[reactos.git] / reactos / base / setup / reactos / reactos.c
1 /*
2 * ReactOS applications
3 * Copyright (C) 2004-2008 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 along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /* $Id$
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS GUI first stage setup application
23 * FILE: base/setup/reactos/reactos.c
24 * PROGRAMMERS: Eric Kohl
25 * Matthias Kupfer
26 * Dmitry Chapyshev (dmitry@reactos.org)
27 */
28
29 #include <windows.h>
30 #include <commctrl.h>
31 #include <tchar.h>
32 #include <setupapi.h>
33 #include <initguid.h>
34 #include <devguid.h>
35 #include <wine/unicode.h>
36
37 #include "resource.h"
38
39 /* GLOBALS ******************************************************************/
40
41 HFONT hTitleFont;
42
43 typedef struct _LANG
44 {
45 TCHAR LangId[9];
46 TCHAR LangName[128];
47 } LANG, *PLANG;
48
49 typedef struct _KBLAYOUT
50 {
51 TCHAR LayoutId[9];
52 TCHAR LayoutName[128];
53 TCHAR DllName[128];
54 } KBLAYOUT, *PKBLAYOUT;
55
56
57 // generic entries with simple 1:1 mapping
58 typedef struct _GENENTRY
59 {
60 TCHAR Id[24];
61 TCHAR Value[128];
62 } GENENTRY, *PGENENTRY;
63
64 struct
65 {
66 // Settings
67 LONG DestDiskNumber; // physical disk
68 LONG DestPartNumber; // partition on disk
69 LONG DestPartSize; // if partition doesn't exist, size of partition
70 LONG FSType; // file system type on partition
71 LONG MBRInstallType; // install bootloader
72 LONG FormatPart; // type of format the partition
73 LONG SelectedLangId; // selected language (table index)
74 LONG SelectedKBLayout; // selected keyboard layout (table index)
75 TCHAR InstallDir[MAX_PATH]; // installation directory on hdd
76 LONG SelectedComputer; // selected computer type (table index)
77 LONG SelectedDisplay; // selected display type (table index)
78 LONG SelectedKeyboard; // selected keyboard type (table index)
79 BOOLEAN RepairUpdateFlag; // flag for update/repair an installed reactos
80 // txtsetup.sif data
81 LONG DefaultLang; // default language (table index)
82 PLANG pLanguages;
83 LONG LangCount;
84 LONG DefaultKBLayout; // default keyboard layout (table index)
85 PKBLAYOUT pKbLayouts;
86 LONG KbLayoutCount;
87 PGENENTRY pComputers;
88 LONG CompCount;
89 PGENENTRY pDisplays;
90 LONG DispCount;
91 PGENENTRY pKeyboards;
92 LONG KeybCount;
93 } SetupData;
94
95 typedef struct _IMGINFO
96 {
97 HBITMAP hBitmap;
98 INT cxSource;
99 INT cySource;
100 } IMGINFO, *PIMGINFO;
101
102 TCHAR abort_msg[512], abort_title[64];
103 HINSTANCE hInstance;
104 BOOL isUnattend;
105
106 LONG LoadGenentry(HINF hinf,PCTSTR name,PGENENTRY *gen,PINFCONTEXT context);
107
108 /* FUNCTIONS ****************************************************************/
109
110 static VOID
111 CenterWindow(HWND hWnd)
112 {
113 HWND hWndParent;
114 RECT rcParent;
115 RECT rcWindow;
116
117 hWndParent = GetParent(hWnd);
118 if (hWndParent == NULL)
119 hWndParent = GetDesktopWindow();
120
121 GetWindowRect(hWndParent, &rcParent);
122 GetWindowRect(hWnd, &rcWindow);
123
124 SetWindowPos(hWnd,
125 HWND_TOP,
126 ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2,
127 ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2,
128 0,
129 0,
130 SWP_NOSIZE);
131 }
132
133 static HFONT
134 CreateTitleFont(VOID)
135 {
136 NONCLIENTMETRICS ncm;
137 LOGFONT LogFont;
138 HDC hdc;
139 INT FontSize;
140 HFONT hFont;
141
142 ncm.cbSize = sizeof(NONCLIENTMETRICS);
143 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
144
145 LogFont = ncm.lfMessageFont;
146 LogFont.lfWeight = FW_BOLD;
147 _tcscpy(LogFont.lfFaceName, _T("MS Shell Dlg"));
148
149 hdc = GetDC(NULL);
150 FontSize = 12;
151 LogFont.lfHeight = 0 - GetDeviceCaps (hdc, LOGPIXELSY) * FontSize / 72;
152 hFont = CreateFontIndirect(&LogFont);
153 ReleaseDC(NULL, hdc);
154
155 return hFont;
156 }
157
158 static VOID
159 InitImageInfo(PIMGINFO ImgInfo)
160 {
161 BITMAP bitmap;
162
163 ZeroMemory(ImgInfo, sizeof(*ImgInfo));
164
165 ImgInfo->hBitmap = LoadImage(hInstance,
166 MAKEINTRESOURCE(IDB_ROSLOGO),
167 IMAGE_BITMAP,
168 0,
169 0,
170 LR_DEFAULTCOLOR);
171
172 if (ImgInfo->hBitmap != NULL)
173 {
174 GetObject(ImgInfo->hBitmap, sizeof(BITMAP), &bitmap);
175
176 ImgInfo->cxSource = bitmap.bmWidth;
177 ImgInfo->cySource = bitmap.bmHeight;
178 }
179 }
180
181 static INT_PTR CALLBACK
182 StartDlgProc(HWND hwndDlg,
183 UINT uMsg,
184 WPARAM wParam,
185 LPARAM lParam)
186 {
187 switch (uMsg)
188 {
189 case WM_INITDIALOG:
190 {
191 HWND hwndControl;
192 DWORD dwStyle;
193
194 hwndControl = GetParent(hwndDlg);
195
196 /* Center the wizard window */
197 CenterWindow (hwndControl);
198
199 dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
200 SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
201
202 /* Hide and disable the 'Cancel' button at the moment,
203 * we use this button to cancel the setup process
204 * like F3 in usetup
205 */
206 hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
207 ShowWindow (hwndControl, SW_HIDE);
208 EnableWindow (hwndControl, FALSE);
209
210 /* Set title font */
211 SendDlgItemMessage(hwndDlg,
212 IDC_STARTTITLE,
213 WM_SETFONT,
214 (WPARAM)hTitleFont,
215 (LPARAM)TRUE);
216 }
217 break;
218
219 case WM_NOTIFY:
220 {
221 LPNMHDR lpnm = (LPNMHDR)lParam;
222
223 switch (lpnm->code)
224 {
225 case PSN_SETACTIVE:
226 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
227 break;
228 default:
229 break;
230 }
231 }
232 break;
233
234 default:
235 break;
236
237 }
238
239 return FALSE;
240 }
241
242 static INT_PTR CALLBACK
243 LangSelDlgProc(HWND hwndDlg,
244 UINT uMsg,
245 WPARAM wParam,
246 LPARAM lParam)
247 {
248 PIMGINFO pImgInfo;
249 LONG i;
250 LRESULT tindex;
251 HWND hList;
252
253 pImgInfo = (PIMGINFO)GetWindowLongPtr(hwndDlg, DWLP_USER);
254
255 switch (uMsg)
256 {
257 case WM_INITDIALOG:
258 {
259 HWND hwndControl;
260 DWORD dwStyle;
261
262 hwndControl = GetParent(hwndDlg);
263
264 dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
265 SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
266
267 hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
268 ShowWindow (hwndControl, SW_SHOW);
269 EnableWindow (hwndControl, TRUE);
270
271 pImgInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IMGINFO));
272 if (pImgInfo == NULL)
273 {
274 EndDialog(hwndDlg, 0);
275 return FALSE;
276 }
277
278 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pImgInfo);
279
280 InitImageInfo(pImgInfo);
281
282 /* Set title font */
283 /*SendDlgItemMessage(hwndDlg,
284 IDC_STARTTITLE,
285 WM_SETFONT,
286 (WPARAM)hTitleFont,
287 (LPARAM)TRUE);*/
288
289 hList = GetDlgItem(hwndDlg, IDC_LANGUAGES);
290
291 for (i=0; i < SetupData.LangCount; i++)
292 {
293 tindex = SendMessage(hList, CB_ADDSTRING, (WPARAM) 0, (LPARAM) SetupData.pLanguages[i].LangName);
294 SendMessage(hList, CB_SETITEMDATA, tindex, i);
295 if (SetupData.DefaultLang == i)
296 SendMessage(hList, CB_SETCURSEL, (WPARAM) tindex,(LPARAM) 0);
297 }
298
299 hList = GetDlgItem(hwndDlg, IDC_KEYLAYOUT);
300
301 for (i=0; i < SetupData.KbLayoutCount; i++)
302 {
303 tindex = SendMessage(hList, CB_ADDSTRING, (WPARAM) 0, (LPARAM)SetupData.pKbLayouts[i].LayoutName);
304 SendMessage(hList, CB_SETITEMDATA, tindex, i);
305 if (SetupData.DefaultKBLayout == i)
306 SendMessage(hList,CB_SETCURSEL,(WPARAM)tindex,(LPARAM)0);
307 }
308 }
309 break;
310
311 case WM_DRAWITEM:
312 {
313 LPDRAWITEMSTRUCT lpDrawItem;
314 lpDrawItem = (LPDRAWITEMSTRUCT) lParam;
315
316 if (lpDrawItem->CtlID == IDB_ROSLOGO)
317 {
318 HDC hdcMem;
319 LONG left;
320
321 /* position image in centre of dialog */
322 left = (lpDrawItem->rcItem.right - pImgInfo->cxSource) / 2;
323
324 hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
325 if (hdcMem != NULL)
326 {
327 SelectObject(hdcMem, pImgInfo->hBitmap);
328 BitBlt(lpDrawItem->hDC,
329 left,
330 lpDrawItem->rcItem.top,
331 lpDrawItem->rcItem.right - lpDrawItem->rcItem.left,
332 lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
333 hdcMem,
334 0,
335 0,
336 SRCCOPY);
337 DeleteDC(hdcMem);
338 }
339 }
340 return TRUE;
341 }
342
343 case WM_NOTIFY:
344 {
345 LPNMHDR lpnm = (LPNMHDR)lParam;
346
347 switch (lpnm->code)
348 {
349 case PSN_SETACTIVE:
350 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
351 break;
352
353 case PSN_QUERYCANCEL:
354 SetWindowLongPtr(hwndDlg,
355 DWL_MSGRESULT,
356 MessageBox(GetParent(hwndDlg),
357 abort_msg,
358 abort_title,
359 MB_YESNO | MB_ICONQUESTION) != IDYES);
360 return TRUE;
361
362 case PSN_WIZNEXT: // set the selected data
363 {
364 hList =GetDlgItem(hwndDlg, IDC_LANGUAGES);
365 tindex = SendMessage(hList,CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
366
367 if (tindex != CB_ERR)
368 {
369 WORD LangID;
370 SetupData.SelectedLangId = SendMessage(hList, CB_GETITEMDATA, (WPARAM) tindex, (LPARAM) 0);
371 LangID = _tcstol(SetupData.pLanguages[SetupData.SelectedLangId].LangId, NULL, 16);
372 SetThreadLocale(MAKELCID(LangID, SORT_DEFAULT));
373 // FIXME: need to reload all resource to force
374 // the new language setting
375 }
376
377 hList = GetDlgItem(hwndDlg, IDC_KEYLAYOUT);
378 tindex = SendMessage(hList,CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
379 if (tindex != CB_ERR)
380 {
381 SetupData.SelectedKBLayout = SendMessage(hList, CB_GETITEMDATA, (WPARAM) tindex, (LPARAM) 0);
382 }
383 return TRUE;
384 }
385
386 default:
387 break;
388 }
389 }
390 break;
391
392 default:
393 break;
394
395 }
396 return FALSE;
397 }
398
399 static INT_PTR CALLBACK
400 TypeDlgProc(HWND hwndDlg,
401 UINT uMsg,
402 WPARAM wParam,
403 LPARAM lParam)
404 {
405 switch (uMsg)
406 {
407 case WM_INITDIALOG:
408 {
409 HWND hwndControl;
410 DWORD dwStyle;
411
412 hwndControl = GetParent(hwndDlg);
413
414 dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
415 SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
416
417 CheckDlgButton(hwndDlg, IDC_INSTALL, BST_CHECKED);
418
419 /* Set title font */
420 /*SendDlgItemMessage(hwndDlg,
421 IDC_STARTTITLE,
422 WM_SETFONT,
423 (WPARAM)hTitleFont,
424 (LPARAM)TRUE);*/
425 }
426 break;
427
428 case WM_NOTIFY:
429 {
430 LPNMHDR lpnm = (LPNMHDR)lParam;
431
432 switch (lpnm->code)
433 {
434 case PSN_SETACTIVE:
435 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
436 break;
437
438 case PSN_QUERYCANCEL:
439 SetWindowLongPtr(hwndDlg,
440 DWL_MSGRESULT,
441 MessageBox(GetParent(hwndDlg),
442 abort_msg,
443 abort_title,
444 MB_YESNO | MB_ICONQUESTION) != IDYES);
445 return TRUE;
446
447 case PSN_WIZNEXT: // set the selected data
448 SetupData.RepairUpdateFlag = !(SendMessage(GetDlgItem(hwndDlg, IDC_INSTALL),
449 BM_GETCHECK,
450 (WPARAM) 0,
451 (LPARAM) 0) == BST_CHECKED);
452 return TRUE;
453
454 default:
455 break;
456 }
457 }
458 break;
459
460 default:
461 break;
462
463 }
464 return FALSE;
465 }
466
467 static INT_PTR CALLBACK
468 DeviceDlgProc(HWND hwndDlg,
469 UINT uMsg,
470 WPARAM wParam,
471 LPARAM lParam)
472 {
473 LONG i;
474 LRESULT tindex;
475 HWND hList;
476
477 switch (uMsg)
478 {
479 case WM_INITDIALOG:
480 {
481 HWND hwndControl;
482 DWORD dwStyle;
483
484 hwndControl = GetParent(hwndDlg);
485
486 dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
487 SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
488
489 /* Set title font */
490 /*SendDlgItemMessage(hwndDlg,
491 IDC_STARTTITLE,
492 WM_SETFONT,
493 (WPARAM)hTitleFont,
494 (LPARAM)TRUE);*/
495
496 hList = GetDlgItem(hwndDlg, IDC_COMPUTER);
497
498 for (i=0; i < SetupData.CompCount; i++)
499 {
500 tindex = SendMessage(hList, CB_ADDSTRING, (WPARAM) 0, (LPARAM) SetupData.pComputers[i].Value);
501 SendMessage(hList, CB_SETITEMDATA, tindex, i);
502 }
503 SendMessage(hList, CB_SETCURSEL, 0, 0); // set first as default
504
505 hList = GetDlgItem(hwndDlg, IDC_DISPLAY);
506
507 for (i=0; i < SetupData.DispCount; i++)
508 {
509 tindex = SendMessage(hList, CB_ADDSTRING, (WPARAM) 0, (LPARAM) SetupData.pDisplays[i].Value);
510 SendMessage(hList, CB_SETITEMDATA, tindex, i);
511 }
512 SendMessage(hList, CB_SETCURSEL, 0, 0); // set first as default
513
514 hList = GetDlgItem(hwndDlg, IDC_KEYBOARD);
515
516 for (i=0; i < SetupData.KeybCount; i++)
517 {
518 tindex = SendMessage(hList,CB_ADDSTRING,(WPARAM)0,(LPARAM)SetupData.pKeyboards[i].Value);
519 SendMessage(hList,CB_SETITEMDATA,tindex,i);
520 }
521 SendMessage(hList,CB_SETCURSEL,0,0); // set first as default
522 }
523 break;
524
525 case WM_NOTIFY:
526 {
527 LPNMHDR lpnm = (LPNMHDR)lParam;
528
529 switch (lpnm->code)
530 {
531 case PSN_SETACTIVE:
532 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
533 break;
534
535 case PSN_QUERYCANCEL:
536 SetWindowLongPtr(hwndDlg,
537 DWL_MSGRESULT,
538 MessageBox(GetParent(hwndDlg),
539 abort_msg,
540 abort_title,
541 MB_YESNO | MB_ICONQUESTION) != IDYES);
542 return TRUE;
543
544 case PSN_WIZNEXT: // set the selected data
545 {
546 hList = GetDlgItem(hwndDlg, IDC_COMPUTER);
547
548 tindex = SendMessage(hList, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
549 if (tindex != CB_ERR)
550 {
551 SetupData.SelectedComputer = SendMessage(hList,
552 CB_GETITEMDATA,
553 (WPARAM) tindex,
554 (LPARAM) 0);
555 }
556
557 hList = GetDlgItem(hwndDlg, IDC_DISPLAY);
558
559 tindex = SendMessage(hList, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
560 if (tindex != CB_ERR)
561 {
562 SetupData.SelectedDisplay = SendMessage(hList,
563 CB_GETITEMDATA,
564 (WPARAM) tindex,
565 (LPARAM) 0);
566 }
567
568 hList =GetDlgItem(hwndDlg, IDC_KEYBOARD);
569
570 tindex = SendMessage(hList, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
571 if (tindex != CB_ERR)
572 {
573 SetupData.SelectedKeyboard = SendMessage(hList,
574 CB_GETITEMDATA,
575 (WPARAM) tindex,
576 (LPARAM) 0);
577 }
578 return TRUE;
579 }
580
581 default:
582 break;
583 }
584 }
585 break;
586
587 default:
588 break;
589
590 }
591 return FALSE;
592 }
593
594 static INT_PTR CALLBACK
595 MoreOptDlgProc(HWND hwndDlg,
596 UINT uMsg,
597 WPARAM wParam,
598 LPARAM lParam)
599 {
600 switch (uMsg)
601 {
602 case WM_INITDIALOG:
603 {
604 CheckDlgButton(hwndDlg, IDC_INSTFREELDR, BST_CHECKED);
605 SendMessage(GetDlgItem(hwndDlg, IDC_PATH),
606 WM_SETTEXT,
607 (WPARAM) 0,
608 (LPARAM) SetupData.InstallDir);
609 }
610 break;
611
612 case WM_COMMAND:
613 {
614 switch(LOWORD(wParam))
615 {
616 case IDOK:
617 {
618 SendMessage(GetDlgItem(hwndDlg, IDC_PATH),
619 WM_GETTEXT,
620 (WPARAM) sizeof(SetupData.InstallDir) / sizeof(TCHAR),
621 (LPARAM) SetupData.InstallDir);
622
623 EndDialog(hwndDlg, IDOK);
624 return TRUE;
625 }
626
627 case IDCANCEL:
628 {
629 EndDialog(hwndDlg, IDCANCEL);
630 return TRUE;
631 }
632 }
633 }
634 }
635
636 return FALSE;
637 }
638
639 static INT_PTR CALLBACK
640 PartitionDlgProc(HWND hwndDlg,
641 UINT uMsg,
642 WPARAM wParam,
643 LPARAM lParam)
644 {
645 switch (uMsg)
646 {
647 case WM_INITDIALOG:
648 break;
649 case WM_COMMAND:
650 {
651 switch(LOWORD(wParam))
652 {
653 case IDOK:
654 EndDialog(hwndDlg, IDOK);
655 return TRUE;
656 case IDCANCEL:
657 EndDialog(hwndDlg, IDCANCEL);
658 return TRUE;
659 }
660 }
661 }
662 return FALSE;
663 }
664
665 static INT_PTR CALLBACK
666 DriveDlgProc(HWND hwndDlg,
667 UINT uMsg,
668 WPARAM wParam,
669 LPARAM lParam)
670 {
671 #if 1
672 HDEVINFO h;
673 HWND hList;
674 SP_DEVINFO_DATA DevInfoData;
675 DWORD i;
676 #endif
677 switch (uMsg)
678 {
679 case WM_INITDIALOG:
680 {
681 HWND hwndControl;
682 DWORD dwStyle;
683
684 hwndControl = GetParent(hwndDlg);
685
686 dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
687 SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
688
689 /* Set title font */
690 /*SendDlgItemMessage(hwndDlg,
691 IDC_STARTTITLE,
692 WM_SETFONT,
693 (WPARAM)hTitleFont,
694 (LPARAM)TRUE);*/
695 #if 1
696 h = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, NULL, NULL, DIGCF_PRESENT);
697 if (h != INVALID_HANDLE_VALUE)
698 {
699 hList =GetDlgItem(hwndDlg, IDC_PARTITION);
700 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
701 for (i=0; SetupDiEnumDeviceInfo(h, i, &DevInfoData); i++)
702 {
703 DWORD DataT;
704 LPTSTR buffer = NULL;
705 DWORD buffersize = 0;
706
707 while (!SetupDiGetDeviceRegistryProperty(h,
708 &DevInfoData,
709 SPDRP_DEVICEDESC,
710 &DataT,
711 (PBYTE)buffer,
712 buffersize,
713 &buffersize))
714 {
715 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
716 {
717 if (buffer) LocalFree(buffer);
718 buffer = LocalAlloc(LPTR, buffersize * 2);
719 }
720 else
721 break;
722 }
723 if (buffer)
724 {
725 SendMessage(hList, LB_ADDSTRING, (WPARAM) 0, (LPARAM) buffer);
726 LocalFree(buffer);
727 }
728 }
729 SetupDiDestroyDeviceInfoList(h);
730 }
731 #endif
732 }
733 break;
734
735 case WM_COMMAND:
736 {
737 switch(LOWORD(wParam))
738 {
739 case IDC_PARTMOREOPTS:
740 DialogBox(hInstance,
741 MAKEINTRESOURCE(IDD_BOOTOPTIONS),
742 hwndDlg,
743 (DLGPROC) MoreOptDlgProc);
744 break;
745 case IDC_PARTCREATE:
746 DialogBox(hInstance,
747 MAKEINTRESOURCE(IDD_PARTITION),
748 hwndDlg,
749 (DLGPROC) PartitionDlgProc);
750 break;
751 case IDC_PARTDELETE:
752 break;
753 }
754 break;
755 }
756
757 case WM_NOTIFY:
758 {
759 LPNMHDR lpnm = (LPNMHDR)lParam;
760
761 switch (lpnm->code)
762 {
763 case PSN_SETACTIVE:
764 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
765 break;
766
767 case PSN_QUERYCANCEL:
768 SetWindowLongPtr(hwndDlg,
769 DWL_MSGRESULT,
770 MessageBox(GetParent(hwndDlg),
771 abort_msg,
772 abort_title,
773 MB_YESNO | MB_ICONQUESTION) != IDYES);
774 return TRUE;
775
776 default:
777 break;
778 }
779 }
780 break;
781
782 default:
783 break;
784
785 }
786
787 return FALSE;
788 }
789
790 static INT_PTR CALLBACK
791 SummaryDlgProc(HWND hwndDlg,
792 UINT uMsg,
793 WPARAM wParam,
794 LPARAM lParam)
795 {
796 switch (uMsg)
797 {
798 case WM_INITDIALOG:
799 {
800 HWND hwndControl;
801 DWORD dwStyle;
802
803 hwndControl = GetParent(hwndDlg);
804
805 dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
806 SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
807
808 /* Set title font */
809 /*SendDlgItemMessage(hwndDlg,
810 IDC_STARTTITLE,
811 WM_SETFONT,
812 (WPARAM)hTitleFont,
813 (LPARAM)TRUE);*/
814 }
815 break;
816
817 case WM_NOTIFY:
818 {
819 LPNMHDR lpnm = (LPNMHDR)lParam;
820
821 switch (lpnm->code)
822 {
823 case PSN_SETACTIVE:
824 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
825 break;
826
827 case PSN_QUERYCANCEL:
828 SetWindowLongPtr(hwndDlg,
829 DWL_MSGRESULT,
830 MessageBox(GetParent(hwndDlg),
831 abort_msg,
832 abort_title,
833 MB_YESNO | MB_ICONQUESTION) != IDYES);
834 return TRUE;
835 default:
836 break;
837 }
838 }
839 break;
840
841 default:
842 break;
843 }
844
845 return FALSE;
846 }
847
848 static INT_PTR CALLBACK
849 ProcessDlgProc(HWND hwndDlg,
850 UINT uMsg,
851 WPARAM wParam,
852 LPARAM lParam)
853 {
854 switch (uMsg)
855 {
856 case WM_INITDIALOG:
857 {
858 HWND hwndControl;
859 DWORD dwStyle;
860
861 hwndControl = GetParent(hwndDlg);
862
863 dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
864 SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
865
866 /* Set title font */
867 /*SendDlgItemMessage(hwndDlg,
868 IDC_STARTTITLE,
869 WM_SETFONT,
870 (WPARAM)hTitleFont,
871 (LPARAM)TRUE);*/
872 }
873 break;
874
875 case WM_NOTIFY:
876 {
877 LPNMHDR lpnm = (LPNMHDR)lParam;
878
879 switch (lpnm->code)
880 {
881 case PSN_SETACTIVE:
882 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
883 // disable all buttons during installation process
884 // PropSheet_SetWizButtons(GetParent(hwndDlg), 0 );
885 break;
886 case PSN_QUERYCANCEL:
887 SetWindowLongPtr(hwndDlg,
888 DWL_MSGRESULT,
889 MessageBox(GetParent(hwndDlg),
890 abort_msg,
891 abort_title,
892 MB_YESNO | MB_ICONQUESTION) != IDYES);
893 return TRUE;
894 default:
895 break;
896 }
897 }
898 break;
899
900 default:
901 break;
902
903 }
904
905 return FALSE;
906 }
907
908 static INT_PTR CALLBACK
909 RestartDlgProc(HWND hwndDlg,
910 UINT uMsg,
911 WPARAM wParam,
912 LPARAM lParam)
913 {
914 switch (uMsg)
915 {
916 case WM_INITDIALOG:
917 {
918 HWND hwndControl;
919 DWORD dwStyle;
920
921 hwndControl = GetParent(hwndDlg);
922
923 dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
924 SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
925
926 hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
927 ShowWindow(hwndControl, SW_HIDE);
928 EnableWindow(hwndControl, FALSE);
929
930 /* Set title font */
931 /*SendDlgItemMessage(hwndDlg,
932 IDC_STARTTITLE,
933 WM_SETFONT,
934 (WPARAM)hTitleFont,
935 (LPARAM)TRUE);*/
936 }
937 break;
938
939 case WM_TIMER:
940 {
941 INT Position;
942 HWND hWndProgress;
943
944 hWndProgress = GetDlgItem(hwndDlg, IDC_RESTART_PROGRESS);
945 Position = SendMessage(hWndProgress, PBM_GETPOS, 0, 0);
946 if (Position == 300)
947 {
948 KillTimer(hwndDlg, 1);
949 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_FINISH);
950 }
951 else
952 {
953 SendMessage(hWndProgress, PBM_SETPOS, Position + 1, 0);
954 }
955 return TRUE;
956 }
957
958 case WM_DESTROY:
959 return TRUE;
960
961 case WM_NOTIFY:
962 {
963 LPNMHDR lpnm = (LPNMHDR)lParam;
964
965 switch (lpnm->code)
966 {
967 case PSN_SETACTIVE: // Only "Finish" for closing the App
968 {
969 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
970 SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM(0, 300));
971 SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETPOS, 0, 0);
972 SetTimer(hwndDlg, 1, 50, NULL);
973 }
974 break;
975
976 default:
977 break;
978 }
979 }
980 break;
981
982 default:
983 break;
984
985 }
986
987 return FALSE;
988 }
989
990 void LoadSetupData()
991 {
992 WCHAR szPath[MAX_PATH];
993 TCHAR tmp[10];
994 WCHAR *ch;
995 HINF hTxtsetupSif;
996 INFCONTEXT InfContext;
997 //TCHAR szValue[MAX_PATH];
998 DWORD LineLength;
999 LONG Count;
1000
1001 GetModuleFileNameW(NULL,szPath,MAX_PATH);
1002 ch = strrchrW(szPath,L'\\');
1003 if (ch != NULL)
1004 *ch = L'\0';
1005
1006 wcscat(szPath, L"\\txtsetup.sif");
1007 hTxtsetupSif = SetupOpenInfFileW(szPath, NULL, INF_STYLE_OLDNT, NULL);
1008 if (hTxtsetupSif != INVALID_HANDLE_VALUE)
1009 {
1010 // get language list
1011 SetupData.LangCount = SetupGetLineCount(hTxtsetupSif, _T("Language"));
1012 if (SetupData.LangCount > 0)
1013 {
1014 SetupData.pLanguages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LANG) * SetupData.LangCount);
1015 if (SetupData.pLanguages != NULL)
1016 {
1017 Count = 0;
1018 if (SetupFindFirstLine(hTxtsetupSif, _T("Language"), NULL, &InfContext))
1019 {
1020 do
1021 {
1022 SetupGetStringField(&InfContext,
1023 0,
1024 SetupData.pLanguages[Count].LangId,
1025 sizeof(SetupData.pLanguages[Count].LangId) / sizeof(TCHAR),
1026 &LineLength);
1027
1028 SetupGetStringField(&InfContext,
1029 1,
1030 SetupData.pLanguages[Count].LangName,
1031 sizeof(SetupData.pLanguages[Count].LangName) / sizeof(TCHAR),
1032 &LineLength);
1033 ++Count;
1034 }
1035 while (SetupFindNextLine(&InfContext, &InfContext) && Count < SetupData.LangCount);
1036 }
1037 }
1038 }
1039
1040 // get keyboard layout list
1041 SetupData.KbLayoutCount = SetupGetLineCount(hTxtsetupSif, _T("KeyboardLayout"));
1042 if (SetupData.KbLayoutCount > 0)
1043 {
1044 SetupData.pKbLayouts = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(KBLAYOUT) * SetupData.KbLayoutCount);
1045 if (SetupData.pKbLayouts != NULL)
1046 {
1047 Count = 0;
1048 if (SetupFindFirstLine(hTxtsetupSif, _T("KeyboardLayout"), NULL, &InfContext))
1049 {
1050 do
1051 {
1052 SetupGetStringField(&InfContext,
1053 0,
1054 SetupData.pKbLayouts[Count].LayoutId,
1055 sizeof(SetupData.pKbLayouts[Count].LayoutId) / sizeof(TCHAR),
1056 &LineLength);
1057
1058 SetupGetStringField(&InfContext,
1059 1,
1060 SetupData.pKbLayouts[Count].LayoutName,
1061 sizeof(SetupData.pKbLayouts[Count].LayoutName) / sizeof(TCHAR),
1062 &LineLength);
1063 ++Count;
1064 }
1065 while (SetupFindNextLine(&InfContext, &InfContext) && Count < SetupData.KbLayoutCount);
1066 }
1067 }
1068 }
1069
1070 // get default for keyboard and language
1071 SetupData.DefaultKBLayout = -1;
1072 SetupData.DefaultLang = -1;
1073
1074 // TODO: get defaults from underlaying running system
1075 if (SetupFindFirstLine(hTxtsetupSif, _T("NLS"), _T("DefaultLayout"), &InfContext))
1076 {
1077 SetupGetStringField(&InfContext, 1, tmp, sizeof(tmp) / sizeof(TCHAR), &LineLength);
1078 for (Count = 0; Count < SetupData.KbLayoutCount; Count++)
1079 if (_tcscmp(tmp, SetupData.pKbLayouts[Count].LayoutId) == 0)
1080 {
1081 SetupData.DefaultKBLayout = Count;
1082 break;
1083 }
1084 }
1085
1086 if (SetupFindFirstLine(hTxtsetupSif, _T("NLS"), _T("DefaultLanguage"), &InfContext))
1087 {
1088 SetupGetStringField(&InfContext, 1, tmp, sizeof(tmp) / sizeof(TCHAR), &LineLength);
1089 for (Count = 0; Count < SetupData.LangCount; Count++)
1090 if (_tcscmp(tmp, SetupData.pLanguages[Count].LangId) == 0)
1091 {
1092 SetupData.DefaultLang = Count;
1093 break;
1094 }
1095 }
1096
1097 // get computers list
1098 SetupData.CompCount = LoadGenentry(hTxtsetupSif,_T("Computer"),&SetupData.pComputers,&InfContext);
1099
1100 // get display list
1101 SetupData.DispCount = LoadGenentry(hTxtsetupSif,_T("Display"),&SetupData.pDisplays,&InfContext);
1102
1103 // get keyboard list
1104 SetupData.KeybCount = LoadGenentry(hTxtsetupSif, _T("Keyboard"),&SetupData.pKeyboards,&InfContext);
1105
1106 // get install directory
1107 if (SetupFindFirstLine(hTxtsetupSif, _T("SetupData"), _T("DefaultPath"), &InfContext))
1108 {
1109 SetupGetStringField(&InfContext,
1110 1,
1111 SetupData.InstallDir,
1112 sizeof(SetupData.InstallDir) / sizeof(TCHAR),
1113 &LineLength);
1114 }
1115 SetupCloseInfFile(hTxtsetupSif);
1116 }
1117 }
1118
1119 LONG LoadGenentry(HINF hinf,PCTSTR name,PGENENTRY *gen,PINFCONTEXT context)
1120 {
1121 LONG TotalCount;
1122 DWORD LineLength;
1123
1124 TotalCount = SetupGetLineCount(hinf, name);
1125 if (TotalCount > 0)
1126 {
1127 *gen = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GENENTRY) * TotalCount);
1128 if (*gen != NULL)
1129 {
1130 if (SetupFindFirstLine(hinf, name, NULL, context))
1131 {
1132 LONG Count = 0;
1133 do
1134 {
1135 SetupGetStringField(context,
1136 0,
1137 (*gen)[Count].Id,
1138 sizeof((*gen)[Count].Id) / sizeof(TCHAR),
1139 &LineLength);
1140
1141 SetupGetStringField(context,
1142 1,
1143 (*gen)[Count].Value,
1144 sizeof((*gen)[Count].Value) / sizeof(TCHAR),
1145 &LineLength);
1146 ++Count;
1147 }
1148 while (SetupFindNextLine(context, context) && Count < TotalCount);
1149 }
1150 }
1151 else return 0;
1152 }
1153 return TotalCount;
1154 }
1155
1156 BOOL isUnattendSetup()
1157 {
1158 WCHAR szPath[MAX_PATH];
1159 WCHAR *ch;
1160 HINF hUnattendedInf;
1161 INFCONTEXT InfContext;
1162 TCHAR szValue[MAX_PATH];
1163 DWORD LineLength;
1164 //HKEY hKey;
1165 BOOL result = 0;
1166
1167 GetModuleFileNameW(NULL, szPath, MAX_PATH);
1168 ch = strrchrW(szPath, L'\\');
1169 if (ch != NULL)
1170 *ch = L'\0';
1171
1172 wcscat(szPath, L"\\unattend.inf");
1173 hUnattendedInf = SetupOpenInfFileW(szPath, NULL, INF_STYLE_OLDNT, NULL);
1174
1175 if (hUnattendedInf != INVALID_HANDLE_VALUE)
1176 {
1177 if (SetupFindFirstLine(hUnattendedInf, _T("Unattend"), _T("UnattendSetupEnabled"),&InfContext))
1178 {
1179 if (SetupGetStringField(&InfContext,
1180 1,
1181 szValue,
1182 sizeof(szValue) / sizeof(TCHAR),
1183 &LineLength) && (_tcsicmp(szValue, _T("yes")) == 0))
1184 {
1185 result = 1; // unattendSetup enabled
1186 // read values and store in SetupData
1187 }
1188 }
1189 SetupCloseInfFile(hUnattendedInf);
1190 }
1191
1192 return result;
1193 }
1194
1195 int WINAPI
1196 _tWinMain(HINSTANCE hInst,
1197 HINSTANCE hPrevInstance,
1198 LPTSTR lpszCmdLine,
1199 int nCmdShow)
1200 {
1201 PROPSHEETHEADER psh;
1202 HPROPSHEETPAGE ahpsp[8];
1203 PROPSHEETPAGE psp = {0};
1204 UINT nPages = 0;
1205 hInstance = hInst;
1206 isUnattend = isUnattendSetup();
1207
1208 LoadString(hInst,IDS_ABORTSETUP, abort_msg, sizeof(abort_msg)/sizeof(TCHAR));
1209 LoadString(hInst,IDS_ABORTSETUP2, abort_title,sizeof(abort_title)/sizeof(TCHAR));
1210 if (!isUnattend)
1211 {
1212
1213 LoadSetupData();
1214
1215 /* Create the Start page, until setup is working */
1216 psp.dwSize = sizeof(PROPSHEETPAGE);
1217 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
1218 psp.hInstance = hInst;
1219 psp.lParam = 0;
1220 psp.pfnDlgProc = StartDlgProc;
1221 psp.pszTemplate = MAKEINTRESOURCE(IDD_STARTPAGE);
1222 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1223
1224 /* Create language selection page */
1225 psp.dwSize = sizeof(PROPSHEETPAGE);
1226 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1227 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_LANGTITLE);
1228 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_LANGSUBTITLE);
1229 psp.hInstance = hInst;
1230 psp.lParam = 0;
1231 psp.pfnDlgProc = LangSelDlgProc;
1232 psp.pszTemplate = MAKEINTRESOURCE(IDD_LANGSELPAGE);
1233 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1234
1235 /* Create install type selection page */
1236 psp.dwSize = sizeof(PROPSHEETPAGE);
1237 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1238 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_TYPETITLE);
1239 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_TYPESUBTITLE);
1240 psp.hInstance = hInst;
1241 psp.lParam = 0;
1242 psp.pfnDlgProc = TypeDlgProc;
1243 psp.pszTemplate = MAKEINTRESOURCE(IDD_TYPEPAGE);
1244 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1245
1246 /* Create device settings page */
1247 psp.dwSize = sizeof(PROPSHEETPAGE);
1248 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1249 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DEVICETITLE);
1250 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DEVICESUBTITLE);
1251 psp.hInstance = hInst;
1252 psp.lParam = 0;
1253 psp.pfnDlgProc = DeviceDlgProc;
1254 psp.pszTemplate = MAKEINTRESOURCE(IDD_DEVICEPAGE);
1255 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1256
1257 /* Create install device settings page / boot method / install directory */
1258 psp.dwSize = sizeof(PROPSHEETPAGE);
1259 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1260 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DRIVETITLE);
1261 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DRIVESUBTITLE);
1262 psp.hInstance = hInst;
1263 psp.lParam = 0;
1264 psp.pfnDlgProc = DriveDlgProc;
1265 psp.pszTemplate = MAKEINTRESOURCE(IDD_DRIVEPAGE);
1266 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1267
1268 /* Create summary page */
1269 psp.dwSize = sizeof(PROPSHEETPAGE);
1270 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1271 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SUMMARYTITLE);
1272 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_SUMMARYSUBTITLE);
1273 psp.hInstance = hInst;
1274 psp.lParam = 0;
1275 psp.pfnDlgProc = SummaryDlgProc;
1276 psp.pszTemplate = MAKEINTRESOURCE(IDD_SUMMARYPAGE);
1277 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1278 }
1279
1280 /* Create installation progress page */
1281 psp.dwSize = sizeof(PROPSHEETPAGE);
1282 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1283 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROCESSTITLE);
1284 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PROCESSSUBTITLE);
1285 psp.hInstance = hInst;
1286 psp.lParam = 0;
1287 psp.pfnDlgProc = ProcessDlgProc;
1288 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROCESSPAGE);
1289 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1290
1291 /* Create finish to reboot page */
1292 psp.dwSize = sizeof(PROPSHEETPAGE);
1293 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1294 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_RESTARTTITLE);
1295 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_RESTARTSUBTITLE);
1296 psp.hInstance = hInst;
1297 psp.lParam = 0;
1298 psp.pfnDlgProc = RestartDlgProc;
1299 psp.pszTemplate = MAKEINTRESOURCE(IDD_RESTARTPAGE);
1300 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1301
1302 /* Create the property sheet */
1303 psh.dwSize = sizeof(PROPSHEETHEADER);
1304 psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
1305 psh.hInstance = hInst;
1306 psh.hwndParent = NULL;
1307 psh.nPages = nPages;
1308 psh.nStartPage = 0;
1309 psh.phpage = ahpsp;
1310 psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
1311 psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
1312
1313 /* Create title font */
1314 hTitleFont = CreateTitleFont();
1315
1316 /* Display the wizard */
1317 PropertySheet(&psh);
1318
1319 DeleteObject(hTitleFont);
1320
1321 return 0;
1322 }
1323
1324 /* EOF */