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