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