ReactOS 0.4.16-dev-112-g52265ae
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
44
46
47/* The partition where to perform the installation */
49// static PVOLENTRY InstallVolume = NULL;
50#define InstallVolume (InstallPartition->Volume)
51/*
52 * The system partition we will actually use. It can be different from
53 * PartitionList->SystemPartition in case we don't support it, or we install
54 * on a removable disk.
55 * We may indeed not support the original system partition in case we do not
56 * have write support on it. Please note that this situation is partly a HACK
57 * and MUST NEVER happen on architectures where real system partitions are
58 * mandatory (because then they are formatted in FAT FS and we support write
59 * operation on them).
60 */
62// static PVOLENTRY SystemVolume = NULL;
63#define SystemVolume (SystemPartition->Volume)
64
65
66/* OTHER Stuff *****/
67
69static WCHAR DefaultLanguage[20]; // Copy of string inside LanguageList
70static WCHAR DefaultKBLayout[20]; // Copy of string inside KeyboardList
71
73
74/* Global partition list on the system */
76
77/* Currently selected partition entry in the list */
79static enum {
80 PartTypeData, // On MBR-disks, primary or logical partition
81 PartTypeExtended // MBR-disk container
83
84/* Flag set in VOLENTRY::New when a partition/volume is created automatically */
85#define VOLUME_NEW_AUTOCREATE 0x80
86
87/* List of supported file systems for the partition to be formatted */
89
90/*****************************************************/
91
94
95#ifdef __REACTOS__ /* HACK */
96
97/* FONT SUBSTITUTION WORKAROUND *************************************************/
98
99/* For font file check */
100FONTSUBSTSETTINGS s_SubstSettings = { FALSE };
101
102static void
103DoWatchDestFileName(LPCWSTR FileName)
104{
105 if (FileName[0] == 'm' || FileName[0] == 'M')
106 {
107 if (wcsicmp(FileName, L"mingliu.ttc") == 0)
108 {
109 DPRINT("mingliu.ttc found\n");
110 s_SubstSettings.bFoundFontMINGLIU = TRUE;
111 }
112 else if (wcsicmp(FileName, L"msgothic.ttc") == 0)
113 {
114 DPRINT("msgothic.ttc found\n");
115 s_SubstSettings.bFoundFontMSGOTHIC = TRUE;
116 }
117 else if (wcsicmp(FileName, L"msmincho.ttc") == 0)
118 {
119 DPRINT("msmincho.ttc found\n");
120 s_SubstSettings.bFoundFontMSMINCHO = TRUE;
121 }
122 else if (wcsicmp(FileName, L"mssong.ttf") == 0)
123 {
124 DPRINT("mssong.ttf found\n");
125 s_SubstSettings.bFoundFontMSSONG = TRUE;
126 }
127 }
128 else
129 {
130 if (wcsicmp(FileName, L"simsun.ttc") == 0)
131 {
132 DPRINT("simsun.ttc found\n");
133 s_SubstSettings.bFoundFontSIMSUN = TRUE;
134 }
135 else if (wcsicmp(FileName, L"gulim.ttc") == 0)
136 {
137 DPRINT("gulim.ttc found\n");
138 s_SubstSettings.bFoundFontGULIM = TRUE;
139 }
140 else if (wcsicmp(FileName, L"batang.ttc") == 0)
141 {
142 DPRINT("batang.ttc found\n");
143 s_SubstSettings.bFoundFontBATANG = TRUE;
144 }
145 }
146}
147#endif /* HACK */
148
149/* FUNCTIONS ****************************************************************/
150
151static VOID
153{
154 CHAR buffer[512];
155 va_list ap;
158
159 va_start(ap, fmt);
161 va_end(ap);
162
167}
168
169
170static VOID
172 IN SHORT yTop,
173 IN SHORT Width,
175{
176 COORD coPos;
177 DWORD Written;
178
179 /* Draw upper left corner */
180 coPos.X = xLeft;
181 coPos.Y = yTop;
183 CharUpperLeftCorner, // '+',
184 1,
185 coPos,
186 &Written);
187
188 /* Draw upper edge */
189 coPos.X = xLeft + 1;
190 coPos.Y = yTop;
192 CharHorizontalLine, // '-',
193 Width - 2,
194 coPos,
195 &Written);
196
197 /* Draw upper right corner */
198 coPos.X = xLeft + Width - 1;
199 coPos.Y = yTop;
201 CharUpperRightCorner, // '+',
202 1,
203 coPos,
204 &Written);
205
206 /* Draw right edge, inner space and left edge */
207 for (coPos.Y = yTop + 1; coPos.Y < yTop + Height - 1; coPos.Y++)
208 {
209 coPos.X = xLeft;
211 CharVerticalLine, // '|',
212 1,
213 coPos,
214 &Written);
215
216 coPos.X = xLeft + 1;
218 ' ',
219 Width - 2,
220 coPos,
221 &Written);
222
223 coPos.X = xLeft + Width - 1;
225 CharVerticalLine, // '|',
226 1,
227 coPos,
228 &Written);
229 }
230
231 /* Draw lower left corner */
232 coPos.X = xLeft;
233 coPos.Y = yTop + Height - 1;
235 CharLowerLeftCorner, // '+',
236 1,
237 coPos,
238 &Written);
239
240 /* Draw lower edge */
241 coPos.X = xLeft + 1;
242 coPos.Y = yTop + Height - 1;
244 CharHorizontalLine, // '-',
245 Width - 2,
246 coPos,
247 &Written);
248
249 /* Draw lower right corner */
250 coPos.X = xLeft + Width - 1;
251 coPos.Y = yTop + Height - 1;
253 CharLowerRightCorner, // '+',
254 1,
255 coPos,
256 &Written);
257}
258
259
260VOID
262 PCCH Status,
263 PINPUT_RECORD Ir,
264 ULONG WaitEvent)
265{
266 SHORT yTop;
267 SHORT xLeft;
268 COORD coPos;
269 DWORD Written;
271 ULONG MaxLength;
272 ULONG Lines;
273 PCHAR p;
274 PCCH pnext;
275 BOOLEAN LastLine;
276 SHORT Width;
278
279 /* Count text lines and longest line */
280 MaxLength = 0;
281 Lines = 0;
282 pnext = Text;
283
284 while (TRUE)
285 {
286 p = strchr(pnext, '\n');
287
288 if (p == NULL)
289 {
290 Length = strlen(pnext);
291 LastLine = TRUE;
292 }
293 else
294 {
295 Length = (ULONG)(p - pnext);
296 LastLine = FALSE;
297 }
298
299 Lines++;
300
301 if (Length > MaxLength)
302 MaxLength = Length;
303
304 if (LastLine)
305 break;
306
307 pnext = p + 1;
308 }
309
310 /* Check length of status line */
311 if (Status != NULL)
312 {
314
315 if (Length > MaxLength)
316 MaxLength = Length;
317 }
318
319 Width = MaxLength + 4;
320 Height = Lines + 2;
321
322 if (Status != NULL)
323 Height += 2;
324
325 yTop = (yScreen - Height) / 2;
326 xLeft = (xScreen - Width) / 2;
327
328
329 /* Set screen attributes */
330 coPos.X = xLeft;
331 for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++)
332 {
335 Width,
336 coPos,
337 &Written);
338 }
339
340 DrawBox(xLeft, yTop, Width, Height);
341
342 /* Print message text */
343 coPos.Y = yTop + 1;
344 pnext = Text;
345 while (TRUE)
346 {
347 p = strchr(pnext, '\n');
348
349 if (p == NULL)
350 {
351 Length = strlen(pnext);
352 LastLine = TRUE;
353 }
354 else
355 {
356 Length = (ULONG)(p - pnext);
357 LastLine = FALSE;
358 }
359
360 if (Length != 0)
361 {
362 coPos.X = xLeft + 2;
364 pnext,
365 Length,
366 coPos,
367 &Written);
368 }
369
370 if (LastLine)
371 break;
372
373 coPos.Y++;
374 pnext = p + 1;
375 }
376
377 /* Print separator line and status text */
378 if (Status != NULL)
379 {
380 coPos.Y = yTop + Height - 3;
381 coPos.X = xLeft;
384 1,
385 coPos,
386 &Written);
387
388 coPos.X = xLeft + 1;
390 CharHorizontalLine, // '-',
391 Width - 2,
392 coPos,
393 &Written);
394
395 coPos.X = xLeft + Width - 1;
398 1,
399 coPos,
400 &Written);
401
402 coPos.Y++;
403 coPos.X = xLeft + 2;
405 Status,
406 min(strlen(Status), (SIZE_T)Width - 4),
407 coPos,
408 &Written);
409 }
410
411 if (WaitEvent == POPUP_WAIT_NONE)
412 return;
413
414 while (TRUE)
415 {
417
418 if (WaitEvent == POPUP_WAIT_ANY_KEY ||
419 Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)
420 {
421 return;
422 }
423 }
424}
425
426
427/*
428 * Confirm quit setup
429 * RETURNS
430 * TRUE: Quit setup.
431 * FALSE: Don't quit setup.
432 */
433static BOOL
435{
436 BOOL Result = FALSE;
438
439 while (TRUE)
440 {
442
443 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
444 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
445 {
446 Result = TRUE;
447 break;
448 }
449 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
450 {
451 Result = FALSE;
452 break;
453 }
454 }
455
456 return Result;
457}
458
459
460static VOID
462{
463 PGENERIC_LIST_ENTRY ListEntry;
464 KLID newLayout;
465
467
469 {
472 {
473 /* FIXME: Handle error! */
474 return;
475 }
476 }
477
478 /* Search for default layout (if provided) */
479 if (newLayout != 0)
480 {
481 for (ListEntry = GetFirstListEntry(USetupData.LayoutList); ListEntry;
482 ListEntry = GetNextListEntry(ListEntry))
483 {
484 PCWSTR pszLayoutId = ((PGENENTRY)GetListEntryData(ListEntry))->Id;
485 KLID LayoutId = (KLID)(pszLayoutId ? wcstoul(pszLayoutId, NULL, 16) : 0);
486 if (newLayout == LayoutId)
487 {
489 break;
490 }
491 }
492 }
493}
494
495
496static NTSTATUS
497NTAPI
501 IN SIZE_T cchBufferSize)
502{
503 return RtlStringCchPrintfA(Buffer, cchBufferSize, "%S",
505}
506
507static NTSTATUS
508NTAPI
512 IN SIZE_T cchBufferSize)
513{
515 PVOLINFO VolInfo = (NtOsInstall->Volume ? &NtOsInstall->Volume->Info : NULL);
516
517 if (VolInfo && VolInfo->DriveLetter)
518 {
519 /* We have retrieved a partition that is mounted */
520 return RtlStringCchPrintfA(Buffer, cchBufferSize,
521 "%C:%S \"%S\"",
522 VolInfo->DriveLetter,
523 NtOsInstall->PathComponent,
524 NtOsInstall->InstallationName);
525 }
526 else
527 {
528 /* We failed somewhere, just show the NT path */
529 return RtlStringCchPrintfA(Buffer, cchBufferSize,
530 "%wZ \"%S\"",
531 &NtOsInstall->SystemNtPath,
532 NtOsInstall->InstallationName);
533 }
534}
535
536
537/*
538 * Start page
539 *
540 * Next pages:
541 * LanguagePage (at once, default)
542 * InstallIntroPage (at once, if unattended)
543 * QuitPage
544 *
545 * SIDEEFFECTS
546 * Init Sdi
547 * Init USetupData.SourcePath
548 * Init USetupData.SourceRootPath
549 * Init USetupData.SourceRootDir
550 * Init USetupData.SetupInf
551 * Init USetupData.RequiredPartitionDiskSpace
552 * Init IsUnattendedSetup
553 * If unattended, init *List and sets the Codepage
554 * If unattended, init SelectedLanguageId
555 * If unattended, init USetupData.LanguageId
556 *
557 * RETURNS
558 * Number of the next page.
559 */
560static PAGE_NUMBER
562{
563 ULONG Error;
564 PGENERIC_LIST_ENTRY ListEntry;
566
568
569 /* Initialize Setup, phase 1 */
571 if (Error != ERROR_SUCCESS)
572 {
574 return QUIT_PAGE;
575 }
576
577 /* Initialize the user-mode PnP manager */
579 DPRINT1("The user-mode PnP manager could not initialize, expect unavailable devices!\n");
580
581 /* Wait for any immediate pending installations to finish */
583 DPRINT1("WaitNoPendingInstallEvents() failed to wait!\n");
584
586
588 {
589 // TODO: Read options from inf
590 /* Load the hardware, language and keyboard layout lists */
591
595
597
598 /* new part */
602
604
605 /* first we hack LanguageList */
606 for (ListEntry = GetFirstListEntry(USetupData.LanguageList); ListEntry;
607 ListEntry = GetNextListEntry(ListEntry))
608 {
609 LocaleId = ((PGENENTRY)GetListEntryData(ListEntry))->Id;
611 {
612 DPRINT("found %S in LanguageList\n", LocaleId);
614 break;
615 }
616 }
617
618 /* now LayoutList */
619 for (ListEntry = GetFirstListEntry(USetupData.LayoutList); ListEntry;
620 ListEntry = GetNextListEntry(ListEntry))
621 {
622 LocaleId = ((PGENENTRY)GetListEntryData(ListEntry))->Id;
624 {
625 DPRINT("found %S in LayoutList\n", LocaleId);
627 break;
628 }
629 }
630
632
633 return INSTALL_INTRO_PAGE;
634 }
635
636 return LANGUAGE_PAGE;
637}
638
639
640/*
641 * Displays the LanguagePage.
642 *
643 * Next pages: WelcomePage, QuitPage
644 *
645 * SIDEEFFECTS
646 * Init SelectedLanguageId
647 * Init USetupData.LanguageId
648 *
649 * RETURNS
650 * Number of the next page.
651 */
652static PAGE_NUMBER
654{
655 GENERIC_LIST_UI ListUi;
656 PCWSTR NewLanguageId;
657 BOOL RefreshPage = FALSE;
658
659 /* Initialize the computer settings list */
661 {
664 {
665 PopupError("Setup failed to initialize available translations", NULL, NULL, POPUP_WAIT_NONE);
666 return WELCOME_PAGE;
667 }
668 }
669
672
673 /* Load the font */
676
677 /*
678 * If there is no language or just a single one in the list,
679 * skip the language selection process altogether.
680 */
682 {
684 return WELCOME_PAGE;
685 }
686
688 DrawGenericList(&ListUi,
689 2, 18,
690 xScreen - 3,
691 yScreen - 3);
692
694
696
697 while (TRUE)
698 {
700
701 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
702 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
703 {
704 ScrollDownGenericList(&ListUi);
705 RefreshPage = TRUE;
706 }
707 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
708 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
709 {
710 ScrollUpGenericList(&ListUi);
711 RefreshPage = TRUE;
712 }
713 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
714 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_NEXT)) /* PAGE DOWN */
715 {
717 RefreshPage = TRUE;
718 }
719 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
720 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_PRIOR)) /* PAGE UP */
721 {
723 RefreshPage = TRUE;
724 }
725 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
726 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
727 {
728 if (ConfirmQuit(Ir))
729 return QUIT_PAGE;
730 else
731 RedrawGenericList(&ListUi);
732 }
733 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
734 {
736
739
741
743 {
745 }
746
747 /* Load the font */
749
750 return WELCOME_PAGE;
751 }
752 else if ((Ir->Event.KeyEvent.uChar.AsciiChar > 0x60) && (Ir->Event.KeyEvent.uChar.AsciiChar < 0x7b))
753 {
754 /* a-z */
756 RefreshPage = TRUE;
757 }
758
759 if (RefreshPage)
760 {
762
763 NewLanguageId =
765
766 if (wcscmp(SelectedLanguageId, NewLanguageId))
767 {
768 /* Clear the language page */
770
771 SelectedLanguageId = NewLanguageId;
772
773 /* Load the font */
775
776 /* Redraw the list */
777 DrawGenericList(&ListUi,
778 2, 18,
779 xScreen - 3,
780 yScreen - 3);
781
782 /* Redraw language selection page in native language */
784 }
785
786 RefreshPage = FALSE;
787 }
788 }
789
790 return WELCOME_PAGE;
791}
792
793
794/*
795 * Displays the WelcomePage.
796 *
797 * Next pages:
798 * InstallIntroPage (default)
799 * RepairIntroPage
800 * RecoveryPage
801 * LicensePage
802 * QuitPage
803 *
804 * RETURNS
805 * Number of the next page.
806 */
807static PAGE_NUMBER
809{
811
812 while (TRUE)
813 {
815
816 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
817 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
818 {
819 if (ConfirmQuit(Ir))
820 return QUIT_PAGE;
821
822 break;
823 }
824 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
825 {
826 return INSTALL_INTRO_PAGE;
827 }
828 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */
829 {
830 return RECOVERY_PAGE; // REPAIR_INTRO_PAGE;
831 }
832 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'L') /* L */
833 {
834 return LICENSE_PAGE;
835 }
836 }
837
838 return WELCOME_PAGE;
839}
840
841
842/*
843 * Displays the License page.
844 *
845 * Next page:
846 * WelcomePage (default)
847 *
848 * RETURNS
849 * Number of the next page.
850 */
851static PAGE_NUMBER
853{
855
856 while (TRUE)
857 {
859
860 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
861 {
862 return WELCOME_PAGE;
863 }
864 }
865
866 return LICENSE_PAGE;
867}
868
869
870/*
871 * Displays the RepairIntroPage.
872 *
873 * Next pages:
874 * RebootPage (default)
875 * InstallIntroPage
876 * RecoveryPage
877 * IntroPage
878 *
879 * RETURNS
880 * Number of the next page.
881 */
882static PAGE_NUMBER
884{
886
887 while (TRUE)
888 {
890
891 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
892 {
893 return REBOOT_PAGE;
894 }
895 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'U') /* U */
896 {
898 return INSTALL_INTRO_PAGE;
899 }
900 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */
901 {
902 return RECOVERY_PAGE;
903 }
904 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
905 {
906 return WELCOME_PAGE;
907 }
908 }
909
910 return REPAIR_INTRO_PAGE;
911}
912
913/*
914 * Displays the UpgradeRepairPage.
915 *
916 * Next pages:
917 * RebootPage (default)
918 * InstallIntroPage
919 * RecoveryPage
920 * WelcomePage
921 *
922 * RETURNS
923 * Number of the next page.
924 */
925static PAGE_NUMBER
927{
928 GENERIC_LIST_UI ListUi;
929
930/*** HACK!! ***/
931 if (PartitionList == NULL)
932 {
934 if (PartitionList == NULL)
935 {
936 /* FIXME: show an error dialog */
938 return QUIT_PAGE;
939 }
941 {
943 return QUIT_PAGE;
944 }
945 }
946/**************/
947
949 if (!NtOsInstallsList)
950 DPRINT1("Failed to get a list of NTOS installations; continue installation...\n");
951
952 /*
953 * If there is no available installation (or just a single one??) that can
954 * be updated in the list, just continue with the regular installation.
955 */
957 {
959
960 // return INSTALL_INTRO_PAGE;
962 // return SCSI_CONTROLLER_PAGE;
963 }
964
966
968 DrawGenericList(&ListUi,
969 2, 23,
970 xScreen - 3,
971 yScreen - 3);
972
973 // return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
974 while (TRUE)
975 {
977
978 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x00)
979 {
980 switch (Ir->Event.KeyEvent.wVirtualKeyCode)
981 {
982 case VK_DOWN: /* DOWN */
983 ScrollDownGenericList(&ListUi);
984 break;
985 case VK_UP: /* UP */
986 ScrollUpGenericList(&ListUi);
987 break;
988 case VK_NEXT: /* PAGE DOWN */
990 break;
991 case VK_PRIOR: /* PAGE UP */
993 break;
994 case VK_F3: /* F3 */
995 {
996 if (ConfirmQuit(Ir))
997 return QUIT_PAGE;
998 else
999 RedrawGenericList(&ListUi);
1000 break;
1001 }
1002#if 1
1003/* TODO: Temporarily kept until correct keyboard layout is in place.
1004 * (Actual AsciiChar of ESCAPE should be 0x1B instead of 0.)
1005 * Addendum to commit 8b94515b.
1006 */
1007 case VK_ESCAPE: /* ESC */
1008 {
1010 // return nextPage; // prevPage;
1011
1012 // return INSTALL_INTRO_PAGE;
1013 return DEVICE_SETTINGS_PAGE;
1014 // return SCSI_CONTROLLER_PAGE;
1015 }
1016
1017#endif
1018 }
1019 }
1020#if 0
1021/* TODO: Restore this once correct keyboard layout is in place. */
1022 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
1023 {
1025 // return nextPage; // prevPage;
1026
1027 // return INSTALL_INTRO_PAGE;
1028 return DEVICE_SETTINGS_PAGE;
1029 // return SCSI_CONTROLLER_PAGE;
1030 }
1031#endif
1032 else
1033 {
1034 // switch (toupper(Ir->Event.KeyEvent.uChar.AsciiChar))
1035 // if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1036 if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'U') /* U */
1037 {
1038 /* Retrieve the current installation */
1040
1043
1044 DPRINT1("Selected installation for repair: \"%S\" ; DiskNumber = %d , PartitionNumber = %d\n",
1046
1048
1049 // return nextPage;
1050 /***/return INSTALL_INTRO_PAGE;/***/
1051 }
1052 else if ((Ir->Event.KeyEvent.uChar.AsciiChar > 0x60) &&
1053 (Ir->Event.KeyEvent.uChar.AsciiChar < 0x7b)) /* a-z */
1054 {
1056 }
1057 }
1058 }
1059
1060 return UPGRADE_REPAIR_PAGE;
1061}
1062
1063
1064/*
1065 * Displays the InstallIntroPage.
1066 *
1067 * Next pages:
1068 * DeviceSettingsPage (At once if repair or update is selected)
1069 * SelectPartitionPage (At once if unattended setup)
1070 * DeviceSettingsPage (default)
1071 * QuitPage
1072 *
1073 * RETURNS
1074 * Number of the next page.
1075 */
1076static PAGE_NUMBER
1078{
1079 if (RepairUpdateFlag)
1080 {
1081#if 1 /* Old code that looks good */
1082
1083 // return SELECT_PARTITION_PAGE;
1084 return DEVICE_SETTINGS_PAGE;
1085
1086#else /* Possible new code? */
1087
1088 return DEVICE_SETTINGS_PAGE;
1089 // return SCSI_CONTROLLER_PAGE;
1090
1091#endif
1092 }
1093
1095 return SELECT_PARTITION_PAGE;
1096
1098
1099 while (TRUE)
1100 {
1101 CONSOLE_ConInKey(Ir);
1102
1103 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1104 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1105 {
1106 if (ConfirmQuit(Ir))
1107 return QUIT_PAGE;
1108
1109 break;
1110 }
1111 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1112 {
1113 return UPGRADE_REPAIR_PAGE;
1114 }
1115 }
1116
1117 return INSTALL_INTRO_PAGE;
1118}
1119
1120
1121#if 0
1122static PAGE_NUMBER
1123ScsiControllerPage(PINPUT_RECORD Ir)
1124{
1125 // MUIDisplayPage(SCSI_CONTROLLER_PAGE);
1126
1127 CONSOLE_SetTextXY(6, 8, "Setup detected the following mass storage devices:");
1128
1129 /* FIXME: print loaded mass storage driver descriptions */
1130#if 0
1131 CONSOLE_SetTextXY(8, 10, "TEST device");
1132#endif
1133
1134 CONSOLE_SetStatusText(" ENTER = Continue F3 = Quit");
1135
1136 while (TRUE)
1137 {
1138 CONSOLE_ConInKey(Ir);
1139
1140 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1141 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1142 {
1143 if (ConfirmQuit(Ir))
1144 return QUIT_PAGE;
1145
1146 break;
1147 }
1148 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1149 {
1150 return DEVICE_SETTINGS_PAGE;
1151 }
1152 }
1153
1154 return SCSI_CONTROLLER_PAGE;
1155}
1156
1157static PAGE_NUMBER
1158OemDriverPage(PINPUT_RECORD Ir)
1159{
1160 // MUIDisplayPage(OEM_DRIVER_PAGE);
1161
1162 CONSOLE_SetTextXY(6, 8, "This is the OEM driver page!");
1163
1164 /* FIXME: Implement!! */
1165
1166 CONSOLE_SetStatusText(" ENTER = Continue F3 = Quit");
1167
1168 while (TRUE)
1169 {
1170 CONSOLE_ConInKey(Ir);
1171
1172 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1173 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1174 {
1175 if (ConfirmQuit(Ir))
1176 return QUIT_PAGE;
1177
1178 break;
1179 }
1180 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1181 {
1182 return DEVICE_SETTINGS_PAGE;
1183 }
1184 }
1185
1186 return OEM_DRIVER_PAGE;
1187}
1188#endif
1189
1190
1191/*
1192 * Displays the DeviceSettingsPage.
1193 *
1194 * Next pages:
1195 * SelectPartitionPage (At once if repair or update is selected)
1196 * ComputerSettingsPage
1197 * DisplaySettingsPage
1198 * KeyboardSettingsPage
1199 * LayoutsettingsPage
1200 * SelectPartitionPage
1201 * QuitPage
1202 *
1203 * SIDEEFFECTS
1204 * Init USetupData.ComputerList
1205 * Init USetupData.DisplayList
1206 * Init USetupData.KeyboardList
1207 * Init USetupData.LayoutList
1208 *
1209 * RETURNS
1210 * Number of the next page.
1211 */
1212static PAGE_NUMBER
1214{
1215 static ULONG Line = 16;
1216
1217 /* Initialize the computer settings list */
1219 {
1222 {
1224 return QUIT_PAGE;
1225 }
1226 }
1227
1228 /* Initialize the display settings list */
1230 {
1233 {
1235 return QUIT_PAGE;
1236 }
1237 }
1238
1239 /* Initialize the keyboard settings list */
1241 {
1244 {
1246 return QUIT_PAGE;
1247 }
1248 }
1249
1250 /* Initialize the keyboard layout list */
1252 {
1255 {
1256 /* FIXME: report error */
1258 return QUIT_PAGE;
1259 }
1260 }
1261
1262 if (RepairUpdateFlag)
1263 return SELECT_PARTITION_PAGE;
1264
1265 // if (IsUnattendedSetup)
1266 // return SELECT_PARTITION_PAGE;
1267
1269
1274
1275 CONSOLE_InvertTextXY(24, Line, 48, 1);
1276
1277 while (TRUE)
1278 {
1279 CONSOLE_ConInKey(Ir);
1280
1281 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1282 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
1283 {
1284 CONSOLE_NormalTextXY(24, Line, 48, 1);
1285
1286 if (Line == 14)
1287 Line = 16;
1288 else if (Line == 16)
1289 Line = 11;
1290 else
1291 Line++;
1292
1293 CONSOLE_InvertTextXY(24, Line, 48, 1);
1294 }
1295 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1296 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
1297 {
1298 CONSOLE_NormalTextXY(24, Line, 48, 1);
1299
1300 if (Line == 11)
1301 Line = 16;
1302 else if (Line == 16)
1303 Line = 14;
1304 else
1305 Line--;
1306
1307 CONSOLE_InvertTextXY(24, Line, 48, 1);
1308 }
1309 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1310 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1311 {
1312 if (ConfirmQuit(Ir))
1313 return QUIT_PAGE;
1314
1315 break;
1316 }
1317 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1318 {
1319 if (Line == 11)
1321 else if (Line == 12)
1322 return DISPLAY_SETTINGS_PAGE;
1323 else if (Line == 13)
1325 else if (Line == 14)
1326 return LAYOUT_SETTINGS_PAGE;
1327 else if (Line == 16)
1328 return SELECT_PARTITION_PAGE;
1329 }
1330 }
1331
1332 return DEVICE_SETTINGS_PAGE;
1333}
1334
1335
1336/*
1337 * Handles generic selection lists.
1338 *
1339 * PARAMS
1340 * GenericList: The list to handle.
1341 * nextPage: The page it needs to jump to after this page.
1342 * Ir: The PINPUT_RECORD
1343 */
1344static PAGE_NUMBER
1346 PAGE_NUMBER nextPage,
1347 PINPUT_RECORD Ir)
1348{
1349 while (TRUE)
1350 {
1351 CONSOLE_ConInKey(Ir);
1352
1353 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1354 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
1355 {
1356 ScrollDownGenericList(ListUi);
1357 }
1358 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1359 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
1360 {
1361 ScrollUpGenericList(ListUi);
1362 }
1363 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1364 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_NEXT)) /* PAGE DOWN */
1365 {
1367 }
1368 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1369 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_PRIOR)) /* PAGE UP */
1370 {
1372 }
1373 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1374 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1375 {
1376 if (ConfirmQuit(Ir))
1377 return QUIT_PAGE;
1378 else
1379 RedrawGenericList(ListUi);
1380 }
1381 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
1382 {
1384 return nextPage; // Use some "prevPage;" instead?
1385 }
1386 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1387 {
1388 return nextPage;
1389 }
1390 else if ((Ir->Event.KeyEvent.uChar.AsciiChar > 0x60) && (Ir->Event.KeyEvent.uChar.AsciiChar < 0x7b))
1391 {
1392 /* a-z */
1394 }
1395 }
1396}
1397
1398
1399/*
1400 * Displays the ComputerSettingsPage.
1401 *
1402 * Next pages:
1403 * DeviceSettingsPage
1404 * QuitPage
1405 *
1406 * RETURNS
1407 * Number of the next page.
1408 */
1409static PAGE_NUMBER
1411{
1412 GENERIC_LIST_UI ListUi;
1414
1416 DrawGenericList(&ListUi,
1417 2, 18,
1418 xScreen - 3,
1419 yScreen - 3);
1420
1421 return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
1422}
1423
1424
1425/*
1426 * Displays the DisplaySettingsPage.
1427 *
1428 * Next pages:
1429 * DeviceSettingsPage
1430 * QuitPage
1431 *
1432 * RETURNS
1433 * Number of the next page.
1434 */
1435static PAGE_NUMBER
1437{
1438 GENERIC_LIST_UI ListUi;
1440
1442 DrawGenericList(&ListUi,
1443 2, 18,
1444 xScreen - 3,
1445 yScreen - 3);
1446
1447 return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
1448}
1449
1450
1451/*
1452 * Displays the KeyboardSettingsPage.
1453 *
1454 * Next pages:
1455 * DeviceSettingsPage
1456 * QuitPage
1457 *
1458 * RETURNS
1459 * Number of the next page.
1460 */
1461static PAGE_NUMBER
1463{
1464 GENERIC_LIST_UI ListUi;
1466
1468 DrawGenericList(&ListUi,
1469 2, 18,
1470 xScreen - 3,
1471 yScreen - 3);
1472
1473 return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
1474}
1475
1476
1477/*
1478 * Displays the LayoutSettingsPage.
1479 *
1480 * Next pages:
1481 * DeviceSettingsPage
1482 * QuitPage
1483 *
1484 * RETURNS
1485 * Number of the next page.
1486 */
1487static PAGE_NUMBER
1489{
1490 GENERIC_LIST_UI ListUi;
1492
1494 DrawGenericList(&ListUi,
1495 2, 18,
1496 xScreen - 3,
1497 yScreen - 3);
1498
1499 return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
1500}
1501
1502
1503static BOOLEAN
1505 _In_ PPARTENTRY PartEntry)
1506{
1507 /* Retrieve the maximum size in MB (rounded up) */
1508 ULONGLONG PartSize = RoundingDivide(GetPartEntrySizeInBytes(PartEntry), MB);
1509
1511 {
1512 /* Partition is too small so ask for another one */
1513 DPRINT1("Partition is too small (size: %I64u MB), required disk space is %lu MB\n",
1515 return FALSE;
1516 }
1517 else
1518 {
1519 return TRUE;
1520 }
1521}
1522
1523
1524/*
1525 * Displays the SelectPartitionPage.
1526 *
1527 * Next pages:
1528 * SelectFileSystemPage (At once if unattended)
1529 * SelectFileSystemPage (Default if free space is selected)
1530 * CreatePartitionPage
1531 * ConfirmDeleteSystemPartitionPage (if the selected partition is the system partition, aka with the boot flag set)
1532 * DeletePartitionPage
1533 * QuitPage
1534 *
1535 * SIDEEFFECTS
1536 * Set InstallShortcut (only if not unattended + free space is selected)
1537 *
1538 * RETURNS
1539 * Number of the next page.
1540 */
1541static PAGE_NUMBER
1543{
1544 PARTLIST_UI ListUi;
1545 ULONG Error;
1546
1547 if (PartitionList == NULL)
1548 {
1550 if (PartitionList == NULL)
1551 {
1553 return QUIT_PAGE;
1554 }
1556 {
1558 return QUIT_PAGE;
1559 }
1560 }
1561
1562 if (RepairUpdateFlag)
1563 {
1565
1566 /* Determine the selected installation disk & partition */
1570 if (!InstallPartition)
1571 {
1572 DPRINT1("RepairUpdateFlag == TRUE, SelectPartition() returned FALSE, assert!\n");
1573 ASSERT(FALSE);
1574 }
1575
1577 }
1578
1580
1583 2, 21,
1584 xScreen - 3,
1585 yScreen - 3);
1586 DrawPartitionList(&ListUi);
1587
1589 {
1590 /* Determine the selected installation disk & partition */
1594 if (!InstallPartition)
1595 {
1597
1599 {
1602
1603 /* Automatically create the partition on the whole empty space;
1604 * it will be formatted later with default parameters */
1607 0ULL,
1608 0);
1611
1612// FIXME?? Aren't we going to enter an infinite loop, if this test fails??
1614 {
1617 return SELECT_PARTITION_PAGE; /* let the user select another partition */
1618 }
1619
1622 }
1623 }
1624 else
1625 {
1627
1628 DrawPartitionList(&ListUi); // FIXME: Doesn't make much sense...
1629
1630// FIXME?? Aren't we going to enter an infinite loop, if this test fails??
1632 {
1635 return SELECT_PARTITION_PAGE; /* let the user select another partition */
1636 }
1637
1639 }
1640 }
1641
1642 while (TRUE)
1643 {
1644 ULONG uID;
1645
1647
1648 /* Update status text */
1649 if (CurrentPartition == NULL)
1650 {
1651 // FIXME: If we get a NULL current partition, this means that
1652 // the current disk is of unrecognized type. So we should display
1653 // instead a status string to initialize the disk with one of
1654 // the recognized partitioning schemes (MBR, later: GPT, etc.)
1655 // For the time being we don't have that, so use instead another
1656 // known string.
1658 }
1659 else
1660 {
1662 {
1666 {
1668 }
1669 }
1670 else
1671 {
1675 }
1676 }
1678
1679 CONSOLE_ConInKey(Ir);
1680
1681 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1682 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1683 {
1684 if (ConfirmQuit(Ir))
1685 {
1688 return QUIT_PAGE;
1689 }
1690
1691 break;
1692 }
1693 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1694 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
1695 {
1697 }
1698 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1699 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
1700 {
1702 }
1703 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
1704 {
1706
1708 continue; // return SELECT_PARTITION_PAGE;
1709
1710 /*
1711 * Check whether the user wants to install ReactOS on a disk that
1712 * is not recognized by the computer's firmware and if so, display
1713 * a warning since such disks may not be bootable.
1714 */
1715 if (CurrentPartition->DiskEntry->MediaType == FixedMedia &&
1716 !CurrentPartition->DiskEntry->BiosFound)
1717 {
1718 PopupError("The disk you have selected for installing ReactOS\n"
1719 "is not visible by the firmware of your computer,\n"
1720 "and so may not be bootable.\n"
1721 "Press ENTER to continue anyway.",
1723 Ir, POPUP_WAIT_ENTER);
1724 // return SELECT_PARTITION_PAGE;
1725 }
1726
1728 {
1730 if (Error != NOT_AN_ERROR)
1731 {
1733 return SELECT_PARTITION_PAGE;
1734 }
1735
1736 /* Automatically create the partition on the whole empty space;
1737 * it will be formatted later with default parameters */
1740 0ULL,
1741 0);
1744 }
1745
1747 {
1750 return SELECT_PARTITION_PAGE; /* let the user select another partition */
1751 }
1752
1755 }
1756 else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'C') /* C */
1757 {
1759
1761 if (Error != NOT_AN_ERROR)
1762 {
1764 return SELECT_PARTITION_PAGE;
1765 }
1766
1768 return CREATE_PARTITION_PAGE;
1769 }
1770 else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'E') /* E */
1771 {
1773
1775 {
1777 if (Error != NOT_AN_ERROR)
1778 {
1780 return SELECT_PARTITION_PAGE;
1781 }
1782
1784 return CREATE_PARTITION_PAGE;
1785 }
1786 }
1787 else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'D') /* D */
1788 {
1790
1791 /* Ignore deletion in case this is not a partitioned entry */
1793 continue;
1794
1795// TODO: Do something similar before trying to format the partition?
1798 {
1799 UNICODE_STRING CurrentPartitionU;
1800 WCHAR PathBuffer[RTL_NUMBER_OF_FIELD(VOLINFO, DeviceName) + 1];
1801
1803
1804 RtlStringCchPrintfW(PathBuffer, _countof(PathBuffer),
1806 RtlInitUnicodeString(&CurrentPartitionU, PathBuffer);
1807
1808 /*
1809 * Check whether the user attempts to delete the partition on which
1810 * the installation source is present. If so, fail with an error.
1811 */
1812 // &USetupData.SourceRootPath
1813 if (RtlPrefixUnicodeString(&CurrentPartitionU, &USetupData.SourcePath, TRUE))
1814 {
1816 return SELECT_PARTITION_PAGE;
1817 }
1818 }
1819
1822 {
1824 }
1825
1826 return DELETE_PARTITION_PAGE;
1827 }
1828 }
1829
1830 return SELECT_PARTITION_PAGE;
1831}
1832
1833
1834#define PARTITION_SIZE_INPUT_FIELD_LENGTH 9
1835/* Restriction for MaxSize */
1836#define PARTITION_MAXSIZE (pow(10, (PARTITION_SIZE_INPUT_FIELD_LENGTH - 1)) - 1)
1837
1838static VOID
1840 SHORT Top,
1841 SHORT Right,
1842 SHORT Bottom,
1843 ULONG MaxSize,
1845 PBOOLEAN Quit,
1847{
1848 INPUT_RECORD Ir;
1849 COORD coPos;
1850 DWORD Written;
1851 CHAR Buffer[128];
1852 INT Length, Pos;
1853 WCHAR ch;
1854 SHORT iLeft;
1855 SHORT iTop;
1856
1857 if (Quit != NULL)
1858 *Quit = FALSE;
1859
1860 if (Cancel != NULL)
1861 *Cancel = FALSE;
1862
1863 DrawBox(Left, Top, Right - Left + 1, Bottom - Top + 1);
1864
1865 /* Print message */
1866 coPos.X = Left + 2;
1867 coPos.Y = Top + 2;
1869 iLeft = coPos.X + (USHORT)strlen(Buffer) + 1;
1870 iTop = coPos.Y;
1871
1873 Buffer,
1874 strlen(Buffer),
1875 coPos,
1876 &Written);
1877
1879 coPos.X = iLeft + PARTITION_SIZE_INPUT_FIELD_LENGTH + 1;
1880 coPos.Y = iTop;
1882 Buffer,
1883 strlen(Buffer),
1884 coPos,
1885 &Written);
1886
1887 swprintf(InputBuffer, L"%lu", MaxSize);
1889 Pos = Length;
1891 iTop,
1893 InputBuffer);
1894 CONSOLE_SetCursorXY(iLeft + Length, iTop);
1896
1897 while (TRUE)
1898 {
1899 CONSOLE_ConInKey(&Ir);
1900
1901 if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1902 (Ir.Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1903 {
1904 if (Quit != NULL)
1905 *Quit = TRUE;
1906
1909 break;
1910 }
1911 else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
1912 {
1914 break;
1915 }
1916 else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
1917 {
1918 if (Cancel != NULL)
1919 *Cancel = TRUE;
1920
1923 break;
1924 }
1925 else if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1926 (Ir.Event.KeyEvent.wVirtualKeyCode == VK_HOME)) /* HOME */
1927 {
1928 Pos = 0;
1929 CONSOLE_SetCursorXY(iLeft + Pos, iTop);
1930 }
1931 else if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1932 (Ir.Event.KeyEvent.wVirtualKeyCode == VK_END)) /* END */
1933 {
1934 Pos = Length;
1935 CONSOLE_SetCursorXY(iLeft + Pos, iTop);
1936 }
1937 else if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1938 (Ir.Event.KeyEvent.wVirtualKeyCode == VK_LEFT)) /* LEFT */
1939 {
1940 if (Pos > 0)
1941 {
1942 Pos--;
1943 CONSOLE_SetCursorXY(iLeft + Pos, iTop);
1944 }
1945 }
1946 else if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1947 (Ir.Event.KeyEvent.wVirtualKeyCode == VK_RIGHT)) /* RIGHT */
1948 {
1949 if (Pos < Length)
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_DELETE)) /* DEL */
1957 {
1958 if (Pos < Length)
1959 {
1961 &InputBuffer[Pos + 1],
1962 (Length - Pos - 1) * sizeof(WCHAR));
1964
1965 Length--;
1967 iTop,
1969 InputBuffer);
1970 CONSOLE_SetCursorXY(iLeft + Pos, iTop);
1971 }
1972 }
1973 else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_BACK) /* BACKSPACE */
1974 {
1975 if (Pos > 0)
1976 {
1977 if (Pos < Length)
1978 memmove(&InputBuffer[Pos - 1],
1979 &InputBuffer[Pos],
1980 (Length - Pos) * sizeof(WCHAR));
1982
1983 Pos--;
1984 Length--;
1986 iTop,
1988 InputBuffer);
1989 CONSOLE_SetCursorXY(iLeft + Pos, iTop);
1990 }
1991 }
1992 else if (Ir.Event.KeyEvent.uChar.AsciiChar != 0x00)
1993 {
1995 {
1997
1998 if ((ch >= L'0') && (ch <= L'9'))
1999 {
2000 if (Pos < Length)
2001 memmove(&InputBuffer[Pos + 1],
2002 &InputBuffer[Pos],
2003 (Length - Pos) * sizeof(WCHAR));
2005 InputBuffer[Pos] = ch;
2006
2007 Pos++;
2008 Length++;
2010 iTop,
2012 InputBuffer);
2013 CONSOLE_SetCursorXY(iLeft + Pos, iTop);
2014 }
2015 }
2016 }
2017 }
2018}
2019
2020
2021/*
2022 * Displays the CreatePartitionPage.
2023 *
2024 * Next pages:
2025 * SelectPartitionPage
2026 * SelectFileSystemPage (default)
2027 * QuitPage
2028 *
2029 * RETURNS
2030 * Number of the next page.
2031 */
2032static PAGE_NUMBER
2034{
2035 PPARTENTRY PartEntry;
2036 PDISKENTRY DiskEntry;
2037 ULONG uID;
2038 ULONG MaxSize;
2039 ULONGLONG MaxPartSize, PartSize;
2040 BOOLEAN Quit, Cancel;
2041 WCHAR InputBuffer[50];
2042 CHAR LineBuffer[100];
2043
2045 {
2046 /* FIXME: show an error dialog */
2047 return QUIT_PAGE;
2048 }
2049
2051 {
2055 }
2056 else // if (PartCreateType == PartTypeExtended)
2057 {
2059 }
2060
2061 CONSOLE_SetTextXY(6, 8, MUIGetString(uID));
2062
2063 PartEntry = CurrentPartition;
2064 DiskEntry = CurrentPartition->DiskEntry;
2065
2066 DiskDescription(DiskEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2068 LineBuffer);
2069
2071
2073
2074 MaxPartSize = GetPartEntrySizeInBytes(PartEntry);
2075
2076 while (TRUE)
2077 {
2078 /* Retrieve the maximum size in MB (rounded up)
2079 * and cap it with what the user can enter */
2080 MaxSize = (ULONG)RoundingDivide(MaxPartSize, MB);
2081 MaxSize = min(MaxSize, PARTITION_MAXSIZE);
2082
2083 ShowPartitionSizeInputBox(12, 14, xScreen - 12, 17,
2084 MaxSize, InputBuffer, &Quit, &Cancel);
2085 if (Quit)
2086 {
2087 if (ConfirmQuit(Ir))
2088 return QUIT_PAGE;
2089 break;
2090 }
2091 else if (Cancel)
2092 {
2093 return SELECT_PARTITION_PAGE;
2094 }
2095
2096 PartSize = _wcstoui64(InputBuffer, NULL, 10);
2097
2098 /* Retry if too small or too large */
2099 if ((PartSize < 1) || (PartSize > MaxSize))
2100 continue;
2101
2102 /*
2103 * If the input size, given in MB, specifies the maximum partition
2104 * size, it may slightly under- or over-estimate the latter due to
2105 * rounding error. In this case, use all of the unpartitioned space.
2106 * Otherwise, directly convert the size to bytes.
2107 */
2108 if (PartSize == MaxSize)
2109 PartSize = MaxPartSize;
2110 else // if (PartSize < MaxSize)
2111 PartSize *= MB;
2112 DPRINT("Partition size: %I64u bytes\n", PartSize);
2113
2114 ASSERT(PartSize <= MaxPartSize);
2115
2118 PartSize,
2120 ? 0
2121 // (PartCreateType == PartTypeExtended)
2123
2124 return SELECT_PARTITION_PAGE;
2125 }
2126
2127 return CREATE_PARTITION_PAGE;
2128}
2129
2130
2131/*
2132 * Displays the ConfirmDeleteSystemPartitionPage.
2133 *
2134 * Next pages:
2135 * DeletePartitionPage (default)
2136 * SelectPartitionPage
2137 *
2138 * RETURNS
2139 * Number of the next page.
2140 */
2141static PAGE_NUMBER
2143{
2145
2146 while (TRUE)
2147 {
2148 CONSOLE_ConInKey(Ir);
2149
2150 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2151 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
2152 {
2153 if (ConfirmQuit(Ir))
2154 return QUIT_PAGE;
2155
2156 break;
2157 }
2158 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
2159 {
2160 return DELETE_PARTITION_PAGE;
2161 }
2162 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
2163 {
2164 return SELECT_PARTITION_PAGE;
2165 }
2166 }
2167
2169}
2170
2171
2172/*
2173 * Displays the DeletePartitionPage.
2174 *
2175 * Next pages:
2176 * SelectPartitionPage (default)
2177 * QuitPage
2178 *
2179 * RETURNS
2180 * Number of the next page.
2181 */
2182static PAGE_NUMBER
2184{
2185 PPARTENTRY PartEntry;
2186 PDISKENTRY DiskEntry;
2187 CHAR LineBuffer[100];
2188
2190 {
2191 /* FIXME: show an error dialog */
2192 return QUIT_PAGE;
2193 }
2194
2195 PartEntry = CurrentPartition;
2196 DiskEntry = CurrentPartition->DiskEntry;
2197
2199
2200 PartitionDescription(PartEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2201 CONSOLE_SetTextXY(6, 10, LineBuffer);
2202
2203 DiskDescription(DiskEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2205 LineBuffer);
2206
2207 while (TRUE)
2208 {
2209 CONSOLE_ConInKey(Ir);
2210
2211 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2212 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
2213 {
2214 if (ConfirmQuit(Ir))
2215 return QUIT_PAGE;
2216
2217 break;
2218 }
2219 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
2220 {
2221 return SELECT_PARTITION_PAGE;
2222 }
2223 else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'L') /* L */
2224 {
2228 return SELECT_PARTITION_PAGE;
2229 }
2230 }
2231
2232 return DELETE_PARTITION_PAGE;
2233}
2234
2235
2236/*
2237 * Displays the SelectFileSystemPage.
2238 *
2239 * Next pages:
2240 * CheckFileSystemPage (At once if RepairUpdate is selected)
2241 * CheckFileSystemPage (At once if Unattended and not USetupData.FormatPartition)
2242 * FormatPartitionPage (Default, at once if Unattended and USetupData.FormatPartition)
2243 * SelectPartitionPage (If the user aborts)
2244 * QuitPage
2245 *
2246 * RETURNS
2247 * Number of the next page.
2248 */
2249// PFSVOL_CALLBACK
2250static FSVOL_OP
2254 _In_ FSVOLNOTIFY FormatStatus,
2255 _In_ ULONG_PTR Param1,
2256 _In_ ULONG_PTR Param2);
2257
2258typedef struct _FSVOL_CONTEXT
2259{
2263
2264static PAGE_NUMBER
2266{
2267 FSVOL_CONTEXT FsVolContext = {Ir, QUIT_PAGE};
2269
2271 {
2272 /* FIXME: show an error dialog */
2273 return QUIT_PAGE;
2274 }
2275
2276 /* Find or set the active system partition before starting formatting */
2281 &FsVolContext);
2282 if (!Success)
2283 return FsVolContext.NextPageOnAbort;
2284 //
2285 // FIXME?? If cannot use any system partition, install FreeLdr on floppy / removable media??
2286 //
2287
2288 /* Set the AUTOCREATE flag if the system partition was automatically created */
2291
2293 CONSOLE_Flush();
2294
2295 /* Apply all pending operations on partitions: formatting and checking */
2300 &FsVolContext);
2301 if (!Success)
2302 return FsVolContext.NextPageOnAbort;
2304}
2305
2306static BOOLEAN
2308 IN PINPUT_RECORD Ir,
2310{
2311 PPARTENTRY PartEntry;
2312 PDISKENTRY DiskEntry;
2313 CHAR LineBuffer[100];
2314
2315 // CONSOLE_ClearScreen();
2316 // CONSOLE_Flush();
2318
2319 PartEntry = PartitionList->SystemPartition;
2320 DiskEntry = PartEntry->DiskEntry;
2321
2322 PartitionDescription(PartEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2323 CONSOLE_SetTextXY(8, 10, LineBuffer);
2324
2325 DiskDescription(DiskEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2327 LineBuffer);
2328
2329
2330 PartEntry = SystemPartition;
2331 DiskEntry = PartEntry->DiskEntry;
2332
2333 PartitionDescription(PartEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2334 CONSOLE_SetTextXY(8, 23, LineBuffer);
2335
2336 while (TRUE)
2337 {
2338 CONSOLE_ConInKey(Ir);
2339
2340 if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
2341 break;
2342 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
2343 return FALSE;
2344 }
2345
2346 return TRUE;
2347}
2348
2349static VOID
2351{
2352 if (!FileSystemList)
2353 return;
2354
2357}
2358
2359static FSVOL_OP
2361 _In_ PFSVOL_CONTEXT FsVolContext,
2363{
2364 PINPUT_RECORD Ir = FsVolContext->Ir;
2365 PPARTENTRY PartEntry = Volume->PartEntry;
2366 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2367 PCWSTR DefaultFs;
2368 BOOLEAN ForceFormat;
2369 CHAR LineBuffer[100];
2370
2371 DPRINT("SelectFileSystemPage()\n");
2372
2373 ForceFormat = (Volume->New || Volume->FormatState == Unformatted);
2374
2375Restart:
2376 /* Reset the file system list for each volume that is to be formatted */
2378
2380 CONSOLE_Flush();
2382
2383 if (Volume->New & VOLUME_NEW_AUTOCREATE)
2384 {
2385 Volume->New &= ~VOLUME_NEW_AUTOCREATE;
2386
2388 }
2389 else if (Volume->New)
2390 {
2391 ULONG uID;
2392
2393 if (Volume == SystemVolume)
2395 else if (Volume == InstallVolume)
2397 else
2399
2400 CONSOLE_SetTextXY(6, 8, MUIGetString(uID));
2401 }
2402 else
2403 {
2405 }
2406
2407 PartitionDescription(PartEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2408 CONSOLE_SetTextXY(6, 10, LineBuffer);
2409
2410 DiskDescription(DiskEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2412 LineBuffer);
2413
2414 /* Show "This Partition will be formatted next" only if it is unformatted */
2415 if (ForceFormat)
2417
2419
2421 {
2423
2424 switch (USetupData.FsType)
2425 {
2426 /* 1 is for BtrFS */
2427 case 1:
2428 DefaultFs = L"BTRFS";
2429 break;
2430
2431 /* If we don't understand input, default to FAT */
2432 default:
2433 DefaultFs = L"FAT";
2434 break;
2435 }
2436 }
2437 else
2438 {
2439 /* By default select the "FAT" file system */
2440 DefaultFs = L"FAT";
2441 }
2442
2443 /* Create the file system list */
2444 // TODO: Display only the FSes compatible with the selected volume!
2445 FileSystemList = CreateFileSystemList(6, 26, ForceFormat, DefaultFs);
2446 if (!FileSystemList)
2447 {
2448 /* FIXME: show an error dialog */
2449 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2450 return FSVOL_ABORT;
2451 }
2452
2454 {
2456 return FSVOL_DOIT;
2457 }
2458
2460
2461 while (TRUE)
2462 {
2463 CONSOLE_ConInKey(Ir);
2464
2465 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2466 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
2467 {
2468 if (ConfirmQuit(Ir))
2469 {
2470 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2471 return FSVOL_ABORT;
2472 }
2473
2474 break;
2475 }
2476 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
2477 {
2478 FsVolContext->NextPageOnAbort = SELECT_PARTITION_PAGE;
2479 return FSVOL_ABORT;
2480 }
2481 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2482 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
2483 {
2485 }
2486 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2487 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
2488 {
2490 }
2491 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
2492 {
2494 {
2495 /* The 'Keep existing filesystem' entry was chosen,
2496 * the volume must be already formatted */
2497 ASSERT(!ForceFormat);
2498
2499 /* Skip formatting this volume. We will also ignore
2500 * file system checks on it, unless it is either the
2501 * system or the installation volume. */
2502 if ((Volume != SystemVolume) && (Volume != InstallVolume))
2503 Volume->NeedsCheck = FALSE;
2504
2505 return FSVOL_SKIP;
2506 }
2507 else
2508 {
2509 /* Format this volume */
2510 return FSVOL_DOIT;
2511 }
2512 }
2513 }
2514
2515 goto Restart;
2516}
2517
2518static FSVOL_OP
2520 _In_ PFSVOL_CONTEXT FsVolContext,
2522{
2523 PINPUT_RECORD Ir = FsVolContext->Ir;
2524 PPARTENTRY PartEntry = Volume->PartEntry;
2525 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2526 CHAR LineBuffer[100];
2527
2528Restart:
2530 CONSOLE_Flush();
2532
2533 PartitionDescription(PartEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2534 CONSOLE_SetTextXY(6, 10, LineBuffer);
2535
2536 DiskDescription(DiskEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2538 LineBuffer);
2539
2540 while (TRUE)
2541 {
2542 if (!IsUnattendedSetup)
2543 CONSOLE_ConInKey(Ir);
2544
2545 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2546 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
2547 {
2548 if (ConfirmQuit(Ir))
2549 {
2550 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2551 return FSVOL_ABORT;
2552 }
2553
2554 goto Restart;
2555 }
2556 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN || IsUnattendedSetup) /* ENTER */
2557 {
2558 /*
2559 * Remove the "Press ENTER to continue" message prompt when the ENTER
2560 * key is pressed as the user wants to begin the partition formatting.
2561 */
2564
2565 return FSVOL_DOIT;
2566 }
2567 }
2568}
2569
2570static VOID
2573{
2574 PPARTENTRY PartEntry = Volume->PartEntry;
2575 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2576 CHAR LineBuffer[100];
2577
2579 CONSOLE_Flush();
2581
2582 PartitionDescription(PartEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2583 CONSOLE_SetTextXY(6, 10, LineBuffer);
2584
2585 DiskDescription(DiskEntry, LineBuffer, ARRAYSIZE(LineBuffer));
2587 LineBuffer);
2588}
2589
2590// PFSVOL_CALLBACK
2591static FSVOL_OP
2595 _In_ FSVOLNOTIFY FormatStatus,
2596 _In_ ULONG_PTR Param1,
2597 _In_ ULONG_PTR Param2)
2598{
2599 PFSVOL_CONTEXT FsVolContext = (PFSVOL_CONTEXT)Context;
2600 PINPUT_RECORD Ir = FsVolContext->Ir;
2601
2602 switch (FormatStatus)
2603 {
2604 // FIXME: Deprecate!
2606 {
2608
2609 FsVolContext->NextPageOnAbort = SELECT_PARTITION_PAGE;
2611 return FSVOL_DOIT;
2612 return FSVOL_ABORT;
2613 }
2614
2616 {
2617 switch (Param1)
2618 {
2620 {
2622 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2623 break;
2624 }
2625
2627 {
2628 /* FIXME: improve the error dialog */
2629 //
2630 // Error dialog should say that we cannot find a suitable
2631 // system partition and create one on the system. At this point,
2632 // it may be nice to ask the user whether he wants to continue,
2633 // or use an external drive as the system drive/partition
2634 // (e.g. floppy, USB drive, etc...)
2635 //
2636 PopupError("The ReactOS Setup could not find a supported system partition\n"
2637 "on your system or could not create a new one. Without such a partition\n"
2638 "the Setup program cannot install ReactOS.\n"
2639 "Press ENTER to return to the partition selection list.",
2641 Ir, POPUP_WAIT_ENTER);
2642
2643 FsVolContext->NextPageOnAbort = SELECT_PARTITION_PAGE;
2644 break;
2645 }
2646
2647 default:
2648 break;
2649 }
2650 return FSVOL_ABORT;
2651 }
2652
2655 // NOTE: If needed, clear screen and flush input.
2656 return FSVOL_DOIT;
2657
2659 {
2660 if ((FSVOL_OP)Param1 == FSVOL_FORMAT)
2661 {
2662 /*
2663 * In case we just repair an existing installation, or make
2664 * an unattended setup without formatting, just go to the
2665 * file system check step.
2666 */
2667 if (RepairUpdateFlag)
2668 return FSVOL_SKIP;
2671 return FSVOL_SKIP;
2672 }
2673 return FSVOL_DOIT;
2674 }
2675
2677 return 0;
2678
2680 {
2681 PFORMAT_VOLUME_INFO FmtInfo = (PFORMAT_VOLUME_INFO)Param1;
2683
2684 // FIXME: See also FSVOLNOTIFY_PARTITIONERROR
2685 if (FmtInfo->ErrorStatus == STATUS_PARTITION_FAILURE)
2686 {
2688 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2689 return FSVOL_ABORT;
2690 }
2691 else
2693 {
2694 /* FIXME: show an error dialog */
2695 // MUIDisplayError(ERROR_FORMATTING_PARTITION, Ir, POPUP_WAIT_ANY_KEY,
2696 // FmtInfo->Volume->Info.DeviceName);
2697 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2698 return FSVOL_ABORT;
2699 }
2700 else
2701 if (FmtInfo->ErrorStatus == STATUS_NOT_SUPPORTED)
2702 {
2704 sizeof(Buffer),
2705 "Setup is currently unable to format a partition in %S.\n"
2706 "\n"
2707 " \x07 Press ENTER to continue Setup.\n"
2708 " \x07 Press F3 to quit Setup.",
2709 FmtInfo->FileSystemName);
2710
2714
2715 while (TRUE)
2716 {
2717 CONSOLE_ConInKey(Ir);
2718
2719 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x00 &&
2720 Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3) /* F3 */
2721 {
2722 if (ConfirmQuit(Ir))
2723 {
2724 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2725 return FSVOL_ABORT;
2726 }
2727 else
2728 {
2729 return FSVOL_RETRY;
2730 }
2731 }
2732 else if (Ir->Event.KeyEvent.uChar.AsciiChar == VK_RETURN) /* ENTER */
2733 {
2734 return FSVOL_RETRY;
2735 }
2736 }
2737 }
2738 else if (!NT_SUCCESS(FmtInfo->ErrorStatus))
2739 {
2740 DPRINT1("FormatPartition() failed: Status 0x%08lx\n", FmtInfo->ErrorStatus);
2742 FmtInfo->Volume->Info.DeviceName);
2743 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2744 return FSVOL_ABORT;
2745 }
2746 return FSVOL_RETRY;
2747 }
2748
2750 {
2751 PCHECK_VOLUME_INFO ChkInfo = (PCHECK_VOLUME_INFO)Param1;
2753
2754 if (ChkInfo->ErrorStatus == STATUS_NOT_SUPPORTED)
2755 {
2757 sizeof(Buffer),
2758 "Setup is currently unable to check a partition formatted in %S.\n"
2759 "\n"
2760 " \x07 Press ENTER to continue Setup.\n"
2761 " \x07 Press F3 to quit Setup.",
2762 ChkInfo->Volume->Info.FileSystem);
2763
2767
2768 while (TRUE)
2769 {
2770 CONSOLE_ConInKey(Ir);
2771
2772 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x00 &&
2773 Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3) /* F3 */
2774 {
2775 if (ConfirmQuit(Ir))
2776 {
2777 FsVolContext->NextPageOnAbort = QUIT_PAGE;
2778 return FSVOL_ABORT;
2779 }
2780 else
2781 {
2782 return FSVOL_SKIP;
2783 }
2784 }
2785 else if (Ir->Event.KeyEvent.uChar.AsciiChar == VK_RETURN) /* ENTER */
2786 {
2787 return FSVOL_SKIP;
2788 }
2789 }
2790 }
2791 else if (!NT_SUCCESS(ChkInfo->ErrorStatus))
2792 {
2793 DPRINT1("ChkdskPartition() failed: Status 0x%08lx\n", ChkInfo->ErrorStatus);
2794
2796 sizeof(Buffer),
2797 "ChkDsk detected some disk errors.\n(Status 0x%08lx).\n",
2798 ChkInfo->ErrorStatus);
2799
2802 Ir, POPUP_WAIT_ENTER);
2803 return FSVOL_SKIP;
2804 }
2805 return FSVOL_SKIP;
2806 }
2807
2809 {
2810 PFORMAT_VOLUME_INFO FmtInfo = (PFORMAT_VOLUME_INFO)Param1;
2812
2813 ASSERT((FSVOL_OP)Param2 == FSVOL_FORMAT);
2814
2815 /* Select the file system */
2816 Result = SelectFileSystemPage(FsVolContext, FmtInfo->Volume);
2817 if (Result != FSVOL_DOIT)
2818 return Result;
2819
2820 /* Display the formatting page */
2821 Result = FormatPartitionPage(FsVolContext, FmtInfo->Volume);
2822 if (Result != FSVOL_DOIT)
2823 return Result;
2824
2826 return FSVOL_DOIT;
2827 }
2828
2830 {
2831 PFORMAT_VOLUME_INFO FmtInfo = (PFORMAT_VOLUME_INFO)Param1;
2832 EndFormat(FmtInfo->ErrorStatus);
2833
2834 /* Reset the file system list */
2836 return 0;
2837 }
2838
2840 {
2841 PCHECK_VOLUME_INFO ChkInfo = (PCHECK_VOLUME_INFO)Param1;
2842
2843 ASSERT((FSVOL_OP)Param2 == FSVOL_CHECK);
2844
2845 CheckFileSystemPage(ChkInfo->Volume);
2846 StartCheck(ChkInfo);
2847 return FSVOL_DOIT;
2848 }
2849
2851 {
2852 PCHECK_VOLUME_INFO ChkInfo = (PCHECK_VOLUME_INFO)Param1;
2853 EndCheck(ChkInfo->ErrorStatus);
2854 return 0;
2855 }
2856 }
2857
2858 return 0;
2859}
2860
2861
2862/*
2863 * Displays the InstallDirectoryPage.
2864 *
2865 * Next pages:
2866 * PrepareCopyPage
2867 * QuitPage
2868 *
2869 * RETURNS
2870 * Number of the next page.
2871 */
2872static PAGE_NUMBER
2874{
2876 ULONG Length, Pos;
2877 WCHAR c;
2878 WCHAR InstallDir[MAX_PATH];
2879
2881 {
2882 /* FIXME: show an error dialog */
2883 return QUIT_PAGE;
2884 }
2885
2886 // if (IsUnattendedSetup)
2887 if (RepairUpdateFlag)
2888 wcscpy(InstallDir, CurrentInstallation->PathComponent); // SystemNtPath
2891 else
2892 wcscpy(InstallDir, L"\\ReactOS");
2893
2894 /*
2895 * Check the validity of the predefined 'InstallDir'. If we are either
2896 * in unattended setup or in update/repair mode, and the installation path
2897 * is valid, just perform the installation. Otherwise (either in the case
2898 * of an invalid path, or we are in regular setup), display the UI and allow
2899 * the user to specify a new installation path.
2900 */
2902 {
2904 if (!NT_SUCCESS(Status))
2905 {
2906 DPRINT1("InitDestinationPaths() failed: Status 0x%lx\n", Status);
2908 return QUIT_PAGE;
2909 }
2910
2911 /*
2912 * Check whether the user attempts to install ReactOS within the
2913 * installation source directory, or in a subdirectory thereof.
2914 * If so, fail with an error.
2915 */
2917 {
2920 }
2921
2922 return PREPARE_COPY_PAGE;
2923 }
2924
2925 Length = wcslen(InstallDir);
2926 Pos = Length;
2927
2929 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
2930 CONSOLE_SetCursorXY(8 + Pos, 11);
2932
2933 while (TRUE)
2934 {
2935 CONSOLE_ConInKey(Ir);
2936
2937 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2938 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
2939 {
2941
2942 if (ConfirmQuit(Ir))
2943 return QUIT_PAGE;
2944
2946 break;
2947 }
2948 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2949 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DELETE)) /* DEL */
2950 {
2951 if (Pos < Length)
2952 {
2953 memmove(&InstallDir[Pos],
2954 &InstallDir[Pos + 1],
2955 (Length - Pos - 1) * sizeof(WCHAR));
2956 InstallDir[Length - 1] = UNICODE_NULL;
2957
2958 Length--;
2959 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
2960 CONSOLE_SetCursorXY(8 + Pos, 11);
2961 }
2962 }
2963 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2964 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_HOME)) /* HOME */
2965 {
2966 Pos = 0;
2967 CONSOLE_SetCursorXY(8 + Pos, 11);
2968 }
2969 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2970 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_END)) /* END */
2971 {
2972 Pos = Length;
2973 CONSOLE_SetCursorXY(8 + Pos, 11);
2974 }
2975 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2976 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_LEFT)) /* LEFT */
2977 {
2978 if (Pos > 0)
2979 {
2980 Pos--;
2981 CONSOLE_SetCursorXY(8 + Pos, 11);
2982 }
2983 }
2984 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
2985 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RIGHT)) /* RIGHT */
2986 {
2987 if (Pos < Length)
2988 {
2989 Pos++;
2990 CONSOLE_SetCursorXY(8 + Pos, 11);
2991 }
2992 }
2993 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
2994 {
2995 /* Erase the whole line */
2996 *InstallDir = UNICODE_NULL;
2997 Pos = Length = 0;
2998 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
2999 CONSOLE_SetCursorXY(8 + Pos, 11);
3000 }
3001 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
3002 {
3004
3005 /*
3006 * Check for the validity of the installation directory and pop up
3007 * an error if it is not the case. Then the user can fix its input.
3008 */
3009 if (!IsValidInstallDirectory(InstallDir))
3010 {
3013 }
3014
3016 if (!NT_SUCCESS(Status))
3017 {
3018 DPRINT1("InitDestinationPaths() failed: Status 0x%lx\n", Status);
3020 return QUIT_PAGE;
3021 }
3022
3023 /*
3024 * Check whether the user attempts to install ReactOS within the
3025 * installation source directory, or in a subdirectory thereof.
3026 * If so, fail with an error.
3027 */
3029 {
3032 }
3033
3034 return PREPARE_COPY_PAGE;
3035 }
3036 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */
3037 {
3038 if (Pos > 0)
3039 {
3040 if (Pos < Length)
3041 memmove(&InstallDir[Pos - 1],
3042 &InstallDir[Pos],
3043 (Length - Pos) * sizeof(WCHAR));
3044 InstallDir[Length - 1] = UNICODE_NULL;
3045
3046 Pos--;
3047 Length--;
3048 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
3049 CONSOLE_SetCursorXY(8 + Pos, 11);
3050 }
3051 }
3052 else if (isprint(Ir->Event.KeyEvent.uChar.AsciiChar))
3053 {
3054 if (Length < 50)
3055 {
3056 /* Only accept valid characters for the installation path */
3059 {
3060 if (Pos < Length)
3061 memmove(&InstallDir[Pos + 1],
3062 &InstallDir[Pos],
3063 (Length - Pos) * sizeof(WCHAR));
3064 InstallDir[Length + 1] = UNICODE_NULL;
3065 InstallDir[Pos] = c;
3066
3067 Pos++;
3068 Length++;
3069 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
3070 CONSOLE_SetCursorXY(8 + Pos, 11);
3071 }
3072 }
3073 }
3074 }
3075
3077}
3078
3079
3080// PSETUP_ERROR_ROUTINE
3081static VOID
3082__cdecl
3084 IN PUSETUP_DATA pSetupData,
3085 ...)
3086{
3087 INPUT_RECORD Ir;
3088 va_list arg_ptr;
3089
3090 va_start(arg_ptr, pSetupData);
3091
3092 if (pSetupData->LastErrorNumber >= ERROR_SUCCESS &&
3093 pSetupData->LastErrorNumber < ERROR_LAST_ERROR_CODE)
3094 {
3095 // Note: the "POPUP_WAIT_ENTER" actually depends on the LastErrorNumber...
3096 MUIDisplayErrorV(pSetupData->LastErrorNumber, &Ir, POPUP_WAIT_ENTER, arg_ptr);
3097 }
3098
3099 va_end(arg_ptr);
3100}
3101
3102/*
3103 * Displays the PrepareCopyPage.
3104 *
3105 * Next pages:
3106 * FileCopyPage(At once)
3107 * QuitPage
3108 *
3109 * SIDEEFFECTS
3110 * Calls PrepareFileCopy
3111 *
3112 * RETURNS
3113 * Number of the next page.
3114 */
3115static PAGE_NUMBER
3117{
3118 // ERROR_NUMBER ErrorNumber;
3120
3122
3123 /* ErrorNumber = */ Success = PrepareFileCopy(&USetupData, NULL);
3124 if (/*ErrorNumber != ERROR_SUCCESS*/ !Success)
3125 {
3126 // MUIDisplayError(ErrorNumber, Ir, POPUP_WAIT_ENTER);
3127 return QUIT_PAGE;
3128 }
3129
3130 return FILE_COPY_PAGE;
3131}
3132
3133typedef struct _COPYCONTEXT
3134{
3140
3141static VOID
3144{
3146
3147 /* Get the memory information from the system */
3149 &PerfInfo,
3150 sizeof(PerfInfo),
3151 NULL);
3152
3153 /* Check if this is initial setup */
3154 if (First)
3155 {
3156 /* Set maximum limits to be total RAM pages */
3157 ProgressSetStepCount(CopyContext->MemoryBars[0], PerfInfo.CommitLimit);
3158 ProgressSetStepCount(CopyContext->MemoryBars[1], PerfInfo.CommitLimit);
3159 ProgressSetStepCount(CopyContext->MemoryBars[2], PerfInfo.CommitLimit);
3160 }
3161
3162 /* Set current values */
3163 ProgressSetStep(CopyContext->MemoryBars[0], PerfInfo.PagedPoolPages + PerfInfo.NonPagedPoolPages);
3164 ProgressSetStep(CopyContext->MemoryBars[1], PerfInfo.ResidentSystemCachePage);
3165 ProgressSetStep(CopyContext->MemoryBars[2], PerfInfo.AvailablePages);
3166}
3167
3168static UINT
3172 UINT_PTR Param1,
3173 UINT_PTR Param2)
3174{
3175 PCOPYCONTEXT CopyContext = (PCOPYCONTEXT)Context;
3176 PFILEPATHS_W FilePathInfo;
3177 PCWSTR SrcFileName, DstFileName;
3178
3179 switch (Notification)
3180 {
3182 {
3183 CopyContext->TotalOperations = (ULONG)Param2;
3184 CopyContext->CompletedOperations = 0;
3185 ProgressSetStepCount(CopyContext->ProgressBar,
3186 CopyContext->TotalOperations);
3187 SetupUpdateMemoryInfo(CopyContext, TRUE);
3188 break;
3189 }
3190
3194 {
3195 FilePathInfo = (PFILEPATHS_W)Param1;
3196
3198 {
3199 /* Display delete message */
3200 ASSERT(Param2 == FILEOP_DELETE);
3201
3202 DstFileName = wcsrchr(FilePathInfo->Target, L'\\');
3203 if (DstFileName) ++DstFileName;
3204 else DstFileName = FilePathInfo->Target;
3205
3207 DstFileName);
3208 }
3210 {
3211 /* Display move/rename message */
3212 ASSERT(Param2 == FILEOP_RENAME);
3213
3214 SrcFileName = wcsrchr(FilePathInfo->Source, L'\\');
3215 if (SrcFileName) ++SrcFileName;
3216 else SrcFileName = FilePathInfo->Source;
3217
3218 DstFileName = wcsrchr(FilePathInfo->Target, L'\\');
3219 if (DstFileName) ++DstFileName;
3220 else DstFileName = FilePathInfo->Target;
3221
3222 if (!wcsicmp(SrcFileName, DstFileName))
3223 Param2 = STRING_MOVING;
3224 else
3225 Param2 = STRING_RENAMING;
3226
3228 SrcFileName, DstFileName);
3229 }
3231 {
3232 static PCSTR s_pszCopying = NULL; /* Cached for speed */
3233
3234 /* Display copy message */
3235 ASSERT(Param2 == FILEOP_COPY);
3236
3237 /* NOTE: When extracting from CABs the Source is the CAB name */
3238 DstFileName = wcsrchr(FilePathInfo->Target, L'\\');
3239 if (DstFileName) ++DstFileName;
3240 else DstFileName = FilePathInfo->Target;
3241
3242 if (!s_pszCopying)
3243 s_pszCopying = MUIGetString(STRING_COPYING);
3244 CONSOLE_SetStatusText(s_pszCopying, DstFileName);
3245#ifdef __REACTOS__ /* HACK */
3246 DoWatchDestFileName(DstFileName);
3247#endif
3248 }
3249
3250 SetupUpdateMemoryInfo(CopyContext, FALSE);
3251 break;
3252 }
3253
3255 {
3256 FilePathInfo = (PFILEPATHS_W)Param1;
3257
3258 DPRINT1("An error happened while trying to copy file '%S' (error 0x%08lx), skipping it...\n",
3259 FilePathInfo->Target, FilePathInfo->Win32Error);
3260 return FILEOP_SKIP;
3261 }
3262
3266 {
3267 CopyContext->CompletedOperations++;
3268
3269 /* SYSREG checkpoint */
3270 if (CopyContext->TotalOperations >> 1 == CopyContext->CompletedOperations)
3271 DPRINT1("CHECKPOINT:HALF_COPIED\n");
3272
3273 ProgressNextStep(CopyContext->ProgressBar);
3274 SetupUpdateMemoryInfo(CopyContext, FALSE);
3275 break;
3276 }
3277 }
3278
3279 return FILEOP_DOIT;
3280}
3281
3282
3283/*
3284 * Displays the FileCopyPage.
3285 *
3286 * Next pages:
3287 * RegistryPage(At once)
3288 *
3289 * SIDEEFFECTS
3290 * Calls DoFileCopy
3291 *
3292 * RETURNS
3293 * Number of the next page.
3294 */
3295static PAGE_NUMBER
3297{
3298 COPYCONTEXT CopyContext;
3299 UINT MemBarWidth;
3300
3302
3303 /* Create context for the copy process */
3304 CopyContext.TotalOperations = 0;
3305 CopyContext.CompletedOperations = 0;
3306
3307 /* Create the progress bar as well */
3308 CopyContext.ProgressBar = CreateProgressBar(13,
3309 26,
3310 xScreen - 13,
3311 yScreen - 20,
3312 10,
3313 24,
3314 TRUE,
3316
3317 // fit memory bars to screen width, distribute them uniform
3318 MemBarWidth = (xScreen - 26) / 5;
3319 MemBarWidth -= MemBarWidth % 2; // make even
3320 /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
3321 /* Create the paged pool progress bar */
3322 CopyContext.MemoryBars[0] = CreateProgressBar(13,
3323 40,
3324 13 + MemBarWidth,
3325 43,
3326 13,
3327 44,
3328 FALSE,
3329 "Kernel Pool");
3330
3331 /* Create the non paged pool progress bar */
3332 CopyContext.MemoryBars[1] = CreateProgressBar((xScreen / 2)- (MemBarWidth / 2),
3333 40,
3334 (xScreen / 2) + (MemBarWidth / 2),
3335 43,
3336 (xScreen / 2)- (MemBarWidth / 2),
3337 44,
3338 FALSE,
3339 "Kernel Cache");
3340
3341 /* Create the global memory progress bar */
3342 CopyContext.MemoryBars[2] = CreateProgressBar(xScreen - 13 - MemBarWidth,
3343 40,
3344 xScreen - 13,
3345 43,
3346 xScreen - 13 - MemBarWidth,
3347 44,
3348 FALSE,
3349 "Free Memory");
3350
3351 /* Do the file copying */
3352 DoFileCopy(&USetupData, FileCopyCallback, &CopyContext);
3353
3354 /* If we get here, we're done, so cleanup the progress bar */
3355 DestroyProgressBar(CopyContext.ProgressBar);
3356 DestroyProgressBar(CopyContext.MemoryBars[0]);
3357 DestroyProgressBar(CopyContext.MemoryBars[1]);
3358 DestroyProgressBar(CopyContext.MemoryBars[2]);
3359
3360 /* Create the $winnt$.inf file */
3362
3363 /* Go display the next page */
3364 return REGISTRY_PAGE;
3365}
3366
3367
3368static VOID
3369__cdecl
3371{
3372 /* WARNING: Please keep this lookup table in sync with the resources! */
3373 static const UINT StringIDs[] =
3374 {
3375 STRING_DONE, /* Success */
3376 STRING_REGHIVEUPDATE, /* RegHiveUpdate */
3377 STRING_IMPORTFILE, /* ImportRegHive */
3378 STRING_DISPLAYSETTINGSUPDATE, /* DisplaySettingsUpdate */
3379 STRING_LOCALESETTINGSUPDATE, /* LocaleSettingsUpdate */
3380 STRING_ADDKBLAYOUTS, /* KeybLayouts */
3381 STRING_KEYBOARDSETTINGSUPDATE, /* KeybSettingsUpdate */
3382 STRING_CODEPAGEINFOUPDATE, /* CodePageInfoUpdate */
3383 };
3384
3385 va_list args;
3386
3387 if (RegStatus < ARRAYSIZE(StringIDs))
3388 {
3389 va_start(args, RegStatus);
3390 CONSOLE_SetStatusTextV(MUIGetString(StringIDs[RegStatus]), args);
3391 va_end(args);
3392 }
3393 else
3394 {
3395 CONSOLE_SetStatusText("Unknown status %d", RegStatus);
3396 }
3397}
3398
3399/*
3400 * Displays the RegistryPage.
3401 *
3402 * Next pages:
3403 * BootLoaderSelectPage
3404 * QuitPage
3405 *
3406 * SIDEEFFECTS
3407 * Calls UpdateRegistry
3408 *
3409 * RETURNS
3410 * Number of the next page.
3411 */
3412static PAGE_NUMBER
3414{
3415 ULONG Error;
3416
3418
3422 InstallVolume->Info.DriveLetter,
3425 &s_SubstSettings);
3426 if (Error != ERROR_SUCCESS)
3427 {
3429 return QUIT_PAGE;
3430 }
3431 else
3432 {
3435 }
3436}
3437
3438
3439/*
3440 * Displays the BootLoaderSelectPage.
3441 *
3442 * Next pages:
3443 * SuccessPage
3444 * QuitPage
3445 *
3446 * RETURNS
3447 * Number of the next page.
3448 */
3449static PAGE_NUMBER
3451{
3452 USHORT Line = 12;
3453
3455
3456 /* We must have a supported system partition by now */
3458
3459 /*
3460 * If we repair an existing installation and we made it up to here,
3461 * this means a valid bootloader and boot entry have been found.
3462 * Thus, there is no need to re-install it: skip its installation.
3463 */
3464 if (RepairUpdateFlag)
3465 {
3467 goto Quit;
3468 }
3469
3470 /* For unattended setup, skip MBR installation or install on removable disk if needed */
3472 {
3473 if ((USetupData.BootLoaderLocation == 0) ||
3475 {
3476 goto Quit;
3477 }
3478 }
3479
3480#if 0 // Deprecated code, whose global logic may need to be moved elsewhere...
3481 /*
3482 * We may install an MBR or VBR, but before that, check whether
3483 * we need to actually install the VBR on removable disk if the
3484 * system partition is not recognized.
3485 */
3486 if ((SystemPartition->DiskEntry->DiskStyle != PARTITION_STYLE_MBR) ||
3488 {
3490 goto Quit;
3491 }
3492#endif
3493
3494 /* Is it an unattended install on hdd? */
3496 {
3497 if ((USetupData.BootLoaderLocation == 2) ||
3499 {
3500 goto Quit;
3501 }
3502 }
3503
3505 CONSOLE_InvertTextXY(8, Line, 60, 1);
3506
3507 while (TRUE)
3508 {
3509 CONSOLE_ConInKey(Ir);
3510
3511 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3512 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
3513 {
3514 CONSOLE_NormalTextXY(8, Line, 60, 1);
3515
3516 Line++;
3517 if (Line < 12)
3518 Line = 15;
3519
3520 if (Line > 15)
3521 Line = 12;
3522
3523 CONSOLE_InvertTextXY(8, Line, 60, 1);
3524 }
3525 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3526 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
3527 {
3528 CONSOLE_NormalTextXY(8, Line, 60, 1);
3529
3530 Line--;
3531 if (Line < 12)
3532 Line = 15;
3533
3534 if (Line > 15)
3535 Line = 12;
3536
3537 CONSOLE_InvertTextXY(8, Line, 60, 1);
3538 }
3539 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3540 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_HOME)) /* HOME */
3541 {
3542 CONSOLE_NormalTextXY(8, Line, 60, 1);
3543
3544 Line = 12;
3545
3546 CONSOLE_InvertTextXY(8, Line, 60, 1);
3547 }
3548 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3549 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_END)) /* END */
3550 {
3551 CONSOLE_NormalTextXY(8, Line, 60, 1);
3552
3553 Line = 15;
3554
3555 CONSOLE_InvertTextXY(8, Line, 60, 1);
3556 }
3557 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3558 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
3559 {
3560 if (ConfirmQuit(Ir))
3561 return QUIT_PAGE;
3562
3563 break;
3564 }
3565 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
3566 {
3567 if (Line == 12)
3568 {
3569 /* Install on both MBR and VBR */
3571 break;
3572 }
3573 else if (Line == 13)
3574 {
3575 /* Install on VBR only */
3577 break;
3578 }
3579 else if (Line == 14)
3580 {
3581 /* Install on removable disk */
3583 break;
3584 }
3585 else if (Line == 15)
3586 {
3587 /* Skip installation */
3589 break;
3590 }
3591
3593 }
3594 }
3595
3596Quit:
3597 /* Continue the installation; the bootloader is installed at the end */
3599}
3600
3601
3602/*
3603 * Installs the bootloader on removable disk.
3604 */
3605static BOOLEAN
3607{
3609
3610Retry:
3612 CONSOLE_Flush();
3614// CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
3615
3616 while (TRUE)
3617 {
3618 CONSOLE_ConInKey(Ir);
3619
3620 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
3621 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
3622 {
3623 if (ConfirmQuit(Ir))
3624 return FALSE;
3625
3626 break;
3627 }
3628 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
3629 {
3632 if (!NT_SUCCESS(Status))
3633 {
3636
3637 /* TODO: Print error message */
3638 goto Retry;
3639 }
3640
3641 return TRUE;
3642 }
3643 }
3644
3645 goto Retry;
3646}
3647
3648/*
3649 * Installs the bootloader on hard-disk.
3650 */
3651static BOOLEAN
3653{
3655 WCHAR DestinationDevicePathBuffer[MAX_PATH];
3656
3658 {
3659 /* Step 1: Write the VBR */
3663 SystemVolume->Info.FileSystem);
3664 if (!NT_SUCCESS(Status))
3665 {
3667 SystemVolume->Info.FileSystem);
3668 return FALSE;
3669 }
3670
3671 /* Step 2: Write the MBR if the disk containing the system partition is not a super-floppy */
3673 {
3674 RtlStringCchPrintfW(DestinationDevicePathBuffer, ARRAYSIZE(DestinationDevicePathBuffer),
3675 L"\\Device\\Harddisk%d\\Partition0",
3676 SystemPartition->DiskEntry->DiskNumber);
3679 DestinationDevicePathBuffer);
3680 if (!NT_SUCCESS(Status))
3681 {
3682 DPRINT1("InstallMbrBootCodeToDisk() failed: Status 0x%lx\n", Status);
3684 return FALSE;
3685 }
3686 }
3687 }
3688 else
3689 {
3693 SystemVolume->Info.FileSystem);
3694 if (!NT_SUCCESS(Status))
3695 {
3697 SystemVolume->Info.FileSystem);
3698 return FALSE;
3699 }
3700 }
3701
3702 return TRUE;
3703}
3704
3705/*
3706 * Actually installs the bootloader at the end of the installation.
3707 * The bootloader installation place has already been chosen before,
3708 * see BootLoaderSelectPage().
3709 *
3710 * Next pages:
3711 * SuccessPage (At once)
3712 * QuitPage
3713 *
3714 * RETURNS
3715 * Number of the next page.
3716 */
3717static PAGE_NUMBER
3719{
3720 WCHAR PathBuffer[MAX_PATH];
3721
3722 // /* We must have a supported system partition by now */
3723 // ASSERT(SystemPartition && SystemPartition->IsPartitioned && SystemPartition->PartitionNumber != 0);
3724
3726 RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
3727 L"\\Device\\Harddisk%lu\\Partition%lu\\",
3728 SystemPartition->DiskEntry->DiskNumber,
3731 DPRINT1("SystemRootPath: %wZ\n", &USetupData.SystemRootPath);
3732
3735
3737 {
3738 /* Skip installation */
3739 case 0:
3740 return SUCCESS_PAGE;
3741
3742 /* Install on removable disk */
3743 case 1:
3745
3746 /* Install on hard-disk (both MBR and VBR, or VBR only) */
3747 case 2:
3748 case 3:
3750
3751 default:
3752 return SUCCESS_PAGE;
3753 }
3754}
3755
3756
3779static
3783 IN BOOLEAN AlwaysUpdate,
3784 OUT PSTR Buffer,
3785 IN SIZE_T cchBufferSize)
3786{
3787 ULONG OldProgress = Bar->Progress;
3788
3789 if (Bar->StepCount == 0)
3790 {
3791 Bar->Progress = 0;
3792 }
3793 else
3794 {
3795 Bar->Progress = Bar->StepCount - Bar->CurrentStep;
3796 }
3797
3798 /* Build the progress string if it has changed */
3799 if (Bar->ProgressFormatText &&
3800 (AlwaysUpdate || (Bar->Progress != OldProgress)))
3801 {
3802 RtlStringCchPrintfA(Buffer, cchBufferSize,
3803 Bar->ProgressFormatText, Bar->Progress / max(1, Bar->Width) + 1);
3804
3805 return TRUE;
3806 }
3807
3808 return FALSE;
3809}
3810
3827static VOID
3829 IN PINPUT_RECORD Ir,
3830 IN LONG TimeOut)
3831{
3833 ULONG StartTime, BarWidth, TimerDiv;
3834 LONG TimeElapsed;
3835 LONG TimerValue, OldTimerValue;
3838 BOOLEAN RefreshProgress = TRUE;
3839
3840 /* Bail out if the timeout is already zero */
3841 if (TimeOut <= 0)
3842 return;
3843
3844 /* Create the timeout progress bar and set it up */
3846 26,
3847 xScreen - 13,
3848 yScreen - 20,
3849 10,
3850 24,
3851 TRUE,
3853 0,
3854 NULL,
3857
3858 BarWidth = max(1, ProgressBar->Width);
3859 TimerValue = TimeOut * BarWidth;
3860 ProgressSetStepCount(ProgressBar, TimerValue);
3861
3863 CONSOLE_Flush();
3864
3865 TimerDiv = 1000 / BarWidth;
3866 TimerDiv = max(1, TimerDiv);
3867 OldTimerValue = TimerValue;
3868 while (TRUE)
3869 {
3870 /* Decrease the timer */
3871
3872 /*
3873 * Compute how much time the previous operations took.
3874 * This allows us in particular to take account for any time
3875 * elapsed if something slowed down.
3876 */
3877 TimeElapsed = NtGetTickCount() - StartTime;
3878 if (TimeElapsed >= TimerDiv)
3879 {
3880 /* Increase StartTime by steps of 1 / ProgressBar->Width seconds */
3881 TimeElapsed /= TimerDiv;
3882 StartTime += (TimerDiv * TimeElapsed);
3883
3884 if (TimeElapsed <= TimerValue)
3885 TimerValue -= TimeElapsed;
3886 else
3887 TimerValue = 0;
3888
3889 RefreshProgress = TRUE;
3890 }
3891
3892 if (RefreshProgress)
3893 {
3894 ProgressSetStep(ProgressBar, OldTimerValue - TimerValue);
3895 RefreshProgress = FALSE;
3896 }
3897
3898 /* Stop when the timer reaches zero */
3899 if (TimerValue <= 0)
3900 break;
3901
3902 /* Check for user key presses */
3903
3904 /*
3905 * If the timer is used, use a passive wait of maximum 1 second
3906 * while monitoring for incoming console input events, so that
3907 * we are still able to display the timing count.
3908 */
3909
3910 /* Wait a maximum of 1 second for input events */
3911 TimeElapsed = NtGetTickCount() - StartTime;
3912 if (TimeElapsed < TimerDiv)
3913 {
3914 /* Convert the time to NT format */
3915 Timeout.QuadPart = (TimerDiv - TimeElapsed) * -10000LL;
3917 }
3918 else
3919 {
3921 }
3922
3923 /* Check whether the input event has been signaled, or a timeout happened */
3924 if (Status == STATUS_TIMEOUT)
3925 {
3926 continue;
3927 }
3928 if (Status != STATUS_WAIT_0)
3929 {
3930 /* An error happened, bail out */
3931 DPRINT1("NtWaitForSingleObject() failed, Status 0x%08lx\n", Status);
3932 break;
3933 }
3934
3935 /* Check for an ENTER key press */
3936 while (CONSOLE_ConInKeyPeek(Ir))
3937 {
3938 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
3939 {
3940 /* Found it, stop waiting */
3941 goto Exit;
3942 }
3943 }
3944 }
3945
3946Exit:
3947 /* Destroy the progress bar and quit */
3949}
3950
3951
3952/*
3953 * Displays the QuitPage.
3954 *
3955 * Next pages:
3956 * FlushPage (At once)
3957 *
3958 * SIDEEFFECTS
3959 * Destroy the Lists
3960 *
3961 * RETURNS
3962 * Number of the next page.
3963 */
3964static PAGE_NUMBER
3966{
3968
3969 /* Destroy the NTOS installations list */
3970 if (NtOsInstallsList != NULL)
3971 {
3974 }
3975
3976 /* Destroy the partition list */
3977 if (PartitionList != NULL)
3978 {
3981 }
3982
3984
3985 /* Wait for maximum 15 seconds or an ENTER key before quitting */
3986 ProgressCountdown(Ir, 15);
3987 return FLUSH_PAGE;
3988}
3989
3990
3991/*
3992 * Displays the SuccessPage.
3993 *
3994 * Next pages:
3995 * FlushPage (At once)
3996 *
3997 * SIDEEFFECTS
3998 * Destroy the Lists
3999 *
4000 * RETURNS
4001 * Number of the next page.
4002 */
4003static PAGE_NUMBER
4005{
4007
4009 return FLUSH_PAGE;
4010
4011 /* Wait for maximum 15 seconds or an ENTER key before quitting */
4012 ProgressCountdown(Ir, 15);
4013 return FLUSH_PAGE;
4014}
4015
4016
4017/*
4018 * Displays the FlushPage.
4019 *
4020 * Next pages:
4021 * RebootPage (At once)
4022 *
4023 * RETURNS
4024 * Number of the next page.
4025 */
4026static PAGE_NUMBER
4028{
4030 return REBOOT_PAGE;
4031}
4032
4033
4034/*
4035 * The start routine and page management
4036 */
4039{
4041 INPUT_RECORD Ir;
4043 BOOLEAN Old;
4044
4046
4047 /* Tell the Cm this is a setup boot, and it has to behave accordingly */
4049 if (!NT_SUCCESS(Status))
4050 DPRINT1("NtInitializeRegistry() failed (Status 0x%08lx)\n", Status);
4051
4052 /* Initialize the user-mode PnP manager */
4054 if (!NT_SUCCESS(Status))
4055 {
4056 // PrintString(??);
4057 DPRINT1("The user-mode PnP manager could not initialize (Status 0x%08lx), expect unavailable devices!\n", Status);
4058 }
4059
4060 if (!CONSOLE_Init())
4061 {
4065
4066 /* We failed to initialize the video, just quit the installer */
4068 }
4069
4070 /* Initialize Setup, phase 0 */
4073
4074 /* Hide the cursor and clear the screen and keyboard buffer */
4077 CONSOLE_Flush();
4078
4079 /* Global Initialization page */
4080 Page = SetupStartPage(&Ir);
4081
4082 while (Page != REBOOT_PAGE && Page != RECOVERY_PAGE)
4083 {
4085 CONSOLE_Flush();
4086
4087 // CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
4088
4089 switch (Page)
4090 {
4091 /* Language page */
4092 case LANGUAGE_PAGE:
4093 Page = LanguagePage(&Ir);
4094 break;
4095
4096 /* Welcome page */
4097 case WELCOME_PAGE:
4098 Page = WelcomePage(&Ir);
4099 break;
4100
4101 /* License page */
4102 case LICENSE_PAGE:
4103 Page = LicensePage(&Ir);
4104 break;
4105
4106 /* Install pages */
4107 case INSTALL_INTRO_PAGE:
4108 Page = InstallIntroPage(&Ir);
4109 break;
4110
4111#if 0
4112 case SCSI_CONTROLLER_PAGE:
4113 Page = ScsiControllerPage(&Ir);
4114 break;
4115
4116 case OEM_DRIVER_PAGE:
4117 Page = OemDriverPage(&Ir);
4118 break;
4119#endif
4120
4122 Page = DeviceSettingsPage(&Ir);
4123 break;
4124
4127 break;
4128
4131 break;
4132
4135 break;
4136
4138 Page = LayoutSettingsPage(&Ir);
4139 break;
4140
4141 /* Partitioning pages */
4144 break;
4145
4148 break;
4149
4152 break;
4153
4156 break;
4157
4158 /* File system partition operations pages */
4161 break;
4162
4163 /* Bootloader selection page */
4166 break;
4167
4168 /* Installation pages */
4171 break;
4172
4173 case PREPARE_COPY_PAGE:
4174 Page = PrepareCopyPage(&Ir);
4175 break;
4176
4177 case FILE_COPY_PAGE:
4178 Page = FileCopyPage(&Ir);
4179 break;
4180
4181 case REGISTRY_PAGE:
4182 Page = RegistryPage(&Ir);
4183 break;
4184
4185 /* Bootloader installation page */
4187 // case BOOTLOADER_REMOVABLE_DISK_PAGE:
4189 break;
4190
4191 /* Repair pages */
4192 case REPAIR_INTRO_PAGE:
4193 Page = RepairIntroPage(&Ir);
4194 break;
4195
4197 Page = UpgradeRepairPage(&Ir);
4198 break;
4199
4200 case SUCCESS_PAGE:
4201 Page = SuccessPage(&Ir);
4202 break;
4203
4204 case FLUSH_PAGE:
4205 Page = FlushPage(&Ir);
4206 break;
4207
4208 case QUIT_PAGE:
4209 Page = QuitPage(&Ir);
4210 break;
4211
4212 /* Virtual pages */
4213 case SETUP_INIT_PAGE:
4216 // case CHECK_FILE_SYSTEM_PAGE:
4217 case REBOOT_PAGE:
4218 case RECOVERY_PAGE:
4219 break;
4220
4221 default:
4222 break;
4223 }
4224 }
4225
4226 /* Terminate the user-mode PnP manager */
4228
4229 /* Setup has finished */
4231
4232 if (Page == RECOVERY_PAGE)
4234
4235 FreeConsole();
4236
4237 /* Reboot */
4241
4242 return STATUS_SUCCESS;
4243}
4244
4245
4246VOID NTAPI
4248{
4251
4253
4255
4257
4258 Status = RunUSetup();
4259
4260 if (NT_SUCCESS(Status))
4261 {
4262 /*
4263 * Avoid a bugcheck if RunUSetup() finishes too quickly by implementing
4264 * a protective waiting.
4265 * This wait is needed because, since we are started as SMSS.EXE,
4266 * the NT kernel explicitly waits 5 seconds for the initial process
4267 * SMSS.EXE to initialize (as a protective measure), and otherwise
4268 * bugchecks with the code SESSION5_INITIALIZATION_FAILED.
4269 */
4270 Time.QuadPart += 50000000;
4272 }
4273 else
4274 {
4275 /* The installer failed to start: raise a hard error (crash the system/BSOD) */
4277 0, 0, NULL, 0, NULL);
4278 }
4279
4281}
4282
4283/* 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 * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
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 DoFileCopy(IN OUT PUSETUP_DATA pSetupData, IN PSP_FILE_CALLBACK_W MsgHandler, IN PVOID Context OPTIONAL)
Definition: install.c:826
BOOLEAN PrepareFileCopy(IN OUT PUSETUP_DATA pSetupData, IN PFILE_COPY_STATUS_ROUTINE StatusRoutine OPTIONAL)
Definition: install.c:684
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 InstallVBRToPartition(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath, IN PCWSTR FileSystemName)
Definition: bootsup.c:1381
NTSTATUS InstallFatBootcodeToFloppy(IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath)
Definition: bootsup.c:1426
NTSTATUS InstallMbrBootCodeToDisk(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PCWSTR DestinationDevicePathBuffer)
Definition: bootsup.c:831
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
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
#define wcsicmp
Definition: compat.h:15
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
#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
#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
VOID SetCurrentListEntry(IN PGENERIC_LIST List, IN PGENERIC_LIST_ENTRY Entry)
Definition: genlist.c:87
PGENERIC_LIST_ENTRY GetFirstListEntry(IN PGENERIC_LIST List)
Definition: genlist.c:104
VOID DestroyGenericList(IN OUT PGENERIC_LIST List, IN BOOLEAN FreeData)
Definition: genlist.c:36
PGENERIC_LIST_ENTRY GetCurrentListEntry(IN PGENERIC_LIST List)
Definition: genlist.c:97
ULONG GetNumberOfListEntries(IN PGENERIC_LIST List)
Definition: genlist.c:140
PVOID GetListEntryData(IN PGENERIC_LIST_ENTRY Entry)
Definition: genlist.c:126
PGENERIC_LIST_ENTRY GetNextListEntry(IN PGENERIC_LIST_ENTRY Entry)
Definition: genlist.c:114
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
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
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)
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)