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