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