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