d5aa41ecac3ae4bcb83676f0b7e64bf2f36db992
[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 "reactos.h"
29 #include "resource.h"
30
31 /* GLOBALS ******************************************************************/
32
33
34 LONG LoadGenentry(HINF hinf,PCTSTR name,PGENENTRY *gen,PINFCONTEXT context);
35
36 /* FUNCTIONS ****************************************************************/
37
38 static VOID
39 CenterWindow(HWND hWnd)
40 {
41 HWND hWndParent;
42 RECT rcParent;
43 RECT rcWindow;
44
45 hWndParent = GetParent(hWnd);
46 if (hWndParent == NULL)
47 hWndParent = GetDesktopWindow();
48
49 GetWindowRect(hWndParent, &rcParent);
50 GetWindowRect(hWnd, &rcWindow);
51
52 SetWindowPos(hWnd,
53 HWND_TOP,
54 ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2,
55 ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2,
56 0,
57 0,
58 SWP_NOSIZE);
59 }
60
61 static HFONT
62 CreateTitleFont(VOID)
63 {
64 NONCLIENTMETRICS ncm;
65 LOGFONT LogFont;
66 HDC hdc;
67 INT FontSize;
68 HFONT hFont;
69
70 ncm.cbSize = sizeof(NONCLIENTMETRICS);
71 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
72
73 LogFont = ncm.lfMessageFont;
74 LogFont.lfWeight = FW_BOLD;
75 _tcscpy(LogFont.lfFaceName, _T("MS Shell Dlg"));
76
77 hdc = GetDC(NULL);
78 FontSize = 12;
79 LogFont.lfHeight = 0 - GetDeviceCaps (hdc, LOGPIXELSY) * FontSize / 72;
80 hFont = CreateFontIndirect(&LogFont);
81 ReleaseDC(NULL, hdc);
82
83 return hFont;
84 }
85
86 static INT_PTR CALLBACK
87 StartDlgProc(HWND hwndDlg,
88 UINT uMsg,
89 WPARAM wParam,
90 LPARAM lParam)
91 {
92 PSETUPDATA pSetupData;
93
94 /* Retrieve pointer to the global setup data */
95 pSetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
96
97 switch (uMsg)
98 {
99 case WM_INITDIALOG:
100 /* Save pointer to the global setup data */
101 pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
102 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pSetupData);
103
104 /* Center the wizard window */
105 CenterWindow(GetParent(hwndDlg));
106
107 /* Set title font */
108 SendDlgItemMessage(hwndDlg,
109 IDC_STARTTITLE,
110 WM_SETFONT,
111 (WPARAM)pSetupData->hTitleFont,
112 (LPARAM)TRUE);
113 break;
114
115 case WM_NOTIFY:
116 {
117 LPNMHDR lpnm = (LPNMHDR)lParam;
118
119 switch (lpnm->code)
120 {
121 case PSN_SETACTIVE:
122 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
123 break;
124
125 default:
126 break;
127 }
128 }
129 break;
130
131 default:
132 break;
133
134 }
135
136 return FALSE;
137 }
138
139 static INT_PTR CALLBACK
140 TypeDlgProc(HWND hwndDlg,
141 UINT uMsg,
142 WPARAM wParam,
143 LPARAM lParam)
144 {
145 PSETUPDATA pSetupData;
146
147 /* Retrieve pointer to the global setup data */
148 pSetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
149
150 switch (uMsg)
151 {
152 case WM_INITDIALOG:
153 /* Save pointer to the global setup data */
154 pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
155 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pSetupData);
156
157 /* Check the 'install' radio button */
158 CheckDlgButton(hwndDlg, IDC_INSTALL, BST_CHECKED);
159
160 /* Disable the 'update' radio button and text */
161 EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE);
162 EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATETEXT), FALSE);
163 break;
164
165 case WM_NOTIFY:
166 {
167 LPNMHDR lpnm = (LPNMHDR)lParam;
168
169 switch (lpnm->code)
170 {
171 case PSN_SETACTIVE:
172 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
173 break;
174
175 case PSN_QUERYCANCEL:
176 SetWindowLongPtr(hwndDlg,
177 DWL_MSGRESULT,
178 MessageBox(GetParent(hwndDlg),
179 pSetupData->szAbortMessage,
180 pSetupData->szAbortTitle,
181 MB_YESNO | MB_ICONQUESTION) != IDYES);
182 return TRUE;
183
184 case PSN_WIZNEXT: // set the selected data
185 pSetupData->RepairUpdateFlag = !(SendMessage(GetDlgItem(hwndDlg, IDC_INSTALL),
186 BM_GETCHECK,
187 (WPARAM) 0,
188 (LPARAM) 0) == BST_CHECKED);
189 return TRUE;
190
191 default:
192 break;
193 }
194 }
195 break;
196
197 default:
198 break;
199
200 }
201 return FALSE;
202 }
203
204 static INT_PTR CALLBACK
205 DeviceDlgProc(HWND hwndDlg,
206 UINT uMsg,
207 WPARAM wParam,
208 LPARAM lParam)
209 {
210 PSETUPDATA pSetupData;
211 LONG i;
212 LRESULT tindex;
213 HWND hList;
214
215 /* Retrieve pointer to the global setup data */
216 pSetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
217
218 switch (uMsg)
219 {
220 case WM_INITDIALOG:
221 /* Save pointer to the global setup data */
222 pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
223 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pSetupData);
224
225 hList = GetDlgItem(hwndDlg, IDC_COMPUTER);
226
227 for (i=0; i < pSetupData->CompCount; i++)
228 {
229 tindex = SendMessage(hList, CB_ADDSTRING, (WPARAM) 0, (LPARAM) pSetupData->pComputers[i].Value);
230 SendMessage(hList, CB_SETITEMDATA, tindex, i);
231 }
232 SendMessage(hList, CB_SETCURSEL, 0, 0); // set first as default
233
234 hList = GetDlgItem(hwndDlg, IDC_DISPLAY);
235
236 for (i=0; i < pSetupData->DispCount; i++)
237 {
238 tindex = SendMessage(hList, CB_ADDSTRING, (WPARAM) 0, (LPARAM) pSetupData->pDisplays[i].Value);
239 SendMessage(hList, CB_SETITEMDATA, tindex, i);
240 }
241 SendMessage(hList, CB_SETCURSEL, 0, 0); // set first as default
242
243 hList = GetDlgItem(hwndDlg, IDC_KEYBOARD);
244
245 for (i=0; i < pSetupData->KeybCount; i++)
246 {
247 tindex = SendMessage(hList,CB_ADDSTRING,(WPARAM)0,(LPARAM)pSetupData->pKeyboards[i].Value);
248 SendMessage(hList,CB_SETITEMDATA,tindex,i);
249 }
250 SendMessage(hList,CB_SETCURSEL,0,0); // set first as default
251 break;
252
253 case WM_NOTIFY:
254 {
255 LPNMHDR lpnm = (LPNMHDR)lParam;
256
257 switch (lpnm->code)
258 {
259 case PSN_SETACTIVE:
260 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
261 break;
262
263 case PSN_QUERYCANCEL:
264 SetWindowLongPtr(hwndDlg,
265 DWL_MSGRESULT,
266 MessageBox(GetParent(hwndDlg),
267 pSetupData->szAbortMessage,
268 pSetupData->szAbortTitle,
269 MB_YESNO | MB_ICONQUESTION) != IDYES);
270 return TRUE;
271
272 case PSN_WIZNEXT: // set the selected data
273 {
274 hList = GetDlgItem(hwndDlg, IDC_COMPUTER);
275
276 tindex = SendMessage(hList, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
277 if (tindex != CB_ERR)
278 {
279 pSetupData->SelectedComputer = SendMessage(hList,
280 CB_GETITEMDATA,
281 (WPARAM) tindex,
282 (LPARAM) 0);
283 }
284
285 hList = GetDlgItem(hwndDlg, IDC_DISPLAY);
286
287 tindex = SendMessage(hList, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
288 if (tindex != CB_ERR)
289 {
290 pSetupData->SelectedDisplay = SendMessage(hList,
291 CB_GETITEMDATA,
292 (WPARAM) tindex,
293 (LPARAM) 0);
294 }
295
296 hList =GetDlgItem(hwndDlg, IDC_KEYBOARD);
297
298 tindex = SendMessage(hList, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
299 if (tindex != CB_ERR)
300 {
301 pSetupData->SelectedKeyboard = SendMessage(hList,
302 CB_GETITEMDATA,
303 (WPARAM) tindex,
304 (LPARAM) 0);
305 }
306 return TRUE;
307 }
308
309 default:
310 break;
311 }
312 }
313 break;
314
315 default:
316 break;
317
318 }
319 return FALSE;
320 }
321
322 static INT_PTR CALLBACK
323 SummaryDlgProc(HWND hwndDlg,
324 UINT uMsg,
325 WPARAM wParam,
326 LPARAM lParam)
327 {
328 PSETUPDATA pSetupData;
329
330 /* Retrieve pointer to the global setup data */
331 pSetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
332
333 switch (uMsg)
334 {
335 case WM_INITDIALOG:
336 /* Save pointer to the global setup data */
337 pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
338 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pSetupData);
339 break;
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 SetWindowLongPtr(hwndDlg,
353 DWL_MSGRESULT,
354 MessageBox(GetParent(hwndDlg),
355 pSetupData->szAbortMessage,
356 pSetupData->szAbortTitle,
357 MB_YESNO | MB_ICONQUESTION) != IDYES);
358 return TRUE;
359 default:
360 break;
361 }
362 }
363 break;
364
365 default:
366 break;
367 }
368
369 return FALSE;
370 }
371
372 static INT_PTR CALLBACK
373 ProcessDlgProc(HWND hwndDlg,
374 UINT uMsg,
375 WPARAM wParam,
376 LPARAM lParam)
377 {
378 PSETUPDATA pSetupData;
379
380 /* Retrieve pointer to the global setup data */
381 pSetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
382
383 switch (uMsg)
384 {
385 case WM_INITDIALOG:
386 /* Save pointer to the global setup data */
387 pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
388 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pSetupData);
389 break;
390
391 case WM_NOTIFY:
392 {
393 LPNMHDR lpnm = (LPNMHDR)lParam;
394
395 switch (lpnm->code)
396 {
397 case PSN_SETACTIVE:
398 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
399 // disable all buttons during installation process
400 // PropSheet_SetWizButtons(GetParent(hwndDlg), 0 );
401 break;
402 case PSN_QUERYCANCEL:
403 SetWindowLongPtr(hwndDlg,
404 DWL_MSGRESULT,
405 MessageBox(GetParent(hwndDlg),
406 pSetupData->szAbortMessage,
407 pSetupData->szAbortTitle,
408 MB_YESNO | MB_ICONQUESTION) != IDYES);
409 return TRUE;
410 default:
411 break;
412 }
413 }
414 break;
415
416 default:
417 break;
418
419 }
420
421 return FALSE;
422 }
423
424 static INT_PTR CALLBACK
425 RestartDlgProc(HWND hwndDlg,
426 UINT uMsg,
427 WPARAM wParam,
428 LPARAM lParam)
429 {
430 PSETUPDATA pSetupData;
431
432 /* Retrieve pointer to the global setup data */
433 pSetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
434
435 switch (uMsg)
436 {
437 case WM_INITDIALOG:
438 /* Save pointer to the global setup data */
439 pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
440 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pSetupData);
441
442 /* Set title font */
443 /*SendDlgItemMessage(hwndDlg,
444 IDC_STARTTITLE,
445 WM_SETFONT,
446 (WPARAM)hTitleFont,
447 (LPARAM)TRUE);*/
448 break;
449
450 case WM_TIMER:
451 {
452 INT Position;
453 HWND hWndProgress;
454
455 hWndProgress = GetDlgItem(hwndDlg, IDC_RESTART_PROGRESS);
456 Position = SendMessage(hWndProgress, PBM_GETPOS, 0, 0);
457 if (Position == 300)
458 {
459 KillTimer(hwndDlg, 1);
460 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_FINISH);
461 }
462 else
463 {
464 SendMessage(hWndProgress, PBM_SETPOS, Position + 1, 0);
465 }
466 return TRUE;
467 }
468
469 case WM_DESTROY:
470 return TRUE;
471
472 case WM_NOTIFY:
473 {
474 LPNMHDR lpnm = (LPNMHDR)lParam;
475
476 switch (lpnm->code)
477 {
478 case PSN_SETACTIVE: // Only "Finish" for closing the App
479 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
480 SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM(0, 300));
481 SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETPOS, 0, 0);
482 SetTimer(hwndDlg, 1, 50, NULL);
483 break;
484
485 default:
486 break;
487 }
488 }
489 break;
490
491 default:
492 break;
493
494 }
495
496 return FALSE;
497 }
498
499 BOOL LoadSetupData(
500 PSETUPDATA pSetupData)
501 {
502 WCHAR szPath[MAX_PATH];
503 TCHAR tmp[10];
504 WCHAR *ch;
505 HINF hTxtsetupSif = INVALID_HANDLE_VALUE;
506 INFCONTEXT InfContext;
507 //TCHAR szValue[MAX_PATH];
508 DWORD LineLength;
509 LONG Count;
510 BOOL ret = TRUE;
511
512 GetModuleFileNameW(NULL,szPath,MAX_PATH);
513 ch = strrchrW(szPath,L'\\');
514 if (ch != NULL)
515 *ch = L'\0';
516
517 wcscat(szPath, L"\\txtsetup.sif");
518 hTxtsetupSif = SetupOpenInfFileW(szPath, NULL, INF_STYLE_OLDNT, NULL);
519 if (hTxtsetupSif == INVALID_HANDLE_VALUE)
520 {
521 TCHAR message[512], caption[64];
522
523 // txtsetup.sif cannot be found
524 LoadString(pSetupData->hInstance, IDS_NO_TXTSETUP_SIF, message, sizeof(message)/sizeof(TCHAR));
525 LoadString(pSetupData->hInstance, IDS_CAPTION, caption, sizeof(caption)/sizeof(TCHAR));
526
527 MessageBox(NULL, message, caption, MB_OK | MB_ICONERROR);
528 return FALSE;
529 }
530
531 // get language list
532 pSetupData->LangCount = SetupGetLineCount(hTxtsetupSif, _T("Language"));
533 if (pSetupData->LangCount > 0)
534 {
535 pSetupData->pLanguages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LANG) * pSetupData->LangCount);
536 if (pSetupData->pLanguages == NULL)
537 {
538 ret = FALSE;
539 goto done;
540 }
541
542 Count = 0;
543 if (SetupFindFirstLine(hTxtsetupSif, _T("Language"), NULL, &InfContext))
544 {
545 do
546 {
547 SetupGetStringField(&InfContext,
548 0,
549 pSetupData->pLanguages[Count].LangId,
550 sizeof(pSetupData->pLanguages[Count].LangId) / sizeof(TCHAR),
551 &LineLength);
552
553 SetupGetStringField(&InfContext,
554 1,
555 pSetupData->pLanguages[Count].LangName,
556 sizeof(pSetupData->pLanguages[Count].LangName) / sizeof(TCHAR),
557 &LineLength);
558 ++Count;
559 }
560 while (SetupFindNextLine(&InfContext, &InfContext) && Count < pSetupData->LangCount);
561 }
562 }
563
564 // get keyboard layout list
565 pSetupData->KbLayoutCount = SetupGetLineCount(hTxtsetupSif, _T("KeyboardLayout"));
566 if (pSetupData->KbLayoutCount > 0)
567 {
568 pSetupData->pKbLayouts = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(KBLAYOUT) * pSetupData->KbLayoutCount);
569 if (pSetupData->pKbLayouts == NULL)
570 {
571 ret = FALSE;
572 goto done;
573 }
574
575 Count = 0;
576 if (SetupFindFirstLine(hTxtsetupSif, _T("KeyboardLayout"), NULL, &InfContext))
577 {
578 do
579 {
580 SetupGetStringField(&InfContext,
581 0,
582 pSetupData->pKbLayouts[Count].LayoutId,
583 sizeof(pSetupData->pKbLayouts[Count].LayoutId) / sizeof(TCHAR),
584 &LineLength);
585
586 SetupGetStringField(&InfContext,
587 1,
588 pSetupData->pKbLayouts[Count].LayoutName,
589 sizeof(pSetupData->pKbLayouts[Count].LayoutName) / sizeof(TCHAR),
590 &LineLength);
591 ++Count;
592 }
593 while (SetupFindNextLine(&InfContext, &InfContext) && Count < pSetupData->KbLayoutCount);
594 }
595 }
596
597 // get default for keyboard and language
598 pSetupData->DefaultKBLayout = -1;
599 pSetupData->DefaultLang = -1;
600
601 // TODO: get defaults from underlaying running system
602 if (SetupFindFirstLine(hTxtsetupSif, _T("NLS"), _T("DefaultLayout"), &InfContext))
603 {
604 SetupGetStringField(&InfContext, 1, tmp, sizeof(tmp) / sizeof(TCHAR), &LineLength);
605 for (Count = 0; Count < pSetupData->KbLayoutCount; Count++)
606 {
607 if (_tcscmp(tmp, pSetupData->pKbLayouts[Count].LayoutId) == 0)
608 {
609 pSetupData->DefaultKBLayout = Count;
610 break;
611 }
612 }
613 }
614
615 if (SetupFindFirstLine(hTxtsetupSif, _T("NLS"), _T("DefaultLanguage"), &InfContext))
616 {
617 SetupGetStringField(&InfContext, 1, tmp, sizeof(tmp) / sizeof(TCHAR), &LineLength);
618 for (Count = 0; Count < pSetupData->LangCount; Count++)
619 {
620 if (_tcscmp(tmp, pSetupData->pLanguages[Count].LangId) == 0)
621 {
622 pSetupData->DefaultLang = Count;
623 break;
624 }
625 }
626 }
627
628 // get computers list
629 pSetupData->CompCount = LoadGenentry(hTxtsetupSif,_T("Computer"),&pSetupData->pComputers,&InfContext);
630
631 // get display list
632 pSetupData->DispCount = LoadGenentry(hTxtsetupSif,_T("Display"),&pSetupData->pDisplays,&InfContext);
633
634 // get keyboard list
635 pSetupData->KeybCount = LoadGenentry(hTxtsetupSif, _T("Keyboard"),&pSetupData->pKeyboards,&InfContext);
636
637 // get install directory
638 if (SetupFindFirstLine(hTxtsetupSif, _T("SetupData"), _T("DefaultPath"), &InfContext))
639 {
640 SetupGetStringField(&InfContext,
641 1,
642 pSetupData->InstallDir,
643 sizeof(pSetupData->InstallDir) / sizeof(TCHAR),
644 &LineLength);
645 }
646
647 done:
648 if (ret == FALSE)
649 {
650 if (pSetupData->pKbLayouts != NULL)
651 {
652 HeapFree(GetProcessHeap(), 0, pSetupData->pKbLayouts);
653 pSetupData->pKbLayouts = NULL;
654 }
655
656 if (pSetupData->pLanguages != NULL)
657 {
658 HeapFree(GetProcessHeap(), 0, pSetupData->pLanguages);
659 pSetupData->pLanguages = NULL;
660 }
661 }
662
663 if (hTxtsetupSif != INVALID_HANDLE_VALUE)
664 SetupCloseInfFile(hTxtsetupSif);
665
666 return ret;
667 }
668
669 LONG LoadGenentry(HINF hinf,PCTSTR name,PGENENTRY *gen,PINFCONTEXT context)
670 {
671 LONG TotalCount;
672 DWORD LineLength;
673
674 TotalCount = SetupGetLineCount(hinf, name);
675 if (TotalCount > 0)
676 {
677 *gen = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GENENTRY) * TotalCount);
678 if (*gen != NULL)
679 {
680 if (SetupFindFirstLine(hinf, name, NULL, context))
681 {
682 LONG Count = 0;
683 do
684 {
685 SetupGetStringField(context,
686 0,
687 (*gen)[Count].Id,
688 sizeof((*gen)[Count].Id) / sizeof(TCHAR),
689 &LineLength);
690
691 SetupGetStringField(context,
692 1,
693 (*gen)[Count].Value,
694 sizeof((*gen)[Count].Value) / sizeof(TCHAR),
695 &LineLength);
696 ++Count;
697 }
698 while (SetupFindNextLine(context, context) && Count < TotalCount);
699 }
700 }
701 else return 0;
702 }
703 return TotalCount;
704 }
705
706 BOOL isUnattendSetup(VOID)
707 {
708 WCHAR szPath[MAX_PATH];
709 WCHAR *ch;
710 HINF hUnattendedInf;
711 INFCONTEXT InfContext;
712 TCHAR szValue[MAX_PATH];
713 DWORD LineLength;
714 //HKEY hKey;
715 BOOL result = 0;
716
717 GetModuleFileNameW(NULL, szPath, MAX_PATH);
718 ch = strrchrW(szPath, L'\\');
719 if (ch != NULL)
720 *ch = L'\0';
721
722 wcscat(szPath, L"\\unattend.inf");
723 hUnattendedInf = SetupOpenInfFileW(szPath, NULL, INF_STYLE_OLDNT, NULL);
724
725 if (hUnattendedInf != INVALID_HANDLE_VALUE)
726 {
727 if (SetupFindFirstLine(hUnattendedInf, _T("Unattend"), _T("UnattendSetupEnabled"),&InfContext))
728 {
729 if (SetupGetStringField(&InfContext,
730 1,
731 szValue,
732 sizeof(szValue) / sizeof(TCHAR),
733 &LineLength) && (_tcsicmp(szValue, _T("yes")) == 0))
734 {
735 result = 1; // unattendSetup enabled
736 // read values and store in SetupData
737 }
738 }
739 SetupCloseInfFile(hUnattendedInf);
740 }
741
742 return result;
743 }
744
745 #if 0
746 static
747 VOID
748 EnableShutdownPrivilege(VOID)
749 {
750 HANDLE hToken = NULL;
751 TOKEN_PRIVILEGES Privileges;
752
753 /* Get shutdown privilege */
754 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
755 {
756 // FatalError("OpenProcessToken() failed!");
757 return;
758 }
759
760 if (!LookupPrivilegeValue(NULL,
761 SE_SHUTDOWN_NAME,
762 &Privileges.Privileges[0].Luid))
763 {
764 // FatalError("LookupPrivilegeValue() failed!");
765 goto done;
766 }
767
768 Privileges.PrivilegeCount = 1;
769 Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
770
771 if (AdjustTokenPrivileges(hToken,
772 FALSE,
773 &Privileges,
774 0,
775 (PTOKEN_PRIVILEGES)NULL,
776 NULL) == 0)
777 {
778 // FatalError("AdjustTokenPrivileges() failed!");
779 goto done;
780 }
781
782 done:
783 if (hToken != NULL)
784 CloseHandle(hToken);
785
786 return;
787 }
788 #endif
789
790 int WINAPI
791 _tWinMain(HINSTANCE hInst,
792 HINSTANCE hPrevInstance,
793 LPTSTR lpszCmdLine,
794 int nCmdShow)
795 {
796 PSETUPDATA pSetupData = NULL;
797 PROPSHEETHEADER psh;
798 HPROPSHEETPAGE ahpsp[8];
799 PROPSHEETPAGE psp = {0};
800 UINT nPages = 0;
801
802 pSetupData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SETUPDATA));
803 if (pSetupData == NULL)
804 {
805 return 1;
806 }
807
808 pSetupData->hInstance = hInst;
809 pSetupData->bUnattend = isUnattendSetup();
810
811 LoadString(hInst,IDS_ABORTSETUP, pSetupData->szAbortMessage, sizeof(pSetupData->szAbortMessage)/sizeof(TCHAR));
812 LoadString(hInst,IDS_ABORTSETUP2, pSetupData->szAbortTitle, sizeof(pSetupData->szAbortTitle)/sizeof(TCHAR));
813
814 /* Create title font */
815 pSetupData->hTitleFont = CreateTitleFont();
816
817 if (!pSetupData->bUnattend)
818 {
819 if (!LoadSetupData(pSetupData))
820 {
821 HeapFree(GetProcessHeap(), 0, pSetupData);
822 return 0;
823 }
824
825 /* Create the Start page, until setup is working */
826 psp.dwSize = sizeof(PROPSHEETPAGE);
827 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
828 psp.hInstance = hInst;
829 psp.lParam = (LPARAM)pSetupData;
830 psp.pfnDlgProc = StartDlgProc;
831 psp.pszTemplate = MAKEINTRESOURCE(IDD_STARTPAGE);
832 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
833
834 /* Create install type selection page */
835 psp.dwSize = sizeof(PROPSHEETPAGE);
836 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
837 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_TYPETITLE);
838 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_TYPESUBTITLE);
839 psp.hInstance = hInst;
840 psp.lParam = (LPARAM)pSetupData;
841 psp.pfnDlgProc = TypeDlgProc;
842 psp.pszTemplate = MAKEINTRESOURCE(IDD_TYPEPAGE);
843 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
844
845 /* Create device settings page */
846 psp.dwSize = sizeof(PROPSHEETPAGE);
847 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
848 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DEVICETITLE);
849 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DEVICESUBTITLE);
850 psp.hInstance = hInst;
851 psp.lParam = (LPARAM)pSetupData;
852 psp.pfnDlgProc = DeviceDlgProc;
853 psp.pszTemplate = MAKEINTRESOURCE(IDD_DEVICEPAGE);
854 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
855
856 /* Create install device settings page / boot method / install directory */
857 psp.dwSize = sizeof(PROPSHEETPAGE);
858 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
859 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DRIVETITLE);
860 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DRIVESUBTITLE);
861 psp.hInstance = hInst;
862 psp.lParam = (LPARAM)pSetupData;
863 psp.pfnDlgProc = DriveDlgProc;
864 psp.pszTemplate = MAKEINTRESOURCE(IDD_DRIVEPAGE);
865 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
866
867 /* Create summary page */
868 psp.dwSize = sizeof(PROPSHEETPAGE);
869 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
870 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SUMMARYTITLE);
871 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_SUMMARYSUBTITLE);
872 psp.hInstance = hInst;
873 psp.lParam = (LPARAM)pSetupData;
874 psp.pfnDlgProc = SummaryDlgProc;
875 psp.pszTemplate = MAKEINTRESOURCE(IDD_SUMMARYPAGE);
876 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
877 }
878
879 /* Create installation progress page */
880 psp.dwSize = sizeof(PROPSHEETPAGE);
881 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
882 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROCESSTITLE);
883 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PROCESSSUBTITLE);
884 psp.hInstance = hInst;
885 psp.lParam = (LPARAM)pSetupData;
886 psp.pfnDlgProc = ProcessDlgProc;
887 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROCESSPAGE);
888 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
889
890 /* Create finish to reboot page */
891 psp.dwSize = sizeof(PROPSHEETPAGE);
892 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
893 psp.hInstance = hInst;
894 psp.lParam = (LPARAM)pSetupData;
895 psp.pfnDlgProc = RestartDlgProc;
896 psp.pszTemplate = MAKEINTRESOURCE(IDD_RESTARTPAGE);
897 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
898
899 /* Create the property sheet */
900 psh.dwSize = sizeof(PROPSHEETHEADER);
901 psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
902 psh.hInstance = hInst;
903 psh.hwndParent = NULL;
904 psh.nPages = nPages;
905 psh.nStartPage = 0;
906 psh.phpage = ahpsp;
907 psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
908 psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
909
910 /* Display the wizard */
911 PropertySheet(&psh);
912
913 if (pSetupData->hTitleFont)
914 DeleteObject(pSetupData->hTitleFont);
915
916 HeapFree(GetProcessHeap(), 0, pSetupData);
917
918 #if 0
919 EnableShutdownPrivilege();
920 ExitWindowsEx(EWX_REBOOT, 0);
921 #endif
922
923 return 0;
924 }
925
926 /* EOF */