- Added ACP, OEMCP and MACCP keys to registry
[reactos.git] / reactos / base / setup / usetup / interface / usetup.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2002, 2003, 2004 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 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/usetup.c
23 * PURPOSE: Text-mode setup
24 * PROGRAMMER: Eric Kohl
25 * Casper S. Hornstrup (chorns@users.sourceforge.net)
26 * Hervé Poussineau (hpoussin@reactos.org)
27 */
28
29 #include "usetup.h"
30
31 #define NDEBUG
32 #include <debug.h>
33
34 /* GLOBALS ******************************************************************/
35
36 HANDLE ProcessHeap;
37 UNICODE_STRING SourceRootPath;
38 UNICODE_STRING SourceRootDir;
39 UNICODE_STRING SourcePath;
40 BOOLEAN IsUnattendedSetup = FALSE;
41 LONG UnattendDestinationDiskNumber;
42 LONG UnattendDestinationPartitionNumber;
43 LONG UnattendMBRInstallType = -1;
44 LONG UnattendFormatPartition = 0;
45 LONG AutoPartition = 0;
46 WCHAR UnattendInstallationDirectory[MAX_PATH];
47 PWCHAR SelectedLanguageId;
48 WCHAR DefaultLanguage[20];
49 WCHAR DefaultKBLayout[20];
50 BOOLEAN RepairUpdateFlag = FALSE;
51 HANDLE hPnpThread = INVALID_HANDLE_VALUE;
52
53 /* LOCALS *******************************************************************/
54
55 static PPARTLIST PartitionList = NULL;
56
57 static PFILE_SYSTEM_LIST FileSystemList = NULL;
58
59 static UNICODE_STRING InstallPath;
60
61 /* Path to the install directory */
62 static UNICODE_STRING DestinationPath;
63 static UNICODE_STRING DestinationArcPath;
64 static UNICODE_STRING DestinationRootPath;
65
66 /* Path to the active partition (boot manager) */
67 static UNICODE_STRING SystemRootPath;
68
69 static HINF SetupInf;
70
71 static HSPFILEQ SetupFileQueue = NULL;
72
73 static BOOLEAN WarnLinuxPartitions = TRUE;
74
75 static PGENERIC_LIST ComputerList = NULL;
76 static PGENERIC_LIST DisplayList = NULL;
77 static PGENERIC_LIST KeyboardList = NULL;
78 static PGENERIC_LIST LayoutList = NULL;
79 static PGENERIC_LIST LanguageList = NULL;
80
81 /* FUNCTIONS ****************************************************************/
82
83 static VOID
84 PrintString(char* fmt,...)
85 {
86 char buffer[512];
87 va_list ap;
88 UNICODE_STRING UnicodeString;
89 ANSI_STRING AnsiString;
90
91 va_start(ap, fmt);
92 vsprintf(buffer, fmt, ap);
93 va_end(ap);
94
95 RtlInitAnsiString(&AnsiString, buffer);
96 RtlAnsiStringToUnicodeString(&UnicodeString,
97 &AnsiString,
98 TRUE);
99 NtDisplayString(&UnicodeString);
100 RtlFreeUnicodeString(&UnicodeString);
101 }
102
103
104 static VOID
105 DrawBox(
106 IN SHORT xLeft,
107 IN SHORT yTop,
108 IN SHORT Width,
109 IN SHORT Height)
110 {
111 COORD coPos;
112 DWORD Written;
113
114 /* draw upper left corner */
115 coPos.X = xLeft;
116 coPos.Y = yTop;
117 FillConsoleOutputCharacterA(
118 StdOutput,
119 0xDA, // '+',
120 1,
121 coPos,
122 &Written);
123
124 /* draw upper edge */
125 coPos.X = xLeft + 1;
126 coPos.Y = yTop;
127 FillConsoleOutputCharacterA(
128 StdOutput,
129 0xC4, // '-',
130 Width - 2,
131 coPos,
132 &Written);
133
134 /* draw upper right corner */
135 coPos.X = xLeft + Width - 1;
136 coPos.Y = yTop;
137 FillConsoleOutputCharacterA(
138 StdOutput,
139 0xBF, // '+',
140 1,
141 coPos,
142 &Written);
143
144 /* Draw right edge, inner space and left edge */
145 for (coPos.Y = yTop + 1; coPos.Y < yTop + Height - 1; coPos.Y++)
146 {
147 coPos.X = xLeft;
148 FillConsoleOutputCharacterA(
149 StdOutput,
150 0xB3, // '|',
151 1,
152 coPos,
153 &Written);
154
155 coPos.X = xLeft + 1;
156 FillConsoleOutputCharacterA(
157 StdOutput,
158 ' ',
159 Width - 2,
160 coPos,
161 &Written);
162
163 coPos.X = xLeft + Width - 1;
164 FillConsoleOutputCharacterA(
165 StdOutput,
166 0xB3, // '|',
167 1,
168 coPos,
169 &Written);
170 }
171
172 /* draw lower left corner */
173 coPos.X = xLeft;
174 coPos.Y = yTop + Height - 1;
175 FillConsoleOutputCharacterA(
176 StdOutput,
177 0xC0, // '+',
178 1,
179 coPos,
180 &Written);
181
182 /* draw lower edge */
183 coPos.X = xLeft + 1;
184 coPos.Y = yTop + Height - 1;
185 FillConsoleOutputCharacterA(
186 StdOutput,
187 0xC4, // '-',
188 Width - 2,
189 coPos,
190 &Written);
191
192 /* draw lower right corner */
193 coPos.X = xLeft + Width - 1;
194 coPos.Y = yTop + Height - 1;
195 FillConsoleOutputCharacterA(
196 StdOutput,
197 0xD9, // '+',
198 1,
199 coPos,
200 &Written);
201 }
202
203 VOID
204 PopupError(PCHAR Text,
205 PCHAR Status,
206 PINPUT_RECORD Ir,
207 ULONG WaitEvent)
208 {
209 SHORT yTop;
210 SHORT xLeft;
211 COORD coPos;
212 DWORD Written;
213 ULONG Length;
214 ULONG MaxLength;
215 ULONG Lines;
216 PCHAR p;
217 PCHAR pnext;
218 BOOLEAN LastLine;
219 SHORT Width;
220 SHORT Height;
221
222 /* Count text lines and longest line */
223 MaxLength = 0;
224 Lines = 0;
225 pnext = Text;
226 while (TRUE)
227 {
228 p = strchr(pnext, '\n');
229 if (p == NULL)
230 {
231 Length = strlen(pnext);
232 LastLine = TRUE;
233 }
234 else
235 {
236 Length = (ULONG)(p - pnext);
237 LastLine = FALSE;
238 }
239
240 Lines++;
241 if (Length > MaxLength)
242 MaxLength = Length;
243
244 if (LastLine == TRUE)
245 break;
246
247 pnext = p + 1;
248 }
249
250 /* Check length of status line */
251 if (Status != NULL)
252 {
253 Length = strlen(Status);
254 if (Length > MaxLength)
255 MaxLength = Length;
256 }
257
258 Width = MaxLength + 4;
259 Height = Lines + 2;
260 if (Status != NULL)
261 Height += 2;
262
263 yTop = (yScreen - Height) / 2;
264 xLeft = (xScreen - Width) / 2;
265
266
267 /* Set screen attributes */
268 coPos.X = xLeft;
269 for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++)
270 {
271 FillConsoleOutputAttribute(StdOutput,
272 FOREGROUND_RED | BACKGROUND_WHITE,
273 Width,
274 coPos,
275 &Written);
276 }
277
278 DrawBox(xLeft, yTop, Width, Height);
279
280 /* Print message text */
281 coPos.Y = yTop + 1;
282 pnext = Text;
283 while (TRUE)
284 {
285 p = strchr(pnext, '\n');
286 if (p == NULL)
287 {
288 Length = strlen(pnext);
289 LastLine = TRUE;
290 }
291 else
292 {
293 Length = (ULONG)(p - pnext);
294 LastLine = FALSE;
295 }
296
297 if (Length != 0)
298 {
299 coPos.X = xLeft + 2;
300 WriteConsoleOutputCharacterA(StdOutput,
301 pnext,
302 Length,
303 coPos,
304 &Written);
305 }
306
307 if (LastLine == TRUE)
308 break;
309
310 coPos.Y++;
311 pnext = p + 1;
312 }
313
314 /* Print separator line and status text */
315 if (Status != NULL)
316 {
317 coPos.Y = yTop + Height - 3;
318 coPos.X = xLeft;
319 FillConsoleOutputCharacterA(StdOutput,
320 0xC3, // '+',
321 1,
322 coPos,
323 &Written);
324
325 coPos.X = xLeft + 1;
326 FillConsoleOutputCharacterA(StdOutput,
327 0xC4, // '-',
328 Width - 2,
329 coPos,
330 &Written);
331
332 coPos.X = xLeft + Width - 1;
333 FillConsoleOutputCharacterA(StdOutput,
334 0xB4, // '+',
335 1,
336 coPos,
337 &Written);
338
339 coPos.Y++;
340 coPos.X = xLeft + 2;
341 WriteConsoleOutputCharacterA(StdOutput,
342 Status,
343 min(strlen(Status), (SIZE_T)Width - 4),
344 coPos,
345 &Written);
346 }
347
348 if (WaitEvent == POPUP_WAIT_NONE)
349 return;
350
351 while (TRUE)
352 {
353 CONSOLE_ConInKey(Ir);
354
355 if (WaitEvent == POPUP_WAIT_ANY_KEY
356 || Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)
357 {
358 return;
359 }
360 }
361 }
362
363
364 /*
365 * Confirm quit setup
366 * RETURNS
367 * TRUE: Quit setup.
368 * FALSE: Don't quit setup.
369 */
370 static BOOL
371 ConfirmQuit(PINPUT_RECORD Ir)
372 {
373 BOOL Result = FALSE;
374 MUIDisplayError(ERROR_NOT_INSTALLED, NULL, POPUP_WAIT_NONE);
375
376 while(TRUE)
377 {
378 CONSOLE_ConInKey(Ir);
379
380 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
381 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
382 {
383 Result = TRUE;
384 break;
385 }
386 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
387 {
388 Result = FALSE;
389 break;
390 }
391 }
392
393 return Result;
394 }
395
396
397 VOID
398 CheckUnattendedSetup(VOID)
399 {
400 WCHAR UnattendInfPath[MAX_PATH];
401 INFCONTEXT Context;
402 HINF UnattendInf;
403 UINT ErrorLine;
404 INT IntValue;
405 PWCHAR Value;
406
407 if (DoesFileExist(SourcePath.Buffer, L"unattend.inf") == FALSE)
408 {
409 DPRINT("Does not exist: %S\\%S\n", SourcePath.Buffer, L"unattend.inf");
410 return;
411 }
412
413 wcscpy(UnattendInfPath, SourcePath.Buffer);
414 wcscat(UnattendInfPath, L"\\unattend.inf");
415
416 /* Load 'unattend.inf' from install media. */
417 UnattendInf = SetupOpenInfFileW(UnattendInfPath,
418 NULL,
419 INF_STYLE_WIN4,
420 &ErrorLine);
421 if (UnattendInf == INVALID_HANDLE_VALUE)
422 {
423 DPRINT("SetupOpenInfFileW() failed\n");
424 return;
425 }
426
427 /* Open 'Unattend' section */
428 if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"Signature", &Context))
429 {
430 DPRINT("SetupFindFirstLineW() failed for section 'Unattend'\n");
431 SetupCloseInfFile(UnattendInf);
432 return;
433 }
434
435 /* Get pointer 'Signature' key */
436 if (!INF_GetData(&Context, NULL, &Value))
437 {
438 DPRINT("INF_GetData() failed for key 'Signature'\n");
439 SetupCloseInfFile(UnattendInf);
440 return;
441 }
442
443 /* Check 'Signature' string */
444 if (_wcsicmp(Value, L"$ReactOS$") != 0)
445 {
446 DPRINT("Signature not $ReactOS$\n");
447 SetupCloseInfFile(UnattendInf);
448 return;
449 }
450
451 /* Check if Unattend setup is enabled */
452 if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"UnattendSetupEnabled", &Context))
453 {
454 DPRINT("Can't find key 'UnattendSetupEnabled'\n");
455 SetupCloseInfFile(UnattendInf);
456 return;
457 }
458 if (!INF_GetData(&Context, NULL, &Value))
459 {
460 DPRINT("Can't read key 'UnattendSetupEnabled'\n");
461 SetupCloseInfFile(UnattendInf);
462 return;
463 }
464 if (_wcsicmp(Value, L"yes") != 0)
465 {
466 DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n");
467 SetupCloseInfFile(UnattendInf);
468 return;
469 }
470
471 /* Search for 'DestinationDiskNumber' in the 'Unattend' section */
472 if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"DestinationDiskNumber", &Context))
473 {
474 DPRINT("SetupFindFirstLine() failed for key 'DestinationDiskNumber'\n");
475 SetupCloseInfFile(UnattendInf);
476 return;
477 }
478 if (!SetupGetIntField(&Context, 1, &IntValue))
479 {
480 DPRINT("SetupGetIntField() failed for key 'DestinationDiskNumber'\n");
481 SetupCloseInfFile(UnattendInf);
482 return;
483 }
484 UnattendDestinationDiskNumber = (LONG)IntValue;
485
486 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
487 if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"DestinationPartitionNumber", &Context))
488 {
489 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
490 SetupCloseInfFile(UnattendInf);
491 return;
492 }
493 if (!SetupGetIntField(&Context, 1, &IntValue))
494 {
495 DPRINT("SetupGetIntField() failed for key 'DestinationPartitionNumber'\n");
496 SetupCloseInfFile(UnattendInf);
497 return;
498 }
499 UnattendDestinationPartitionNumber = IntValue;
500
501 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
502 if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"DestinationPartitionNumber", &Context))
503 {
504 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
505 SetupCloseInfFile(UnattendInf);
506 return;
507 }
508
509 /* Get pointer 'InstallationDirectory' key */
510 if (!INF_GetData(&Context, NULL, &Value))
511 {
512 DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n");
513 SetupCloseInfFile(UnattendInf);
514 return;
515 }
516 wcscpy(UnattendInstallationDirectory, Value);
517
518 IsUnattendedSetup = TRUE;
519
520 /* Search for 'MBRInstallType' in the 'Unattend' section */
521 if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"MBRInstallType", &Context))
522 {
523 if (SetupGetIntField(&Context, 1, &IntValue))
524 {
525 UnattendMBRInstallType = IntValue;
526 }
527 }
528 /* Search for 'FormatPartition' in the 'Unattend' section */
529 if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"FormatPartition", &Context))
530 {
531 if (SetupGetIntField(&Context, 1, &IntValue))
532 {
533 UnattendFormatPartition = IntValue;
534 }
535 }
536 if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"AutoPartition", &Context))
537 {
538 if (SetupGetIntField(&Context, 1, &IntValue))
539 {
540 AutoPartition = IntValue;
541 }
542 }
543 SetupCloseInfFile(UnattendInf);
544
545 DPRINT("Running unattended setup\n");
546 }
547
548 void
549 UpdateKBLayout()
550 {
551 PLIST_ENTRY Entry;
552 PGENERIC_LIST_ENTRY ListEntry;
553 WCHAR szNewLayout[20];
554
555 MUIDefaultKeyboardLayout(szNewLayout);
556
557 if (LayoutList == NULL)
558 {
559 LayoutList = CreateKeyboardLayoutList(SetupInf, DefaultKBLayout);
560 }
561 Entry = LayoutList->ListHead.Flink;
562 while (Entry != &LayoutList->ListHead)
563 {
564 ListEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry);
565 if (!wcscmp(szNewLayout, ListEntry->UserData))
566 {
567 LayoutList->CurrentEntry = ListEntry;
568 break;
569 }
570 Entry = Entry->Flink;
571 }
572 }
573
574 static PAGE_NUMBER
575 LanguagePage(PINPUT_RECORD Ir)
576 {
577 /* Initialize the computer settings list */
578 if (LanguageList == NULL)
579 {
580 LanguageList = CreateLanguageList(SetupInf, DefaultLanguage);
581 if (LanguageList == NULL)
582 {
583 PopupError("Setup failed to initialize available translations", NULL, NULL, POPUP_WAIT_NONE);
584 return INTRO_PAGE;
585 }
586 }
587
588 DrawGenericList(LanguageList,
589 2,
590 18,
591 xScreen - 3,
592 yScreen - 3);
593
594 MUIDisplayPage(LANGUAGE_PAGE);
595
596 while(TRUE)
597 {
598 CONSOLE_ConInKey(Ir);
599
600 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
601 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
602 {
603 #if 0 //Dynamically update user interface
604 SelectedLanguageId = (PWCHAR)LanguageList->CurrentEntry->UserData;
605 MUIDisplayPage(LANGUAGE_PAGE);
606 #endif
607 ScrollDownGenericList (LanguageList);
608 }
609 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
610 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
611 {
612 #if 0
613 SelectedLanguageId = (PWCHAR)LanguageList->CurrentEntry->UserData;
614 MUIDisplayPage(LANGUAGE_PAGE);
615 #endif
616 ScrollUpGenericList (LanguageList);
617 }
618 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
619 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
620 {
621 if (ConfirmQuit(Ir) == TRUE)
622 return QUIT_PAGE;
623 }
624 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
625 {
626 SelectedLanguageId = (PWCHAR)LanguageList->CurrentEntry->UserData;
627 if (wcscmp(SelectedLanguageId, DefaultLanguage))
628 {
629 UpdateKBLayout();
630 }
631 return INTRO_PAGE;
632 }
633 }
634
635 return INTRO_PAGE;
636 }
637
638
639 /*
640 * Start page
641 * RETURNS
642 * Number of the next page.
643 */
644 static PAGE_NUMBER
645 SetupStartPage(PINPUT_RECORD Ir)
646 {
647 SYSTEM_DEVICE_INFORMATION Sdi;
648 NTSTATUS Status;
649 WCHAR FileNameBuffer[MAX_PATH];
650 INFCONTEXT Context;
651 PWCHAR Value;
652 UINT ErrorLine;
653 SIZE_T ReturnSize;
654
655 CONSOLE_SetStatusText(" Please wait...");
656
657
658 /* Check whether a harddisk is available */
659 Status = NtQuerySystemInformation (SystemDeviceInformation,
660 &Sdi,
661 sizeof(SYSTEM_DEVICE_INFORMATION),
662 &ReturnSize);
663 if (!NT_SUCCESS (Status))
664 {
665 CONSOLE_PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status);
666 MUIDisplayError(ERROR_DRIVE_INFORMATION, Ir, POPUP_WAIT_ENTER);
667 return QUIT_PAGE;
668 }
669
670 if (Sdi.NumberOfDisks == 0)
671 {
672 MUIDisplayError(ERROR_NO_HDD, Ir, POPUP_WAIT_ENTER);
673 return QUIT_PAGE;
674 }
675
676 /* Get the source path and source root path */
677 Status = GetSourcePaths(&SourcePath,
678 &SourceRootPath,
679 &SourceRootDir);
680 if (!NT_SUCCESS(Status))
681 {
682 CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status);
683 MUIDisplayError(ERROR_NO_SOURCE_DRIVE, Ir, POPUP_WAIT_ENTER);
684 return QUIT_PAGE;
685 }
686 #if 0
687 else
688 {
689 CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath);
690 CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath);
691 CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir);
692 }
693 #endif
694
695 /* Load txtsetup.sif from install media. */
696 wcscpy(FileNameBuffer, SourcePath.Buffer);
697 wcscat(FileNameBuffer, L"\\txtsetup.sif");
698
699 SetupInf = SetupOpenInfFileW(FileNameBuffer,
700 NULL,
701 INF_STYLE_WIN4,
702 &ErrorLine);
703 if (SetupInf == INVALID_HANDLE_VALUE)
704 {
705 MUIDisplayError(ERROR_LOAD_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER);
706 return QUIT_PAGE;
707 }
708
709 /* Open 'Version' section */
710 if (!SetupFindFirstLineW (SetupInf, L"Version", L"Signature", &Context))
711 {
712 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER);
713 return QUIT_PAGE;
714 }
715
716
717 /* Get pointer 'Signature' key */
718 if (!INF_GetData (&Context, NULL, &Value))
719 {
720 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER);
721 return QUIT_PAGE;
722 }
723
724 /* Check 'Signature' string */
725 if (_wcsicmp(Value, L"$ReactOS$") != 0)
726 {
727 MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER);
728 return QUIT_PAGE;
729 }
730
731 /* Start PnP thread */
732 if (hPnpThread != INVALID_HANDLE_VALUE)
733 {
734 //HACK: Commented out till the problem with CM is solved
735 //NtResumeThread(hPnpThread, NULL);
736 hPnpThread = INVALID_HANDLE_VALUE;
737 }
738
739 CheckUnattendedSetup();
740
741 if (IsUnattendedSetup)
742 {
743 //TODO
744 //read options from inf
745 ComputerList = CreateComputerTypeList(SetupInf);
746 DisplayList = CreateDisplayDriverList(SetupInf);
747 KeyboardList = CreateKeyboardDriverList(SetupInf);
748 LayoutList = CreateKeyboardLayoutList(SetupInf, DefaultKBLayout);
749 LanguageList = CreateLanguageList(SetupInf, DefaultLanguage);
750
751 return INSTALL_INTRO_PAGE;
752 }
753
754 return LANGUAGE_PAGE;
755 }
756
757
758 /*
759 * First setup page
760 * RETURNS
761 * Next page number.
762 */
763 static PAGE_NUMBER
764 IntroPage(PINPUT_RECORD Ir)
765 {
766 MUIDisplayPage(START_PAGE);
767
768 while (TRUE)
769 {
770 CONSOLE_ConInKey(Ir);
771
772 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
773 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
774 {
775 if (ConfirmQuit(Ir) == TRUE)
776 return QUIT_PAGE;
777 break;
778 }
779 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
780 {
781 return INSTALL_INTRO_PAGE;
782 break;
783 }
784 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */
785 {
786 return REPAIR_INTRO_PAGE;
787 break;
788 }
789 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'L') /* R */
790 {
791 return LICENSE_PAGE;
792 break;
793 }
794 }
795
796 return INTRO_PAGE;
797 }
798
799 /*
800 * License Page
801 * RETURNS
802 * Back to main setup page.
803 */
804 static PAGE_NUMBER
805 LicensePage(PINPUT_RECORD Ir)
806 {
807 MUIDisplayPage(LICENSE_PAGE);
808
809 while (TRUE)
810 {
811 CONSOLE_ConInKey(Ir);
812
813 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
814 {
815 return INTRO_PAGE;
816 break;
817 }
818 }
819
820 return LICENSE_PAGE;
821 }
822
823 static PAGE_NUMBER
824 RepairIntroPage(PINPUT_RECORD Ir)
825 {
826 MUIDisplayPage(REPAIR_INTRO_PAGE);
827
828 while(TRUE)
829 {
830 CONSOLE_ConInKey(Ir);
831
832 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
833 {
834 return REBOOT_PAGE;
835 }
836 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'U') /* U */
837 {
838 RepairUpdateFlag = TRUE;
839 return INSTALL_INTRO_PAGE;
840 }
841 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */
842 {
843 return INTRO_PAGE;
844 }
845 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
846 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
847 {
848 return INTRO_PAGE;
849 }
850 }
851
852 return REPAIR_INTRO_PAGE;
853 }
854
855
856 static PAGE_NUMBER
857 InstallIntroPage(PINPUT_RECORD Ir)
858 {
859 MUIDisplayPage(INSTALL_INTRO_PAGE);
860
861 if (RepairUpdateFlag)
862 {
863 //return SELECT_PARTITION_PAGE;
864 return DEVICE_SETTINGS_PAGE;
865 }
866
867 if (IsUnattendedSetup)
868 {
869 return SELECT_PARTITION_PAGE;
870 }
871
872 while(TRUE)
873 {
874 CONSOLE_ConInKey(Ir);
875
876 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
877 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
878 {
879 if (ConfirmQuit(Ir) == TRUE)
880 return QUIT_PAGE;
881 break;
882 }
883 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
884 {
885 return DEVICE_SETTINGS_PAGE;
886 // return SCSI_CONTROLLER_PAGE;
887 }
888 }
889
890 return INSTALL_INTRO_PAGE;
891 }
892
893
894 #if 0
895 static PAGE_NUMBER
896 ScsiControllerPage(PINPUT_RECORD Ir)
897 {
898 SetTextXY(6, 8, "Setup detected the following mass storage devices:");
899
900 /* FIXME: print loaded mass storage driver descriptions */
901 #if 0
902 SetTextXY(8, 10, "TEST device");
903 #endif
904
905
906 SetStatusText(" ENTER = Continue F3 = Quit");
907
908 while(TRUE)
909 {
910 ConInKey(Ir);
911
912 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
913 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
914 {
915 if (ConfirmQuit(Ir) == TRUE)
916 return QUIT_PAGE;
917 break;
918 }
919 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
920 {
921 return DEVICE_SETTINGS_PAGE;
922 }
923 }
924
925 return SCSI_CONTROLLER_PAGE;
926 }
927 #endif
928
929
930 static PAGE_NUMBER
931 DeviceSettingsPage(PINPUT_RECORD Ir)
932 {
933 static ULONG Line = 16;
934 MUIDisplayPage(DEVICE_SETTINGS_PAGE);
935
936 /* Initialize the computer settings list */
937 if (ComputerList == NULL)
938 {
939 ComputerList = CreateComputerTypeList(SetupInf);
940 if (ComputerList == NULL)
941 {
942 MUIDisplayError(ERROR_LOAD_COMPUTER, Ir, POPUP_WAIT_ENTER);
943 return QUIT_PAGE;
944 }
945 }
946
947 /* Initialize the display settings list */
948 if (DisplayList == NULL)
949 {
950 DisplayList = CreateDisplayDriverList(SetupInf);
951 if (DisplayList == NULL)
952 {
953 MUIDisplayError(ERROR_LOAD_DISPLAY, Ir, POPUP_WAIT_ENTER);
954 return QUIT_PAGE;
955 }
956 }
957
958 /* Initialize the keyboard settings list */
959 if (KeyboardList == NULL)
960 {
961 KeyboardList = CreateKeyboardDriverList(SetupInf);
962 if (KeyboardList == NULL)
963 {
964 MUIDisplayError(ERROR_LOAD_KEYBOARD, Ir, POPUP_WAIT_ENTER);
965 return QUIT_PAGE;
966 }
967 }
968
969 /* Initialize the keyboard layout list */
970 if (LayoutList == NULL)
971 {
972 LayoutList = CreateKeyboardLayoutList(SetupInf, DefaultKBLayout);
973 if (LayoutList == NULL)
974 {
975 /* FIXME: report error */
976 MUIDisplayError(ERROR_LOAD_KBLAYOUT, Ir, POPUP_WAIT_ENTER);
977 return QUIT_PAGE;
978 }
979 }
980
981 MUIDisplayPage(DEVICE_SETTINGS_PAGE);
982
983
984 CONSOLE_SetTextXY(25, 11, GetGenericListEntry(ComputerList)->Text);
985 CONSOLE_SetTextXY(25, 12, GetGenericListEntry(DisplayList)->Text);
986 CONSOLE_SetTextXY(25, 13, GetGenericListEntry(KeyboardList)->Text);
987 CONSOLE_SetTextXY(25, 14, GetGenericListEntry(LayoutList)->Text);
988
989 CONSOLE_InvertTextXY (24, Line, 48, 1);
990
991 if (RepairUpdateFlag)
992 {
993 return SELECT_PARTITION_PAGE;
994 }
995
996 while(TRUE)
997 {
998 CONSOLE_ConInKey(Ir);
999
1000 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1001 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
1002 {
1003 CONSOLE_NormalTextXY (24, Line, 48, 1);
1004 if (Line == 14)
1005 Line = 16;
1006 else if (Line == 16)
1007 Line = 11;
1008 else
1009 Line++;
1010 CONSOLE_InvertTextXY (24, Line, 48, 1);
1011 }
1012 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1013 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
1014 {
1015 CONSOLE_NormalTextXY (24, Line, 48, 1);
1016 if (Line == 11)
1017 Line = 16;
1018 else if (Line == 16)
1019 Line = 14;
1020 else
1021 Line--;
1022 CONSOLE_InvertTextXY (24, Line, 48, 1);
1023 }
1024 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1025 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1026 {
1027 if (ConfirmQuit(Ir) == TRUE)
1028 return QUIT_PAGE;
1029 break;
1030 }
1031 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1032 {
1033 if (Line == 11)
1034 return COMPUTER_SETTINGS_PAGE;
1035 else if (Line == 12)
1036 return DISPLAY_SETTINGS_PAGE;
1037 else if (Line == 13)
1038 return KEYBOARD_SETTINGS_PAGE;
1039 else if (Line == 14)
1040 return LAYOUT_SETTINGS_PAGE;
1041 else if (Line == 16)
1042 return SELECT_PARTITION_PAGE;
1043 }
1044 }
1045
1046 return DEVICE_SETTINGS_PAGE;
1047 }
1048
1049
1050 static PAGE_NUMBER
1051 ComputerSettingsPage(PINPUT_RECORD Ir)
1052 {
1053 MUIDisplayPage(COMPUTER_SETTINGS_PAGE);
1054
1055 DrawGenericList(ComputerList,
1056 2,
1057 18,
1058 xScreen - 3,
1059 yScreen - 3);
1060
1061 SaveGenericListState(ComputerList);
1062
1063 while(TRUE)
1064 {
1065 CONSOLE_ConInKey(Ir);
1066
1067 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1068 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
1069 {
1070 ScrollDownGenericList (ComputerList);
1071 }
1072 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1073 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
1074 {
1075 ScrollUpGenericList (ComputerList);
1076 }
1077 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1078 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1079 {
1080 if (ConfirmQuit(Ir) == TRUE)
1081 return QUIT_PAGE;
1082 break;
1083 }
1084 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1085 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
1086 {
1087 RestoreGenericListState(ComputerList);
1088 return DEVICE_SETTINGS_PAGE;
1089 }
1090 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1091 {
1092 return DEVICE_SETTINGS_PAGE;
1093 }
1094 }
1095
1096 return COMPUTER_SETTINGS_PAGE;
1097 }
1098
1099
1100 static PAGE_NUMBER
1101 DisplaySettingsPage(PINPUT_RECORD Ir)
1102 {
1103 MUIDisplayPage(DISPLAY_SETTINGS_PAGE);
1104
1105 DrawGenericList(DisplayList,
1106 2,
1107 18,
1108 xScreen - 3,
1109 yScreen - 3);
1110
1111 SaveGenericListState(DisplayList);
1112
1113 while(TRUE)
1114 {
1115 CONSOLE_ConInKey(Ir);
1116
1117 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1118 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
1119 {
1120 ScrollDownGenericList (DisplayList);
1121 }
1122 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1123 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
1124 {
1125 ScrollUpGenericList (DisplayList);
1126 }
1127 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1128 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1129 {
1130 if (ConfirmQuit(Ir) == TRUE)
1131 {
1132 return QUIT_PAGE;
1133 }
1134 break;
1135 }
1136 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1137 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
1138 {
1139 RestoreGenericListState(DisplayList);
1140 return DEVICE_SETTINGS_PAGE;
1141 }
1142 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1143 {
1144 return DEVICE_SETTINGS_PAGE;
1145 }
1146 }
1147
1148 return DISPLAY_SETTINGS_PAGE;
1149 }
1150
1151
1152 static PAGE_NUMBER
1153 KeyboardSettingsPage(PINPUT_RECORD Ir)
1154 {
1155 MUIDisplayPage(KEYBOARD_SETTINGS_PAGE);
1156
1157 DrawGenericList(KeyboardList,
1158 2,
1159 18,
1160 xScreen - 3,
1161 yScreen - 3);
1162
1163
1164
1165 SaveGenericListState(KeyboardList);
1166
1167 while(TRUE)
1168 {
1169 CONSOLE_ConInKey(Ir);
1170
1171 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1172 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
1173 {
1174 ScrollDownGenericList (KeyboardList);
1175 }
1176 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1177 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
1178 {
1179 ScrollUpGenericList (KeyboardList);
1180 }
1181 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1182 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1183 {
1184 if (ConfirmQuit(Ir) == TRUE)
1185 return QUIT_PAGE;
1186 break;
1187 }
1188 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1189 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
1190 {
1191 RestoreGenericListState(KeyboardList);
1192 return DEVICE_SETTINGS_PAGE;
1193 }
1194 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1195 {
1196 return DEVICE_SETTINGS_PAGE;
1197 }
1198 }
1199
1200 return DISPLAY_SETTINGS_PAGE;
1201 }
1202
1203
1204 static PAGE_NUMBER
1205 LayoutSettingsPage(PINPUT_RECORD Ir)
1206 {
1207 MUIDisplayPage(LAYOUT_SETTINGS_PAGE);
1208
1209 DrawGenericList(LayoutList,
1210 2,
1211 15,
1212 xScreen - 3,
1213 yScreen - 3);
1214
1215 SaveGenericListState(LayoutList);
1216
1217 while(TRUE)
1218 {
1219 CONSOLE_ConInKey(Ir);
1220
1221 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1222 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
1223 {
1224 ScrollDownGenericList (LayoutList);
1225 }
1226 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1227 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
1228 {
1229 ScrollUpGenericList (LayoutList);
1230 }
1231 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1232 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1233 {
1234 if (ConfirmQuit(Ir) == TRUE)
1235 return QUIT_PAGE;
1236 break;
1237 }
1238 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1239 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
1240 {
1241 RestoreGenericListState(LayoutList);
1242 return DEVICE_SETTINGS_PAGE;
1243 }
1244 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1245 {
1246 return DEVICE_SETTINGS_PAGE;
1247 }
1248 }
1249
1250 return DISPLAY_SETTINGS_PAGE;
1251 }
1252
1253
1254 static PAGE_NUMBER
1255 SelectPartitionPage(PINPUT_RECORD Ir)
1256 {
1257 MUIDisplayPage(SELECT_PARTITION_PAGE);
1258
1259 if (PartitionList == NULL)
1260 {
1261 PartitionList = CreatePartitionList (2,
1262 19,
1263 xScreen - 3,
1264 yScreen - 3);
1265 if (PartitionList == NULL)
1266 {
1267 /* FIXME: show an error dialog */
1268 return QUIT_PAGE;
1269 }
1270 }
1271
1272 CheckActiveBootPartition (PartitionList);
1273
1274 DrawPartitionList (PartitionList);
1275
1276 /* Warn about partitions created by Linux Fdisk */
1277 if (WarnLinuxPartitions == TRUE &&
1278 CheckForLinuxFdiskPartitions (PartitionList) == TRUE)
1279 {
1280 MUIDisplayError(ERROR_WARN_PARTITION, NULL, POPUP_WAIT_NONE);
1281 while (TRUE)
1282 {
1283 CONSOLE_ConInKey (Ir);
1284
1285 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1286 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1287 {
1288 return QUIT_PAGE;
1289 }
1290 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
1291 {
1292 WarnLinuxPartitions = FALSE;
1293 return SELECT_PARTITION_PAGE;
1294 }
1295 }
1296 }
1297
1298 if (IsUnattendedSetup)
1299 {
1300 if (!SelectPartition(PartitionList, UnattendDestinationDiskNumber, UnattendDestinationPartitionNumber))
1301 {
1302 if (AutoPartition)
1303 {
1304 PPARTENTRY PartEntry = PartEntry = PartitionList->CurrentPartition;
1305 ULONG MaxSize = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20; /* in MBytes (rounded) */
1306 CreateNewPartition (PartitionList,
1307 MaxSize,
1308 TRUE);
1309 return (SELECT_FILE_SYSTEM_PAGE);
1310 }
1311 }
1312 else
1313 {
1314 return(SELECT_FILE_SYSTEM_PAGE);
1315 }
1316 }
1317
1318 while(TRUE)
1319 {
1320 /* Update status text */
1321 if (PartitionList->CurrentPartition == NULL ||
1322 PartitionList->CurrentPartition->Unpartitioned == TRUE)
1323 {
1324 CONSOLE_SetStatusText (" ENTER = Install C = Create Partition F3 = Quit");
1325 }
1326 else
1327 {
1328 CONSOLE_SetStatusText (" ENTER = Install D = Delete Partition F3 = Quit");
1329 }
1330
1331 CONSOLE_ConInKey(Ir);
1332
1333 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1334 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1335 {
1336 if (ConfirmQuit(Ir) == TRUE)
1337 {
1338 DestroyPartitionList (PartitionList);
1339 PartitionList = NULL;
1340 return QUIT_PAGE;
1341 }
1342 break;
1343 }
1344 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1345 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
1346 {
1347 ScrollDownPartitionList (PartitionList);
1348 }
1349 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1350 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
1351 {
1352 ScrollUpPartitionList (PartitionList);
1353 }
1354 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
1355 {
1356 if (PartitionList->CurrentPartition == NULL ||
1357 PartitionList->CurrentPartition->Unpartitioned == TRUE)
1358 {
1359 CreateNewPartition (PartitionList,
1360 0ULL,
1361 TRUE);
1362 }
1363
1364 return SELECT_FILE_SYSTEM_PAGE;
1365 }
1366 else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'C') /* C */
1367 {
1368 if (PartitionList->CurrentPartition->Unpartitioned == FALSE)
1369 {
1370 MUIDisplayError(ERROR_NEW_PARTITION, Ir, POPUP_WAIT_ANY_KEY);
1371 return SELECT_PARTITION_PAGE;
1372 }
1373
1374 return CREATE_PARTITION_PAGE;
1375 }
1376 else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'D') /* D */
1377 {
1378 if (PartitionList->CurrentPartition->Unpartitioned == TRUE)
1379 {
1380 MUIDisplayError(ERROR_DELETE_SPACE, Ir, POPUP_WAIT_ANY_KEY);
1381 return SELECT_PARTITION_PAGE;
1382 }
1383
1384 return DELETE_PARTITION_PAGE;
1385 }
1386 }
1387
1388 return SELECT_PARTITION_PAGE;
1389 }
1390
1391
1392 static VOID
1393 DrawInputField(ULONG FieldLength,
1394 SHORT Left,
1395 SHORT Top,
1396 PCHAR FieldContent)
1397 {
1398 CHAR buf[100];
1399 COORD coPos;
1400 DWORD Written;
1401
1402 coPos.X = Left;
1403 coPos.Y = Top;
1404 memset(buf, '_', sizeof(buf));
1405 buf[FieldLength - strlen(FieldContent)] = 0;
1406 strcat(buf, FieldContent);
1407
1408 WriteConsoleOutputCharacterA (StdOutput,
1409 buf,
1410 strlen (buf),
1411 coPos,
1412 &Written);
1413 }
1414
1415
1416 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1417
1418 static VOID
1419 ShowPartitionSizeInputBox(SHORT Left,
1420 SHORT Top,
1421 SHORT Right,
1422 SHORT Bottom,
1423 ULONG MaxSize,
1424 PCHAR InputBuffer,
1425 PBOOLEAN Quit,
1426 PBOOLEAN Cancel)
1427 {
1428 INPUT_RECORD Ir;
1429 COORD coPos;
1430 DWORD Written;
1431 CHAR Buffer[100];
1432 ULONG Index;
1433 CHAR ch;
1434 SHORT iLeft;
1435 SHORT iTop;
1436
1437 if (Quit != NULL)
1438 *Quit = FALSE;
1439
1440 if (Cancel != NULL)
1441 *Cancel = FALSE;
1442
1443 DrawBox(Left, Top, Right - Left + 1, Bottom - Top + 1);
1444
1445 /* Print message */
1446 coPos.X = Left + 2;
1447 coPos.Y = Top + 2;
1448 strcpy (Buffer, "Size of new partition:");
1449 iLeft = coPos.X + strlen (Buffer) + 1;
1450 iTop = coPos.Y;
1451 WriteConsoleOutputCharacterA (StdOutput,
1452 Buffer,
1453 strlen (Buffer),
1454 coPos,
1455 &Written);
1456
1457 sprintf (Buffer, "MB (max. %lu MB)", MaxSize);
1458 coPos.X = iLeft + PARTITION_SIZE_INPUT_FIELD_LENGTH + 1;
1459 coPos.Y = iTop;
1460 WriteConsoleOutputCharacterA (StdOutput,
1461 Buffer,
1462 strlen (Buffer),
1463 coPos,
1464 &Written);
1465
1466 sprintf(Buffer, "%lu", MaxSize);
1467 Index = strlen(Buffer);
1468 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH,
1469 iLeft,
1470 iTop,
1471 Buffer);
1472
1473 while (TRUE)
1474 {
1475 CONSOLE_ConInKey (&Ir);
1476
1477 if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1478 (Ir.Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1479 {
1480 if (Quit != NULL)
1481 *Quit = TRUE;
1482 Buffer[0] = 0;
1483 break;
1484 }
1485 else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
1486 {
1487 break;
1488 }
1489 else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESCAPE */
1490 {
1491 if (Cancel != NULL)
1492 *Cancel = TRUE;
1493 Buffer[0] = 0;
1494 break;
1495 }
1496 else if ((Ir.Event.KeyEvent.wVirtualKeyCode == VK_BACK) && /* BACKSPACE */
1497 (Index > 0))
1498 {
1499 Index--;
1500 Buffer[Index] = 0;
1501 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH,
1502 iLeft,
1503 iTop,
1504 Buffer);
1505 }
1506 else if ((Ir.Event.KeyEvent.uChar.AsciiChar != 0x00) &&
1507 (Index < PARTITION_SIZE_INPUT_FIELD_LENGTH))
1508 {
1509 ch = Ir.Event.KeyEvent.uChar.AsciiChar;
1510 if ((ch >= '0') && (ch <= '9'))
1511 {
1512 Buffer[Index] = ch;
1513 Index++;
1514 Buffer[Index] = 0;
1515 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH,
1516 iLeft,
1517 iTop,
1518 Buffer);
1519 }
1520 }
1521 }
1522
1523 strcpy (InputBuffer,
1524 Buffer);
1525 }
1526
1527
1528 static PAGE_NUMBER
1529 CreatePartitionPage (PINPUT_RECORD Ir)
1530 {
1531 PDISKENTRY DiskEntry;
1532 PPARTENTRY PartEntry;
1533 BOOLEAN Quit;
1534 BOOLEAN Cancel;
1535 CHAR InputBuffer[50];
1536 ULONG MaxSize;
1537 ULONGLONG PartSize;
1538 ULONGLONG DiskSize;
1539 PCHAR Unit;
1540
1541 if (PartitionList == NULL ||
1542 PartitionList->CurrentDisk == NULL ||
1543 PartitionList->CurrentPartition == NULL)
1544 {
1545 /* FIXME: show an error dialog */
1546 return QUIT_PAGE;
1547 }
1548
1549 DiskEntry = PartitionList->CurrentDisk;
1550 PartEntry = PartitionList->CurrentPartition;
1551
1552 CONSOLE_SetStatusText (" Please wait...");
1553
1554 CONSOLE_SetTextXY (6, 8, "You have chosen to create a new partition on");
1555
1556 #if 0
1557 if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
1558 {
1559 DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
1560 Unit = "GB";
1561 }
1562 else
1563 #endif
1564 {
1565 DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
1566 if (DiskSize == 0)
1567 DiskSize = 1;
1568 Unit = "MB";
1569 }
1570
1571 if (DiskEntry->DriverName.Length > 0)
1572 {
1573 CONSOLE_PrintTextXY (6, 10,
1574 "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) on %wZ.",
1575 DiskSize,
1576 Unit,
1577 DiskEntry->DiskNumber,
1578 DiskEntry->Port,
1579 DiskEntry->Bus,
1580 DiskEntry->Id,
1581 &DiskEntry->DriverName);
1582 }
1583 else
1584 {
1585 CONSOLE_PrintTextXY (6, 10,
1586 "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu).",
1587 DiskSize,
1588 Unit,
1589 DiskEntry->DiskNumber,
1590 DiskEntry->Port,
1591 DiskEntry->Bus,
1592 DiskEntry->Id);
1593 }
1594
1595
1596 CONSOLE_SetTextXY (6, 12, "Please enter the size of the new partition in megabytes.");
1597
1598 #if 0
1599 CONSOLE_PrintTextXY (8, 10, "Maximum size of the new partition is %I64u MB",
1600 PartitionList->CurrentPartition->UnpartitionedLength / (1024*1024));
1601 #endif
1602
1603 CONSOLE_SetStatusText (" ENTER = Create Partition ESC = Cancel F3 = Quit");
1604
1605 PartEntry = PartitionList->CurrentPartition;
1606 while (TRUE)
1607 {
1608 MaxSize = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20; /* in MBytes (rounded) */
1609 ShowPartitionSizeInputBox (12, 14, xScreen - 12, 17, /* left, top, right, bottom */
1610 MaxSize, InputBuffer, &Quit, &Cancel);
1611 if (Quit == TRUE)
1612 {
1613 if (ConfirmQuit (Ir) == TRUE)
1614 {
1615 return QUIT_PAGE;
1616 }
1617 }
1618 else if (Cancel == TRUE)
1619 {
1620 return SELECT_PARTITION_PAGE;
1621 }
1622 else
1623 {
1624 PartSize = atoi (InputBuffer);
1625 if (PartSize < 1)
1626 {
1627 /* Too small */
1628 continue;
1629 }
1630
1631 if (PartSize > MaxSize)
1632 {
1633 /* Too large */
1634 continue;
1635 }
1636
1637 /* Convert to bytes */
1638 if (PartSize == MaxSize)
1639 {
1640 /* Use all of the unpartitioned disk space */
1641 PartSize = PartEntry->UnpartitionedLength;
1642 }
1643 else
1644 {
1645 /* Round-up by cylinder size */
1646 PartSize = ROUND_UP (PartSize * 1024 * 1024,
1647 DiskEntry->CylinderSize);
1648
1649 /* But never get larger than the unpartitioned disk space */
1650 if (PartSize > PartEntry->UnpartitionedLength)
1651 PartSize = PartEntry->UnpartitionedLength;
1652 }
1653
1654 DPRINT ("Partition size: %I64u bytes\n", PartSize);
1655
1656 CreateNewPartition (PartitionList,
1657 PartSize,
1658 FALSE);
1659
1660 return SELECT_PARTITION_PAGE;
1661 }
1662 }
1663
1664 return CREATE_PARTITION_PAGE;
1665 }
1666
1667
1668 static PAGE_NUMBER
1669 DeletePartitionPage (PINPUT_RECORD Ir)
1670 {
1671 PDISKENTRY DiskEntry;
1672 PPARTENTRY PartEntry;
1673 ULONGLONG DiskSize;
1674 ULONGLONG PartSize;
1675 PCHAR Unit;
1676 PCHAR PartType;
1677
1678 if (PartitionList == NULL ||
1679 PartitionList->CurrentDisk == NULL ||
1680 PartitionList->CurrentPartition == NULL)
1681 {
1682 /* FIXME: show an error dialog */
1683 return QUIT_PAGE;
1684 }
1685
1686 DiskEntry = PartitionList->CurrentDisk;
1687 PartEntry = PartitionList->CurrentPartition;
1688
1689 MUIDisplayPage(DELETE_PARTITION_PAGE);
1690
1691 /* Determine partition type */
1692 PartType = NULL;
1693 if (PartEntry->New == TRUE)
1694 {
1695 PartType = "New (Unformatted)";
1696 }
1697 else if (PartEntry->Unpartitioned == FALSE)
1698 {
1699 if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_12) ||
1700 (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_16) ||
1701 (PartEntry->PartInfo[0].PartitionType == PARTITION_HUGE) ||
1702 (PartEntry->PartInfo[0].PartitionType == PARTITION_XINT13))
1703 {
1704 PartType = "FAT";
1705 }
1706 else if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32) ||
1707 (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
1708 {
1709 PartType = "FAT32";
1710 }
1711 else if (PartEntry->PartInfo[0].PartitionType == PARTITION_IFS)
1712 {
1713 PartType = "NTFS"; /* FIXME: Not quite correct! */
1714 }
1715 }
1716
1717 #if 0
1718 if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */
1719 {
1720 PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 29)) >> 30;
1721 Unit = "GB";
1722 }
1723 else
1724 #endif
1725 if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0xA00000LL) /* 10 MB */
1726 {
1727 PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 19)) >> 20;
1728 Unit = "MB";
1729 }
1730 else
1731 {
1732 PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 9)) >> 10;
1733 Unit = "KB";
1734 }
1735
1736 if (PartType == NULL)
1737 {
1738 CONSOLE_PrintTextXY (6, 10,
1739 " %c%c Type %lu %I64u %s",
1740 (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
1741 (PartEntry->DriveLetter == 0) ? '-' : ':',
1742 PartEntry->PartInfo[0].PartitionType,
1743 PartSize,
1744 Unit);
1745 }
1746 else
1747 {
1748 CONSOLE_PrintTextXY (6, 10,
1749 " %c%c %s %I64u %s",
1750 (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
1751 (PartEntry->DriveLetter == 0) ? '-' : ':',
1752 PartType,
1753 PartSize,
1754 Unit);
1755 }
1756
1757 #if 0
1758 if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
1759 {
1760 DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
1761 Unit = "GB";
1762 }
1763 else
1764 #endif
1765 {
1766 DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
1767 if (DiskSize == 0)
1768 DiskSize = 1;
1769 Unit = "MB";
1770 }
1771
1772 if (DiskEntry->DriverName.Length > 0)
1773 {
1774 CONSOLE_PrintTextXY (6, 12,
1775 "on %I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) on %wZ.",
1776 DiskSize,
1777 Unit,
1778 DiskEntry->DiskNumber,
1779 DiskEntry->Port,
1780 DiskEntry->Bus,
1781 DiskEntry->Id,
1782 &DiskEntry->DriverName);
1783 }
1784 else
1785 {
1786 CONSOLE_PrintTextXY (6, 12,
1787 "on %I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu).",
1788 DiskSize,
1789 Unit,
1790 DiskEntry->DiskNumber,
1791 DiskEntry->Port,
1792 DiskEntry->Bus,
1793 DiskEntry->Id);
1794 }
1795
1796 while (TRUE)
1797 {
1798 CONSOLE_ConInKey (Ir);
1799
1800 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1801 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1802 {
1803 if (ConfirmQuit (Ir) == TRUE)
1804 {
1805 return QUIT_PAGE;
1806 }
1807 break;
1808 }
1809 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
1810 {
1811 return SELECT_PARTITION_PAGE;
1812 }
1813 else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'D') /* D */
1814 {
1815 DeleteCurrentPartition (PartitionList);
1816
1817 return SELECT_PARTITION_PAGE;
1818 }
1819 }
1820
1821 return DELETE_PARTITION_PAGE;
1822 }
1823
1824
1825 static PAGE_NUMBER
1826 SelectFileSystemPage (PINPUT_RECORD Ir)
1827 {
1828 PDISKENTRY DiskEntry;
1829 PPARTENTRY PartEntry;
1830 ULONGLONG DiskSize;
1831 ULONGLONG PartSize;
1832 PCHAR DiskUnit;
1833 PCHAR PartUnit;
1834 PCHAR PartType;
1835
1836 if (PartitionList == NULL ||
1837 PartitionList->CurrentDisk == NULL ||
1838 PartitionList->CurrentPartition == NULL)
1839 {
1840 /* FIXME: show an error dialog */
1841 return QUIT_PAGE;
1842 }
1843
1844 DiskEntry = PartitionList->CurrentDisk;
1845 PartEntry = PartitionList->CurrentPartition;
1846
1847 /* adjust disk size */
1848 if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
1849 {
1850 DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
1851 DiskUnit = "GB";
1852 }
1853 else
1854 {
1855 DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
1856 DiskUnit = "MB";
1857 }
1858
1859 /* adjust partition size */
1860 if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */
1861 {
1862 PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 29)) >> 30;
1863 PartUnit = "GB";
1864 }
1865 else
1866 {
1867 PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 19)) >> 20;
1868 PartUnit = "MB";
1869 }
1870
1871 /* adjust partition type */
1872 if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_12) ||
1873 (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_16) ||
1874 (PartEntry->PartInfo[0].PartitionType == PARTITION_HUGE) ||
1875 (PartEntry->PartInfo[0].PartitionType == PARTITION_XINT13))
1876 {
1877 PartType = "FAT";
1878 }
1879 else if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32) ||
1880 (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
1881 {
1882 PartType = "FAT32";
1883 }
1884 else if (PartEntry->PartInfo[0].PartitionType == PARTITION_IFS)
1885 {
1886 PartType = "NTFS"; /* FIXME: Not quite correct! */
1887 }
1888 else if (PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED)
1889 {
1890 PartType = "Unused";
1891 }
1892 else
1893 {
1894 PartType = "Unknown";
1895 }
1896
1897 if (PartEntry->AutoCreate == TRUE)
1898 {
1899 CONSOLE_SetTextXY(6, 8, "Setup created a new partition on");
1900
1901 #if 0
1902 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
1903 PartEntry->PartInfo[0].PartitionNumber,
1904 PartSize,
1905 PartUnit,
1906 PartType);
1907 #endif
1908
1909 CONSOLE_PrintTextXY(8, 10, "Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
1910 DiskEntry->DiskNumber,
1911 DiskSize,
1912 DiskUnit,
1913 DiskEntry->Port,
1914 DiskEntry->Bus,
1915 DiskEntry->Id,
1916 &DiskEntry->DriverName);
1917
1918 CONSOLE_SetTextXY(6, 12, "This Partition will be formatted next.");
1919
1920
1921 PartEntry->AutoCreate = FALSE;
1922 }
1923 else if (PartEntry->New == TRUE)
1924 {
1925 CONSOLE_SetTextXY(6, 8, "You chose to install ReactOS on a new or unformatted Partition.");
1926 CONSOLE_SetTextXY(6, 10, "This Partition will be formatted next.");
1927 }
1928 else
1929 {
1930 CONSOLE_SetTextXY(6, 8, "Setup install ReactOS onto Partition");
1931
1932 if (PartType == NULL)
1933 {
1934 CONSOLE_PrintTextXY (8, 10,
1935 "%c%c Type %lu %I64u %s",
1936 (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
1937 (PartEntry->DriveLetter == 0) ? '-' : ':',
1938 PartEntry->PartInfo[0].PartitionType,
1939 PartSize,
1940 PartUnit);
1941 }
1942 else
1943 {
1944 CONSOLE_PrintTextXY (8, 10,
1945 "%c%c %s %I64u %s",
1946 (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
1947 (PartEntry->DriveLetter == 0) ? '-' : ':',
1948 PartType,
1949 PartSize,
1950 PartUnit);
1951 }
1952
1953 CONSOLE_PrintTextXY(6, 12, "on Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
1954 DiskEntry->DiskNumber,
1955 DiskSize,
1956 DiskUnit,
1957 DiskEntry->Port,
1958 DiskEntry->Bus,
1959 DiskEntry->Id,
1960 &DiskEntry->DriverName);
1961 }
1962
1963 MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE);
1964
1965 if (FileSystemList == NULL)
1966 {
1967 FileSystemList = CreateFileSystemList (6, 26, PartEntry->New, L"FAT");
1968 if (FileSystemList == NULL)
1969 {
1970 /* FIXME: show an error dialog */
1971 return QUIT_PAGE;
1972 }
1973
1974 /* FIXME: Add file systems to list */
1975 }
1976 DrawFileSystemList (FileSystemList);
1977
1978 if (RepairUpdateFlag)
1979 {
1980 return (CHECK_FILE_SYSTEM_PAGE);
1981 //return SELECT_PARTITION_PAGE;
1982 }
1983
1984 if (IsUnattendedSetup)
1985 {
1986 if (UnattendFormatPartition)
1987 {
1988 return FORMAT_PARTITION_PAGE;
1989 }
1990 return(CHECK_FILE_SYSTEM_PAGE);
1991 }
1992
1993 while (TRUE)
1994 {
1995 CONSOLE_ConInKey (Ir);
1996
1997 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1998 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1999 {
2000 if (ConfirmQuit (Ir) == TRUE)
2001 {
2002 return QUIT_PAGE;
2003 }
2004 break;
2005 }
2006 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2007 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
2008 {
2009 return SELECT_PARTITION_PAGE;
2010 }
2011 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2012 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
2013 {
2014 ScrollDownFileSystemList (FileSystemList);
2015 }
2016 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2017 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
2018 {
2019 ScrollUpFileSystemList (FileSystemList);
2020 }
2021 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
2022 {
2023 if (!FileSystemList->Selected->FormatFunc)
2024 {
2025 return CHECK_FILE_SYSTEM_PAGE;
2026 }
2027 else
2028 {
2029 return FORMAT_PARTITION_PAGE;
2030 }
2031 }
2032 }
2033
2034 return SELECT_FILE_SYSTEM_PAGE;
2035 }
2036
2037
2038 static ULONG
2039 FormatPartitionPage (PINPUT_RECORD Ir)
2040 {
2041 WCHAR PathBuffer[MAX_PATH];
2042 PDISKENTRY DiskEntry;
2043 PPARTENTRY PartEntry;
2044 NTSTATUS Status;
2045
2046 #ifndef NDEBUG
2047 ULONG Line;
2048 ULONG i;
2049 PLIST_ENTRY Entry;
2050 #endif
2051
2052 MUIDisplayPage(FORMAT_PARTITION_PAGE);
2053
2054 if (PartitionList == NULL ||
2055 PartitionList->CurrentDisk == NULL ||
2056 PartitionList->CurrentPartition == NULL)
2057 {
2058 /* FIXME: show an error dialog */
2059 return QUIT_PAGE;
2060 }
2061
2062 DiskEntry = PartitionList->CurrentDisk;
2063 PartEntry = PartitionList->CurrentPartition;
2064
2065 while(TRUE)
2066 {
2067 if (!IsUnattendedSetup)
2068 {
2069 CONSOLE_ConInKey(Ir);
2070 }
2071
2072 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2073 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
2074 {
2075 if (ConfirmQuit (Ir) == TRUE)
2076 {
2077 return QUIT_PAGE;
2078 }
2079 break;
2080 }
2081 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN || IsUnattendedSetup) /* ENTER */
2082 {
2083 CONSOLE_SetStatusText (" Please wait ...");
2084
2085 if (PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED)
2086 {
2087 if (wcscmp(FileSystemList->Selected->FileSystem, L"FAT") == 0)
2088 {
2089 if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (4200LL * 1024LL))
2090 {
2091 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
2092 PartEntry->PartInfo[0].PartitionType = PARTITION_FAT_12;
2093 }
2094 else if (PartEntry->PartInfo[0].StartingOffset.QuadPart < (1024LL * 255LL * 63LL * 512LL))
2095 {
2096 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2097
2098 if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (32LL * 1024LL * 1024LL))
2099 {
2100 /* FAT16 CHS partition (partiton size < 32MB) */
2101 PartEntry->PartInfo[0].PartitionType = PARTITION_FAT_16;
2102 }
2103 else if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL))
2104 {
2105 /* FAT16 CHS partition (partition size < 512MB) */
2106 PartEntry->PartInfo[0].PartitionType = PARTITION_HUGE;
2107 }
2108 else
2109 {
2110 /* FAT32 CHS partition (partition size >= 512MB) */
2111 PartEntry->PartInfo[0].PartitionType = PARTITION_FAT32;
2112 }
2113 }
2114 else
2115 {
2116 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2117
2118 if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL))
2119 {
2120 /* FAT16 LBA partition (partition size < 512MB) */
2121 PartEntry->PartInfo[0].PartitionType = PARTITION_XINT13;
2122 }
2123 else
2124 {
2125 /* FAT32 LBA partition (partition size >= 512MB) */
2126 PartEntry->PartInfo[0].PartitionType = PARTITION_FAT32_XINT13;
2127 }
2128 }
2129 }
2130 else if (!FileSystemList->Selected->FormatFunc)
2131 return QUIT_PAGE;
2132 }
2133
2134 CheckActiveBootPartition (PartitionList);
2135
2136 #ifndef NDEBUG
2137 CONSOLE_PrintTextXY (6, 12,
2138 "Disk: %I64u Cylinder: %I64u Track: %I64u",
2139 DiskEntry->DiskSize,
2140 DiskEntry->CylinderSize,
2141 DiskEntry->TrackSize);
2142
2143 Line = 13;
2144 DiskEntry = PartitionList->CurrentDisk;
2145 Entry = DiskEntry->PartListHead.Flink;
2146 while (Entry != &DiskEntry->PartListHead)
2147 {
2148 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2149
2150 if (PartEntry->Unpartitioned == FALSE)
2151 {
2152
2153 for (i = 0; i < 4; i++)
2154 {
2155 CONSOLE_PrintTextXY (6, Line,
2156 "%2u: %2u %c %12I64u %12I64u %2u %c",
2157 i,
2158 PartEntry->PartInfo[i].PartitionNumber,
2159 PartEntry->PartInfo[i].BootIndicator ? 'A' : '-',
2160 PartEntry->PartInfo[i].StartingOffset.QuadPart,
2161 PartEntry->PartInfo[i].PartitionLength.QuadPart,
2162 PartEntry->PartInfo[i].PartitionType,
2163 PartEntry->PartInfo[i].RewritePartition ? '*' : ' ');
2164
2165 Line++;
2166 }
2167
2168 Line++;
2169 }
2170
2171 Entry = Entry->Flink;
2172 }
2173
2174 /* Restore the old entry */
2175 PartEntry = PartitionList->CurrentPartition;
2176 #endif
2177
2178 if (WritePartitionsToDisk (PartitionList) == FALSE)
2179 {
2180 DPRINT ("WritePartitionsToDisk() failed\n");
2181 MUIDisplayError(ERROR_WRITE_PTABLE, Ir, POPUP_WAIT_ENTER);
2182 return QUIT_PAGE;
2183 }
2184
2185 /* Set DestinationRootPath */
2186 RtlFreeUnicodeString (&DestinationRootPath);
2187 swprintf (PathBuffer,
2188 L"\\Device\\Harddisk%lu\\Partition%lu",
2189 PartitionList->CurrentDisk->DiskNumber,
2190 PartitionList->CurrentPartition->PartInfo[0].PartitionNumber);
2191 RtlCreateUnicodeString (&DestinationRootPath,
2192 PathBuffer);
2193 DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath);
2194
2195
2196 /* Set SystemRootPath */
2197 RtlFreeUnicodeString (&SystemRootPath);
2198 swprintf (PathBuffer,
2199 L"\\Device\\Harddisk%lu\\Partition%lu",
2200 PartitionList->ActiveBootDisk->DiskNumber,
2201 PartitionList->ActiveBootPartition->PartInfo[0].PartitionNumber);
2202 RtlCreateUnicodeString (&SystemRootPath,
2203 PathBuffer);
2204 DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath);
2205
2206
2207 if (FileSystemList->Selected->FormatFunc)
2208 {
2209 Status = FormatPartition(&DestinationRootPath, FileSystemList->Selected);
2210 if (!NT_SUCCESS(Status))
2211 {
2212 DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status);
2213 /* FIXME: show an error dialog */
2214 return QUIT_PAGE;
2215 }
2216
2217 PartEntry->New = FALSE;
2218
2219 CheckActiveBootPartition(PartitionList);
2220 }
2221
2222 if (wcscmp(FileSystemList->Selected->FileSystem, L"FAT") == 0)
2223 {
2224 /* FIXME: Install boot code. This is a hack! */
2225 if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13)
2226 || (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32))
2227 {
2228 wcscpy(PathBuffer, SourceRootPath.Buffer);
2229 wcscat(PathBuffer, L"\\loader\\fat32.bin");
2230
2231 DPRINT("Install FAT32 bootcode: %S ==> %S\n", PathBuffer,
2232 DestinationRootPath.Buffer);
2233 Status = InstallFat32BootCodeToDisk(PathBuffer,
2234 DestinationRootPath.Buffer);
2235 if (!NT_SUCCESS(Status))
2236 {
2237 DPRINT1("InstallFat32BootCodeToDisk() failed with status 0x%08lx\n", Status);
2238 /* FIXME: show an error dialog */
2239 DestroyFileSystemList(FileSystemList);
2240 FileSystemList = NULL;
2241 return QUIT_PAGE;
2242 }
2243 }
2244 else
2245 {
2246 wcscpy(PathBuffer, SourceRootPath.Buffer);
2247 wcscat(PathBuffer, L"\\loader\\fat.bin");
2248
2249 DPRINT("Install FAT bootcode: %S ==> %S\n", PathBuffer,
2250 DestinationRootPath.Buffer);
2251 Status = InstallFat16BootCodeToDisk(PathBuffer,
2252 DestinationRootPath.Buffer);
2253 if (!NT_SUCCESS(Status))
2254 {
2255 DPRINT1("InstallFat16BootCodeToDisk() failed with status 0x%.08x\n", Status);
2256 /* FIXME: show an error dialog */
2257 DestroyFileSystemList(FileSystemList);
2258 FileSystemList = NULL;
2259 return QUIT_PAGE;
2260 }
2261 }
2262 }
2263 else if (FileSystemList->Selected->FormatFunc)
2264 {
2265 DestroyFileSystemList(FileSystemList);
2266 FileSystemList = NULL;
2267 return QUIT_PAGE;
2268 }
2269
2270 #ifndef NDEBUG
2271 CONSOLE_SetStatusText (" Done. Press any key ...");
2272 CONSOLE_ConInKey(Ir);
2273 #endif
2274
2275 DestroyFileSystemList(FileSystemList);
2276 FileSystemList = NULL;
2277 return INSTALL_DIRECTORY_PAGE;
2278 }
2279 }
2280
2281 return FORMAT_PARTITION_PAGE;
2282 }
2283
2284
2285 static ULONG
2286 CheckFileSystemPage(PINPUT_RECORD Ir)
2287 {
2288 PFILE_SYSTEM_ITEM CurrentFileSystem;
2289 WCHAR PathBuffer[MAX_PATH];
2290 CHAR Buffer[MAX_PATH];
2291 NTSTATUS Status;
2292
2293 /* FIXME: code duplicated in FormatPartitionPage */
2294 /* Set DestinationRootPath */
2295 RtlFreeUnicodeString(&DestinationRootPath);
2296 swprintf(PathBuffer,
2297 L"\\Device\\Harddisk%lu\\Partition%lu",
2298 PartitionList->CurrentDisk->DiskNumber,
2299 PartitionList->CurrentPartition->PartInfo[0].PartitionNumber);
2300 RtlCreateUnicodeString(&DestinationRootPath, PathBuffer);
2301 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath);
2302
2303 /* Set SystemRootPath */
2304 RtlFreeUnicodeString(&SystemRootPath);
2305 swprintf(PathBuffer,
2306 L"\\Device\\Harddisk%lu\\Partition%lu",
2307 PartitionList->ActiveBootDisk->DiskNumber,
2308 PartitionList->ActiveBootPartition->PartInfo[0].PartitionNumber);
2309 RtlCreateUnicodeString(&SystemRootPath, PathBuffer);
2310 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath);
2311
2312 CONSOLE_SetTextXY(6, 8, "Setup is now checking the selected partition.");
2313
2314 CONSOLE_SetStatusText(" Please wait...");
2315
2316 /* WRONG: first filesystem is not necesseraly the one of the current partition! */
2317 CurrentFileSystem = CONTAINING_RECORD(FileSystemList->ListHead.Flink, FILE_SYSTEM_ITEM, ListEntry);
2318
2319 if (!CurrentFileSystem->ChkdskFunc)
2320 {
2321 sprintf(Buffer,
2322 "Setup is currently unable to check a partition formatted in %S.\n"
2323 "\n"
2324 " \x07 Press ENTER to continue Setup.\n"
2325 " \x07 Press F3 to quit Setup.",
2326 CurrentFileSystem->FileSystem);
2327 PopupError(
2328 Buffer,
2329 "F3= Quit ENTER = Continue",
2330 NULL, POPUP_WAIT_NONE);
2331
2332 while(TRUE)
2333 {
2334 CONSOLE_ConInKey(Ir);
2335
2336 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x00
2337 && Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3) /* F3 */
2338 {
2339 if (ConfirmQuit(Ir))
2340 return QUIT_PAGE;
2341 else
2342 return CHECK_FILE_SYSTEM_PAGE;
2343 }
2344 else if (Ir->Event.KeyEvent.uChar.AsciiChar == VK_RETURN) /* ENTER */
2345 {
2346 return INSTALL_DIRECTORY_PAGE;
2347 }
2348 }
2349 }
2350 else
2351 {
2352 Status = ChkdskPartition(&DestinationRootPath, CurrentFileSystem);
2353 if (!NT_SUCCESS(Status))
2354 {
2355 DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status);
2356 sprintf(Buffer, "Setup failed to verify the selected partition.\n"
2357 "(Status 0x%08lx).\n", Status);
2358 PopupError(Buffer,
2359 "ENTER = Reboot computer",
2360 Ir, POPUP_WAIT_ENTER);
2361 return QUIT_PAGE;
2362 }
2363
2364 return INSTALL_DIRECTORY_PAGE;
2365 }
2366 }
2367
2368
2369 static PAGE_NUMBER
2370 InstallDirectoryPage1(PWCHAR InstallDir, PDISKENTRY DiskEntry, PPARTENTRY PartEntry)
2371 {
2372 WCHAR PathBuffer[MAX_PATH];
2373
2374 /* Create 'InstallPath' string */
2375 RtlFreeUnicodeString(&InstallPath);
2376 RtlCreateUnicodeString(&InstallPath,
2377 InstallDir);
2378
2379 /* Create 'DestinationPath' string */
2380 RtlFreeUnicodeString(&DestinationPath);
2381 wcscpy(PathBuffer,
2382 DestinationRootPath.Buffer);
2383 if (InstallDir[0] != L'\\')
2384 wcscat(PathBuffer,
2385 L"\\");
2386 wcscat(PathBuffer, InstallDir);
2387 RtlCreateUnicodeString(&DestinationPath,
2388 PathBuffer);
2389
2390 /* Create 'DestinationArcPath' */
2391 RtlFreeUnicodeString(&DestinationArcPath);
2392 swprintf(PathBuffer,
2393 L"multi(0)disk(0)rdisk(%lu)partition(%lu)",
2394 DiskEntry->BiosDiskNumber,
2395 PartEntry->PartInfo[0].PartitionNumber);
2396 if (InstallDir[0] != L'\\')
2397 wcscat(PathBuffer,
2398 L"\\");
2399 wcscat(PathBuffer, InstallDir);
2400 RtlCreateUnicodeString(&DestinationArcPath,
2401 PathBuffer);
2402
2403 return(PREPARE_COPY_PAGE);
2404 }
2405
2406
2407 static PAGE_NUMBER
2408 InstallDirectoryPage(PINPUT_RECORD Ir)
2409 {
2410 PDISKENTRY DiskEntry;
2411 PPARTENTRY PartEntry;
2412 WCHAR InstallDir[51];
2413 PWCHAR DefaultPath;
2414 INFCONTEXT Context;
2415 ULONG Length;
2416
2417 if (PartitionList == NULL ||
2418 PartitionList->CurrentDisk == NULL ||
2419 PartitionList->CurrentPartition == NULL)
2420 {
2421 /* FIXME: show an error dialog */
2422 return QUIT_PAGE;
2423 }
2424
2425 DiskEntry = PartitionList->CurrentDisk;
2426 PartEntry = PartitionList->CurrentPartition;
2427
2428 /* Search for 'DefaultPath' in the 'SetupData' section */
2429 if (!SetupFindFirstLineW (SetupInf, L"SetupData", L"DefaultPath", &Context))
2430 {
2431 MUIDisplayError(ERROR_FIND_SETUPDATA, Ir, POPUP_WAIT_ENTER);
2432 return QUIT_PAGE;
2433 }
2434
2435 /* Read the 'DefaultPath' data */
2436 if (INF_GetData (&Context, NULL, &DefaultPath))
2437 {
2438 wcscpy(InstallDir, DefaultPath);
2439 }
2440 else
2441 {
2442 wcscpy(InstallDir, L"\\ReactOS");
2443 }
2444 Length = wcslen(InstallDir);
2445 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
2446 MUIDisplayPage(INSTALL_DIRECTORY_PAGE);
2447
2448 if (IsUnattendedSetup)
2449 {
2450 return(InstallDirectoryPage1 (InstallDir, DiskEntry, PartEntry));
2451 }
2452
2453 while(TRUE)
2454 {
2455 CONSOLE_ConInKey(Ir);
2456
2457 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2458 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
2459 {
2460 if (ConfirmQuit(Ir) == TRUE)
2461 return(QUIT_PAGE);
2462 break;
2463 }
2464 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2465 {
2466 return (InstallDirectoryPage1 (InstallDir, DiskEntry, PartEntry));
2467 }
2468 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */
2469 {
2470 if (Length > 0)
2471 {
2472 Length--;
2473 InstallDir[Length] = 0;
2474 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
2475 }
2476 }
2477 else if (isprint(Ir->Event.KeyEvent.uChar.AsciiChar))
2478 {
2479 if (Length < 50)
2480 {
2481 InstallDir[Length] = (WCHAR)Ir->Event.KeyEvent.uChar.AsciiChar;
2482 Length++;
2483 InstallDir[Length] = 0;
2484 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
2485 }
2486 }
2487 }
2488
2489 return(INSTALL_DIRECTORY_PAGE);
2490 }
2491
2492 static BOOLEAN
2493 AddSectionToCopyQueueCab(HINF InfFile,
2494 PWCHAR SectionName,
2495 PWCHAR SourceCabinet,
2496 PCUNICODE_STRING DestinationPath,
2497 PINPUT_RECORD Ir)
2498 {
2499 INFCONTEXT FilesContext;
2500 INFCONTEXT DirContext;
2501 PWCHAR FileKeyName;
2502 PWCHAR FileKeyValue;
2503 PWCHAR DirKeyValue;
2504 PWCHAR TargetFileName;
2505
2506 /* Search for the SectionName section */
2507 if (!SetupFindFirstLineW (InfFile, SectionName, NULL, &FilesContext))
2508 {
2509 char Buffer[128];
2510 sprintf(Buffer, "Setup failed to find the '%S' section\nin TXTSETUP.SIF.\n", SectionName);
2511 PopupError(Buffer, "ENTER = Reboot computer", Ir, POPUP_WAIT_ENTER);
2512 return(FALSE);
2513 }
2514
2515 /*
2516 * Enumerate the files in the section
2517 * and add them to the file queue.
2518 */
2519 do
2520 {
2521 /* Get source file name and target directory id */
2522 if (!INF_GetData (&FilesContext, &FileKeyName, &FileKeyValue))
2523 {
2524 /* FIXME: Handle error! */
2525 DPRINT1("INF_GetData() failed\n");
2526 break;
2527 }
2528
2529 /* Get optional target file name */
2530 if (!INF_GetDataField (&FilesContext, 2, &TargetFileName))
2531 TargetFileName = NULL;
2532
2533 DPRINT ("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
2534
2535 /* Lookup target directory */
2536 if (!SetupFindFirstLineW (InfFile, L"Directories", FileKeyValue, &DirContext))
2537 {
2538 /* FIXME: Handle error! */
2539 DPRINT1("SetupFindFirstLine() failed\n");
2540 break;
2541 }
2542
2543 if (!INF_GetData (&DirContext, NULL, &DirKeyValue))
2544 {
2545 /* FIXME: Handle error! */
2546 DPRINT1("INF_GetData() failed\n");
2547 break;
2548 }
2549
2550 if (!SetupQueueCopy(SetupFileQueue,
2551 SourceCabinet,
2552 SourceRootPath.Buffer,
2553 SourceRootDir.Buffer,
2554 FileKeyName,
2555 DirKeyValue,
2556 TargetFileName))
2557 {
2558 /* FIXME: Handle error! */
2559 DPRINT1("SetupQueueCopy() failed\n");
2560 }
2561 }
2562 while (SetupFindNextLine(&FilesContext, &FilesContext));
2563
2564 return TRUE;
2565 }
2566
2567 static BOOLEAN
2568 AddSectionToCopyQueue(HINF InfFile,
2569 PWCHAR SectionName,
2570 PWCHAR SourceCabinet,
2571 PCUNICODE_STRING DestinationPath,
2572 PINPUT_RECORD Ir)
2573 {
2574 INFCONTEXT FilesContext;
2575 INFCONTEXT DirContext;
2576 PWCHAR FileKeyName;
2577 PWCHAR FileKeyValue;
2578 PWCHAR DirKeyValue;
2579 PWCHAR TargetFileName;
2580
2581 if (SourceCabinet)
2582 return AddSectionToCopyQueueCab(InfFile, L"SourceFiles", SourceCabinet, DestinationPath, Ir);
2583
2584 /* Search for the SectionName section */
2585 if (!SetupFindFirstLineW (InfFile, SectionName, NULL, &FilesContext))
2586 {
2587 char Buffer[128];
2588 sprintf(Buffer, "Setup failed to find the '%S' section\nin TXTSETUP.SIF.\n", SectionName);
2589 PopupError(Buffer, "ENTER = Reboot computer", Ir, POPUP_WAIT_ENTER);
2590 return(FALSE);
2591 }
2592
2593 /*
2594 * Enumerate the files in the section
2595 * and add them to the file queue.
2596 */
2597 do
2598 {
2599 /* Get source file name and target directory id */
2600 if (!INF_GetData (&FilesContext, &FileKeyName, &FileKeyValue))
2601 {
2602 /* FIXME: Handle error! */
2603 DPRINT1("INF_GetData() failed\n");
2604 break;
2605 }
2606
2607 /* Get target directory id */
2608 if (!INF_GetDataField (&FilesContext, 13, &FileKeyValue))
2609 {
2610 /* FIXME: Handle error! */
2611 DPRINT1("INF_GetData() failed\n");
2612 break;
2613 }
2614
2615 /* Get optional target file name */
2616 if (!INF_GetDataField (&FilesContext, 11, &TargetFileName))
2617 TargetFileName = NULL;
2618 else if (!*TargetFileName)
2619 TargetFileName = NULL;
2620
2621 DPRINT ("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
2622
2623 /* Lookup target directory */
2624 if (!SetupFindFirstLineW (InfFile, L"Directories", FileKeyValue, &DirContext))
2625 {
2626 /* FIXME: Handle error! */
2627 DPRINT1("SetupFindFirstLine() failed\n");
2628 break;
2629 }
2630
2631 if (!INF_GetData (&DirContext, NULL, &DirKeyValue))
2632 {
2633 /* FIXME: Handle error! */
2634 DPRINT1("INF_GetData() failed\n");
2635 break;
2636 }
2637
2638 if (!SetupQueueCopy(SetupFileQueue,
2639 SourceCabinet,
2640 SourceRootPath.Buffer,
2641 SourceRootDir.Buffer,
2642 FileKeyName,
2643 DirKeyValue,
2644 TargetFileName))
2645 {
2646 /* FIXME: Handle error! */
2647 DPRINT1("SetupQueueCopy() failed\n");
2648 }
2649 }
2650 while (SetupFindNextLine(&FilesContext, &FilesContext));
2651
2652 return TRUE;
2653 }
2654
2655 static BOOLEAN
2656 PrepareCopyPageInfFile(HINF InfFile,
2657 PWCHAR SourceCabinet,
2658 PINPUT_RECORD Ir)
2659 {
2660 WCHAR PathBuffer[MAX_PATH];
2661 INFCONTEXT DirContext;
2662 PWCHAR AdditionalSectionName = NULL;
2663 PWCHAR KeyValue;
2664 ULONG Length;
2665 NTSTATUS Status;
2666
2667 /* Add common files */
2668 if (!AddSectionToCopyQueue(InfFile, L"SourceDisksFiles", SourceCabinet, &DestinationPath, Ir))
2669 return FALSE;
2670
2671 /* Add specific files depending of computer type */
2672 if (SourceCabinet == NULL)
2673 {
2674 if (!ProcessComputerFiles(InfFile, ComputerList, &AdditionalSectionName))
2675 return FALSE;
2676 if (AdditionalSectionName)
2677 {
2678 if (!AddSectionToCopyQueue(InfFile, AdditionalSectionName, SourceCabinet, &DestinationPath, Ir))
2679 return FALSE;
2680 }
2681 }
2682
2683 /* Create directories */
2684
2685 /*
2686 * FIXME:
2687 * Install directories like '\reactos\test' are not handled yet.
2688 */
2689
2690 /* Get destination path */
2691 wcscpy(PathBuffer, DestinationPath.Buffer);
2692
2693 /* Remove trailing backslash */
2694 Length = wcslen(PathBuffer);
2695 if ((Length > 0) && (PathBuffer[Length - 1] == '\\'))
2696 {
2697 PathBuffer[Length - 1] = 0;
2698 }
2699
2700 /* Create the install directory */
2701 Status = SetupCreateDirectory(PathBuffer);
2702 if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
2703 {
2704 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
2705 MUIDisplayError(ERROR_CREATE_INSTALL_DIR, Ir, POPUP_WAIT_ENTER);
2706 return(FALSE);
2707 }
2708
2709
2710 /* Search for the 'Directories' section */
2711 if (!SetupFindFirstLineW(InfFile, L"Directories", NULL, &DirContext))
2712 {
2713 if (SourceCabinet)
2714 {
2715 MUIDisplayError(ERROR_CABINET_SECTION, Ir, POPUP_WAIT_ENTER);
2716 }
2717 else
2718 {
2719 MUIDisplayError(ERROR_TXTSETUP_SECTION, Ir, POPUP_WAIT_ENTER);
2720 }
2721 return(FALSE);
2722 }
2723
2724 /* Enumerate the directory values and create the subdirectories */
2725 do
2726 {
2727 if (!INF_GetData (&DirContext, NULL, &KeyValue))
2728 {
2729 DPRINT1("break\n");
2730 break;
2731 }
2732
2733 if (KeyValue[0] == L'\\' && KeyValue[1] != 0)
2734 {
2735 DPRINT("Absolute Path: '%S'\n", KeyValue);
2736
2737 wcscpy(PathBuffer, DestinationRootPath.Buffer);
2738 wcscat(PathBuffer, KeyValue);
2739
2740 DPRINT("FullPath: '%S'\n", PathBuffer);
2741 }
2742 else if (KeyValue[0] != L'\\')
2743 {
2744 DPRINT("RelativePath: '%S'\n", KeyValue);
2745 wcscpy(PathBuffer, DestinationPath.Buffer);
2746 wcscat(PathBuffer, L"\\");
2747 wcscat(PathBuffer, KeyValue);
2748
2749 DPRINT("FullPath: '%S'\n", PathBuffer);
2750
2751 Status = SetupCreateDirectory(PathBuffer);
2752 if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
2753 {
2754 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
2755 MUIDisplayError(ERROR_CREATE_DIR, Ir, POPUP_WAIT_ENTER);
2756 return(FALSE);
2757 }
2758 }
2759 }
2760 while (SetupFindNextLine (&DirContext, &DirContext));
2761
2762 return(TRUE);
2763 }
2764
2765 static PAGE_NUMBER
2766 PrepareCopyPage(PINPUT_RECORD Ir)
2767 {
2768 HINF InfHandle;
2769 WCHAR PathBuffer[MAX_PATH];
2770 INFCONTEXT CabinetsContext;
2771 ULONG InfFileSize;
2772 PWCHAR KeyValue;
2773 UINT ErrorLine;
2774 PVOID InfFileData;
2775
2776 MUIDisplayPage(PREPARE_COPY_PAGE);
2777
2778 /* Create the file queue */
2779 SetupFileQueue = SetupOpenFileQueue();
2780 if (SetupFileQueue == NULL)
2781 {
2782 MUIDisplayError(ERROR_COPY_QUEUE, Ir, POPUP_WAIT_ENTER);
2783 return(QUIT_PAGE);
2784 }
2785
2786 if (!PrepareCopyPageInfFile(SetupInf, NULL, Ir))
2787 {
2788 return QUIT_PAGE;
2789 }
2790
2791 /* Search for the 'Cabinets' section */
2792 if (!SetupFindFirstLineW (SetupInf, L"Cabinets", NULL, &CabinetsContext))
2793 {
2794 return FILE_COPY_PAGE;
2795 }
2796
2797 /*
2798 * Enumerate the directory values in the 'Cabinets'
2799 * section and parse their inf files.
2800 */
2801 do
2802 {
2803 if (!INF_GetData (&CabinetsContext, NULL, &KeyValue))
2804 break;
2805
2806 wcscpy(PathBuffer, SourcePath.Buffer);
2807 wcscat(PathBuffer, L"\\");
2808 wcscat(PathBuffer, KeyValue);
2809
2810 #ifdef __REACTOS__
2811 CabinetInitialize();
2812 CabinetSetEventHandlers(NULL, NULL, NULL);
2813 CabinetSetCabinetName(PathBuffer);
2814
2815 if (CabinetOpen() == CAB_STATUS_SUCCESS)
2816 {
2817 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
2818
2819 InfFileData = CabinetGetCabinetReservedArea(&InfFileSize);
2820 if (InfFileData == NULL)
2821 {
2822 MUIDisplayError(ERROR_CABINET_SCRIPT, Ir, POPUP_WAIT_ENTER);
2823 return QUIT_PAGE;
2824 }
2825 }
2826 else
2827 {
2828 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
2829 MUIDisplayError(ERROR_CABINET_MISSING, Ir, POPUP_WAIT_ENTER);
2830 return QUIT_PAGE;
2831 }
2832
2833 InfHandle = INF_OpenBufferedFileA((CHAR*) InfFileData,
2834 InfFileSize,
2835 (const CHAR*) NULL,
2836 INF_STYLE_WIN4,
2837 &ErrorLine);
2838 if (InfHandle == INVALID_HANDLE_VALUE)
2839 {
2840 MUIDisplayError(ERROR_INVALID_CABINET_INF, Ir, POPUP_WAIT_ENTER);
2841 return QUIT_PAGE;
2842 }
2843
2844 CabinetCleanup();
2845
2846 if (!PrepareCopyPageInfFile(InfHandle, KeyValue, Ir))
2847 {
2848 return QUIT_PAGE;
2849 }
2850 #endif
2851 }
2852 while (SetupFindNextLine (&CabinetsContext, &CabinetsContext));
2853
2854 return FILE_COPY_PAGE;
2855 }
2856
2857 VOID
2858 NTAPI
2859 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext,
2860 IN BOOLEAN First)
2861 {
2862 SYSTEM_PERFORMANCE_INFORMATION PerfInfo;
2863
2864 /* Get the memory information from the system */
2865 NtQuerySystemInformation(SystemPerformanceInformation,
2866 &PerfInfo,
2867 sizeof(PerfInfo),
2868 NULL);
2869
2870 /* Check if this is initial setup */
2871 if (First)
2872 {
2873 /* Set maximum limits to be total RAM pages */
2874 ProgressSetStepCount(CopyContext->MemoryBars[0], PerfInfo.CommitLimit);
2875 ProgressSetStepCount(CopyContext->MemoryBars[1], PerfInfo.CommitLimit);
2876 ProgressSetStepCount(CopyContext->MemoryBars[2], PerfInfo.CommitLimit);
2877 }
2878
2879 /* Set current values */
2880 ProgressSetStep(CopyContext->MemoryBars[0], PerfInfo.PagedPoolPages);
2881 ProgressSetStep(CopyContext->MemoryBars[1], PerfInfo.NonPagedPoolPages);
2882 ProgressSetStep(CopyContext->MemoryBars[2], PerfInfo.AvailablePages);
2883
2884 /* Check if memory dropped below 40%! */
2885 if (CopyContext->MemoryBars[2]->Percent <= 40)
2886 {
2887 /* Wait a while until Mm does its thing */
2888 LARGE_INTEGER Interval;
2889 Interval.QuadPart = -1 * 15 * 1000 * 100;
2890 NtDelayExecution(FALSE, &Interval);
2891 }
2892 }
2893
2894 static UINT CALLBACK
2895 FileCopyCallback(PVOID Context,
2896 UINT Notification,
2897 UINT_PTR Param1,
2898 UINT_PTR Param2)
2899 {
2900 PCOPYCONTEXT CopyContext;
2901
2902 CopyContext = (PCOPYCONTEXT)Context;
2903
2904 switch (Notification)
2905 {
2906 case SPFILENOTIFY_STARTSUBQUEUE:
2907 CopyContext->TotalOperations = (ULONG)Param2;
2908 ProgressSetStepCount(CopyContext->ProgressBar,
2909 CopyContext->TotalOperations);
2910 SetupUpdateMemoryInfo(CopyContext, TRUE);
2911 break;
2912
2913 case SPFILENOTIFY_STARTCOPY:
2914 /* Display copy message */
2915 CONSOLE_SetStatusText(" \xB3 Copying file: %S", (PWSTR)Param1);
2916 SetupUpdateMemoryInfo(CopyContext, FALSE);
2917 break;
2918
2919 case SPFILENOTIFY_ENDCOPY:
2920 CopyContext->CompletedOperations++;
2921 ProgressNextStep(CopyContext->ProgressBar);
2922 SetupUpdateMemoryInfo(CopyContext, FALSE);
2923 break;
2924 }
2925
2926 return 0;
2927 }
2928
2929 static
2930 PAGE_NUMBER
2931 FileCopyPage(PINPUT_RECORD Ir)
2932 {
2933 COPYCONTEXT CopyContext;
2934
2935 MUIDisplayPage(FILE_COPY_PAGE);
2936
2937 /* Create context for the copy process */
2938 CopyContext.DestinationRootPath = DestinationRootPath.Buffer;
2939 CopyContext.InstallPath = InstallPath.Buffer;
2940 CopyContext.TotalOperations = 0;
2941 CopyContext.CompletedOperations = 0;
2942
2943 /* Create the progress bar as well */
2944 CopyContext.ProgressBar = CreateProgressBar(13,
2945 26,
2946 xScreen - 13,
2947 yScreen - 20,
2948 10,
2949 24,
2950 TRUE,
2951 "Setup is copying files...");
2952
2953 /* Create the paged pool progress bar */
2954 CopyContext.MemoryBars[0] = CreateProgressBar(13,
2955 40,
2956 18,
2957 43,
2958 10,
2959 44,
2960 FALSE,
2961 "Paged Memory");
2962
2963 /* Create the non paged pool progress bar */
2964 CopyContext.MemoryBars[1] = CreateProgressBar(28,
2965 40,
2966 33,
2967 43,
2968 24,
2969 44,
2970 FALSE,
2971 "Nonpaged Memory");
2972
2973 /* Create the global memory progress bar */
2974 CopyContext.MemoryBars[2] = CreateProgressBar(43,
2975 40,
2976 48,
2977 43,
2978 40,
2979 44,
2980 FALSE,
2981 "Free Memory");
2982
2983 /* Do the file copying */
2984 SetupCommitFileQueueW(NULL,
2985 SetupFileQueue,
2986 FileCopyCallback,
2987 &CopyContext);
2988
2989 /* If we get here, we're done, so cleanup the queue and progress bar */
2990 SetupCloseFileQueue(SetupFileQueue);
2991 DestroyProgressBar(CopyContext.ProgressBar);
2992 DestroyProgressBar(CopyContext.MemoryBars[0]);
2993 DestroyProgressBar(CopyContext.MemoryBars[1]);
2994 DestroyProgressBar(CopyContext.MemoryBars[2]);
2995
2996 /* Go display the next page */
2997 return REGISTRY_PAGE;
2998 }
2999
3000 static PAGE_NUMBER
3001 RegistryPage(PINPUT_RECORD Ir)
3002 {
3003 INFCONTEXT InfContext;
3004 PWSTR Action;
3005 PWSTR File;
3006 PWSTR Section;
3007 BOOLEAN Delete;
3008 NTSTATUS Status;
3009
3010 MUIDisplayPage(REGISTRY_PAGE);
3011
3012 if (RepairUpdateFlag)
3013 {
3014 return SUCCESS_PAGE;
3015 }
3016
3017 if (!SetInstallPathValue(&DestinationPath))
3018 {
3019 DPRINT("SetInstallPathValue() failed\n");
3020 MUIDisplayError(ERROR_INITIALIZE_REGISTRY, Ir, POPUP_WAIT_ENTER);
3021 return QUIT_PAGE;
3022 }
3023
3024 /* Create the default hives */
3025 #ifdef __REACTOS__
3026 Status = NtInitializeRegistry(CM_BOOT_FLAG_SETUP);
3027 if (!NT_SUCCESS(Status))
3028 {
3029 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status);
3030 MUIDisplayError(ERROR_CREATE_HIVE, Ir, POPUP_WAIT_ENTER);
3031 return QUIT_PAGE;
3032 }
3033 #else
3034 RegInitializeRegistry();
3035 #endif
3036
3037 /* Update registry */
3038 CONSOLE_SetStatusText(" Updating registry hives...");
3039
3040 if (!SetupFindFirstLineW(SetupInf, L"HiveInfs.Install", NULL, &InfContext))
3041 {
3042 DPRINT1("SetupFindFirstLine() failed\n");
3043 MUIDisplayError(ERROR_FIND_REGISTRY, Ir, POPUP_WAIT_ENTER);
3044 return QUIT_PAGE;
3045 }
3046
3047 do
3048 {
3049 INF_GetDataField (&InfContext, 0, &Action);
3050 INF_GetDataField (&InfContext, 1, &File);
3051 INF_GetDataField (&InfContext, 2, &Section);
3052
3053 DPRINT("Action: %S File: %S Section %S\n", Action, File, Section);
3054
3055 if (!_wcsicmp (Action, L"AddReg"))
3056 {
3057 Delete = FALSE;
3058 }
3059 else if (!_wcsicmp (Action, L"DelReg"))
3060 {
3061 Delete = TRUE;
3062 }
3063 else
3064 {
3065 continue;
3066 }
3067
3068 CONSOLE_SetStatusText(" Importing %S...", File);
3069
3070 if (!ImportRegistryFile(File, Section, Delete))
3071 {
3072 DPRINT("Importing %S failed\n", File);
3073
3074 MUIDisplayError(ERROR_IMPORT_HIVE, Ir, POPUP_WAIT_ENTER);
3075 return QUIT_PAGE;
3076 }
3077 }
3078 while (SetupFindNextLine (&InfContext, &InfContext));
3079
3080 /* Update display registry settings */
3081 CONSOLE_SetStatusText(" Updating display registry settings...");
3082 if (!ProcessDisplayRegistry(SetupInf, DisplayList))
3083 {
3084 MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS, Ir, POPUP_WAIT_ENTER);
3085 return QUIT_PAGE;
3086 }
3087
3088 /* Update keyboard layout settings */
3089 CONSOLE_SetStatusText(" Updating keyboard layout settings...");
3090 if (!ProcessKeyboardLayoutRegistry(LanguageList))
3091 {
3092 MUIDisplayError(ERROR_UPDATE_KBSETTINGS, Ir, POPUP_WAIT_ENTER);
3093 return QUIT_PAGE;
3094 }
3095
3096 /* Add codepage information to registry */
3097 CONSOLE_SetStatusText(" Adding codepage information to registry...");
3098 if (!AddCodePage())
3099 {
3100 MUIDisplayError(ERROR_ADDING_CODEPAGE, Ir, POPUP_WAIT_ENTER);
3101 return QUIT_PAGE;
3102 }
3103
3104 /* Update the mounted devices list */
3105 SetMountedDeviceValues(PartitionList);
3106
3107 CONSOLE_SetStatusText(" Done...");
3108
3109 return BOOT_LOADER_PAGE;
3110 }
3111
3112
3113 static PAGE_NUMBER
3114 BootLoaderPage(PINPUT_RECORD Ir)
3115 {
3116 UCHAR PartitionType;
3117 BOOLEAN InstallOnFloppy;
3118 USHORT Line = 12;
3119
3120 CONSOLE_SetStatusText(" Please wait...");
3121
3122 PartitionType = PartitionList->ActiveBootPartition->PartInfo[0].PartitionType;
3123
3124 if (PartitionType == PARTITION_ENTRY_UNUSED)
3125 {
3126 DPRINT("Error: active partition invalid (unused)\n");
3127 InstallOnFloppy = TRUE;
3128 }
3129 else if (PartitionType == 0x0A)
3130 {
3131 /* OS/2 boot manager partition */
3132 DPRINT("Found OS/2 boot manager partition\n");
3133 InstallOnFloppy = TRUE;
3134 }
3135 else if (PartitionType == 0x83)
3136 {
3137 /* Linux ext2 partition */
3138 DPRINT("Found Linux ext2 partition\n");
3139 InstallOnFloppy = TRUE;
3140 }
3141 else if (PartitionType == PARTITION_IFS)
3142 {
3143 /* NTFS partition */
3144 DPRINT("Found NTFS partition\n");
3145 InstallOnFloppy = TRUE;
3146 }
3147 else if ((PartitionType == PARTITION_FAT_12) ||
3148 (PartitionType == PARTITION_FAT_16) ||
3149 (PartitionType == PARTITION_HUGE) ||
3150 (PartitionType == PARTITION_XINT13) ||
3151 (PartitionType == PARTITION_FAT32) ||
3152 (PartitionType == PARTITION_FAT32_XINT13))
3153 {
3154 DPRINT("Found FAT partition\n");
3155 InstallOnFloppy = FALSE;
3156 }
3157 else
3158 {
3159 /* Unknown partition */
3160 DPRINT("Unknown partition found\n");
3161 InstallOnFloppy = TRUE;
3162 }
3163
3164 if (InstallOnFloppy == TRUE)
3165 {
3166 return BOOT_LOADER_FLOPPY_PAGE;
3167 }
3168
3169 if (IsUnattendedSetup)
3170 {
3171 if (UnattendMBRInstallType == 0) /* skip MBR installation */
3172 {
3173 return SUCCESS_PAGE;
3174 }
3175 else if (UnattendMBRInstallType == 1) /* install on floppy */
3176 {
3177 return BOOT_LOADER_FLOPPY_PAGE;
3178 }
3179 else if (UnattendMBRInstallType == 2) /* install on hdd */
3180 {
3181 return BOOT_LOADER_HARDDISK_PAGE;
3182 }
3183 }
3184
3185 MUIDisplayPage(BOOT_LOADER_PAGE);
3186 CONSOLE_InvertTextXY (8, Line, 60, 1);
3187
3188 while(TRUE)
3189 {
3190 CONSOLE_ConInKey(Ir);
3191
3192 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3193 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
3194 {
3195 CONSOLE_NormalTextXY (8, Line, 60, 1);
3196
3197 Line++;
3198 if (Line<12) Line=14;
3199 if (Line>14) Line=12;
3200
3201
3202
3203 CONSOLE_InvertTextXY (8, Line, 60, 1);
3204 }
3205 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3206 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
3207 {
3208 CONSOLE_NormalTextXY (8, Line, 48, 1);
3209
3210 Line--;
3211 if (Line<12) Line=14;
3212 if (Line>14) Line=12;
3213
3214
3215 CONSOLE_InvertTextXY (8, Line, 48, 1);
3216 }
3217 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3218 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
3219 {
3220 if (ConfirmQuit(Ir) == TRUE)
3221 return QUIT_PAGE;
3222 break;
3223 }
3224 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
3225 {
3226 if (Line == 12)
3227 {
3228 return BOOT_LOADER_HARDDISK_PAGE;
3229 }
3230 else if (Line == 13)
3231 {
3232 return BOOT_LOADER_FLOPPY_PAGE;
3233 }
3234 else if (Line == 14)
3235 {
3236 return SUCCESS_PAGE;;
3237 }
3238
3239 return BOOT_LOADER_PAGE;
3240 }
3241
3242 }
3243
3244 return BOOT_LOADER_PAGE;
3245 }
3246
3247
3248 static PAGE_NUMBER
3249 BootLoaderFloppyPage(PINPUT_RECORD Ir)
3250 {
3251 NTSTATUS Status;
3252
3253 MUIDisplayPage(BOOT_LOADER_FLOPPY_PAGE);
3254
3255 // SetStatusText(" Please wait...");
3256
3257 while(TRUE)
3258 {
3259 CONSOLE_ConInKey(Ir);
3260
3261 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3262 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
3263 {
3264 if (ConfirmQuit(Ir) == TRUE)
3265 return QUIT_PAGE;
3266 break;
3267 }
3268 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
3269 {
3270 if (DoesFileExist(L"\\Device\\Floppy0", L"\\") == FALSE)
3271 {
3272 MUIDisplayError(ERROR_NO_FLOPPY, Ir, POPUP_WAIT_ENTER);
3273 return BOOT_LOADER_FLOPPY_PAGE;
3274 }
3275
3276 Status = InstallFatBootcodeToFloppy(&SourceRootPath,
3277 &DestinationArcPath);
3278 if (!NT_SUCCESS(Status))
3279 {
3280 /* Print error message */
3281 return BOOT_LOADER_FLOPPY_PAGE;
3282 }
3283
3284 return SUCCESS_PAGE;
3285 }
3286 }
3287
3288 return BOOT_LOADER_FLOPPY_PAGE;
3289 }
3290
3291
3292 static PAGE_NUMBER
3293 BootLoaderHarddiskPage(PINPUT_RECORD Ir)
3294 {
3295 UCHAR PartitionType;
3296 NTSTATUS Status;
3297
3298 PartitionType = PartitionList->ActiveBootPartition->PartInfo[0].PartitionType;
3299 if ((PartitionType == PARTITION_FAT_12) ||
3300 (PartitionType == PARTITION_FAT_16) ||
3301 (PartitionType == PARTITION_HUGE) ||
3302 (PartitionType == PARTITION_XINT13) ||
3303 (PartitionType == PARTITION_FAT32) ||
3304 (PartitionType == PARTITION_FAT32_XINT13))
3305 {
3306 Status = InstallFatBootcodeToPartition(&SystemRootPath,
3307 &SourceRootPath,
3308 &DestinationArcPath,
3309 PartitionType);
3310 if (!NT_SUCCESS(Status))
3311 {
3312 MUIDisplayError(ERROR_INSTALL_BOOTCODE, Ir, POPUP_WAIT_ENTER);
3313 return QUIT_PAGE;
3314 }
3315
3316 return SUCCESS_PAGE;
3317 }
3318 else
3319 {
3320 MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER);
3321 return QUIT_PAGE;
3322 }
3323
3324 return BOOT_LOADER_HARDDISK_PAGE;
3325 }
3326
3327
3328 static PAGE_NUMBER
3329 QuitPage(PINPUT_RECORD Ir)
3330 {
3331 MUIDisplayPage(QUIT_PAGE);
3332
3333 /* Destroy partition list */
3334 if (PartitionList != NULL)
3335 {
3336 DestroyPartitionList (PartitionList);
3337 PartitionList = NULL;
3338 }
3339
3340 /* Destroy filesystem list */
3341 if (FileSystemList != NULL)
3342 {
3343 DestroyFileSystemList (FileSystemList);
3344 FileSystemList = NULL;
3345 }
3346
3347 /* Destroy computer settings list */
3348 if (ComputerList != NULL)
3349 {
3350 DestroyGenericList(ComputerList, TRUE);
3351 ComputerList = NULL;
3352 }
3353
3354 /* Destroy display settings list */
3355 if (DisplayList != NULL)
3356 {
3357 DestroyGenericList(DisplayList, TRUE);
3358 DisplayList = NULL;
3359 }
3360
3361 /* Destroy keyboard settings list */
3362 if (KeyboardList != NULL)
3363 {
3364 DestroyGenericList(KeyboardList, TRUE);
3365 KeyboardList = NULL;
3366 }
3367
3368 /* Destroy keyboard layout list */
3369 if (LayoutList != NULL)
3370 {
3371 DestroyGenericList(LayoutList, TRUE);
3372 LayoutList = NULL;
3373 }
3374
3375 if (LanguageList != NULL)
3376 {
3377 DestroyGenericList(LanguageList, FALSE);
3378 LanguageList = NULL;
3379 }
3380
3381 CONSOLE_SetStatusText(" ENTER = Reboot computer");
3382
3383 while(TRUE)
3384 {
3385 CONSOLE_ConInKey(Ir);
3386
3387 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
3388 {
3389 return FLUSH_PAGE;
3390 }
3391 }
3392 }
3393
3394
3395 static PAGE_NUMBER
3396 SuccessPage(PINPUT_RECORD Ir)
3397 {
3398 MUIDisplayPage(SUCCESS_PAGE);
3399
3400 if (IsUnattendedSetup)
3401 {
3402 return FLUSH_PAGE;
3403 }
3404
3405 while(TRUE)
3406 {
3407 CONSOLE_ConInKey(Ir);
3408
3409 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
3410 {
3411 return FLUSH_PAGE;
3412 }
3413 }
3414 }
3415
3416
3417 static PAGE_NUMBER
3418 FlushPage(PINPUT_RECORD Ir)
3419 {
3420 MUIDisplayPage(FLUSH_PAGE);
3421 return REBOOT_PAGE;
3422 }
3423
3424
3425 DWORD WINAPI
3426 PnpEventThread(IN LPVOID lpParameter);
3427
3428 VOID
3429 RunUSetup(VOID)
3430 {
3431 INPUT_RECORD Ir;
3432 PAGE_NUMBER Page;
3433 LARGE_INTEGER Time;
3434 NTSTATUS Status;
3435
3436 NtQuerySystemTime(&Time);
3437
3438 Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0, PnpEventThread, &SetupInf, &hPnpThread, NULL);
3439 if (!NT_SUCCESS(Status))
3440 hPnpThread = INVALID_HANDLE_VALUE;
3441 if (!CONSOLE_Init())
3442 {
3443 PrintString("Unable to open the console\n\n");
3444 PrintString("The most common cause of this is using an USB keyboard\n");
3445 PrintString("USB keyboards are not fully supported yet\n");
3446
3447 /* Raise a hard error (crash the system/BSOD) */
3448 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED,
3449 0,0,0,0,0);
3450 }
3451
3452 /* Initialize global unicode strings */
3453 RtlInitUnicodeString(&SourcePath, NULL);
3454 RtlInitUnicodeString(&SourceRootPath, NULL);
3455 RtlInitUnicodeString(&SourceRootDir, NULL);
3456 RtlInitUnicodeString(&InstallPath, NULL);
3457 RtlInitUnicodeString(&DestinationPath, NULL);
3458 RtlInitUnicodeString(&DestinationArcPath, NULL);
3459 RtlInitUnicodeString(&DestinationRootPath, NULL);
3460 RtlInitUnicodeString(&SystemRootPath, NULL);
3461
3462 /* Hide the cursor */
3463 CONSOLE_SetCursorType(TRUE, FALSE);
3464
3465 Page = START_PAGE;
3466 while (Page != REBOOT_PAGE)
3467 {
3468 CONSOLE_ClearScreen();
3469 CONSOLE_Flush();
3470
3471 //CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
3472 //CONSOLE_Flush();
3473
3474 switch (Page)
3475 {
3476 /* Start page */
3477 case START_PAGE:
3478 Page = SetupStartPage(&Ir);
3479 break;
3480 /* Language page */
3481 case LANGUAGE_PAGE:
3482 Page = LanguagePage(&Ir);
3483 break;
3484 /* License page */
3485 case LICENSE_PAGE:
3486 Page = LicensePage(&Ir);
3487 break;
3488
3489 /* Intro page */
3490 case INTRO_PAGE:
3491 Page = IntroPage(&Ir);
3492 break;
3493
3494 /* Install pages */
3495 case INSTALL_INTRO_PAGE:
3496 Page = InstallIntroPage(&Ir);
3497 break;
3498
3499 #if 0
3500 case SCSI_CONTROLLER_PAGE:
3501 Page = ScsiControllerPage(&Ir);
3502 break;
3503 #endif
3504
3505 #if 0
3506 case OEM_DRIVER_PAGE:
3507 Page = OemDriverPage(&Ir);
3508 break;
3509 #endif
3510
3511 case DEVICE_SETTINGS_PAGE:
3512 Page = DeviceSettingsPage(&Ir);
3513 break;
3514
3515 case COMPUTER_SETTINGS_PAGE:
3516 Page = ComputerSettingsPage(&Ir);
3517 break;
3518
3519 case DISPLAY_SETTINGS_PAGE:
3520 Page = DisplaySettingsPage(&Ir);
3521 break;
3522
3523 case KEYBOARD_SETTINGS_PAGE:
3524 Page = KeyboardSettingsPage(&Ir);
3525 break;
3526
3527 case LAYOUT_SETTINGS_PAGE:
3528 Page = LayoutSettingsPage(&Ir);
3529 break;
3530
3531 case SELECT_PARTITION_PAGE:
3532 Page = SelectPartitionPage(&Ir);
3533 break;
3534
3535 case CREATE_PARTITION_PAGE:
3536 Page = CreatePartitionPage(&Ir);
3537 break;
3538
3539 case DELETE_PARTITION_PAGE:
3540 Page = DeletePartitionPage(&Ir);
3541 break;
3542
3543 case SELECT_FILE_SYSTEM_PAGE:
3544 Page = SelectFileSystemPage(&Ir);
3545 break;
3546
3547 case FORMAT_PARTITION_PAGE:
3548 Page = (PAGE_NUMBER) FormatPartitionPage(&Ir);
3549 break;
3550
3551 case CHECK_FILE_SYSTEM_PAGE:
3552 Page = (PAGE_NUMBER) CheckFileSystemPage(&Ir);
3553 break;
3554
3555 case INSTALL_DIRECTORY_PAGE:
3556 Page = InstallDirectoryPage(&Ir);
3557 break;
3558
3559 case PREPARE_COPY_PAGE:
3560 Page = PrepareCopyPage(&Ir);
3561 break;
3562
3563 case FILE_COPY_PAGE:
3564 Page = FileCopyPage(&Ir);
3565 break;
3566
3567 case REGISTRY_PAGE:
3568 Page = RegistryPage(&Ir);
3569 break;
3570
3571 case BOOT_LOADER_PAGE:
3572 Page = BootLoaderPage(&Ir);
3573 break;
3574
3575 case BOOT_LOADER_FLOPPY_PAGE:
3576 Page = BootLoaderFloppyPage(&Ir);
3577 break;
3578
3579 case BOOT_LOADER_HARDDISK_PAGE:
3580 Page = BootLoaderHarddiskPage(&Ir);
3581 break;
3582
3583 /* Repair pages */
3584 case REPAIR_INTRO_PAGE:
3585 Page = RepairIntroPage(&Ir);
3586 break;
3587
3588 case SUCCESS_PAGE:
3589 Page = SuccessPage(&Ir);
3590 break;
3591
3592 case FLUSH_PAGE:
3593 Page = FlushPage(&Ir);
3594 break;
3595
3596 case QUIT_PAGE:
3597 Page = QuitPage(&Ir);
3598 break;
3599
3600 case REBOOT_PAGE:
3601 break;
3602 }
3603 }
3604
3605 /// THE FOLLOWING DPRINT IS FOR THE SYSTEM REGRESSION TOOL
3606 /// DO NOT REMOVE!!!
3607 DPRINT1("SYSREG_CHECKPOINT:USETUP_COMPLETE\n");
3608
3609 FreeConsole();
3610
3611 /* Avoid bugcheck */
3612 Time.QuadPart += 50000000;
3613 NtDelayExecution(FALSE, &Time);
3614
3615 /* Reboot */
3616 NtShutdownSystem(ShutdownReboot);
3617 NtTerminateProcess(NtCurrentProcess(), 0);
3618 }
3619
3620
3621 #ifdef __REACTOS__
3622
3623 VOID NTAPI
3624 NtProcessStartup(PPEB Peb)
3625 {
3626 RtlNormalizeProcessParams(Peb->ProcessParameters);
3627
3628 ProcessHeap = Peb->ProcessHeap;
3629 INF_SetHeap(ProcessHeap);
3630 RunUSetup();
3631 }
3632 #endif /* __REACTOS__ */
3633
3634 /* EOF */