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