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