ReactOS 0.4.16-dev-737-g3368adc
usetup.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2002, 2003, 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19/*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: base/setup/usetup/usetup.c
23 * PURPOSE: Text-mode setup
24 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
25 * Hervé Poussineau (hpoussin@reactos.org)
26 */
27
28#include <usetup.h>
29#include <math.h>
30#include <ntstrsafe.h>
31
32#include "cmdcons.h"
33#include "devinst.h"
34#include "fmtchk.h"
35
36#define NDEBUG
37#include <debug.h>
38
39
40/* GLOBALS & LOCALS *********************************************************/
41
43
45
46/* The partition where to perform the installation */
48// static PVOLENTRY InstallVolume = NULL;
49#define InstallVolume (InstallPartition->Volume)
50/*
51 * The system partition we will actually use. It can be different from
52 * PartitionList->SystemPartition in case we don't support it, or we install
53 * on a removable disk.
54 * We may indeed not support the original system partition in case we do not
55 * have write support on it. Please note that this situation is partly a HACK
56 * and MUST NEVER happen on architectures where real system partitions are
57 * mandatory (because then they are formatted in FAT FS and we support write
58 * operation on them).
59 */
61// static PVOLENTRY SystemVolume = NULL;
62#define SystemVolume (SystemPartition->Volume)
63
64
65/* OTHER Stuff *****/
66
68static WCHAR DefaultLanguage[20]; // Copy of string inside LanguageList
69static WCHAR DefaultKBLayout[20]; // Copy of string inside KeyboardList
70
72
73/* Global partition list on the system */
75
76/* Currently selected partition entry in the list */
78static enum {
79 PartTypeData, // On MBR-disks, primary or logical partition
80 PartTypeExtended // MBR-disk container
82
83/* Flag set in VOLENTRY::New when a partition/volume is created automatically */
84#define VOLUME_NEW_AUTOCREATE 0x80
85
86/* List of supported file systems for the partition to be formatted */
88
89/*****************************************************/
90
93
94#ifdef __REACTOS__ /* HACK */
95
96/* FONT SUBSTITUTION WORKAROUND *************************************************/
97
98/* For font file check */
99FONTSUBSTSETTINGS s_SubstSettings = { FALSE };
100
101static void
102DoWatchDestFileName(LPCWSTR FileName)
103{
104 if (FileName[0] == 'm' || FileName[0] == 'M')
105 {
106 if (_wcsicmp(FileName, L"mingliu.ttc") == 0)
107 {
108 DPRINT("mingliu.ttc found\n");
109 s_SubstSettings.bFoundFontMINGLIU = TRUE;
110 }
111 else if (_wcsicmp(FileName, L"msgothic.ttc") == 0)
112 {
113 DPRINT("msgothic.ttc found\n");
114 s_SubstSettings.bFoundFontMSGOTHIC = TRUE;
115 }
116 else if (_wcsicmp(FileName, L"msmincho.ttc") == 0)
117 {
118 DPRINT("msmincho.ttc found\n");
119 s_SubstSettings.bFoundFontMSMINCHO = TRUE;
120 }
121 else if (_wcsicmp(FileName, L"mssong.ttf") == 0)
122 {
123 DPRINT("mssong.ttf found\n");
124 s_SubstSettings.bFoundFontMSSONG = TRUE;
125 }
126 }
127 else
128 {
129 if (_wcsicmp(FileName, L"simsun.ttc") == 0)
130 {
131 DPRINT("simsun.ttc found\n");
132 s_SubstSettings.bFoundFontSIMSUN = TRUE;
133 }
134 else if (_wcsicmp(FileName, L"gulim.ttc") == 0)
135 {
136 DPRINT("gulim.ttc found\n");
137 s_SubstSettings.bFoundFontGULIM = TRUE;
138 }
139 else if (_wcsicmp(FileName, L"batang.ttc") == 0)
140 {
141 DPRINT("batang.ttc found\n");
142 s_SubstSettings.bFoundFontBATANG = TRUE;
143 }
144 }
145}
146#endif /* HACK */
147
148/* FUNCTIONS ****************************************************************/
149
150static VOID
152{
153 CHAR buffer[512];
154 va_list ap;
157
158 va_start(ap, fmt);
160 va_end(ap);
161
166}
167
168
169static VOID
171 IN SHORT yTop,
172 IN SHORT Width,
174{
175 COORD coPos;
176 DWORD Written;
177
178 /* Draw upper left corner */
179 coPos.X = xLeft;
180 coPos.Y = yTop;
182 CharUpperLeftCorner, // '+',
183 1,
184 coPos,
185 &Written);
186
187 /* Draw upper edge */
188 coPos.X = xLeft + 1;
189 coPos.Y = yTop;
191 CharHorizontalLine, // '-',
192 Width - 2,
193 coPos,
194 &Written);
195
196 /* Draw upper right corner */
197 coPos.X = xLeft + Width - 1;
198 coPos.Y = yTop;
200 CharUpperRightCorner, // '+',
201 1,
202 coPos,
203 &Written);
204
205 /* Draw right edge, inner space and left edge */
206 for (coPos.Y = yTop + 1; coPos.Y < yTop + Height - 1; coPos.Y++)
207 {
208 coPos.X = xLeft;
210 CharVerticalLine, // '|',
211 1,
212 coPos,
213 &Written);
214
215 coPos.X = xLeft + 1;
217 ' ',
218 Width - 2,
219 coPos,
220 &Written);
221
222 coPos.X = xLeft + Width - 1;
224 CharVerticalLine, // '|',
225 1,
226 coPos,
227 &Written);
228 }
229
230 /* Draw lower left corner */
231 coPos.X = xLeft;
232 coPos.Y = yTop + Height - 1;
234 CharLowerLeftCorner, // '+',
235 1,
236 coPos,
237 &Written);
238
239 /* Draw lower edge */
240 coPos.X = xLeft + 1;
241 coPos.Y = yTop + Height - 1;
243 CharHorizontalLine, // '-',
244 Width - 2,
245 coPos,
246 &Written);
247
248 /* Draw lower right corner */
249 coPos.X = xLeft + Width - 1;
250 coPos.Y = yTop + Height - 1;
252 CharLowerRightCorner, // '+',
253 1,
254 coPos,
255 &Written);
256}
257
258
259VOID
261 PCCH Status,
262 PINPUT_RECORD Ir,
263 ULONG WaitEvent)
264{
265 SHORT yTop;
266 SHORT xLeft;
267 COORD coPos;
268 DWORD Written;
270 ULONG MaxLength;
271 ULONG Lines;
272 PCHAR p;
273 PCCH pnext;
274 BOOLEAN LastLine;
275 SHORT Width;
277
278 /* Count text lines and longest line */
279 MaxLength = 0;
280 Lines = 0;
281 pnext = Text;
282
283 while (TRUE)
284 {
285 p = strchr(pnext, '\n');
286
287 if (p == NULL)
288 {
289 Length = strlen(pnext);
290 LastLine = TRUE;
291 }
292 else
293 {
294 Length = (ULONG)(p - pnext);
295 LastLine = FALSE;
296 }
297
298 Lines++;
299
300 if (Length > MaxLength)
301 MaxLength = Length;
302
303 if (LastLine)
304 break;
305
306 pnext = p + 1;
307 }
308
309 /* Check length of status line */
310 if (Status != NULL)
311 {
313
314 if (Length > MaxLength)
315 MaxLength = Length;
316 }
317
318 Width = MaxLength + 4;
319 Height = Lines + 2;
320
321 if (Status != NULL)
322 Height += 2;
323
324 yTop = (yScreen - Height) / 2;
325 xLeft = (xScreen - Width) / 2;
326
327
328 /* Set screen attributes */
329 coPos.X = xLeft;
330 for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++)
331 {
334 Width,
335 coPos,
336 &Written);
337 }
338
339 DrawBox(xLeft, yTop, Width, Height);
340
341 /* Print message text */
342 coPos.Y = yTop + 1;
343 pnext = Text;
344 while (TRUE)
345 {
346 p = strchr(pnext, '\n');
347
348 if (p == NULL)
349 {
350 Length = strlen(pnext);
351 LastLine = TRUE;
352 }
353 else
354 {
355 Length = (ULONG)(p - pnext);
356 LastLine = FALSE;
357 }
358
359 if (Length != 0)
360 {
361 coPos.X = xLeft + 2;
363 pnext,
364 Length,
365 coPos,
366 &Written);
367 }
368
369 if (LastLine)
370 break;
371
372 coPos.Y++;
373 pnext = p + 1;
374 }
375
376 /* Print separator line and status text */
377 if (Status != NULL)
378 {
379 coPos.Y = yTop + Height - 3;
380 coPos.X = xLeft;
383 1,
384 coPos,
385 &Written);
386
387 coPos.X = xLeft + 1;
389 CharHorizontalLine, // '-',
390 Width - 2,
391 coPos,
392 &Written);
393
394 coPos.X = xLeft + Width - 1;
397 1,
398 coPos,
399 &Written);
400
401 coPos.Y++;
402 coPos.X = xLeft + 2;
404 Status,
405 min(strlen(Status), (SIZE_T)Width - 4),
406 coPos,
407 &Written);
408 }
409
410 if (WaitEvent == POPUP_WAIT_NONE)
411 return;
412
413 while (TRUE)
414 {
416
417 if (WaitEvent == POPUP_WAIT_ANY_KEY ||
418 Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)
419 {
420 return;
421 }
422 }
423}
424
425
426/*
427 * Confirm quit setup
428 * RETURNS
429 * TRUE: Quit setup.
430 * FALSE: Don't quit setup.
431 */
432static BOOL
434{
435 BOOL Result = FALSE;
437
438 while (TRUE)
439 {
441
442 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
443 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
444 {
445 Result = TRUE;
446 break;
447 }
448 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
449 {
450 Result = FALSE;
451 break;
452 }
453 }
454
455 return Result;
456}
457
458
459static VOID
461{
462 PGENERIC_LIST_ENTRY ListEntry;
463 KLID newLayout;
464
466
468 {
471 {
472 /* FIXME: Handle error! */
473 return;
474 }
475 }
476
477 /* Search for default layout (if provided) */
478 if (newLayout != 0)
479 {
480 for (ListEntry = GetFirstListEntry(USetupData.LayoutList); ListEntry;
481 ListEntry = GetNextListEntry(ListEntry))
482 {
483 PCWSTR pszLayoutId = ((PGENENTRY)GetListEntryData(ListEntry))->Id;
484 KLID LayoutId = (KLID)(pszLayoutId ? wcstoul(pszLayoutId, NULL, 16) : 0);
485 if (newLayout == LayoutId)
486 {
488 break;
489 }
490 }
491 }
492}
493
494
495static NTSTATUS
496NTAPI
500 IN SIZE_T cchBufferSize)
501{
502 return RtlStringCchPrintfA(Buffer, cchBufferSize, "%S",
504}
505
506static NTSTATUS
507NTAPI
511 IN SIZE_T cchBufferSize)
512{
514 PVOLINFO VolInfo = (NtOsInstall->Volume ? &NtOsInstall->Volume->Info : NULL);
515
516 if (VolInfo && VolInfo->DriveLetter)
517 {
518 /* We have retrieved a partition that is mounted */
519 return RtlStringCchPrintfA(Buffer, cchBufferSize,
520 "%C:%S \"%S\"",
521 VolInfo->DriveLetter,
522 NtOsInstall->PathComponent,
523 NtOsInstall->InstallationName);
524 }
525 else
526 {
527 /* We failed somewhere, just show the NT path */
528 return RtlStringCchPrintfA(Buffer, cchBufferSize,
529 "%wZ \"%S\"",
530 &NtOsInstall->SystemNtPath,
531 NtOsInstall->InstallationName);
532 }
533}
534
535
536// PSETUP_ERROR_ROUTINE
537static VOID
540 IN PUSETUP_DATA pSetupData,
541 ...)
542{
543 INPUT_RECORD Ir;
544 va_list arg_ptr;
545
546 va_start(arg_ptr, pSetupData);
547
548 if (pSetupData->LastErrorNumber >= ERROR_SUCCESS &&
549 pSetupData->LastErrorNumber < ERROR_LAST_ERROR_CODE)
550 {
551 // Note: the "POPUP_WAIT_ENTER" actually depends on the LastErrorNumber...
552 MUIDisplayErrorV(pSetupData->LastErrorNumber, &Ir, POPUP_WAIT_ENTER, arg_ptr);
553 }
554
555 va_end(arg_ptr);
556}
557
558/*
559 * Start page
560 *
561 * Next pages:
562 * LanguagePage (at once, default)
563 * InstallIntroPage (at once, if unattended)
564 * QuitPage
565 *
566 * SIDEEFFECTS
567 * Init Sdi
568 * Init USetupData.SourcePath
569 * Init USetupData.SourceRootPath
570 * Init USetupData.SourceRootDir
571 * Init USetupData.SetupInf
572 * Init USetupData.RequiredPartitionDiskSpace
573 * Init IsUnattendedSetup
574 * If unattended, init *List and sets the Codepage
575 * If unattended, init SelectedLanguageId
576 * If unattended, init USetupData.LanguageId
577 *
578 * RETURNS
579 * Number of the next page.
580 */
581static PAGE_NUMBER
583{
584 ULONG Error;
585 PGENERIC_LIST_ENTRY ListEntry;
587
589
590 /* Initialize Setup */
593 if (Error != ERROR_SUCCESS)
594 {
596 return QUIT_PAGE;
597 }
598
599 /* Initialize the user-mode PnP manager */
601 DPRINT1("The user-mode PnP manager could not initialize, expect unavailable devices!\n");
602
603 /* Wait for any immediate pending installations to finish */
605 DPRINT1("WaitNoPendingInstallEvents() failed to wait!\n");
606
608
610 {
611 // TODO: Read options from inf
612 /* Load the hardware, language and keyboard layout lists */
613
617
619
620 /* new part */
624
626
627 /* first we hack LanguageList */
628 for (ListEntry = GetFirstListEntry(USetupData.LanguageList); ListEntry;
629 ListEntry = GetNextListEntry(ListEntry))
630 {
631 LocaleId = ((PGENENTRY)GetListEntryData(ListEntry))->Id;
633 {
634 DPRINT("found %S in LanguageList\n", LocaleId);
636 break;
637 }
638 }
639
640 /* now LayoutList */
641 for (ListEntry = GetFirstListEntry(USetupData.LayoutList); ListEntry;
642 ListEntry = GetNextListEntry(ListEntry))
643 {
644 LocaleId = ((PGENENTRY)GetListEntryData(ListEntry))->Id;
646 {
647 DPRINT("found %S in LayoutList\n", LocaleId);
649 break;
650 }
651 }
652
654
655 return INSTALL_INTRO_PAGE;
656 }
657
658 return LANGUAGE_PAGE;
659}
660
661
662/*
663 * Displays the LanguagePage.
664 *
665 * Next pages: WelcomePage, QuitPage
666 *
667 * SIDEEFFECTS
668 * Init SelectedLanguageId
669 * Init USetupData.LanguageId
670 *
671 * RETURNS
672 * Number of the next page.
673 */
674static PAGE_NUMBER
676{
677 GENERIC_LIST_UI ListUi;
678 PCWSTR NewLanguageId;
679 BOOL RefreshPage = FALSE;
680
681 /* Initialize the computer settings list */
683 {
686 {
687 PopupError("Setup failed to initialize available translations", NULL, NULL, POPUP_WAIT_NONE);
688 return WELCOME_PAGE;
689 }
690 }
691
694
695 /* Load the font */
698
699 /*
700 * If there is no language or just a single one in the list,
701 * skip the language selection process altogether.
702 */
704 {
706 return WELCOME_PAGE;
707 }
708
710 DrawGenericList(&ListUi,
711 2, 18,
712 xScreen - 3,
713 yScreen - 3);
714
716
718
719 while (TRUE)
720 {
722
723 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
724 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
725 {
726 ScrollDownGenericList(&ListUi);
727 RefreshPage = TRUE;
728 }
729 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
730 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
731 {
732 ScrollUpGenericList(&ListUi);
733 RefreshPage = TRUE;
734 }
735 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
736 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_NEXT)) /* PAGE DOWN */
737 {
739 RefreshPage = TRUE;
740 }
741 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
742 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_PRIOR)) /* PAGE UP */
743 {
745 RefreshPage = TRUE;
746 }
747 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
748 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
749 {
750 if (ConfirmQuit(Ir))
751 return QUIT_PAGE;
752 RedrawGenericList(&ListUi);
753 }
754 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
755 {
757
760
762
764 {
766 }
767
768 /* Load the font */
770
771 return WELCOME_PAGE;
772 }
773 else if ((Ir->Event.KeyEvent.uChar.AsciiChar > 0x60) && (Ir->Event.KeyEvent.uChar.AsciiChar < 0x7b))
774 {
775 /* a-z */
777 RefreshPage = TRUE;
778 }
779
780 if (RefreshPage)
781 {
783
784 NewLanguageId =
786
787 if (wcscmp(SelectedLanguageId, NewLanguageId))
788 {
789 /* Clear the language page */
791
792 SelectedLanguageId = NewLanguageId;
793
794 /* Load the font */
796
797 /* Redraw the list */
798 DrawGenericList(&ListUi,
799 2, 18,
800 xScreen - 3,
801 yScreen - 3);
802
803 /* Redraw language selection page in native language */
805 }
806
807 RefreshPage = FALSE;
808 }
809 }
810
811 return WELCOME_PAGE;
812}
813
814
815/*
816 * Displays the WelcomePage.
817 *
818 * Next pages:
819 * InstallIntroPage (default)
820 * RepairIntroPage
821 * RecoveryPage
822 * LicensePage
823 * QuitPage
824 *
825 * RETURNS
826 * Number of the next page.
827 */
828static PAGE_NUMBER
830{
832
833 while (TRUE)
834 {
836
837 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
838 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
839 {
840 if (ConfirmQuit(Ir))
841 return QUIT_PAGE;
842 break;
843 }
844 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
845 {
846 return INSTALL_INTRO_PAGE;
847 }
848 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */
849 {
850 return RECOVERY_PAGE; // REPAIR_INTRO_PAGE;
851 }
852 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'L') /* L */
853 {
854 return LICENSE_PAGE;
855 }
856 }
857
858 return WELCOME_PAGE;
859}
860
861
862/*
863 * Displays the License page.
864 *
865 * Next page:
866 * WelcomePage (default)
867 *
868 * RETURNS
869 * Number of the next page.
870 */
871static PAGE_NUMBER
873{
875
876 while (TRUE)
877 {
879
880 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
881 {
882 return WELCOME_PAGE;
883 }
884 }
885
886 return LICENSE_PAGE;
887}
888
889
890/*
891 * Displays the RepairIntroPage.
892 *
893 * Next pages:
894 * RebootPage (default)
895 * InstallIntroPage
896 * RecoveryPage
897 * IntroPage
898 *
899 * RETURNS
900 * Number of the next page.
901 */
902static PAGE_NUMBER
904{
906
907 while (TRUE)
908 {
910
911 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
912 {
913 return REBOOT_PAGE;
914 }
915 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'U') /* U */
916 {
918 return INSTALL_INTRO_PAGE;
919 }
920 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */
921 {
922 return RECOVERY_PAGE;
923 }
924 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
925 {
926 return WELCOME_PAGE;
927 }
928 }
929
930 return REPAIR_INTRO_PAGE;
931}
932
933/*
934 * Displays the UpgradeRepairPage.
935 *
936 * Next pages:
937 * RebootPage (default)
938 * InstallIntroPage
939 * RecoveryPage
940 * WelcomePage
941 *
942 * RETURNS
943 * Number of the next page.
944 */
945static PAGE_NUMBER
947{
948 GENERIC_LIST_UI ListUi;
949
950/*** HACK!! ***/
951 if (PartitionList == NULL)
952 {
954 if (PartitionList == NULL)
955 {
956 /* FIXME: show an error dialog */
958 return QUIT_PAGE;
959 }
961 {
963 return QUIT_PAGE;
964 }
965 }
966/**************/
967
969 if (!NtOsInstallsList)
970 DPRINT1("Failed to get a list of NTOS installations; continue installation...\n");
971
972 /*
973 * If there is no available installation (or just a single one??) that can
974 * be updated in the list, just continue with the regular installation.
975 */
977 {
979
980 // return INSTALL_INTRO_PAGE;
982 // return SCSI_CONTROLLER_PAGE;
983 }
984
986
988 DrawGenericList(&ListUi,
989 2, 23,
990 xScreen - 3,
991 yScreen - 3);
992
993 // return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
994 while (TRUE)
995 {
997
998 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x00)
999 {
1000 switch (Ir->Event.KeyEvent.wVirtualKeyCode)
1001 {
1002 case VK_DOWN: /* DOWN */
1003 ScrollDownGenericList(&ListUi);
1004 break;
1005 case VK_UP: /* UP */
1006 ScrollUpGenericList(&ListUi);
1007 break;
1008 case VK_NEXT: /* PAGE DOWN */
1010 break;
1011 case VK_PRIOR: /* PAGE UP */
1012 ScrollPageUpGenericList(&ListUi);
1013 break;
1014 case VK_F3: /* F3 */
1015 {
1016 if (ConfirmQuit(Ir))
1017 return QUIT_PAGE;
1018 RedrawGenericList(&ListUi);
1019 break;
1020 }
1021#if 1
1022/* TODO: Temporarily kept until correct keyboard layout is in place.
1023 * (Actual AsciiChar of ESCAPE should be 0x1B instead of 0.)
1024 * Addendum to commit 8b94515b.
1025 */
1026 case VK_ESCAPE: /* ESC */
1027 {
1029 // return nextPage; // prevPage;
1030
1031 // return INSTALL_INTRO_PAGE;
1032 return DEVICE_SETTINGS_PAGE;
1033 // return SCSI_CONTROLLER_PAGE;
1034 }
1035
1036#endif
1037 }
1038 }
1039#if 0
1040/* TODO: Restore this once correct keyboard layout is in place. */
1041 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
1042 {
1044 // return nextPage; // prevPage;
1045
1046 // return INSTALL_INTRO_PAGE;
1047 return DEVICE_SETTINGS_PAGE;
1048 // return SCSI_CONTROLLER_PAGE;
1049 }
1050#endif
1051 else
1052 {
1053 // switch (toupper(Ir->Event.KeyEvent.uChar.AsciiChar))
1054 // if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1055 if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'U') /* U */
1056 {
1057 /* Retrieve the current installation */
1059
1062
1063 DPRINT1("Selected installation for repair: \"%S\" ; DiskNumber = %d , PartitionNumber = %d\n",
1065
1067
1068 // return nextPage;
1069 /***/return INSTALL_INTRO_PAGE;/***/
1070 }
1071 else if ((Ir->Event.KeyEvent.uChar.AsciiChar > 0x60) &&
1072 (Ir->Event.KeyEvent.uChar.AsciiChar < 0x7b)) /* a-z */
1073 {
1075 }
1076 }
1077 }
1078
1079 return UPGRADE_REPAIR_PAGE;
1080}
1081
1082
1083/*
1084 * Displays the InstallIntroPage.
1085 *
1086 * Next pages:
1087 * DeviceSettingsPage (At once if repair or update is selected)
1088 * SelectPartitionPage (At once if unattended setup)
1089 * DeviceSettingsPage (default)
1090 * QuitPage
1091 *
1092 * RETURNS
1093 * Number of the next page.
1094 */
1095static PAGE_NUMBER
1097{
1098 if (RepairUpdateFlag)
1099 {
1100#if 1 /* Old code that looks good */
1101
1102 // return SELECT_PARTITION_PAGE;
1103 return DEVICE_SETTINGS_PAGE;
1104
1105#else /* Possible new code? */
1106
1107 return DEVICE_SETTINGS_PAGE;
1108 // return SCSI_CONTROLLER_PAGE;
1109
1110#endif
1111 }
1112
1114 return SELECT_PARTITION_PAGE;
1115
1117
1118 while (TRUE)
1119 {
1120 CONSOLE_ConInKey(Ir);
1121
1122 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1123 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1124 {
1125 if (ConfirmQuit(Ir))
1126 return QUIT_PAGE;
1127 break;
1128 }
1129 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1130 {
1131 return UPGRADE_REPAIR_PAGE;
1132 }
1133 }
1134
1135 return INSTALL_INTRO_PAGE;
1136}
1137
1138
1139#if 0
1140static PAGE_NUMBER
1141ScsiControllerPage(PINPUT_RECORD Ir)
1142{
1143 // MUIDisplayPage(SCSI_CONTROLLER_PAGE);
1144
1145 CONSOLE_SetTextXY(6, 8, "Setup detected the following mass storage devices:");
1146
1147 /* FIXME: print loaded mass storage driver descriptions */
1148#if 0
1149 CONSOLE_SetTextXY(8, 10, "TEST device");
1150#endif
1151
1152 CONSOLE_SetStatusText(" ENTER = Continue F3 = Quit");
1153
1154 while (TRUE)
1155 {
1156 CONSOLE_ConInKey(Ir);
1157
1158 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1159 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1160 {
1161 if (ConfirmQuit(Ir))
1162 return QUIT_PAGE;
1163 break;
1164 }
1165 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1166 {
1167 return DEVICE_SETTINGS_PAGE;
1168 }
1169 }
1170
1171 return SCSI_CONTROLLER_PAGE;
1172}
1173
1174static PAGE_NUMBER
1175OemDriverPage(PINPUT_RECORD Ir)
1176{
1177 // MUIDisplayPage(OEM_DRIVER_PAGE);
1178
1179 CONSOLE_SetTextXY(6, 8, "This is the OEM driver page!");
1180
1181 /* FIXME: Implement!! */
1182
1183 CONSOLE_SetStatusText(" ENTER = Continue F3 = Quit");
1184
1185 while (TRUE)
1186 {
1187 CONSOLE_ConInKey(Ir);
1188
1189 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1190 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1191 {
1192 if (ConfirmQuit(Ir))
1193 return QUIT_PAGE;
1194 break;
1195 }
1196 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1197 {
1198 return DEVICE_SETTINGS_PAGE;
1199 }
1200 }
1201
1202 return OEM_DRIVER_PAGE;
1203}
1204#endif
1205
1206
1207/*
1208 * Displays the DeviceSettingsPage.
1209 *
1210 * Next pages:
1211 * SelectPartitionPage (At once if repair or update is selected)
1212 * ComputerSettingsPage
1213 * DisplaySettingsPage
1214 * KeyboardSettingsPage
1215 * LayoutsettingsPage
1216 * SelectPartitionPage
1217 * QuitPage
1218 *
1219 * SIDEEFFECTS
1220 * Init USetupData.ComputerList
1221 * Init USetupData.DisplayList
1222 * Init USetupData.KeyboardList
1223 * Init USetupData.LayoutList
1224 *
1225 * RETURNS
1226 * Number of the next page.
1227 */
1228static PAGE_NUMBER
1230{
1231 static ULONG Line = 16;
1232
1233 /* Initialize the computer settings list */
1235 {
1238 {
1240 return QUIT_PAGE;
1241 }
1242 }
1243
1244 /* Initialize the display settings list */
1246 {
1249 {
1251 return QUIT_PAGE;
1252 }
1253 }
1254
1255 /* Initialize the keyboard settings list */
1257 {
1260 {
1262 return QUIT_PAGE;
1263 }
1264 }
1265
1266 /* Initialize the keyboard layout list */
1268 {
1271 {
1272 /* FIXME: report error */
1274 return QUIT_PAGE;
1275 }
1276 }
1277
1278 if (RepairUpdateFlag)
1279 return SELECT_PARTITION_PAGE;
1280
1281 // if (IsUnattendedSetup)
1282 // return SELECT_PARTITION_PAGE;
1283
1285
1290
1291 CONSOLE_InvertTextXY(24, Line, 48, 1);
1292
1293 while (TRUE)
1294 {
1295 CONSOLE_ConInKey(Ir);
1296
1297 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1298 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
1299 {
1300 CONSOLE_NormalTextXY(24, Line, 48, 1);
1301
1302 if (Line == 14)
1303 Line = 16;
1304 else if (Line == 16)
1305 Line = 11;
1306 else
1307 Line++;
1308
1309 CONSOLE_InvertTextXY(24, Line, 48, 1);
1310 }
1311 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1312 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
1313 {
1314 CONSOLE_NormalTextXY(24, Line, 48, 1);
1315
1316 if (Line == 11)
1317 Line = 16;
1318 else if (Line == 16)
1319 Line = 14;
1320 else
1321 Line--;
1322
1323 CONSOLE_InvertTextXY(24, Line, 48, 1);
1324 }
1325 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1326 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1327 {
1328 if (ConfirmQuit(Ir))
1329 return QUIT_PAGE;
1330 break;
1331 }
1332 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1333 {
1334 if (Line == 11)
1336 else if (Line == 12)
1337 return DISPLAY_SETTINGS_PAGE;
1338 else if (Line == 13)
1340 else if (Line == 14)
1341 return LAYOUT_SETTINGS_PAGE;
1342 else if (Line == 16)
1343 return SELECT_PARTITION_PAGE;
1344 }
1345 }
1346
1347 return DEVICE_SETTINGS_PAGE;
1348}
1349
1350
1351/*
1352 * Handles generic selection lists.
1353 *
1354 * PARAMS
1355 * GenericList: The list to handle.
1356 * nextPage: The page it needs to jump to after this page.
1357 * Ir: The PINPUT_RECORD
1358 */
1359static PAGE_NUMBER
1361 PAGE_NUMBER nextPage,
1362 PINPUT_RECORD Ir)
1363{
1364 while (TRUE)
1365 {
1366 CONSOLE_ConInKey(Ir);
1367
1368 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1369 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
1370 {
1371 ScrollDownGenericList(ListUi);
1372 }
1373 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1374 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
1375 {
1376 ScrollUpGenericList(ListUi);
1377 }
1378 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1379 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_NEXT)) /* PAGE DOWN */
1380 {
1382 }
1383 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1384 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_PRIOR)) /* PAGE UP */
1385 {
1387 }
1388 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1389 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1390 {
1391 if (ConfirmQuit(Ir))
1392 return QUIT_PAGE;
1393 RedrawGenericList(ListUi);
1394 }
1395 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
1396 {
1398 return nextPage; // Use some "prevPage;" instead?
1399 }
1400 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1401 {
1402 return nextPage;
1403 }
1404 else if ((Ir->Event.KeyEvent.uChar.AsciiChar > 0x60) && (Ir->Event.KeyEvent.uChar.AsciiChar < 0x7b))
1405 {
1406 /* a-z */
1408 }
1409 }
1410}
1411
1412
1413/*
1414 * Displays the ComputerSettingsPage.
1415 *
1416 * Next pages:
1417 * DeviceSettingsPage
1418 * QuitPage
1419 *
1420 * RETURNS
1421 * Number of the next page.
1422 */
1423static PAGE_NUMBER
1425{
1426 GENERIC_LIST_UI ListUi;
1428
1430 DrawGenericList(&ListUi,
1431 2, 18,
1432 xScreen - 3,
1433 yScreen - 3);
1434
1435 return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
1436}
1437
1438
1439/*
1440 * Displays the DisplaySettingsPage.
1441 *
1442 * Next pages:
1443 * DeviceSettingsPage
1444 * QuitPage
1445 *
1446 * RETURNS
1447 * Number of the next page.
1448 */
1449static PAGE_NUMBER
1451{
1452 GENERIC_LIST_UI ListUi;
1454
1456 DrawGenericList(&ListUi,
1457 2, 18,
1458 xScreen - 3,
1459 yScreen - 3);
1460
1461 return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
1462}
1463
1464
1465/*
1466 * Displays the KeyboardSettingsPage.
1467 *
1468 * Next pages:
1469 * DeviceSettingsPage
1470 * QuitPage
1471 *
1472 * RETURNS
1473 * Number of the next page.
1474 */
1475static PAGE_NUMBER
1477{
1478 GENERIC_LIST_UI ListUi;
1480
1482 DrawGenericList(&ListUi,
1483 2, 18,
1484 xScreen - 3,
1485 yScreen - 3);
1486
1487 return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
1488}
1489
1490
1491/*
1492 * Displays the LayoutSettingsPage.
1493 *
1494 * Next pages:
1495 * DeviceSettingsPage
1496 * QuitPage
1497 *
1498 * RETURNS
1499 * Number of the next page.
1500 */
1501static PAGE_NUMBER
1503{
1504 GENERIC_LIST_UI ListUi;
1506
1508 DrawGenericList(&ListUi,
1509 2, 18,
1510 xScreen - 3,
1511 yScreen - 3);
1512
1513 return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
1514}
1515
1516
1517static BOOLEAN
1519 _In_ ULONGLONG SizeInBytes)
1520{
1521 /* Retrieve the maximum size in MB (rounded up) */
1522 ULONGLONG SizeInMB = RoundingDivide(SizeInBytes, MB);
1523
1524 /* Check the medium size */
1526 {
1527 DPRINT1("Partition/Volume is too small (size: %I64u MB), required space is %lu MB\n",
1529 return FALSE;
1530 }
1531 return TRUE;
1532}
1533
1534
1535/*
1536 * Displays the SelectPartitionPage.
1537 *
1538 * Next pages:
1539 * SelectFileSystemPage (At once if unattended)
1540 * SelectFileSystemPage (Default if free space is selected)
1541 * CreatePartitionPage
1542 * ConfirmDeleteSystemPartitionPage (if the selected partition is the system partition, aka with the boot flag set)
1543 * DeletePartitionPage
1544 * QuitPage
1545 *
1546 * SIDEEFFECTS
1547 * Set InstallShortcut (only if not unattended + free space is selected)
1548 *
1549 * RETURNS
1550 * Number of the next page.
1551 */
1552static PAGE_NUMBER
1554{
1555 PARTLIST_UI ListUi;
1556 ULONG Error;
1557 ULONGLONG MaxTargetSize;
1558
1559 if (PartitionList == NULL)
1560 {
1562 if (PartitionList == NULL)
1563 {
1565 return QUIT_PAGE;
1566 }
1568 {
1570 return QUIT_PAGE;
1571 }
1572 }
1573
1574 if (RepairUpdateFlag)
1575 {
1577
1578 /* Determine the selected installation disk & partition.
1579 * It must exist and be valid, since this is the partition
1580 * where the existing installation already resides. */
1584 if (!InstallPartition)
1585 {
1586 DPRINT1("RepairUpdateFlag == TRUE, SelectPartition() returned FALSE, assert!\n");
1587 ASSERT(FALSE);
1588 }
1591
1593 }
1594
1596
1599 2, 21,
1600 xScreen - 3,
1601 yScreen - 3);
1602 DrawPartitionList(&ListUi);
1603
1604 if (IsUnattendedSetup) do
1605 {
1606 /* If DestinationDiskNumber or DestinationPartitionNumber are invalid
1607 * (see below), don't select the partition and show the list instead */
1610 {
1611 break;
1612 }
1613
1614 /* Determine the selected installation disk & partition */
1618
1619 /* Now reset DestinationDiskNumber and DestinationPartitionNumber
1620 * to *invalid* values, so that if the corresponding partition is
1621 * determined to be invalid by the code below or in CreateInstallPartition,
1622 * we don't reselect it when SelectPartitionPage() is called again */
1625
1626 // FIXME: Here and in the AutoPartition case below, the CurrentPartition
1627 // may actually be unsuitable (MBR-extended, non-simple volume...).
1628 // More checks need to be made here!
1629 //
1630 // NOTE: We don't check for CurrentPartition->Volume in case
1631 // the partition doesn't contain a recognized volume/none exists.
1632 // We also don't check whether IsPartitioned is TRUE, because if
1633 // the partition is still empty space, we'll try to partition it.
1635 goto CreateInstallPartition;
1636
1638 {
1640 // TODO: Do more checks, and loop until we find a valid partition.
1641 goto CreateInstallPartition;
1642 }
1643 } while (0);
1644
1645 while (TRUE)
1646 {
1647 ULONG uID;
1648
1650
1651 /* Update status text */
1652 if (!CurrentPartition)
1653 {
1654 // FIXME: If we get a NULL current partition, this means that
1655 // the current disk is of unrecognized type. So we should display
1656 // instead a status string to initialize the disk with one of
1657 // the recognized partitioning schemes (MBR, later: GPT, etc.)
1658 // For the time being we don't have that, so use instead another
1659 // known string.
1661 }
1662 else
1663 {
1665 {
1669 {
1671 }
1672 }
1673 else
1674 {
1678 }
1679 }
1681
1682 CONSOLE_ConInKey(Ir);
1683
1684 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1685 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1686 {
1687 if (ConfirmQuit(Ir))
1688 {
1691 return QUIT_PAGE;
1692 }
1693 return SELECT_PARTITION_PAGE;
1694 }
1695 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1696 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
1697 {
1699 }
1700 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1701 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
1702 {
1704 }
1705 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
1706 {
1708
1709 /* Don't select an extended partition for OS installation */
1711 continue;
1712
1713 /*
1714 * Check whether the user wants to install ReactOS on a disk that
1715 * is not recognized by the computer's firmware and if so, display
1716 * a warning since such disks may not be bootable.
1717 */
1718 if (CurrentPartition->DiskEntry->MediaType == FixedMedia &&
1719 !CurrentPartition->DiskEntry->BiosFound)
1720 {
1721 PopupError("The disk you have selected for installing ReactOS\n"
1722 "is not visible by the firmware of your computer,\n"
1723 "and so may not be bootable.\n"
1724 "Press ENTER to continue anyway.",
1726 Ir, POPUP_WAIT_ENTER);
1727 // return SELECT_PARTITION_PAGE;
1728 }
1729
1730 goto CreateInstallPartition;
1731 }
1732 else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'C') /* C */
1733 {
1735
1737 if (Error != NOT_AN_ERROR)
1738 {
1740 return SELECT_PARTITION_PAGE;
1741 }
1742
1744 return CREATE_PARTITION_PAGE;
1745 }
1746 else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'E') /* E */
1747 {
1749
1750 /* Don't create an extended partition within a logical partition */
1752 continue;
1753
1755 if (Error != NOT_AN_ERROR)
1756 {
1758 return SELECT_PARTITION_PAGE;
1759 }
1760
1762 return CREATE_PARTITION_PAGE;
1763 }
1764 else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'D') /* D */
1765 {
1767
1768 /* Ignore deletion in case this is not a partitioned entry */
1770 continue;
1771
1772// TODO: Do something similar before trying to format the partition?
1775 {
1776 UNICODE_STRING CurrentPartitionU;
1777 WCHAR PathBuffer[RTL_NUMBER_OF_FIELD(VOLINFO, DeviceName) + 1];
1778
1780
1781 RtlStringCchPrintfW(PathBuffer, _countof(PathBuffer),
1783 RtlInitUnicodeString(&CurrentPartitionU, PathBuffer);
1784
1785 /*
1786 * Check whether the user attempts to delete the partition on which
1787 * the installation source is present. If so, fail with an error.
1788 */
1789 // &USetupData.SourceRootPath
1790 if (RtlPrefixUnicodeString(&CurrentPartitionU, &USetupData.SourcePath, TRUE))
1791 {
1793 return SELECT_PARTITION_PAGE;
1794 }
1795 }
1796
1799 {
1801 }
1802
1803 return DELETE_PARTITION_PAGE;
1804 }
1805 }
1806
1807CreateInstallPartition:
1810
1811 /* Create the partition if the selected region is empty */
1813 {
1815 if (Error != NOT_AN_ERROR)
1816 {
1818 return SELECT_PARTITION_PAGE;
1819 }
1820
1821 /* Automatically create the partition on the whole empty space;
1822 * it will be formatted later with default parameters */
1825 0ULL,
1826 0);
1830 }
1831
1832 /* Verify the target medium size */
1834 if (!IsMediumLargeEnough(MaxTargetSize))
1835 {
1838 return SELECT_PARTITION_PAGE; /* Let the user select another partition */
1839 }
1840
1843}
1844
1845
1846#define PARTITION_SIZE_INPUT_FIELD_LENGTH 9
1847/* Restriction for MaxSize */
1848#define PARTITION_MAXSIZE (pow(10, (PARTITION_SIZE_INPUT_FIELD_LENGTH - 1)) - 1)
1849
1850static VOID
1852 SHORT Top,
1853 SHORT Right,
1854 SHORT Bottom,
1855 ULONG MaxSize,
1857 PBOOLEAN Quit,
1859{
1860 INPUT_RECORD Ir;
1861 COORD coPos;
1862 DWORD Written;
1863 CHAR Buffer[128];
1864 INT Length, Pos;
1865 WCHAR ch;
1866 SHORT iLeft;
1867 SHORT iTop;
1868
1869 if (Quit != NULL)
1870 *Quit = FALSE;
1871
1872 if (Cancel != NULL)
1873 *Cancel = FALSE;
1874
1875 DrawBox(Left, Top, Right - Left + 1, Bottom - Top + 1);
1876
1877 /* Print message */
1878 coPos.X = Left + 2;
1879 coPos.Y = Top + 2;
1881 iLeft = coPos.X + (USHORT)strlen(Buffer) + 1;
1882 iTop = coPos.Y;
1883
1885 Buffer,
1886 strlen(Buffer),
1887 coPos,
1888 &Written);
1889
1891 coPos.X = iLeft + PARTITION_SIZE_INPUT_FIELD_LENGTH + 1;
1892 coPos.Y = iTop;
1894 Buffer,
1895 strlen(Buffer),
1896 coPos,
1897 &Written);
1898
1899 swprintf(InputBuffer, L"%lu", MaxSize);
1901 Pos = Length;
1903 iTop,
1905 InputBuffer);
1906 CONSOLE_SetCursorXY(iLeft + Length, iTop);
1908
1909 while (TRUE)
1910 {
1911 CONSOLE_ConInKey(&Ir);
1912
1913 if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1914 (Ir.Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1915 {
1916 if (Quit != NULL)
1917 *Quit = TRUE;
1918
1920 break;
1921 }
1922 else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
1923 {
1924 break;
1925 }
1926 else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
1927 {
1928 if (Cancel != NULL)
1929 *Cancel = TRUE;
1930
1932 break;
1933 }
1934 else if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1935 (Ir.Event.KeyEvent.wVirtualKeyCode == VK_HOME)) /* HOME */
1936 {
1937 Pos = 0;
1938 CONSOLE_SetCursorXY(iLeft + Pos, iTop);
1939 }
1940 else if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1941 (Ir.Event.KeyEvent.wVirtualKeyCode == VK_END)) /* END */
1942 {
1943 Pos = Length;
1944 CONSOLE_SetCursorXY(iLeft + Pos, iTop);
1945 }
1946 else if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1947 (Ir.Event.KeyEvent.wVirtualKeyCode == VK_LEFT)) /* LEFT */
1948 {
1949 if (Pos > 0)
1950 {
1951 Pos--;
1952 CONSOLE_SetCursorXY(iLeft + Pos, iTop);
1953 }
1954 }
1955 else if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1956 (Ir.Event.KeyEvent.wVirtualKeyCode == VK_RIGHT)) /* RIGHT */
1957 {
1958 if (Pos < Length)
1959 {
1960 Pos++;
1961 CONSOLE_SetCursorXY(iLeft + Pos, iTop);
1962 }
1963 }
1964 else if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1965 (Ir.Event.KeyEvent.wVirtualKeyCode == VK_DELETE)) /* DEL */
1966 {
1967 if (Pos < Length)
1968 {
1970 &InputBuffer[Pos + 1],
1971 (Length - Pos - 1) * sizeof(WCHAR));
1973
1974 Length--;
1976 iTop,
1978 InputBuffer);
1979 CONSOLE_SetCursorXY(iLeft + Pos, iTop);
1980 }
1981 }
1982 else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_BACK) /* BACKSPACE */
1983 {
1984 if (Pos > 0)
1985 {
1986 if (Pos < Length)
1987 memmove(&InputBuffer[Pos - 1],
1988 &InputBuffer[Pos],
1989 (Length - Pos) * sizeof(WCHAR));
1991
1992 Pos--;
1993 Length--;
1995 iTop,
1997 InputBuffer);
1998 CONSOLE_SetCursorXY(iLeft + Pos, iTop);
1999 }
2000 }
2001 else if (Ir.Event.KeyEvent.uChar.AsciiChar != 0x00)
2002 {
2004 {
2006
2007 if ((ch >= L'0') && (ch <= L'9'))
2008 {
2009 if (Pos < Length)
2010 memmove(&InputBuffer[Pos + 1],
2011 &InputBuffer[Pos],
2012 (Length - Pos) * sizeof(WCHAR));
2014 InputBuffer[Pos] = ch;
2015
2016 Pos++;
2017 Length++;
2019 iTop,
2021 InputBuffer);
2022 CONSOLE_SetCursorXY(iLeft + Pos, iTop);
2023 }
2024 }
2025 }
2026 }
2027
2029}
2030
2031
2032/*
2033 * Displays the CreatePartitionPage.
2034 *
2035 * Next pages:
2036 * SelectPartitionPage
2037 * SelectFileSystemPage (default)
2038 * QuitPage
2039 *
2040 * RETURNS
2041 * Number of the next page.
2042 */
2043static PAGE_NUMBER
2045{
2046 PPARTENTRY PartEntry;
2047 PDISKENTRY DiskEntry;
2048 ULONG uID;
2049 ULONG MaxSize;
2050 ULONGLONG MaxPartSize, PartSize;
2051 BOOLEAN Quit, Cancel;
2052 WCHAR InputBuffer[50];
2053 CHAR LineBuffer[100];
2054
2056 {
2057 /* FIXME: show an error dialog */
2058 return QUIT_PAGE;
2059 }
2060
2062 {
2066 }
2067 else // if (PartCreateType == PartTypeExtended)
2068 {
2070 }
2071
2072 CONSOLE_SetTextXY(6, 8, MUIGetString(uID));
2073
2074 PartEntry = CurrentPartition;
2075 DiskEntry = CurrentPartition->DiskEntry;
2076
2077 DiskDescription(DiskEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2079 LineBuffer);
2080
2082
2084
2085 MaxPartSize = GetPartEntrySizeInBytes(PartEntry);
2086
2087 while (TRUE)
2088 {
2089 /* Retrieve the maximum size in MB (rounded up)
2090 * and cap it with what the user can enter */
2091 MaxSize = (ULONG)RoundingDivide(MaxPartSize, MB);
2092 MaxSize = min(MaxSize, PARTITION_MAXSIZE);
2093
2094 ShowPartitionSizeInputBox(12, 14, xScreen - 12, 17,
2095 MaxSize, InputBuffer, &Quit, &Cancel);
2096 if (Quit)
2097 {
2098 if (ConfirmQuit(Ir))
2099 return QUIT_PAGE;
2100 break;
2101 }
2102 else if (Cancel)
2103 {
2104 return SELECT_PARTITION_PAGE;
2105 }
2106
2107 PartSize = _wcstoui64(InputBuffer, NULL, 10);
2108
2109 /* Retry if too small or too large */
2110 if ((PartSize < 1) || (PartSize > MaxSize))
2111 continue;
2112
2113 /*
2114 * If the input size, given in MB, specifies the maximum partition
2115 * size, it may slightly under- or over-estimate the latter due to
2116 * rounding error. In this case, use all of the unpartitioned space.
2117 * Otherwise, directly convert the size to bytes.
2118 */
2119 if (PartSize == MaxSize)
2120 PartSize = MaxPartSize;
2121 else // if (PartSize < MaxSize)
2122 PartSize *= MB;
2123 DPRINT("Partition size: %I64u bytes\n", PartSize);
2124
2125 ASSERT(PartSize <= MaxPartSize);
2126
2129 PartSize,
2131 ? 0
2132 // (PartCreateType == PartTypeExtended)
2134
2135 return SELECT_PARTITION_PAGE;
2136 }
2137
2138 return CREATE_PARTITION_PAGE;
2139}
2140
2141
2142/*
2143 * Displays the ConfirmDeleteSystemPartitionPage.
2144 *
2145 * Next pages:
2146 * DeletePartitionPage (default)
2147 * SelectPartitionPage
2148 *
2149 * RETURNS
2150 * Number of the next page.
2151 */
2152static PAGE_NUMBER
2154{
2156
2157 while (TRUE)
2158 {
2159 CONSOLE_ConInKey(Ir);
2160
2161 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2162 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
2163 {
2164 if (ConfirmQuit(Ir))
2165 return QUIT_PAGE;
2166 break;
2167 }
2168 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
2169 {
2170 return DELETE_PARTITION_PAGE;
2171 }
2172 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
2173 {
2174 return SELECT_PARTITION_PAGE;
2175 }
2176 }
2177
2179}
2180
2181
2182/*
2183 * Displays the DeletePartitionPage.
2184 *
2185 * Next pages:
2186 * SelectPartitionPage (default)
2187 * QuitPage
2188 *
2189 * RETURNS
2190 * Number of the next page.
2191 */
2192static PAGE_NUMBER
2194{
2195 PPARTENTRY PartEntry;
2196 PDISKENTRY DiskEntry;
2197 CHAR LineBuffer[100];
2198
2200 {
2201 /* FIXME: show an error dialog */
2202 return QUIT_PAGE;
2203 }
2204
2205 PartEntry = CurrentPartition;
2206 DiskEntry = CurrentPartition->DiskEntry;
2207
2209
2210 PartitionDescription(PartEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2211 CONSOLE_SetTextXY(6, 10, LineBuffer);
2212
2213 DiskDescription(DiskEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2215 LineBuffer);
2216
2217 while (TRUE)
2218 {
2219 CONSOLE_ConInKey(Ir);
2220
2221 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2222 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
2223 {
2224 if (ConfirmQuit(Ir))
2225 return QUIT_PAGE;
2226 break;
2227 }
2228 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
2229 {
2230 return SELECT_PARTITION_PAGE;
2231 }
2232 else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'L') /* L */
2233 {
2237 return SELECT_PARTITION_PAGE;
2238 }
2239 }
2240
2241 return DELETE_PARTITION_PAGE;
2242}
2243
2244
2245/*
2246 * Displays the SelectFileSystemPage.
2247 *
2248 * Next pages:
2249 * CheckFileSystemPage (At once if RepairUpdate is selected)
2250 * CheckFileSystemPage (At once if Unattended and not USetupData.FormatPartition)
2251 * FormatPartitionPage (Default, at once if Unattended and USetupData.FormatPartition)
2252 * SelectPartitionPage (If the user aborts)
2253 * QuitPage
2254 *
2255 * RETURNS
2256 * Number of the next page.
2257 */
2258// PFSVOL_CALLBACK
2259static FSVOL_OP
2263 _In_ FSVOLNOTIFY FormatStatus,
2264 _In_ ULONG_PTR Param1,
2265 _In_ ULONG_PTR Param2);
2266
2267typedef struct _FSVOL_CONTEXT
2268{
2272
2273static PAGE_NUMBER
2275{
2276 FSVOL_CONTEXT FsVolContext = {Ir, QUIT_PAGE};
2278
2280 {
2281 /* FIXME: show an error dialog */
2282 return QUIT_PAGE;
2283 }
2284
2285 /* Find or set the active system partition before starting formatting */
2290 &FsVolContext);
2291 if (!Success)
2292 return FsVolContext.NextPageOnAbort;
2293 //
2294 // FIXME?? If cannot use any system partition, install FreeLdr on floppy / removable media??
2295 //
2296
2297 /* Set the AUTOCREATE flag if the system partition was automatically created */
2300
2302 CONSOLE_Flush();
2303
2304 /* Apply all pending operations on partitions: formatting and checking */
2309 &FsVolContext);
2310 if (!Success)
2311 return FsVolContext.NextPageOnAbort;
2313}
2314
2315static BOOLEAN
2317 IN PINPUT_RECORD Ir,
2319{
2320 PPARTENTRY PartEntry;
2321 PDISKENTRY DiskEntry;
2322 CHAR LineBuffer[100];
2323
2324 // CONSOLE_ClearScreen();
2325 // CONSOLE_Flush();
2327
2328 PartEntry = PartitionList->SystemPartition;
2329 DiskEntry = PartEntry->DiskEntry;
2330
2331 PartitionDescription(PartEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2332 CONSOLE_SetTextXY(8, 10, LineBuffer);
2333
2334 DiskDescription(DiskEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2336 LineBuffer);
2337
2338
2339 PartEntry = SystemPartition;
2340 DiskEntry = PartEntry->DiskEntry;
2341
2342 PartitionDescription(PartEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2343 CONSOLE_SetTextXY(8, 23, LineBuffer);
2344
2345 while (TRUE)
2346 {
2347 CONSOLE_ConInKey(Ir);
2348
2349 if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
2350 break;
2351 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
2352 return FALSE;
2353 }
2354
2355 return TRUE;
2356}
2357
2358static VOID
2360{
2361 if (!FileSystemList)
2362 return;
2363
2366}
2367
2368static FSVOL_OP
2370 _In_ PFSVOL_CONTEXT FsVolContext,
2372{
2373 PINPUT_RECORD Ir = FsVolContext->Ir;
2374 PPARTENTRY PartEntry = Volume->PartEntry;
2375 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2376 PCWSTR DefaultFs;
2377 BOOLEAN ForceFormat;
2378 CHAR LineBuffer[100];
2379
2380 DPRINT("SelectFileSystemPage()\n");
2381
2382 ForceFormat = (Volume->New || Volume->FormatState == Unformatted);
2383
2384Restart:
2385 /* Reset the file system list for each volume that is to be formatted */
2387
2389 CONSOLE_Flush();
2391
2392 if (Volume->New & VOLUME_NEW_AUTOCREATE)
2393 {
2394 Volume->New &= ~VOLUME_NEW_AUTOCREATE;
2395
2397 }
2398 else if (Volume->New)
2399 {
2400 ULONG uID;
2401
2402 if (Volume == SystemVolume)
2404 else if (Volume == InstallVolume)
2406 else
2408
2409 CONSOLE_SetTextXY(6, 8, MUIGetString(uID));
2410 }
2411 else
2412 {
2414 }
2415
2416 PartitionDescription(PartEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2417 CONSOLE_SetTextXY(6, 10, LineBuffer);
2418
2419 DiskDescription(DiskEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2421 LineBuffer);
2422
2423 /* Show "This Partition will be formatted next" only if it is unformatted */
2424 if (ForceFormat)
2426
2428
2430 {
2432
2433 switch (USetupData.FsType)
2434 {
2435 /* 1 is for BtrFS */
2436 case 1:
2437 DefaultFs = L"BTRFS";
2438 break;
2439
2440 /* If we don't understand input, default to FAT */
2441 default:
2442 DefaultFs = L"FAT";
2443 break;
2444 }
2445 }
2446 else
2447 {
2448 /* By default select the "FAT" file system */
2449 DefaultFs = L"FAT";
2450 }
2451
2452 /* Create the file system list */
2453 // TODO: Display only the FSes compatible with the selected volume!
2454 FileSystemList = CreateFileSystemList(6, 26, ForceFormat, DefaultFs);
2455 if (!FileSystemList)
2456 {
2457 /* FIXME: show an error dialog */
2458 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2459 return FSVOL_ABORT;
2460 }
2461
2463 {
2465 return FSVOL_DOIT;
2466 }
2467
2469
2470 while (TRUE)
2471 {
2472 CONSOLE_ConInKey(Ir);
2473
2474 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2475 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
2476 {
2477 if (ConfirmQuit(Ir))
2478 {
2479 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2480 return FSVOL_ABORT;
2481 }
2482 break;
2483 }
2484 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
2485 {
2486 FsVolContext->NextPageOnAbort = SELECT_PARTITION_PAGE;
2487 return FSVOL_ABORT;
2488 }
2489 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2490 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
2491 {
2493 }
2494 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2495 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
2496 {
2498 }
2499 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
2500 {
2502 {
2503 /* The 'Keep existing filesystem' entry was chosen,
2504 * the volume must be already formatted */
2505 ASSERT(!ForceFormat);
2506
2507 /* Skip formatting this volume. We will also ignore
2508 * file system checks on it, unless it is either the
2509 * system or the installation volume. */
2510 if ((Volume != SystemVolume) && (Volume != InstallVolume))
2511 Volume->NeedsCheck = FALSE;
2512
2513 return FSVOL_SKIP;
2514 }
2515 else
2516 {
2517 /* Format this volume */
2518 return FSVOL_DOIT;
2519 }
2520 }
2521 }
2522
2523 goto Restart;
2524}
2525
2526static FSVOL_OP
2528 _In_ PFSVOL_CONTEXT FsVolContext,
2530{
2531 PINPUT_RECORD Ir = FsVolContext->Ir;
2532 PPARTENTRY PartEntry = Volume->PartEntry;
2533 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2534 CHAR LineBuffer[100];
2535
2536Restart:
2538 CONSOLE_Flush();
2540
2541 PartitionDescription(PartEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2542 CONSOLE_SetTextXY(6, 10, LineBuffer);
2543
2544 DiskDescription(DiskEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2546 LineBuffer);
2547
2548 while (TRUE)
2549 {
2550 if (!IsUnattendedSetup)
2551 CONSOLE_ConInKey(Ir);
2552
2553 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2554 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
2555 {
2556 if (ConfirmQuit(Ir))
2557 {
2558 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2559 return FSVOL_ABORT;
2560 }
2561 goto Restart;
2562 }
2563 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN || IsUnattendedSetup) /* ENTER */
2564 {
2565 /*
2566 * Remove the "Press ENTER to continue" message prompt when the ENTER
2567 * key is pressed as the user wants to begin the partition formatting.
2568 */
2571
2572 return FSVOL_DOIT;
2573 }
2574 }
2575}
2576
2577static VOID
2580{
2581 PPARTENTRY PartEntry = Volume->PartEntry;
2582 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2583 CHAR LineBuffer[100];
2584
2586 CONSOLE_Flush();
2588
2589 PartitionDescription(PartEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2590 CONSOLE_SetTextXY(6, 10, LineBuffer);
2591
2592 DiskDescription(DiskEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2594 LineBuffer);
2595}
2596
2597// PFSVOL_CALLBACK
2598static FSVOL_OP
2602 _In_ FSVOLNOTIFY FormatStatus,
2603 _In_ ULONG_PTR Param1,
2604 _In_ ULONG_PTR Param2)
2605{
2606 PFSVOL_CONTEXT FsVolContext = (PFSVOL_CONTEXT)Context;
2607 PINPUT_RECORD Ir = FsVolContext->Ir;
2608
2609 switch (FormatStatus)
2610 {
2611 // FIXME: Deprecate!
2613 {
2615
2616 FsVolContext->NextPageOnAbort = SELECT_PARTITION_PAGE;
2618 return FSVOL_DOIT;
2619 return FSVOL_ABORT;
2620 }
2621
2623 {
2624 switch (Param1)
2625 {
2627 {
2629 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2630 break;
2631 }
2632
2634 {
2635 /* FIXME: improve the error dialog */
2636 //
2637 // Error dialog should say that we cannot find a suitable
2638 // system partition and create one on the system. At this point,
2639 // it may be nice to ask the user whether he wants to continue,
2640 // or use an external drive as the system drive/partition
2641 // (e.g. floppy, USB drive, etc...)
2642 //
2643 PopupError("The ReactOS Setup could not find a supported system partition\n"
2644 "on your system or could not create a new one. Without such a partition\n"
2645 "the Setup program cannot install ReactOS.\n"
2646 "Press ENTER to return to the partition selection list.",
2648 Ir, POPUP_WAIT_ENTER);
2649
2650 FsVolContext->NextPageOnAbort = SELECT_PARTITION_PAGE;
2651 break;
2652 }
2653
2654 default:
2655 break;
2656 }
2657 return FSVOL_ABORT;
2658 }
2659
2662 // NOTE: If needed, clear screen and flush input.
2663 return FSVOL_DOIT;
2664
2666 {
2667 if ((FSVOL_OP)Param1 == FSVOL_FORMAT)
2668 {
2669 /*
2670 * In case we just repair an existing installation, or make
2671 * an unattended setup without formatting, just go to the
2672 * file system check step.
2673 */
2674 if (RepairUpdateFlag)
2675 return FSVOL_SKIP;
2678 return FSVOL_SKIP;
2679 }
2680 return FSVOL_DOIT;
2681 }
2682
2684 return 0;
2685
2687 {
2688 PFORMAT_VOLUME_INFO FmtInfo = (PFORMAT_VOLUME_INFO)Param1;
2690
2691 // FIXME: See also FSVOLNOTIFY_PARTITIONERROR
2692 if (FmtInfo->ErrorStatus == STATUS_PARTITION_FAILURE)
2693 {
2695 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2696 return FSVOL_ABORT;
2697 }
2698 else
2700 {
2701 /* FIXME: show an error dialog */
2702 // MUIDisplayError(ERROR_FORMATTING_PARTITION, Ir, POPUP_WAIT_ANY_KEY,
2703 // FmtInfo->Volume->Info.DeviceName);
2704 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2705 return FSVOL_ABORT;
2706 }
2707 else
2708 if (FmtInfo->ErrorStatus == STATUS_NOT_SUPPORTED)
2709 {
2711 sizeof(Buffer),
2712 "Setup is currently unable to format a partition in %S.\n"
2713 "\n"
2714 " \x07 Press ENTER to continue Setup.\n"
2715 " \x07 Press F3 to quit Setup.",
2716 FmtInfo->FileSystemName);
2717
2721
2722 while (TRUE)
2723 {
2724 CONSOLE_ConInKey(Ir);
2725
2726 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x00 &&
2727 Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3) /* F3 */
2728 {
2729 if (ConfirmQuit(Ir))
2730 {
2731 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2732 return FSVOL_ABORT;
2733 }
2734 return FSVOL_RETRY;
2735 }
2736 else if (Ir->Event.KeyEvent.uChar.AsciiChar == VK_RETURN) /* ENTER */
2737 {
2738 return FSVOL_RETRY;
2739 }
2740 }
2741 }
2742 else if (!NT_SUCCESS(FmtInfo->ErrorStatus))
2743 {
2744 DPRINT1("FormatPartition() failed: Status 0x%08lx\n", FmtInfo->ErrorStatus);
2746 FmtInfo->Volume->Info.DeviceName);
2747 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2748 return FSVOL_ABORT;
2749 }
2750 return FSVOL_RETRY;
2751 }
2752
2754 {
2755 PCHECK_VOLUME_INFO ChkInfo = (PCHECK_VOLUME_INFO)Param1;
2757
2758 if (ChkInfo->ErrorStatus == STATUS_NOT_SUPPORTED)
2759 {
2761 sizeof(Buffer),
2762 "Setup is currently unable to check a partition formatted in %S.\n"
2763 "\n"
2764 " \x07 Press ENTER to continue Setup.\n"
2765 " \x07 Press F3 to quit Setup.",
2766 ChkInfo->Volume->Info.FileSystem);
2767
2771
2772 while (TRUE)
2773 {
2774 CONSOLE_ConInKey(Ir);
2775
2776 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x00 &&
2777 Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3) /* F3 */
2778 {
2779 if (ConfirmQuit(Ir))
2780 {
2781 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2782 return FSVOL_ABORT;
2783 }
2784 return FSVOL_SKIP;
2785 }
2786 else if (Ir->Event.KeyEvent.uChar.AsciiChar == VK_RETURN) /* ENTER */
2787 {
2788 return FSVOL_SKIP;
2789 }
2790 }
2791 }
2792 else if (!NT_SUCCESS(ChkInfo->ErrorStatus))
2793 {
2794 DPRINT1("ChkdskPartition() failed: Status 0x%08lx\n", ChkInfo->ErrorStatus);
2795
2797 sizeof(Buffer),
2798 "ChkDsk detected some disk errors.\n(Status 0x%08lx).\n",
2799 ChkInfo->ErrorStatus);
2800
2803 Ir, POPUP_WAIT_ENTER);
2804 return FSVOL_SKIP;
2805 }
2806 return FSVOL_SKIP;
2807 }
2808
2810 {
2811 PFORMAT_VOLUME_INFO FmtInfo = (PFORMAT_VOLUME_INFO)Param1;
2813
2814 ASSERT((FSVOL_OP)Param2 == FSVOL_FORMAT);
2815
2816 /* Select the file system */
2817 Result = SelectFileSystemPage(FsVolContext, FmtInfo->Volume);
2818 if (Result != FSVOL_DOIT)
2819 return Result;
2820
2821 /* Display the formatting page */
2822 Result = FormatPartitionPage(FsVolContext, FmtInfo->Volume);
2823 if (Result != FSVOL_DOIT)
2824 return Result;
2825
2827 return FSVOL_DOIT;
2828 }
2829
2831 {
2832 PFORMAT_VOLUME_INFO FmtInfo = (PFORMAT_VOLUME_INFO)Param1;
2833 EndFormat(FmtInfo->ErrorStatus);
2834
2835 /* Reset the file system list */
2837 return 0;
2838 }
2839
2841 {
2842 PCHECK_VOLUME_INFO ChkInfo = (PCHECK_VOLUME_INFO)Param1;
2843
2844 ASSERT((FSVOL_OP)Param2 == FSVOL_CHECK);
2845
2846 CheckFileSystemPage(ChkInfo->Volume);
2847 StartCheck(ChkInfo);
2848 return FSVOL_DOIT;
2849 }
2850
2852 {
2853 PCHECK_VOLUME_INFO ChkInfo = (PCHECK_VOLUME_INFO)Param1;
2854 EndCheck(ChkInfo->ErrorStatus);
2855 return 0;
2856 }
2857 }
2858
2859 return 0;
2860}
2861
2862
2863/*
2864 * Displays the InstallDirectoryPage.
2865 *
2866 * Next pages:
2867 * PrepareCopyPage
2868 * QuitPage
2869 *
2870 * RETURNS
2871 * Number of the next page.
2872 */
2873static PAGE_NUMBER
2875{
2877 ULONG Length, Pos;
2878 WCHAR c;
2879 WCHAR InstallDir[MAX_PATH];
2880
2882 {
2883 /* FIXME: show an error dialog */
2884 return QUIT_PAGE;
2885 }
2886
2887 // if (IsUnattendedSetup)
2888 if (RepairUpdateFlag)
2889 wcscpy(InstallDir, CurrentInstallation->PathComponent); // SystemNtPath
2892 else
2893 wcscpy(InstallDir, L"\\ReactOS");
2894
2895 /*
2896 * Check the validity of the predefined 'InstallDir'. If we are either
2897 * in unattended setup or in update/repair mode, and the installation path
2898 * is valid, just perform the installation. Otherwise (either in the case
2899 * of an invalid path, or we are in regular setup), display the UI and allow
2900 * the user to specify a new installation path.
2901 */
2903 {
2904 /* Check for the validity of the installation directory and pop up
2905 * an error if it is not the case. Then the user can fix it. */
2906 if (IsValidInstallDirectory(InstallDir))
2907 goto InitInstallDir;
2908
2910 }
2911
2912 Length = wcslen(InstallDir);
2913 Pos = Length;
2914
2916 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
2917 CONSOLE_SetCursorXY(8 + Pos, 11);
2919
2920 while (TRUE)
2921 {
2922 CONSOLE_ConInKey(Ir);
2923
2924 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2925 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
2926 {
2928
2929 if (ConfirmQuit(Ir))
2930 return QUIT_PAGE;
2932 }
2933 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2934 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DELETE)) /* DEL */
2935 {
2936 if (Pos < Length)
2937 {
2938 memmove(&InstallDir[Pos],
2939 &InstallDir[Pos + 1],
2940 (Length - Pos - 1) * sizeof(WCHAR));
2941 InstallDir[Length - 1] = UNICODE_NULL;
2942
2943 Length--;
2944 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
2945 CONSOLE_SetCursorXY(8 + Pos, 11);
2946 }
2947 }
2948 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2949 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_HOME)) /* HOME */
2950 {
2951 Pos = 0;
2952 CONSOLE_SetCursorXY(8 + Pos, 11);
2953 }
2954 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2955 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_END)) /* END */
2956 {
2957 Pos = Length;
2958 CONSOLE_SetCursorXY(8 + Pos, 11);
2959 }
2960 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2961 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_LEFT)) /* LEFT */
2962 {
2963 if (Pos > 0)
2964 {
2965 Pos--;
2966 CONSOLE_SetCursorXY(8 + Pos, 11);
2967 }
2968 }
2969 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2970 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RIGHT)) /* RIGHT */
2971 {
2972 if (Pos < Length)
2973 {
2974 Pos++;
2975 CONSOLE_SetCursorXY(8 + Pos, 11);
2976 }
2977 }
2978 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
2979 {
2980 /* Erase the whole line */
2981 *InstallDir = UNICODE_NULL;
2982 Pos = Length = 0;
2983 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
2984 CONSOLE_SetCursorXY(8 + Pos, 11);
2985 }
2986 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2987 {
2989
2990 /* Check for the validity of the installation directory and pop up
2991 * an error if it is not the case. Then the user can fix it. */
2992 if (IsValidInstallDirectory(InstallDir))
2993 goto InitInstallDir;
2994
2997 }
2998 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */
2999 {
3000 if (Pos > 0)
3001 {
3002 if (Pos < Length)
3003 memmove(&InstallDir[Pos - 1],
3004 &InstallDir[Pos],
3005 (Length - Pos) * sizeof(WCHAR));
3006 InstallDir[Length - 1] = UNICODE_NULL;
3007
3008 Pos--;
3009 Length--;
3010 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
3011 CONSOLE_SetCursorXY(8 + Pos, 11);
3012 }
3013 }
3014 else if (isprint(Ir->Event.KeyEvent.uChar.AsciiChar))
3015 {
3016 if (Length < 50)
3017 {
3018 /* Only accept valid characters for the installation path */
3021 {
3022 if (Pos < Length)
3023 memmove(&InstallDir[Pos + 1],
3024 &InstallDir[Pos],
3025 (Length - Pos) * sizeof(WCHAR));
3026 InstallDir[Length + 1] = UNICODE_NULL;
3027 InstallDir[Pos] = c;
3028
3029 Pos++;
3030 Length++;
3031 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
3032 CONSOLE_SetCursorXY(8 + Pos, 11);
3033 }
3034 }
3035 }
3036 }
3037
3038InitInstallDir:
3040 if (!NT_SUCCESS(Status))
3041 {
3042 DPRINT1("InitDestinationPaths() failed: Status 0x%lx\n", Status);
3044 return QUIT_PAGE;
3045 }
3046
3047 /*
3048 * Check whether the user attempts to install ReactOS within the
3049 * installation source directory, or in a subdirectory thereof.
3050 * If so, fail with an error.
3051 */
3053 {
3056 }
3057
3058 return PREPARE_COPY_PAGE;
3059}
3060
3061
3062/*
3063 * Displays the PrepareCopyPage.
3064 *
3065 * Next pages:
3066 * FileCopyPage(At once)
3067 * QuitPage
3068 *
3069 * SIDEEFFECTS
3070 * Calls PrepareFileCopy
3071 *
3072 * RETURNS
3073 * Number of the next page.
3074 */
3075static PAGE_NUMBER
3077{
3078 // ERROR_NUMBER ErrorNumber;
3080
3082
3083 /* ErrorNumber = */ Success = PrepareFileCopy(&USetupData, NULL);
3084 if (/*ErrorNumber != ERROR_SUCCESS*/ !Success)
3085 {
3086 // MUIDisplayError(ErrorNumber, Ir, POPUP_WAIT_ENTER);
3087 return QUIT_PAGE;
3088 }
3089
3090 return FILE_COPY_PAGE;
3091}
3092
3093typedef struct _COPYCONTEXT
3094{
3100
3101static VOID
3104{
3106
3107 /* Get the memory information from the system */
3109 &PerfInfo,
3110 sizeof(PerfInfo),
3111 NULL);
3112
3113 /* Check if this is initial setup */
3114 if (First)
3115 {
3116 /* Set maximum limits to be total RAM pages */
3117 ProgressSetStepCount(CopyContext->MemoryBars[0], PerfInfo.CommitLimit);
3118 ProgressSetStepCount(CopyContext->MemoryBars[1], PerfInfo.CommitLimit);
3119 ProgressSetStepCount(CopyContext->MemoryBars[2], PerfInfo.CommitLimit);
3120 }
3121
3122 /* Set current values */
3123 ProgressSetStep(CopyContext->MemoryBars[0], PerfInfo.PagedPoolPages + PerfInfo.NonPagedPoolPages);
3124 ProgressSetStep(CopyContext->MemoryBars[1], PerfInfo.ResidentSystemCachePage);
3125 ProgressSetStep(CopyContext->MemoryBars[2], PerfInfo.AvailablePages);
3126}
3127
3128static UINT
3132 UINT_PTR Param1,
3133 UINT_PTR Param2)
3134{
3135 PCOPYCONTEXT CopyContext = (PCOPYCONTEXT)Context;
3136 PFILEPATHS_W FilePathInfo;
3137 PCWSTR SrcFileName, DstFileName;
3138
3139 switch (Notification)
3140 {
3142 {
3143 CopyContext->TotalOperations = (ULONG)Param2;
3144 CopyContext->CompletedOperations = 0;
3145 ProgressSetStepCount(CopyContext->ProgressBar,
3146 CopyContext->TotalOperations);
3147 SetupUpdateMemoryInfo(CopyContext, TRUE);
3148 break;
3149 }
3150
3154 {
3155 FilePathInfo = (PFILEPATHS_W)Param1;
3156
3158 {
3159 /* Display delete message */
3160 ASSERT(Param2 == FILEOP_DELETE);
3161
3162 DstFileName = wcsrchr(FilePathInfo->Target, L'\\');
3163 if (DstFileName) ++DstFileName;
3164 else DstFileName = FilePathInfo->Target;
3165
3167 DstFileName);
3168 }
3170 {
3171 /* Display move/rename message */
3172 ASSERT(Param2 == FILEOP_RENAME);
3173
3174 SrcFileName = wcsrchr(FilePathInfo->Source, L'\\');
3175 if (SrcFileName) ++SrcFileName;
3176 else SrcFileName = FilePathInfo->Source;
3177
3178 DstFileName = wcsrchr(FilePathInfo->Target, L'\\');
3179 if (DstFileName) ++DstFileName;
3180 else DstFileName = FilePathInfo->Target;
3181
3182 if (!_wcsicmp(SrcFileName, DstFileName))
3183 Param2 = STRING_MOVING;
3184 else
3185 Param2 = STRING_RENAMING;
3186
3188 SrcFileName, DstFileName);
3189 }
3191 {
3192 static PCSTR s_pszCopying = NULL; /* Cached for speed */
3193
3194 /* Display copy message */
3195 ASSERT(Param2 == FILEOP_COPY);
3196
3197 /* NOTE: When extracting from CABs the Source is the CAB name */
3198 DstFileName = wcsrchr(FilePathInfo->Target, L'\\');
3199 if (DstFileName) ++DstFileName;
3200 else DstFileName = FilePathInfo->Target;
3201
3202 if (!s_pszCopying)
3203 s_pszCopying = MUIGetString(STRING_COPYING);
3204 CONSOLE_SetStatusText(s_pszCopying, DstFileName);
3205#ifdef __REACTOS__ /* HACK */
3206 DoWatchDestFileName(DstFileName);
3207#endif
3208 }
3209
3210 SetupUpdateMemoryInfo(CopyContext, FALSE);
3211 break;
3212 }
3213
3215 {
3216 FilePathInfo = (PFILEPATHS_W)Param1;
3217
3218 DPRINT1("An error happened while trying to copy file '%S' (error 0x%08lx), skipping it...\n",
3219 FilePathInfo->Target, FilePathInfo->Win32Error);
3220 return FILEOP_SKIP;
3221 }
3222
3226 {
3227 CopyContext->CompletedOperations++;
3228
3229 /* SYSREG checkpoint */
3230 if (CopyContext->TotalOperations >> 1 == CopyContext->CompletedOperations)
3231 DPRINT1("CHECKPOINT:HALF_COPIED\n");
3232
3233 ProgressNextStep(CopyContext->ProgressBar);
3234 SetupUpdateMemoryInfo(CopyContext, FALSE);
3235 break;
3236 }
3237 }
3238
3239 return FILEOP_DOIT;
3240}
3241
3242
3243/*
3244 * Displays the FileCopyPage.
3245 *
3246 * Next pages:
3247 * RegistryPage(At once)
3248 *
3249 * SIDEEFFECTS
3250 * Calls DoFileCopy
3251 *
3252 * RETURNS
3253 * Number of the next page.
3254 */
3255static PAGE_NUMBER
3257{
3258 COPYCONTEXT CopyContext;
3259 UINT MemBarWidth;
3260
3262
3263 /* Create context for the copy process */
3264 CopyContext.TotalOperations = 0;
3265 CopyContext.CompletedOperations = 0;
3266
3267 /* Create the progress bar as well */
3268 CopyContext.ProgressBar = CreateProgressBar(13,
3269 26,
3270 xScreen - 13,
3271 yScreen - 20,
3272 10,
3273 24,
3274 TRUE,
3276
3277 // fit memory bars to screen width, distribute them uniform
3278 MemBarWidth = (xScreen - 26) / 5;
3279 MemBarWidth -= MemBarWidth % 2; // make even
3280 /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
3281 /* Create the paged pool progress bar */
3282 CopyContext.MemoryBars[0] = CreateProgressBar(13,
3283 40,
3284 13 + MemBarWidth,
3285 43,
3286 13,
3287 44,
3288 FALSE,
3289 "Kernel Pool");
3290
3291 /* Create the non paged pool progress bar */
3292 CopyContext.MemoryBars[1] = CreateProgressBar((xScreen / 2)- (MemBarWidth / 2),
3293 40,
3294 (xScreen / 2) + (MemBarWidth / 2),
3295 43,
3296 (xScreen / 2)- (MemBarWidth / 2),
3297 44,
3298 FALSE,
3299 "Kernel Cache");
3300
3301 /* Create the global memory progress bar */
3302 CopyContext.MemoryBars[2] = CreateProgressBar(xScreen - 13 - MemBarWidth,
3303 40,
3304 xScreen - 13,
3305 43,
3306 xScreen - 13 - MemBarWidth,
3307 44,
3308 FALSE,
3309 "Free Memory");
3310
3311 /* Do the file copying */
3312 DoFileCopy(&USetupData, FileCopyCallback, &CopyContext);
3313
3314 /* If we get here, we're done, so cleanup the progress bar */
3315 DestroyProgressBar(CopyContext.ProgressBar);
3316 DestroyProgressBar(CopyContext.MemoryBars[0]);
3317 DestroyProgressBar(CopyContext.MemoryBars[1]);
3318 DestroyProgressBar(CopyContext.MemoryBars[2]);
3319
3320 /* Create the $winnt$.inf file */
3322
3323 /* Go display the next page */
3324 return REGISTRY_PAGE;
3325}
3326
3327
3328static VOID
3329__cdecl
3331{
3332 /* WARNING: Please keep this lookup table in sync with the resources! */
3333 static const UINT StringIDs[] =
3334 {
3335 STRING_DONE, /* Success */
3336 STRING_REGHIVEUPDATE, /* RegHiveUpdate */
3337 STRING_IMPORTFILE, /* ImportRegHive */
3338 STRING_DISPLAYSETTINGSUPDATE, /* DisplaySettingsUpdate */
3339 STRING_LOCALESETTINGSUPDATE, /* LocaleSettingsUpdate */
3340 STRING_ADDKBLAYOUTS, /* KeybLayouts */
3341 STRING_KEYBOARDSETTINGSUPDATE, /* KeybSettingsUpdate */
3342 STRING_CODEPAGEINFOUPDATE, /* CodePageInfoUpdate */
3343 };
3344
3345 va_list args;
3346
3347 if (RegStatus < ARRAYSIZE(StringIDs))
3348 {
3349 va_start(args, RegStatus);
3350 CONSOLE_SetStatusTextV(MUIGetString(StringIDs[RegStatus]), args);
3351 va_end(args);
3352 }
3353 else
3354 {
3355 CONSOLE_SetStatusText("Unknown status %d", RegStatus);
3356 }
3357}
3358
3359/*
3360 * Displays the RegistryPage.
3361 *
3362 * Next pages:
3363 * BootLoaderSelectPage
3364 * QuitPage
3365 *
3366 * SIDEEFFECTS
3367 * Calls UpdateRegistry
3368 *
3369 * RETURNS
3370 * Number of the next page.
3371 */
3372static PAGE_NUMBER
3374{
3375 ULONG Error;
3376
3378
3382 InstallVolume->Info.DriveLetter,
3385 &s_SubstSettings);
3386 if (Error != ERROR_SUCCESS)
3387 {
3389 return QUIT_PAGE;
3390 }
3391 else
3392 {
3395 }
3396}
3397
3398
3399/*
3400 * Displays the BootLoaderSelectPage.
3401 *
3402 * Next pages:
3403 * SuccessPage
3404 * QuitPage
3405 *
3406 * RETURNS
3407 * Number of the next page.
3408 */
3409static PAGE_NUMBER
3411{
3412 USHORT Line = 12;
3413
3415
3416 /* We must have a supported system partition by now */
3418
3419 /*
3420 * If we repair an existing installation and we made it up to here,
3421 * this means a valid bootloader and boot entry have been found.
3422 * Thus, there is no need to re-install it: skip its installation.
3423 */
3424 if (RepairUpdateFlag)
3425 {
3427 goto Quit;
3428 }
3429
3430 /* For unattended setup, skip MBR installation or install on removable disk if needed */
3432 {
3433 if ((USetupData.BootLoaderLocation == 0) ||
3435 {
3436 goto Quit;
3437 }
3438 }
3439
3440#if 0 // Deprecated code, whose global logic may need to be moved elsewhere...
3441 /*
3442 * We may install an MBR or VBR, but before that, check whether
3443 * we need to actually install the VBR on removable disk if the
3444 * system partition is not recognized.
3445 */
3446 if ((SystemPartition->DiskEntry->DiskStyle != PARTITION_STYLE_MBR) ||
3448 {
3450 goto Quit;
3451 }
3452#endif
3453
3454 /* Is it an unattended install on hdd? */
3456 {
3457 if ((USetupData.BootLoaderLocation == 2) ||
3459 {
3460 goto Quit;
3461 }
3462 }
3463
3465 CONSOLE_InvertTextXY(8, Line, 60, 1);
3466
3467 while (TRUE)
3468 {
3469 CONSOLE_ConInKey(Ir);
3470
3471 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3472 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
3473 {
3474 CONSOLE_NormalTextXY(8, Line, 60, 1);
3475
3476 Line++;
3477 if (Line < 12)
3478 Line = 15;
3479
3480 if (Line > 15)
3481 Line = 12;
3482
3483 CONSOLE_InvertTextXY(8, Line, 60, 1);
3484 }
3485 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3486 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
3487 {
3488 CONSOLE_NormalTextXY(8, Line, 60, 1);
3489
3490 Line--;
3491 if (Line < 12)
3492 Line = 15;
3493
3494 if (Line > 15)
3495 Line = 12;
3496
3497 CONSOLE_InvertTextXY(8, Line, 60, 1);
3498 }
3499 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3500 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_HOME)) /* HOME */
3501 {
3502 CONSOLE_NormalTextXY(8, Line, 60, 1);
3503
3504 Line = 12;
3505
3506 CONSOLE_InvertTextXY(8, Line, 60, 1);
3507 }
3508 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3509 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_END)) /* END */
3510 {
3511 CONSOLE_NormalTextXY(8, Line, 60, 1);
3512
3513 Line = 15;
3514
3515 CONSOLE_InvertTextXY(8, Line, 60, 1);
3516 }
3517 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3518 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
3519 {
3520 if (ConfirmQuit(Ir))
3521 return QUIT_PAGE;
3522 break;
3523 }
3524 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
3525 {
3526 if (Line == 12)
3527 {
3528 /* Install on both MBR and VBR */
3530 break;
3531 }
3532 else if (Line == 13)
3533 {
3534 /* Install on VBR only */
3536 break;
3537 }
3538 else if (Line == 14)
3539 {
3540 /* Install on removable disk */
3542 break;
3543 }
3544 else if (Line == 15)
3545 {
3546 /* Skip installation */
3548 break;
3549 }
3550
3552 }
3553 }
3554
3555Quit:
3556 /* Continue the installation; the bootloader is installed at the end */
3558}
3559
3560
3561/*
3562 * Installs the bootloader on removable disk.
3563 */
3564static BOOLEAN
3566{
3568
3569Retry:
3571 CONSOLE_Flush();
3573// CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
3574
3575 while (TRUE)
3576 {
3577 CONSOLE_ConInKey(Ir);
3578
3579 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3580 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
3581 {
3582 if (ConfirmQuit(Ir))
3583 return FALSE;
3584 break;
3585 }
3586 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
3587 {
3588 // FIXME: So far USETUP only supports the 1st floppy.
3589 static const UNICODE_STRING FloppyDrive = RTL_CONSTANT_STRING(L"\\Device\\Floppy0\\");
3591 &FloppyDrive,
3594 if (Status == STATUS_SUCCESS)
3595 return TRUE; /* Successful installation */
3596
3598 {
3600 }
3601 else if (!NT_SUCCESS(Status))
3602 {
3603 /* Any other NTSTATUS failure code */
3605
3606 DPRINT1("InstallBootcodeToRemovable() failed: Status 0x%lx\n", Status);
3608 "Setup could not install the bootloader.\n"
3609 "(Status 0x%08lx).\n"
3610 "Press ENTER to continue anyway.",
3611 Status);
3614 Ir, POPUP_WAIT_ENTER);
3615 }
3616 goto Retry;
3617 }
3618 }
3619 goto Retry;
3620}
3621
3622/*
3623 * Installs the bootloader on hard-disk.
3624 */
3625static BOOLEAN
3627{
3629
3630 /* Copy FreeLoader to the disk and save the boot entries */
3637 ? 1 /* Install MBR and VBR */
3638 : 0 /* Install VBR only */);
3639 if (Status == STATUS_SUCCESS)
3640 return TRUE; /* Successful installation */
3641
3642 if (Status == ERROR_WRITE_BOOT)
3643 {
3644 /* Error when writing the VBR */
3646 SystemVolume->Info.FileSystem);
3647 }
3648 else if (Status == ERROR_INSTALL_BOOTCODE)
3649 {
3650 /* Error when writing the MBR */
3652 }
3653 else if (Status == STATUS_NOT_SUPPORTED)
3654 {
3655 PopupError("Setup does not currently support installing\n"
3656 "the bootloader on the computer you are using.\n"
3657 "Press ENTER to continue anyway.",
3659 Ir, POPUP_WAIT_ENTER);
3660 }
3661 else if (!NT_SUCCESS(Status))
3662 {
3663 /* Any other NTSTATUS failure code */
3665
3666 DPRINT1("InstallBootManagerAndBootEntries() failed: Status 0x%lx\n", Status);
3668 "Setup could not install the bootloader.\n"
3669 "(Status 0x%08lx).\n"
3670 "Press ENTER to continue anyway.",
3671 Status);
3674 Ir, POPUP_WAIT_ENTER);
3675 }
3676 return FALSE;
3677}
3678
3679/*
3680 * Actually installs the bootloader at the end of the installation.
3681 * The bootloader installation place has already been chosen before,
3682 * see BootLoaderSelectPage().
3683 *
3684 * Next pages:
3685 * SuccessPage (At once)
3686 * QuitPage
3687 *
3688 * RETURNS
3689 * Number of the next page.
3690 */
3691static PAGE_NUMBER
3693{
3695
3697 RtlStringCchPrintfW(PathBuffer, _countof(PathBuffer),
3698 L"%s\\", SystemPartition->DeviceName);
3700 DPRINT1("SystemRootPath: %wZ\n", &USetupData.SystemRootPath);
3701
3704
3706 {
3707 /* Install on removable disk */
3708 case 1:
3710
3711 /* Install on hard-disk */
3712 case 2: // System partition / MBR and VBR (on BIOS-based PC)
3713 case 3: // VBR only (on BIOS-based PC)
3715
3716 /* Skip installation */
3717 case 0:
3718 default:
3719 return SUCCESS_PAGE;
3720 }
3721}
3722
3723
3746static
3750 IN BOOLEAN AlwaysUpdate,
3751 OUT PSTR Buffer,
3752 IN SIZE_T cchBufferSize)
3753{
3754 ULONG OldProgress = Bar->Progress;
3755
3756 if (Bar->StepCount == 0)
3757 {
3758 Bar->Progress = 0;
3759 }
3760 else
3761 {
3762 Bar->Progress = Bar->StepCount - Bar->CurrentStep;
3763 }
3764
3765 /* Build the progress string if it has changed */
3766 if (Bar->ProgressFormatText &&
3767 (AlwaysUpdate || (Bar->Progress != OldProgress)))
3768 {
3769 RtlStringCchPrintfA(Buffer, cchBufferSize,
3770 Bar->ProgressFormatText, Bar->Progress / max(1, Bar->Width) + 1);
3771
3772 return TRUE;
3773 }
3774
3775 return FALSE;
3776}
3777
3794static VOID
3796 IN PINPUT_RECORD Ir,
3797 IN LONG TimeOut)
3798{
3800 ULONG StartTime, BarWidth, TimerDiv;
3801 LONG TimeElapsed;
3802 LONG TimerValue, OldTimerValue;
3805 BOOLEAN RefreshProgress = TRUE;
3806
3807 /* Bail out if the timeout is already zero */
3808 if (TimeOut <= 0)
3809 return;
3810
3811 /* Create the timeout progress bar and set it up */
3813 26,
3814 xScreen - 13,
3815 yScreen - 20,
3816 10,
3817 24,
3818 TRUE,
3820 0,
3821 NULL,
3824
3825 BarWidth = max(1, ProgressBar->Width);
3826 TimerValue = TimeOut * BarWidth;
3827 ProgressSetStepCount(ProgressBar, TimerValue);
3828
3830 CONSOLE_Flush();
3831
3832 TimerDiv = 1000 / BarWidth;
3833 TimerDiv = max(1, TimerDiv);
3834 OldTimerValue = TimerValue;
3835 while (TRUE)
3836 {
3837 /* Decrease the timer */
3838
3839 /*
3840 * Compute how much time the previous operations took.
3841 * This allows us in particular to take account for any time
3842 * elapsed if something slowed down.
3843 */
3844 TimeElapsed = NtGetTickCount() - StartTime;
3845 if (TimeElapsed >= TimerDiv)
3846 {
3847 /* Increase StartTime by steps of 1 / ProgressBar->Width seconds */
3848 TimeElapsed /= TimerDiv;
3849 StartTime += (TimerDiv * TimeElapsed);
3850
3851 if (TimeElapsed <= TimerValue)
3852 TimerValue -= TimeElapsed;
3853 else
3854 TimerValue = 0;
3855
3856 RefreshProgress = TRUE;
3857 }
3858
3859 if (RefreshProgress)
3860 {
3861 ProgressSetStep(ProgressBar, OldTimerValue - TimerValue);
3862 RefreshProgress = FALSE;
3863 }
3864
3865 /* Stop when the timer reaches zero */
3866 if (TimerValue <= 0)
3867 break;
3868
3869 /* Check for user key presses */
3870
3871 /*
3872 * If the timer is used, use a passive wait of maximum 1 second
3873 * while monitoring for incoming console input events, so that
3874 * we are still able to display the timing count.
3875 */
3876
3877 /* Wait a maximum of 1 second for input events */
3878 TimeElapsed = NtGetTickCount() - StartTime;
3879 if (TimeElapsed < TimerDiv)
3880 {
3881 /* Convert the time to NT format */
3882 Timeout.QuadPart = (TimerDiv - TimeElapsed) * -10000LL;
3884 }
3885 else
3886 {
3888 }
3889
3890 /* Check whether the input event has been signaled, or a timeout happened */
3891 if (Status == STATUS_TIMEOUT)
3892 {
3893 continue;
3894 }
3895 if (Status != STATUS_WAIT_0)
3896 {
3897 /* An error happened, bail out */
3898 DPRINT1("NtWaitForSingleObject() failed, Status 0x%08lx\n", Status);
3899 break;
3900 }
3901
3902 /* Check for an ENTER key press */
3903 while (CONSOLE_ConInKeyPeek(Ir))
3904 {
3905 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
3906 {
3907 /* Found it, stop waiting */
3908 goto Exit;
3909 }
3910 }
3911 }
3912
3913Exit:
3914 /* Destroy the progress bar and quit */
3916}
3917
3918
3919/*
3920 * Displays the QuitPage.
3921 *
3922 * Next pages:
3923 * FlushPage (At once)
3924 *
3925 * SIDEEFFECTS
3926 * Destroy the Lists
3927 *
3928 * RETURNS
3929 * Number of the next page.
3930 */
3931static PAGE_NUMBER
3933{
3935
3936 /* Destroy the NTOS installations list */
3937 if (NtOsInstallsList != NULL)
3938 {
3941 }
3942
3943 /* Destroy the partition list */
3944 if (PartitionList != NULL)
3945 {
3948 }
3949
3951
3952 /* Wait for maximum 15 seconds or an ENTER key before quitting */
3953 ProgressCountdown(Ir, 15);
3954 return FLUSH_PAGE;
3955}
3956
3957
3958/*
3959 * Displays the SuccessPage.
3960 *
3961 * Next pages:
3962 * FlushPage (At once)
3963 *
3964 * SIDEEFFECTS
3965 * Destroy the Lists
3966 *
3967 * RETURNS
3968 * Number of the next page.
3969 */
3970static PAGE_NUMBER
3972{
3974
3976 return FLUSH_PAGE;
3977
3978 /* Wait for maximum 15 seconds or an ENTER key before quitting */
3979 ProgressCountdown(Ir, 15);
3980 return FLUSH_PAGE;
3981}
3982
3983
3984/*
3985 * Displays the FlushPage.
3986 *
3987 * Next pages:
3988 * RebootPage (At once)
3989 *
3990 * RETURNS
3991 * Number of the next page.
3992 */
3993static PAGE_NUMBER
3995{
3997 return REBOOT_PAGE;
3998}
3999
4000
4001/*
4002 * The start routine and page management
4003 */
4006{
4008 INPUT_RECORD Ir;
4010 BOOLEAN Old;
4011
4013
4014 /* Tell the Cm this is a setup boot, and it has to behave accordingly */
4016 if (!NT_SUCCESS(Status))
4017 DPRINT1("NtInitializeRegistry() failed (Status 0x%08lx)\n", Status);
4018
4019 /* Initialize the user-mode PnP manager */
4021 if (!NT_SUCCESS(Status))
4022 {
4023 // PrintString(??);
4024 DPRINT1("The user-mode PnP manager could not initialize (Status 0x%08lx), expect unavailable devices!\n", Status);
4025 }
4026
4027 if (!CONSOLE_Init())
4028 {
4032
4033 /* We failed to initialize the video, just quit the installer */
4035 }
4036
4037 /* Hide the cursor and clear the screen and keyboard buffer */
4040 CONSOLE_Flush();
4041
4042 /* Global Initialization page */
4043 Page = SetupStartPage(&Ir);
4044
4045 while (Page != REBOOT_PAGE && Page != RECOVERY_PAGE)
4046 {
4048 CONSOLE_Flush();
4049
4050 // CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
4051
4052 switch (Page)
4053 {
4054 /* Language page */
4055 case LANGUAGE_PAGE:
4056 Page = LanguagePage(&Ir);
4057 break;
4058
4059 /* Welcome page */
4060 case WELCOME_PAGE:
4061 Page = WelcomePage(&Ir);
4062 break;
4063
4064 /* License page */
4065 case LICENSE_PAGE:
4066 Page = LicensePage(&Ir);
4067 break;
4068
4069 /* Install pages */
4070 case INSTALL_INTRO_PAGE:
4071 Page = InstallIntroPage(&Ir);
4072 break;
4073
4074#if 0
4075 case SCSI_CONTROLLER_PAGE:
4076 Page = ScsiControllerPage(&Ir);
4077 break;
4078
4079 case OEM_DRIVER_PAGE:
4080 Page = OemDriverPage(&Ir);
4081 break;
4082#endif
4083
4085 Page = DeviceSettingsPage(&Ir);
4086 break;
4087
4090 break;
4091
4094 break;
4095
4098 break;
4099
4101 Page = LayoutSettingsPage(&Ir);
4102 break;
4103
4104 /* Partitioning pages */
4107 break;
4108
4111 break;
4112
4115 break;
4116
4119 break;
4120
4121 /* File system partition operations pages */
4124 break;
4125
4126 /* Bootloader selection page */
4129 break;
4130
4131 /* Installation pages */
4134 break;
4135
4136 case PREPARE_COPY_PAGE:
4137 Page = PrepareCopyPage(&Ir);
4138 break;
4139
4140 case FILE_COPY_PAGE:
4141 Page = FileCopyPage(&Ir);
4142 break;
4143
4144 case REGISTRY_PAGE:
4145 Page = RegistryPage(&Ir);
4146 break;
4147
4148 /* Bootloader installation page */
4150 // case BOOTLOADER_REMOVABLE_DISK_PAGE:
4152 break;
4153
4154 /* Repair pages */
4155 case REPAIR_INTRO_PAGE:
4156 Page = RepairIntroPage(&Ir);
4157 break;
4158
4160 Page = UpgradeRepairPage(&Ir);
4161 break;
4162
4163 case SUCCESS_PAGE:
4164 Page = SuccessPage(&Ir);
4165 break;
4166
4167 case FLUSH_PAGE:
4168 Page = FlushPage(&Ir);
4169 break;
4170
4171 case QUIT_PAGE:
4172 Page = QuitPage(&Ir);
4173 break;
4174
4175 /* Virtual pages */
4176 case SETUP_INIT_PAGE:
4179 // case CHECK_FILE_SYSTEM_PAGE:
4180 case REBOOT_PAGE:
4181 case RECOVERY_PAGE:
4182 break;
4183
4184 default:
4185 break;
4186 }
4187 }
4188
4189 /* Terminate the user-mode PnP manager */
4191
4192 /* Setup has finished */
4194
4195 if (Page == RECOVERY_PAGE)
4197
4198 FreeConsole();
4199
4200 /* Reboot */
4204
4205 return STATUS_SUCCESS;
4206}
4207
4208
4209VOID NTAPI
4211{
4214
4216
4218
4220
4221 Status = RunUSetup();
4222
4223 if (NT_SUCCESS(Status))
4224 {
4225 /*
4226 * Avoid a bugcheck if RunUSetup() finishes too quickly by implementing
4227 * a protective waiting.
4228 * This wait is needed because, since we are started as SMSS.EXE,
4229 * the NT kernel explicitly waits 5 seconds for the initial process
4230 * SMSS.EXE to initialize (as a protective measure), and otherwise
4231 * bugchecks with the code SESSION5_INITIALIZATION_FAILED.
4232 */
4233 Time.QuadPart += 50000000;
4235 }
4236 else
4237 {
4238 /* The installer failed to start: raise a hard error (crash the system/BSOD) */
4240 0, 0, NULL, 0, NULL);
4241 }
4242
4244}
4245
4246/* EOF */
DWORD Id
WCHAR First[]
Definition: FormatMessage.c:11
unsigned char BOOLEAN
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define isprint(c)
Definition: acclib.h:73
int toupper(int c)
Definition: utclib.c:881
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define __cdecl
Definition: accygwin.h:79
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
BOOLEAN NTAPI PrepareFileCopy(IN OUT PUSETUP_DATA pSetupData, IN PFILE_COPY_STATUS_ROUTINE StatusRoutine OPTIONAL)
Definition: install.c:685
BOOLEAN NTAPI DoFileCopy(IN OUT PUSETUP_DATA pSetupData, IN PSP_FILE_CALLBACK_W MsgHandler, IN PVOID Context OPTIONAL)
Definition: install.c:828
PGENERIC_LIST CreateKeyboardDriverList(IN HINF InfFile)
Definition: settings.c:1072
PGENERIC_LIST CreateComputerTypeList(IN HINF InfFile)
Definition: settings.c:524
ULONG GetDefaultLanguageIndex(VOID)
Definition: settings.c:1098
PGENERIC_LIST CreateDisplayDriverList(IN HINF InfFile)
Definition: settings.c:708
PGENERIC_LIST CreateKeyboardLayoutList(IN HINF InfFile, IN PCWSTR LanguageId, OUT PWSTR DefaultKBLayout)
Definition: settings.c:1209
PGENERIC_LIST CreateLanguageList(IN HINF InfFile, OUT PWSTR DefaultLanguage)
Definition: settings.c:1159
struct _GENENTRY * PGENENTRY
BOOL WINAPI WriteConsoleOutputCharacterA(HANDLE hConsoleOutput, IN LPCSTR lpCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: console.c:407
BOOL WINAPI FillConsoleOutputCharacterA(IN HANDLE hConsoleOutput, IN CHAR cCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: console.c:560
BOOL WINAPI FreeConsole(VOID)
Definition: console.c:156
BOOL WINAPI FillConsoleOutputAttribute(IN HANDLE hConsoleOutput, IN WORD wAttribute, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfAttrsWritten)
Definition: console.c:525
NTSTATUS InitializeUserModePnpManager(IN HINF *phSetupInf)
Definition: devinst.c:559
VOID TerminateUserModePnpManager(VOID)
Definition: devinst.c:690
NTSTATUS WaitNoPendingInstallEvents(IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: devinst.c:514
BOOLEAN EnableUserModePnpManager(VOID)
Definition: devinst.c:521
VOID ProgressSetStep(IN PPROGRESSBAR Bar, IN ULONG Step)
Definition: progress.c:368
VOID ProgressNextStep(IN PPROGRESSBAR Bar)
Definition: progress.c:361
PPROGRESSBAR CreateProgressBarEx(IN SHORT Left, IN SHORT Top, IN SHORT Right, IN SHORT Bottom, IN SHORT TextTop, IN SHORT TextRight, IN BOOLEAN DoubleEdge, IN SHORT ProgressColour, IN ULONG StepCount, IN PCSTR DescriptionText OPTIONAL, IN PCSTR ProgressFormatText OPTIONAL, IN PUPDATE_PROGRESS UpdateProgressProc OPTIONAL)
Definition: progress.c:272
VOID ProgressSetStepCount(IN PPROGRESSBAR Bar, IN ULONG StepCount)
Definition: progress.c:347
PPROGRESSBAR CreateProgressBar(IN SHORT Left, IN SHORT Top, IN SHORT Right, IN SHORT Bottom, IN SHORT TextTop, IN SHORT TextRight, IN BOOLEAN DoubleEdge, IN PCSTR DescriptionText OPTIONAL)
Definition: progress.c:317
VOID DestroyProgressBar(IN OUT PPROGRESSBAR Bar)
Definition: progress.c:339
static LPHIST_ENTRY Bottom
Definition: history.c:54
static LPHIST_ENTRY Top
Definition: history.c:53
BOOL Error
Definition: chkdsk.c:66
#define BACKGROUND_BLUE
Definition: blue.h:65
#define FOREGROUND_RED
Definition: blue.h:63
#define PARTITION_EXTENDED
Definition: disk.h:92
NTSTATUS NTAPI InstallBootcodeToRemovable(_In_ ARCHITECTURE_TYPE ArchType, _In_ PCUNICODE_STRING RemovableRootPath, _In_ PCUNICODE_STRING SourceRootPath, _In_ PCUNICODE_STRING DestinationArcPath)
Definition: bootsup.c:1829
NTSTATUS NTAPI InstallBootManagerAndBootEntries(_In_ ARCHITECTURE_TYPE ArchType, _In_ PCUNICODE_STRING SystemRootPath, _In_ PCUNICODE_STRING SourceRootPath, _In_ PCUNICODE_STRING DestinationArcPath, _In_ ULONG_PTR Options)
Installs FreeLoader on the system and configure the boot entries.
Definition: bootsup.c:1673
Definition: bufpool.h:45
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:312
VOID RecoveryConsole(VOID)
Definition: cmdcons.c:1160
char * Text
Definition: combotst.c:136
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
BOOL CONSOLE_Flush(VOID)
Definition: consup.c:175
VOID CONSOLE_SetInputTextXY(IN SHORT x, IN SHORT y, IN SHORT len, IN LPCWSTR Text)
Definition: consup.c:357
VOID CONSOLE_InvertTextXY(IN SHORT x, IN SHORT y, IN SHORT col, IN SHORT row)
Definition: consup.c:276
VOID CONSOLE_SetCursorXY(IN SHORT x, IN SHORT y)
Definition: consup.c:227
VOID CONSOLE_NormalTextXY(IN SHORT x, IN SHORT y, IN SHORT col, IN SHORT row)
Definition: consup.c:298
SHORT yScreen
Definition: consup.c:40
VOID __cdecl CONSOLE_SetStatusText(IN LPCSTR fmt,...)
Definition: consup.c:480
VOID CONSOLE_SetTextXY(IN SHORT x, IN SHORT y, IN LPCSTR Text)
Definition: consup.c:320
SHORT xScreen
Definition: consup.c:39
VOID CONSOLE_ConInKey(OUT PINPUT_RECORD Buffer)
Definition: consup.c:70
VOID __cdecl CONSOLE_PrintTextXY(IN SHORT x, IN SHORT y, IN LPCSTR fmt,...)
Definition: consup.c:595
VOID CONSOLE_ClearScreen(VOID)
Definition: consup.c:239
BOOLEAN CONSOLE_Init(VOID)
Definition: consup.c:45
VOID CONSOLE_SetStatusTextV(IN LPCSTR fmt, IN va_list args)
Definition: consup.c:471
BOOLEAN CONSOLE_ConInKeyPeek(OUT PINPUT_RECORD Buffer)
Definition: consup.c:89
VOID CONSOLE_SetCursorType(IN BOOL bInsert, IN BOOL bVisible)
Definition: consup.c:214
HANDLE StdOutput
Definition: consup.c:37
HANDLE StdInput
Definition: consup.c:36
#define TEXT_TYPE_REGULAR
Definition: consup.h:39
#define BACKGROUND_WHITE
Definition: consup.h:31
wcscpy
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
ush Pos
Definition: deflate.h:92
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define wcsrchr
Definition: compat.h:16
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
PPEB Peb
Definition: dllmain.c:27
#define swprintf
Definition: precomp.h:40
@ AnsiString
Definition: dnslib.h:19
static VOID DrawPartitionList(_In_ HWND hWndList, _In_ PPARTLIST List)
Definition: drivepage.c:1381
static PDISK_IMAGE FloppyDrive[2]
Definition: dskbios32.c:36
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
@ ERROR_SOURCE_DIR
Definition: errorcode.h:21
@ ERROR_LOAD_KBLAYOUT
Definition: errorcode.h:32
@ ERROR_LOAD_KEYBOARD
Definition: errorcode.h:31
@ ERROR_WRITE_BOOT
Definition: errorcode.h:28
@ NOT_AN_ERROR
Definition: errorcode.h:17
@ ERROR_DIRECTORY_NAME
Definition: errorcode.h:56
@ ERROR_LAST_ERROR_CODE
Definition: errorcode.h:62
@ ERROR_LOAD_DISPLAY
Definition: errorcode.h:30
@ ERROR_DRIVE_INFORMATION
Definition: errorcode.h:27
@ ERROR_INSUFFICIENT_PARTITION_SIZE
Definition: errorcode.h:57
@ ERROR_LOAD_COMPUTER
Definition: errorcode.h:29
@ ERROR_SOURCE_PATH
Definition: errorcode.h:20
@ ERROR_NO_BUILD_PATH
Definition: errorcode.h:19
@ ERROR_WRITE_PTABLE
Definition: errorcode.h:51
@ ERROR_NO_HDD
Definition: errorcode.h:22
@ ERROR_FORMATTING_PARTITION
Definition: errorcode.h:60
@ ERROR_INSTALL_BOOTCODE
Definition: errorcode.h:35
@ ERROR_NO_FLOPPY
Definition: errorcode.h:36
@ Success
Definition: eventcreate.c:712
#define SPFILENOTIFY_ENDDELETE
Definition: fileqsup.h:28
#define FILEOP_COPY
Definition: fileqsup.h:42
struct _FILEPATHS_W * PFILEPATHS_W
#define FILEOP_SKIP
Definition: fileqsup.h:49
#define SPFILENOTIFY_STARTDELETE
Definition: fileqsup.h:27
#define SPFILENOTIFY_STARTSUBQUEUE
Definition: fileqsup.h:24
#define FILEOP_DOIT
Definition: fileqsup.h:48
#define SPFILENOTIFY_ENDCOPY
Definition: fileqsup.h:36
#define SPFILENOTIFY_STARTCOPY
Definition: fileqsup.h:35
#define SPFILENOTIFY_COPYERROR
Definition: fileqsup.h:37
#define FILEOP_RENAME
Definition: fileqsup.h:43
#define SPFILENOTIFY_STARTRENAME
Definition: fileqsup.h:31
#define SPFILENOTIFY_ENDRENAME
Definition: fileqsup.h:32
#define FILEOP_DELETE
Definition: fileqsup.h:44
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
VOID EndCheck(_In_ NTSTATUS Status)
Definition: fmtchk.c:150
VOID StartCheck(_Inout_ PCHECK_VOLUME_INFO ChkInfo)
Definition: fmtchk.c:127
VOID StartFormat(_Inout_ PFORMAT_VOLUME_INFO FmtInfo, _In_ PFILE_SYSTEM_ITEM SelectedFileSystem)
Definition: fmtchk.c:70
static PPROGRESSBAR ProgressBar
Definition: fmtchk.c:17
VOID EndFormat(_In_ NTSTATUS Status)
Definition: fmtchk.c:97
VOID ScrollUpFileSystemList(IN PFILE_SYSTEM_LIST List)
Definition: fslist.c:236
VOID DrawFileSystemList(IN PFILE_SYSTEM_LIST List)
Definition: fslist.c:167
VOID ScrollDownFileSystemList(IN PFILE_SYSTEM_LIST List)
Definition: fslist.c:225
PFILE_SYSTEM_LIST CreateFileSystemList(IN SHORT Left, IN SHORT Top, IN BOOLEAN ForceFormat, IN PCWSTR SelectFileSystem)
Definition: fslist.c:109
VOID DestroyFileSystemList(IN PFILE_SYSTEM_LIST List)
Definition: fslist.c:149
Status
Definition: gdiplustypes.h:25
GLuint buffer
Definition: glext.h:5915
const GLubyte * c
Definition: glext.h:8905
GLfloat GLfloat p
Definition: glext.h:8902
NTSTATUS NTAPI NtRaiseHardError(IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters, IN ULONG ValidResponseOptions, OUT PULONG Response)
Definition: harderr.c:551
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
VOID InfSetHeap(PVOID Heap)
Definition: infrosgen.c:40
static LARGE_INTEGER StartTime
Definition: sys_arch.c:13
#define c
Definition: ke_i.h:80
KLID MUIDefaultKeyboardLayout(IN PCWSTR LanguageId)
Definition: mui.c:88
USHORT LANGID
Definition: mui.h:9
ULONG KLID
Definition: mui.h:10
SPFILE_EXPORTS SpFileExports
Definition: fileqsup.c:23
SPINF_EXPORTS SpInfExports
Definition: infsupp.c:24
ULONG NTAPI GetNumberOfListEntries(IN PGENERIC_LIST List)
Definition: genlist.c:149
VOID NTAPI SetCurrentListEntry(IN PGENERIC_LIST List, IN PGENERIC_LIST_ENTRY Entry)
Definition: genlist.c:91
VOID NTAPI DestroyGenericList(IN OUT PGENERIC_LIST List, IN BOOLEAN FreeData)
Definition: genlist.c:38
PGENERIC_LIST_ENTRY NTAPI GetFirstListEntry(IN PGENERIC_LIST List)
Definition: genlist.c:110
PGENERIC_LIST_ENTRY NTAPI GetNextListEntry(IN PGENERIC_LIST_ENTRY Entry)
Definition: genlist.c:121
PGENERIC_LIST_ENTRY NTAPI GetCurrentListEntry(IN PGENERIC_LIST List)
Definition: genlist.c:102
PVOID NTAPI GetListEntryData(IN PGENERIC_LIST_ENTRY Entry)
Definition: genlist.c:134
struct _PARTENTRY * PPARTENTRY
Definition: partlist.h:42
@ Unformatted
Definition: partlist.h:34
#define GetPartEntrySizeInBytes(PartEntry)
Definition: partlist.h:254
if(dx< 0)
Definition: linetemp.h:194
#define SystemPerformanceInformation
Definition: memtest.h:87
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
UNICODE_STRING Volume
Definition: fltkernel.h:1172
#define ASSERT(a)
Definition: mode.c:44
void Cancel(int sigNum)
Definition: shell.c:481
@ PARTITION_STYLE_MBR
Definition: imports.h:201
void Bar(void)
Definition: terminate.cpp:70
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define SE_SHUTDOWN_PRIVILEGE
Definition: security.c:673
#define ULL(a, b)
Definition: format_msg.c:27
static PLARGE_INTEGER Time
Definition: time.c:105
#define min(a, b)
Definition: monoChain.cc:55
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
#define CM_BOOT_FLAG_SETUP
Definition: cmtypes.h:159
@ ShutdownReboot
Definition: extypes.h:177
NTSYSAPI PRTL_USER_PROCESS_PARAMETERS NTAPI RtlNormalizeProcessParams(_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
NTSYSAPI NTSTATUS NTAPI RtlAdjustPrivilege(_In_ ULONG Privilege, _In_ BOOLEAN NewValue, _In_ BOOLEAN ForThread, _Out_ PBOOLEAN OldValue)
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
NTSTATUS NTAPI NtDisplayString(PUNICODE_STRING String)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSTATUS NTAPI NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval)
Definition: wait.c:876
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
NTSTATUS NTAPI NtInitializeRegistry(IN USHORT Flag)
Definition: ntapi.c:1318
#define RTL_NUMBER_OF_FIELD(type, field)
Definition: ntbasedef.h:711
#define UNICODE_NULL
CONST CHAR * PCCH
Definition: ntbasedef.h:400
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:321
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
@ FixedMedia
Definition: ntdddisk.h:383
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
NTSTATUS NTAPI NtShutdownSystem(IN SHUTDOWN_ACTION Action)
Definition: shutdown.c:43
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
Definition: time.c:569
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1313
#define STATUS_WAIT_0
Definition: ntstatus.h:237
#define STATUS_PARTITION_FAILURE
Definition: ntstatus.h:604
#define STATUS_SYSTEM_PROCESS_TERMINATED
Definition: ntstatus.h:670
#define STATUS_APP_INIT_FAILURE
Definition: ntstatus.h:561
NTSTRSAFEVAPI RtlStringCchPrintfA(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1085
NTSTRSAFEVAPI RtlS