Prepared bootloader installation.
[reactos.git] / reactos / subsys / system / usetup / usetup.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2002 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/usetup.c
23 * PURPOSE: Text-mode setup
24 * PROGRAMMER: Eric Kohl
25 */
26
27 #include <ddk/ntddk.h>
28 #include <ntdll/rtl.h>
29
30 #include <ntos/minmax.h>
31 #include <reactos/resource.h>
32
33 #include "usetup.h"
34 #include "console.h"
35 #include "partlist.h"
36 #include "inicache.h"
37 #include "filequeue.h"
38 #include "progress.h"
39 #include "bootsup.h"
40
41
42 #define START_PAGE 0
43 #define INTRO_PAGE 1
44 #define INSTALL_INTRO_PAGE 2
45
46 #define SELECT_PARTITION_PAGE 4
47 #define SELECT_FILE_SYSTEM_PAGE 5
48 #define CHECK_FILE_SYSTEM_PAGE 6
49 #define PREPARE_COPY_PAGE 7
50 #define INSTALL_DIRECTORY_PAGE 8
51 #define FILE_COPY_PAGE 9
52 #define REGISTRY_PAGE 10
53 #define BOOT_LOADER_PAGE 11
54
55 #define REPAIR_INTRO_PAGE 20
56
57 #define SUCCESS_PAGE 100
58 #define QUIT_PAGE 101
59 #define REBOOT_PAGE 102
60
61
62 typedef struct _COPYCONTEXT
63 {
64 ULONG TotalOperations;
65 ULONG CompletedOperations;
66 PPROGRESS ProgressBar;
67 } COPYCONTEXT, *PCOPYCONTEXT;
68
69
70 /* GLOBALS ******************************************************************/
71
72 HANDLE ProcessHeap;
73
74 BOOLEAN PartDataValid;
75 PARTDATA PartData;
76
77 BOOLEAN ActivePartitionValid;
78 PARTDATA ActivePartition;
79
80 UNICODE_STRING SourcePath;
81 UNICODE_STRING SourceRootPath;
82
83 UNICODE_STRING InstallPath;
84 UNICODE_STRING DestinationPath;
85 UNICODE_STRING DestinationRootPath;
86
87 UNICODE_STRING SystemRootPath; /* Path to the active partition */
88
89 PINICACHE IniCache;
90
91 HSPFILEQ SetupFileQueue = NULL;
92
93
94 /* FUNCTIONS ****************************************************************/
95
96 static VOID
97 PrintString(char* fmt,...)
98 {
99 char buffer[512];
100 va_list ap;
101 UNICODE_STRING UnicodeString;
102 ANSI_STRING AnsiString;
103
104 va_start(ap, fmt);
105 vsprintf(buffer, fmt, ap);
106 va_end(ap);
107
108 RtlInitAnsiString(&AnsiString, buffer);
109 RtlAnsiStringToUnicodeString(&UnicodeString,
110 &AnsiString,
111 TRUE);
112 NtDisplayString(&UnicodeString);
113 RtlFreeUnicodeString(&UnicodeString);
114 }
115
116
117 static VOID
118 PopupError(PCHAR Text,
119 PCHAR Status)
120 {
121 SHORT xScreen;
122 SHORT yScreen;
123 SHORT yTop;
124 SHORT xLeft;
125 COORD coPos;
126 ULONG Written;
127 ULONG Length;
128 ULONG MaxLength;
129 ULONG Lines;
130 PCHAR p;
131 PCHAR pnext;
132 BOOLEAN LastLine;
133 SHORT Width;
134 SHORT Height;
135
136
137 /* Count text lines and longest line */
138 MaxLength = 0;
139 Lines = 0;
140 pnext = Text;
141 while (TRUE)
142 {
143 p = strchr(pnext, '\n');
144 if (p == NULL)
145 {
146 Length = strlen(pnext);
147 LastLine = TRUE;
148 }
149 else
150 {
151 Length = (ULONG)(p - pnext);
152 LastLine = FALSE;
153 }
154
155 Lines++;
156 if (Length > MaxLength)
157 MaxLength = Length;
158
159 if (LastLine == TRUE)
160 break;
161
162 pnext = p + 1;
163 }
164
165 /* Check length of status line */
166 if (Status != NULL)
167 {
168 Length = strlen(Status);
169 if (Length > MaxLength)
170 MaxLength = Length;
171 }
172
173 GetScreenSize(&xScreen, &yScreen);
174
175 Width = MaxLength + 4;
176 Height = Lines + 2;
177 if (Status != NULL)
178 Height += 2;
179
180 yTop = (yScreen - Height) / 2;
181 xLeft = (xScreen - Width) / 2;
182
183
184 /* Set screen attributes */
185 coPos.X = xLeft;
186 for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++)
187 {
188 FillConsoleOutputAttribute(0x74,
189 Width,
190 coPos,
191 &Written);
192 }
193
194 /* draw upper left corner */
195 coPos.X = xLeft;
196 coPos.Y = yTop;
197 FillConsoleOutputCharacter(0xDA, // '+',
198 1,
199 coPos,
200 &Written);
201
202 /* draw upper edge */
203 coPos.X = xLeft + 1;
204 coPos.Y = yTop;
205 FillConsoleOutputCharacter(0xC4, // '-',
206 Width - 2,
207 coPos,
208 &Written);
209
210 /* draw upper right corner */
211 coPos.X = xLeft + Width - 1;
212 coPos.Y = yTop;
213 FillConsoleOutputCharacter(0xBF, // '+',
214 1,
215 coPos,
216 &Written);
217
218 /* Draw right edge, inner space and left edge */
219 for (coPos.Y = yTop + 1; coPos.Y < yTop + Height - 1; coPos.Y++)
220 {
221 coPos.X = xLeft;
222 FillConsoleOutputCharacter(0xB3, // '|',
223 1,
224 coPos,
225 &Written);
226
227 coPos.X = xLeft + 1;
228 FillConsoleOutputCharacter(' ',
229 Width - 2,
230 coPos,
231 &Written);
232
233 coPos.X = xLeft + Width - 1;
234 FillConsoleOutputCharacter(0xB3, // '|',
235 1,
236 coPos,
237 &Written);
238 }
239
240 /* draw lower left corner */
241 coPos.X = xLeft;
242 coPos.Y = yTop + Height - 1;
243 FillConsoleOutputCharacter(0xC0, // '+',
244 1,
245 coPos,
246 &Written);
247
248 /* draw lower edge */
249 coPos.X = xLeft + 1;
250 coPos.Y = yTop + Height - 1;
251 FillConsoleOutputCharacter(0xC4, // '-',
252 Width - 2,
253 coPos,
254 &Written);
255
256 /* draw lower right corner */
257 coPos.X = xLeft + Width - 1;
258 coPos.Y = yTop + Height - 1;
259 FillConsoleOutputCharacter(0xD9, // '+',
260 1,
261 coPos,
262 &Written);
263
264 /* Print message text */
265 coPos.Y = yTop + 1;
266 pnext = Text;
267 while (TRUE)
268 {
269 p = strchr(pnext, '\n');
270 if (p == NULL)
271 {
272 Length = strlen(pnext);
273 LastLine = TRUE;
274 }
275 else
276 {
277 Length = (ULONG)(p - pnext);
278 LastLine = FALSE;
279 }
280
281 if (Length != 0)
282 {
283 coPos.X = xLeft + 2;
284 WriteConsoleOutputCharacters(pnext,
285 Length,
286 coPos);
287 }
288
289 if (LastLine == TRUE)
290 break;
291
292 coPos.Y++;
293 pnext = p + 1;
294 }
295
296 /* Print separator line and status text */
297 if (Status != NULL)
298 {
299 coPos.Y = yTop + Height - 3;
300 coPos.X = xLeft;
301 FillConsoleOutputCharacter(0xC3, // '+',
302 1,
303 coPos,
304 &Written);
305
306 coPos.X = xLeft + 1;
307 FillConsoleOutputCharacter(0xC4, // '-',
308 Width - 2,
309 coPos,
310 &Written);
311
312 coPos.X = xLeft + Width - 1;
313 FillConsoleOutputCharacter(0xB4, // '+',
314 1,
315 coPos,
316 &Written);
317
318 coPos.Y++;
319 coPos.X = xLeft + 2;
320 WriteConsoleOutputCharacters(Status,
321 min(strlen(Status), Width - 4),
322 coPos);
323 }
324 }
325
326
327 /*
328 * Confirm quit setup
329 * RETURNS
330 * TRUE: Quit setup.
331 * FALSE: Don't quit setup.
332 */
333 static BOOL
334 ConfirmQuit(PINPUT_RECORD Ir)
335 {
336 BOOL Result = FALSE;
337
338 PopupError("ReactOS is not completely installed on your\n"
339 "computer. If you quit Setup now, you will need to\n"
340 "run Setup again to install ReactOS.\n"
341 "\n"
342 " * Press ENTER to continue Setup.\n"
343 " * Press F3 to quit Setup.",
344 "F3= Quit ENTER = Continue");
345
346 while(TRUE)
347 {
348 ConInKey(Ir);
349
350 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
351 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
352 {
353 Result = TRUE;
354 break;
355 }
356 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
357 {
358 Result = FALSE;
359 break;
360 }
361 }
362
363 return(Result);
364 }
365
366
367
368 /*
369 * Start page
370 * RETURNS
371 * Number of the next page.
372 */
373 static ULONG
374 StartPage(PINPUT_RECORD Ir)
375 {
376 NTSTATUS Status;
377 WCHAR FileNameBuffer[MAX_PATH];
378 UNICODE_STRING FileName;
379
380 PINICACHESECTION Section;
381 PWCHAR Value;
382
383
384 SetStatusText(" Please wait...");
385
386 Status = GetSourcePaths(&SourcePath,
387 &SourceRootPath);
388 if (!NT_SUCCESS(Status))
389 {
390 PrintTextXY(6, 15, "GetSourcePath() failed (Status 0x%08lx)", Status);
391 }
392 else
393 {
394 PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath);
395 PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath);
396 }
397
398
399 /* Load txtsetup.sif from install media. */
400 wcscpy(FileNameBuffer, SourceRootPath.Buffer);
401 wcscat(FileNameBuffer, L"\\install\\txtsetup.sif");
402 RtlInitUnicodeString(&FileName,
403 FileNameBuffer);
404
405 IniCache = NULL;
406 Status = IniCacheLoad(&IniCache,
407 &FileName);
408 if (!NT_SUCCESS(Status))
409 {
410 PopupError("Setup failed to load the file TXTSETUP.SIF.\n",
411 "ENTER = Reboot computer");
412
413 while(TRUE)
414 {
415 ConInKey(Ir);
416
417 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
418 {
419 return(QUIT_PAGE);
420 }
421 }
422 }
423
424 /* Open 'Version' section */
425 Section = IniCacheGetSection(IniCache,
426 L"Version");
427 if (Section == NULL)
428 {
429 PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
430 "ENTER = Reboot computer");
431
432 while(TRUE)
433 {
434 ConInKey(Ir);
435
436 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
437 {
438 return(QUIT_PAGE);
439 }
440 }
441 }
442
443
444 /* Get pointer 'Signature' key */
445 Status = IniCacheGetKey(Section,
446 L"Signature",
447 &Value);
448 if (!NT_SUCCESS(Status))
449 {
450 PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
451 "ENTER = Reboot computer");
452
453 while(TRUE)
454 {
455 ConInKey(Ir);
456
457 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
458 {
459 return(QUIT_PAGE);
460 }
461 }
462 }
463
464 /* Check 'Signature' string */
465 if (_wcsicmp(Value, L"$ReactOS$") != 0)
466 {
467 PopupError("Setup found an invalid signature in TXTSETUP.SIF.\n",
468 "ENTER = Reboot computer");
469
470 while(TRUE)
471 {
472 ConInKey(Ir);
473
474 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
475 {
476 return(QUIT_PAGE);
477 }
478 }
479 }
480
481 #if 0
482 PopupError("This is a test error.", "ENTER = Reboot computer");
483
484 SetStatusText(" ENTER = Continue");
485
486 while(TRUE)
487 {
488 ConInKey(Ir);
489
490 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
491 {
492 return(INTRO_PAGE);
493 }
494 }
495
496 return(START_PAGE);
497 #endif
498
499 return(INTRO_PAGE);
500 }
501
502
503
504 static ULONG
505 RepairIntroPage(PINPUT_RECORD Ir)
506 {
507 SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
508 SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
509
510 SetTextXY(6, 12, "The repair functions are not implemented yet.");
511
512 SetTextXY(8, 15, "\xf9 Press ESC to return to the main page.");
513
514 SetTextXY(8, 17, "\xf9 Press ENTER to reboot your computer.");
515
516 SetStatusText(" ESC = Main page ENTER = Reboot");
517
518 while(TRUE)
519 {
520 ConInKey(Ir);
521
522 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
523 {
524 return(REBOOT_PAGE);
525 }
526 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
527 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
528 {
529 return(INTRO_PAGE);
530 }
531 }
532
533 return(REPAIR_INTRO_PAGE);
534 }
535
536
537 /*
538 * First setup page
539 * RETURNS
540 * TRUE: setup/repair completed successfully
541 * FALSE: setup/repair terminated by user
542 */
543 static ULONG
544 IntroPage(PINPUT_RECORD Ir)
545 {
546 SetHighlightedTextXY(6, 8, "Welcome to ReactOS Setup");
547
548 SetTextXY(6, 11, "This part of the setup copies the ReactOS Operating System to your");
549 SetTextXY(6, 12, "computer and prepares the second part of the setup.");
550
551 SetTextXY(8, 15, "\xf9 Press ENTER to install ReactOS.");
552
553 SetTextXY(8, 17, "\xf9 Press E to start the emergency repair console.");
554
555 SetTextXY(8, 19, "\xf9 Press R to repair ReactOS.");
556
557 SetTextXY(8, 21, "\xf9 Press F3 to quit without installing ReactOS.");
558
559
560 SetStatusText(" ENTER = Continue F3 = Quit");
561
562 while(TRUE)
563 {
564 ConInKey(Ir);
565
566 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
567 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
568 {
569 if (ConfirmQuit(Ir) == TRUE)
570 return(QUIT_PAGE);
571 break;
572 }
573 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
574 {
575 return(INSTALL_INTRO_PAGE);
576 }
577 #if 0
578 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'E') /* E */
579 {
580 return(RepairConsole());
581 }
582 #endif
583 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */
584 {
585 return(REPAIR_INTRO_PAGE);
586 }
587 }
588
589 return(INTRO_PAGE);
590 }
591
592
593 static ULONG
594 InstallIntroPage(PINPUT_RECORD Ir)
595 {
596 SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
597 SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
598
599 SetTextXY(6, 12, "The following functions are missing:");
600 SetTextXY(8, 13, "- Creating and deleting harddisk partitions.");
601 SetTextXY(8, 14, "- Formatting partitions.");
602 SetTextXY(8, 15, "- Support for non-FAT file systems.");
603 SetTextXY(8, 16, "- Checking file systems.");
604 SetTextXY(8, 17, "- Installing the bootloader.");
605
606
607
608 SetTextXY(8, 21, "\xf9 Press ENTER to install ReactOS.");
609
610 SetTextXY(8, 23, "\xf9 Press F3 to quit without installing ReactOS.");
611
612
613 SetStatusText(" ENTER = Continue F3 = Quit");
614
615 while(TRUE)
616 {
617 ConInKey(Ir);
618
619 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
620 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
621 {
622 if (ConfirmQuit(Ir) == TRUE)
623 return(QUIT_PAGE);
624 break;
625 }
626 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
627 {
628 return(SELECT_PARTITION_PAGE);
629 }
630 }
631
632 return(INSTALL_INTRO_PAGE);
633 }
634
635
636 static ULONG
637 SelectPartitionPage(PINPUT_RECORD Ir)
638 {
639 WCHAR PathBuffer[MAX_PATH];
640 PPARTLIST PartList;
641 SHORT xScreen;
642 SHORT yScreen;
643
644 SetTextXY(6, 8, "The list below shows existing partitions and unused disk");
645 SetTextXY(6, 9, "space for new partitions.");
646
647 SetTextXY(8, 11, "\xf9 Press UP or DOWN to select a list entry.");
648 SetTextXY(8, 13, "\xf9 Press ENTER to install ReactOS onto the selected partition.");
649 SetTextXY(8, 15, "\xf9 Press C to create a new partition.");
650 SetTextXY(8, 17, "\xf9 Press D to delete an existing partition.");
651
652 SetStatusText(" Please wait...");
653
654 RtlFreeUnicodeString(&DestinationPath);
655 RtlFreeUnicodeString(&DestinationRootPath);
656
657 GetScreenSize(&xScreen, &yScreen);
658
659 PartList = CreatePartitionList(2, 19, xScreen - 3, yScreen - 3);
660 if (PartList == NULL)
661 {
662 /* FIXME: show an error dialog */
663 return(QUIT_PAGE);
664 }
665
666 SetStatusText(" ENTER = Continue F3 = Quit");
667
668 while(TRUE)
669 {
670 ConInKey(Ir);
671
672 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
673 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
674 {
675 if (ConfirmQuit(Ir) == TRUE)
676 {
677 DestroyPartitionList(PartList);
678 return(QUIT_PAGE);
679 }
680 break;
681 }
682 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
683 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
684 {
685 ScrollDownPartitionList(PartList);
686 }
687 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
688 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
689 {
690 ScrollUpPartitionList(PartList);
691 }
692 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
693 {
694 PartDataValid = GetSelectedPartition(PartList,
695 &PartData);
696 ActivePartitionValid = GetActiveBootPartition(PartList,
697 &ActivePartition);
698 DestroyPartitionList(PartList);
699
700 RtlFreeUnicodeString(&DestinationRootPath);
701 swprintf(PathBuffer,
702 L"\\Device\\Harddisk%lu\\Partition%lu",
703 PartData.DiskNumber,
704 PartData.PartNumber);
705 RtlCreateUnicodeString(&DestinationRootPath,
706 PathBuffer);
707
708 RtlFreeUnicodeString(&SystemRootPath);
709 swprintf(PathBuffer,
710 L"\\Device\\Harddisk%lu\\Partition%lu",
711 ActivePartition.DiskNumber,
712 ActivePartition.PartNumber);
713 RtlCreateUnicodeString(&SystemRootPath,
714 PathBuffer);
715
716 return(SELECT_FILE_SYSTEM_PAGE);
717 }
718
719 /* FIXME: Update status text */
720
721 }
722
723 DestroyPartitionList(PartList);
724
725 return(SELECT_PARTITION_PAGE);
726 }
727
728
729 static ULONG
730 SelectFileSystemPage(PINPUT_RECORD Ir)
731 {
732 ULONGLONG DiskSize;
733 ULONGLONG PartSize;
734 PCHAR DiskUnit;
735 PCHAR PartUnit;
736 PCHAR PartType;
737
738 if (PartDataValid == FALSE)
739 {
740 /* FIXME: show an error dialog */
741 return(QUIT_PAGE);
742 }
743
744 /* adjust disk size */
745 if (PartData.DiskSize >= 0x280000000ULL) /* 10 GB */
746 {
747 DiskSize = (PartData.DiskSize + (1 << 29)) >> 30;
748 DiskUnit = "GB";
749 }
750 else
751 {
752 DiskSize = (PartData.DiskSize + (1 << 19)) >> 20;
753 DiskUnit = "MB";
754 }
755
756 /* adjust partition size */
757 if (PartData.PartSize >= 0x280000000ULL) /* 10 GB */
758 {
759 PartSize = (PartData.PartSize + (1 << 29)) >> 30;
760 PartUnit = "GB";
761 }
762 else
763 {
764 PartSize = (PartData.PartSize + (1 << 19)) >> 20;
765 PartUnit = "MB";
766 }
767
768 /* adjust partition type */
769 if ((PartData.PartType == PARTITION_FAT_12) ||
770 (PartData.PartType == PARTITION_FAT_16) ||
771 (PartData.PartType == PARTITION_HUGE) ||
772 (PartData.PartType == PARTITION_XINT13))
773 {
774 PartType = "FAT";
775 }
776 else if ((PartData.PartType == PARTITION_FAT32) ||
777 (PartData.PartType == PARTITION_FAT32_XINT13))
778 {
779 PartType = "FAT32";
780 }
781 else if (PartData.PartType == PARTITION_IFS)
782 {
783 PartType = "NTFS"; /* FIXME: Not quite correct! */
784 }
785 else
786 {
787 PartType = "Unknown";
788 }
789
790 SetTextXY(6, 8, "Setup will install ReactOS on");
791
792 PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s on",
793 PartData.PartNumber,
794 PartSize,
795 PartUnit,
796 PartType);
797
798 PrintTextXY(8, 12, "Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
799 PartData.DiskNumber,
800 DiskSize,
801 DiskUnit,
802 PartData.Port,
803 PartData.Bus,
804 PartData.Id,
805 &PartData.DriverName);
806
807
808 SetTextXY(6, 17, "Select a file system for the partition from the list below.");
809
810 SetTextXY(8, 19, "\xf9 Press UP or DOWN to select a file system.");
811 SetTextXY(8, 21, "\xf9 Press ENTER to format the partition.");
812 SetTextXY(8, 23, "\xf9 Press ESC to select another partition.");
813
814 /* FIXME: use a real list later */
815 SetInvertedTextXY(6, 26, " Keep current file system (no changes) ");
816
817
818 SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit");
819
820 while(TRUE)
821 {
822 ConInKey(Ir);
823
824 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
825 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
826 {
827 if (ConfirmQuit(Ir) == TRUE)
828 return(QUIT_PAGE);
829 break;
830 }
831 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
832 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
833 {
834 return(SELECT_PARTITION_PAGE);
835 }
836 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
837 {
838 return(CHECK_FILE_SYSTEM_PAGE);
839 }
840 }
841
842 return(SELECT_FILE_SYSTEM_PAGE);
843 }
844
845
846 static ULONG
847 CheckFileSystemPage(PINPUT_RECORD Ir)
848 {
849 SetTextXY(6, 8, "Check file system");
850
851 SetTextXY(6, 10, "At present, ReactOS can not check file systems.");
852
853 SetStatusText(" Please wait ...");
854
855
856 SetStatusText(" ENTER = Continue F3 = Quit");
857
858 while(TRUE)
859 {
860 ConInKey(Ir);
861
862 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
863 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
864 {
865 if (ConfirmQuit(Ir) == TRUE)
866 return(QUIT_PAGE);
867 break;
868 }
869 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
870 {
871 return(INSTALL_DIRECTORY_PAGE);
872 }
873 }
874
875 return(CHECK_FILE_SYSTEM_PAGE);
876 }
877
878
879 static ULONG
880 InstallDirectoryPage(PINPUT_RECORD Ir)
881 {
882 WCHAR PathBuffer[MAX_PATH];
883 WCHAR InstallDir[51];
884 ULONG Length;
885
886 SetTextXY(6, 8, "Setup installs ReactOS files onto the selected partition. Choose a");
887 SetTextXY(6, 9, "directory where you want ReactOS to be installed:");
888
889 wcscpy(InstallDir, L"\\reactos");
890 Length = wcslen(InstallDir);
891
892 SetInputTextXY(8, 11, 51, InstallDir);
893
894 SetTextXY(6, 14, "To change the suggested directory, press BACKSPACE to delete");
895 SetTextXY(6, 15, "characters and then type the directory where you want ReactOS to");
896 SetTextXY(6, 16, "be installed.");
897
898
899 SetStatusText(" ENTER = Continue F3 = Quit");
900
901 while(TRUE)
902 {
903 ConInKey(Ir);
904
905 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
906 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
907 {
908 if (ConfirmQuit(Ir) == TRUE)
909 return(QUIT_PAGE);
910 break;
911 }
912 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
913 {
914 /* Create 'DestinationPath' string */
915 RtlFreeUnicodeString(&InstallPath);
916 RtlCreateUnicodeString(&InstallPath,
917 InstallDir);
918
919 /* Create 'DestinationPath' string */
920 RtlFreeUnicodeString(&DestinationPath);
921 wcscpy(PathBuffer,
922 DestinationRootPath.Buffer);
923 if (InstallDir[0] != L'\\')
924 wcscat(PathBuffer,
925 L"\\");
926 wcscat(PathBuffer, InstallDir);
927 RtlCreateUnicodeString(&DestinationPath,
928 PathBuffer);
929
930 return(PREPARE_COPY_PAGE);
931 }
932 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */
933 {
934 if (Length > 0)
935 {
936 Length--;
937 InstallDir[Length] = 0;
938 SetInputTextXY(8, 11, 51, InstallDir);
939 }
940 }
941 else if (isprint(Ir->Event.KeyEvent.uChar.AsciiChar))
942 {
943 if (Length < 50)
944 {
945 InstallDir[Length] = (WCHAR)Ir->Event.KeyEvent.uChar.AsciiChar;
946 Length++;
947 InstallDir[Length] = 0;
948 SetInputTextXY(8, 11, 51, InstallDir);
949 }
950 }
951 }
952
953 return(INSTALL_DIRECTORY_PAGE);
954 }
955
956
957 static ULONG
958 PrepareCopyPage(PINPUT_RECORD Ir)
959 {
960 WCHAR PathBuffer[MAX_PATH];
961 PINICACHESECTION DirSection;
962 PINICACHESECTION FilesSection;
963 PINICACHEITERATOR Iterator;
964 PWCHAR KeyName;
965 PWCHAR KeyValue;
966 ULONG Length;
967 NTSTATUS Status;
968
969 PWCHAR FileKeyName;
970 PWCHAR FileKeyValue;
971 PWCHAR DirKeyName;
972 PWCHAR DirKeyValue;
973
974 SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. ");
975
976
977 SetTextXY(8, 12, "Build file copy list");
978
979 SetTextXY(8, 14, "Create directories");
980
981 SetStatusText(" Please wait...");
982
983
984 /*
985 * Build the file copy list
986 */
987 SetInvertedTextXY(8, 12, "Build file copy list");
988
989
990 /* Open 'Directories' section */
991 DirSection = IniCacheGetSection(IniCache,
992 L"Directories");
993 if (DirSection == NULL)
994 {
995 PopupError("Setup failed to find the 'Directories' section\n"
996 "in TXTSETUP.SIF.\n",
997 "ENTER = Reboot computer");
998
999 while(TRUE)
1000 {
1001 ConInKey(Ir);
1002
1003 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1004 {
1005 return(QUIT_PAGE);
1006 }
1007 }
1008 }
1009
1010 /* Open 'SourceFiles' section */
1011 FilesSection = IniCacheGetSection(IniCache,
1012 L"SourceFiles");
1013 if (FilesSection == NULL)
1014 {
1015 PopupError("Setup failed to find the 'SourceFiles' section\n"
1016 "in TXTSETUP.SIF.\n",
1017 "ENTER = Reboot computer");
1018
1019 while(TRUE)
1020 {
1021 ConInKey(Ir);
1022
1023 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1024 {
1025 return(QUIT_PAGE);
1026 }
1027 }
1028 }
1029
1030
1031 /* Create the file queue */
1032 SetupFileQueue = SetupOpenFileQueue();
1033 if (SetupFileQueue == NULL)
1034 {
1035 PopupError("Setup failed to open the copy file queue.\n",
1036 "ENTER = Reboot computer");
1037
1038 while(TRUE)
1039 {
1040 ConInKey(Ir);
1041
1042 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1043 {
1044 return(QUIT_PAGE);
1045 }
1046 }
1047 }
1048
1049 /*
1050 * Enumerate the files in the 'SourceFiles' section
1051 * and add them to the file queue.
1052 */
1053 Iterator = IniCacheFindFirstValue(FilesSection,
1054 &FileKeyName,
1055 &FileKeyValue);
1056 if (Iterator != NULL)
1057 {
1058 do
1059 {
1060 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
1061
1062 /* Lookup target directory */
1063 Status = IniCacheGetKey(DirSection,
1064 FileKeyValue,
1065 &DirKeyValue);
1066 if (!NT_SUCCESS(Status))
1067 {
1068 /* FIXME: Handle error! */
1069 DPRINT1("IniCacheGetKey() failed (Status 0x%lX)\n", Status);
1070 }
1071
1072 if (SetupQueueCopy(SetupFileQueue,
1073 SourceRootPath.Buffer,
1074 L"\\install",
1075 FileKeyName,
1076 DirKeyValue,
1077 NULL) == FALSE)
1078 {
1079 /* FIXME: Handle error! */
1080 DPRINT1("SetupQueueCopy() failed\n");
1081 }
1082 }
1083 while (IniCacheFindNextValue(Iterator, &FileKeyName, &FileKeyValue));
1084
1085 IniCacheFindClose(Iterator);
1086 }
1087
1088 /* Report that the file queue has been built */
1089 SetTextXY(8, 12, "Build file copy list");
1090 SetHighlightedTextXY(50, 12, "Done");
1091
1092 /* create directories */
1093 SetInvertedTextXY(8, 14, "Create directories");
1094
1095
1096 /*
1097 * FIXME:
1098 * Install directories like '\reactos\test' are not handled yet.
1099 */
1100
1101 /* Get destination path */
1102 wcscpy(PathBuffer, DestinationPath.Buffer);
1103
1104 /* Remove trailing backslash */
1105 Length = wcslen(PathBuffer);
1106 if ((Length > 0) && (PathBuffer[Length - 1] == '\\'))
1107 PathBuffer[Length - 1] = 0;
1108
1109 /* Create the install directory */
1110 Status = CreateDirectory(PathBuffer);
1111 if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
1112 {
1113 DPRINT1("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
1114
1115 PopupError("Setup could not create the install directory.",
1116 "ENTER = Reboot computer");
1117
1118 while(TRUE)
1119 {
1120 ConInKey(Ir);
1121
1122 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1123 {
1124 return(QUIT_PAGE);
1125 }
1126 }
1127 }
1128
1129
1130 /* Enumerate the directory values and create the subdirectories */
1131 Iterator = IniCacheFindFirstValue(DirSection,
1132 &KeyName,
1133 &KeyValue);
1134 if (Iterator != NULL)
1135 {
1136 do
1137 {
1138 if (KeyValue[0] == L'\\' && KeyValue[1] != 0)
1139 {
1140 DPRINT("Absolute Path: '%S'\n", KeyValue);
1141
1142 wcscpy(PathBuffer, DestinationRootPath.Buffer);
1143 wcscat(PathBuffer, KeyValue);
1144
1145 DPRINT("FullPath: '%S'\n", PathBuffer);
1146 }
1147 else if (KeyValue[0] != L'\\')
1148 {
1149 DPRINT("RelativePath: '%S'\n", KeyValue);
1150 wcscpy(PathBuffer, DestinationPath.Buffer);
1151 wcscat(PathBuffer, L"\\");
1152 wcscat(PathBuffer, KeyValue);
1153
1154 DPRINT("FullPath: '%S'\n", PathBuffer);
1155
1156 Status = CreateDirectory(PathBuffer);
1157 if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
1158 {
1159 DPRINT1("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
1160
1161 PopupError("Setup could not create install directories.",
1162 "ENTER = Reboot computer");
1163
1164 while(TRUE)
1165 {
1166 ConInKey(Ir);
1167
1168 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1169 {
1170 IniCacheFindClose(Iterator);
1171 return(QUIT_PAGE);
1172 }
1173 }
1174 }
1175 }
1176 }
1177 while (IniCacheFindNextValue(Iterator, &KeyName, &KeyValue));
1178
1179 IniCacheFindClose(Iterator);
1180 }
1181
1182
1183 SetTextXY(8, 14, "Create directories");
1184 SetHighlightedTextXY(50, 14, "Done");
1185
1186
1187 SetStatusText(" ENTER = Continue F3 = Quit");
1188
1189 while(TRUE)
1190 {
1191 ConInKey(Ir);
1192
1193 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1194 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1195 {
1196 if (ConfirmQuit(Ir) == TRUE)
1197 return(QUIT_PAGE);
1198 break;
1199 }
1200 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1201 {
1202 return(FILE_COPY_PAGE);
1203 }
1204 }
1205
1206 return(PREPARE_COPY_PAGE);
1207 }
1208
1209
1210 static ULONG
1211 FileCopyCallback(PVOID Context,
1212 ULONG Notification,
1213 PVOID Param1,
1214 PVOID Param2)
1215 {
1216 PCOPYCONTEXT CopyContext;
1217
1218 CopyContext = (PCOPYCONTEXT)Context;
1219
1220 switch (Notification)
1221 {
1222 case SPFILENOTIFY_STARTSUBQUEUE:
1223 CopyContext->TotalOperations = (ULONG)Param2;
1224 ProgressSetStepCount(CopyContext->ProgressBar,
1225 CopyContext->TotalOperations);
1226 break;
1227
1228 case SPFILENOTIFY_STARTCOPY:
1229 /* Display copy message */
1230 PrintTextXYN(6, 16, 60, "Copying file: %S", (PWSTR)Param1);
1231
1232 PrintTextXYN(6, 18, 60, "File %lu of %lu",
1233 CopyContext->CompletedOperations + 1,
1234 CopyContext->TotalOperations);
1235 break;
1236
1237
1238 case SPFILENOTIFY_ENDCOPY:
1239 CopyContext->CompletedOperations++;
1240 ProgressNextStep(CopyContext->ProgressBar);
1241 break;
1242 }
1243
1244 return(0);
1245 }
1246
1247
1248 static ULONG
1249 FileCopyPage(PINPUT_RECORD Ir)
1250 {
1251 COPYCONTEXT CopyContext;
1252 SHORT xScreen;
1253 SHORT yScreen;
1254
1255 SetStatusText(" Please wait...");
1256
1257 SetTextXY(6, 8, "Copying files");
1258
1259 GetScreenSize(&xScreen, &yScreen);
1260
1261 CopyContext.TotalOperations = 0;
1262 CopyContext.CompletedOperations = 0;
1263 CopyContext.ProgressBar = CreateProgressBar(6,
1264 yScreen - 14,
1265 xScreen - 7,
1266 yScreen - 10);
1267
1268 SetupCommitFileQueue(SetupFileQueue,
1269 DestinationRootPath.Buffer,
1270 InstallPath.Buffer,
1271 (PSP_FILE_CALLBACK)FileCopyCallback,
1272 &CopyContext);
1273
1274 SetupCloseFileQueue(SetupFileQueue);
1275
1276 DestroyProgressBar(CopyContext.ProgressBar);
1277
1278 SetStatusText(" ENTER = Continue F3 = Quit");
1279
1280 while(TRUE)
1281 {
1282 ConInKey(Ir);
1283
1284 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1285 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1286 {
1287 if (ConfirmQuit(Ir) == TRUE)
1288 return(QUIT_PAGE);
1289 break;
1290 }
1291 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1292 {
1293 return(REGISTRY_PAGE);
1294 }
1295 }
1296
1297 return(FILE_COPY_PAGE);
1298 }
1299
1300
1301
1302 static ULONG
1303 RegistryPage(PINPUT_RECORD Ir)
1304 {
1305 OBJECT_ATTRIBUTES ObjectAttributes;
1306 UNICODE_STRING KeyName;
1307 UNICODE_STRING ValueName;
1308 HANDLE KeyHandle;
1309 NTSTATUS Status;
1310
1311 SetTextXY(6, 8, "Initializing system settings");
1312
1313
1314 SetTextXY(6, 12, "Create registry hives");
1315
1316 SetTextXY(6, 14, "Update registry hives");
1317
1318
1319 SetStatusText(" Please wait...");
1320
1321
1322 /* Create the 'secret' InstallPath key */
1323 RtlInitUnicodeStringFromLiteral(&KeyName,
1324 L"\\Registry\\Machine\\HARDWARE");
1325 InitializeObjectAttributes(&ObjectAttributes,
1326 &KeyName,
1327 OBJ_CASE_INSENSITIVE,
1328 NULL,
1329 NULL);
1330 Status = NtOpenKey(&KeyHandle,
1331 KEY_ALL_ACCESS,
1332 &ObjectAttributes);
1333 if (!NT_SUCCESS(Status))
1334 {
1335 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
1336 }
1337
1338 RtlInitUnicodeStringFromLiteral(&ValueName,
1339 L"InstallPath");
1340
1341 Status = NtSetValueKey(KeyHandle,
1342 &ValueName,
1343 0,
1344 REG_SZ,
1345 (PVOID)DestinationPath.Buffer,
1346 DestinationPath.Length);
1347 NtClose(KeyHandle);
1348 if (!NT_SUCCESS(Status))
1349 {
1350 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
1351 }
1352
1353 /* Create the standard hives */
1354 Status = NtInitializeRegistry(TRUE);
1355 if (!NT_SUCCESS(Status))
1356 {
1357 DPRINT1("NtInitializeRegistry() failed (Status %lx)\n", Status);
1358 }
1359
1360
1361
1362 /* Update registry */
1363
1364 /* FIXME: Create key '\Registry\Machine\System\Setup' */
1365
1366 /* FIXME: Create value 'SystemSetupInProgress' */
1367
1368
1369
1370 SetStatusText(" ENTER = Continue F3 = Quit");
1371
1372 while(TRUE)
1373 {
1374 ConInKey(Ir);
1375
1376 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1377 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1378 {
1379 if (ConfirmQuit(Ir) == TRUE)
1380 return(QUIT_PAGE);
1381 break;
1382 }
1383 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1384 {
1385 return(BOOT_LOADER_PAGE);
1386 }
1387 }
1388
1389 return(REGISTRY_PAGE);
1390 }
1391
1392
1393 static ULONG
1394 BootLoaderPage(PINPUT_RECORD Ir)
1395 {
1396 WCHAR SrcPath[MAX_PATH];
1397 WCHAR DstPath[MAX_PATH];
1398 PINICACHE IniCache;
1399 PINICACHESECTION IniSection;
1400
1401 SetTextXY(6, 8, "Installing the boot loader");
1402
1403 SetStatusText(" Please wait...");
1404
1405 if (ActivePartitionValid == FALSE)
1406 {
1407 SetTextXY(6, 10, "Error: no active partition found");
1408 for(;;);
1409 }
1410
1411 if (ActivePartition.PartType == PARTITION_ENTRY_UNUSED)
1412 {
1413 SetTextXY(6, 10, "Error: active partition invalid (unused)");
1414 for(;;);
1415 }
1416
1417 if (ActivePartition.PartType == 0x0A)
1418 {
1419 /* OS/2 boot manager partition */
1420 SetTextXY(6, 12, "Found OS/2 boot manager");
1421
1422 }
1423 else if (ActivePartition.PartType == 0x83)
1424 {
1425 /* Linux ext2 partition */
1426 SetTextXY(6, 12, "Found Linux ext2 partition");
1427
1428 }
1429 else if (ActivePartition.PartType == PARTITION_IFS)
1430 {
1431 /* NTFS partition */
1432 SetTextXY(6, 12, "Found NTFS partition");
1433
1434 }
1435 else if ((ActivePartition.PartType == PARTITION_FAT_12) ||
1436 (ActivePartition.PartType == PARTITION_FAT_16) ||
1437 (ActivePartition.PartType == PARTITION_HUGE) ||
1438 (ActivePartition.PartType == PARTITION_XINT13) ||
1439 (ActivePartition.PartType == PARTITION_FAT32) ||
1440 (ActivePartition.PartType == PARTITION_FAT32_XINT13))
1441 {
1442 /* FAT or FAT 32 partition */
1443 PrintTextXY(6, 10, "System path: '%wZ'", &SystemRootPath);
1444
1445 if (DoesFileExist(SystemRootPath.Buffer, L"ntldr") == TRUE ||
1446 DoesFileExist(SystemRootPath.Buffer, L"boot.ini") == TRUE)
1447 {
1448 /* Search root directory for 'ntldr' and 'boot.ini'. */
1449 SetTextXY(6, 12, "Found Microsoft Windows NT/2000/XP boot loader");
1450
1451
1452 }
1453 else if (DoesFileExist(SystemRootPath.Buffer, L"io.sys") == TRUE ||
1454 DoesFileExist(SystemRootPath.Buffer, L"msdos.sys") == TRUE)
1455 {
1456 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
1457 SetTextXY(6, 12, "Found Microsoft DOS or Windows 9x boot loader");
1458
1459 /* Copy FreeLoader to the boot partition */
1460 wcscpy(SrcPath, SourceRootPath.Buffer);
1461 wcscat(SrcPath, L"\\loader\\freeldr.sys");
1462 wcscpy(DstPath, SystemRootPath.Buffer);
1463 wcscat(DstPath, L"\\freeldr.sys");
1464
1465 PrintTextXY(6, 14, "Copy: %S ==> %S", SrcPath, DstPath);
1466
1467 SetupCopyFile(SrcPath, DstPath);
1468
1469 /* Create freeldr.ini */
1470 wcscpy(DstPath, SystemRootPath.Buffer);
1471 wcscat(DstPath, L"\\freeldr.ini");
1472
1473 CreateFreeLoaderIniForDos(DstPath,
1474 DestinationPath.Buffer);
1475
1476 /* Copy current bootsector to 'BOOTSECT.DOS' */
1477 if ((ActivePartition.PartType == PARTITION_FAT32) ||
1478 (ActivePartition.PartType == PARTITION_FAT32_XINT13))
1479 {
1480
1481 }
1482 else
1483 {
1484
1485 }
1486 }
1487 else
1488 {
1489
1490 SetTextXY(6, 12, "No or unknown boot loader found");
1491
1492 }
1493 }
1494 else
1495 {
1496 /* unknown partition */
1497 SetTextXY(6, 12, "Unknown partition found");
1498 }
1499
1500 SetStatusText(" ENTER = Continue F3 = Quit");
1501
1502 while(TRUE)
1503 {
1504 ConInKey(Ir);
1505
1506 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1507 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1508 {
1509 if (ConfirmQuit(Ir) == TRUE)
1510 return(QUIT_PAGE);
1511 break;
1512 }
1513 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1514 {
1515 return(SUCCESS_PAGE);
1516 }
1517 }
1518
1519 return(BOOT_LOADER_PAGE);
1520 }
1521
1522
1523
1524 static ULONG
1525 QuitPage(PINPUT_RECORD Ir)
1526 {
1527 SetTextXY(10, 6, "ReactOS is not completely installed");
1528
1529 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
1530 SetTextXY(10, 9, "all CD-ROMs from CD-Drive.");
1531
1532 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
1533
1534 SetStatusText(" ENTER = Reboot computer");
1535
1536 while(TRUE)
1537 {
1538 ConInKey(Ir);
1539
1540 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1541 {
1542 return(REBOOT_PAGE);
1543 }
1544 }
1545 }
1546
1547
1548 static ULONG
1549 SuccessPage(PINPUT_RECORD Ir)
1550 {
1551 SetTextXY(10, 6, "The basic components of ReactOS have been installed successfully.");
1552
1553 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
1554 SetTextXY(10, 9, "all CD-ROMs from CD-Drive.");
1555
1556 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
1557
1558 SetStatusText(" ENTER = Reboot computer");
1559
1560 while(TRUE)
1561 {
1562 ConInKey(Ir);
1563
1564 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1565 {
1566 return(REBOOT_PAGE);
1567 }
1568 }
1569 }
1570
1571
1572 VOID STDCALL
1573 NtProcessStartup(PPEB Peb)
1574 {
1575 NTSTATUS Status;
1576 INPUT_RECORD Ir;
1577 ULONG Page;
1578
1579 RtlNormalizeProcessParams(Peb->ProcessParameters);
1580
1581 ProcessHeap = Peb->ProcessHeap;
1582
1583 Status = AllocConsole();
1584 if (!NT_SUCCESS(Status))
1585 {
1586 PrintString("AllocConsole() failed (Status = 0x%08lx)\n", Status);
1587
1588 /* Raise a hard error (crash the system/BSOD) */
1589 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED,
1590 0,0,0,0,0);
1591 }
1592
1593 PartDataValid = FALSE;
1594
1595 /* Initialize global unicode strings */
1596 RtlInitUnicodeString(&SourcePath, NULL);
1597 RtlInitUnicodeString(&SourceRootPath, NULL);
1598 RtlInitUnicodeString(&InstallPath, NULL);
1599 RtlInitUnicodeString(&DestinationPath, NULL);
1600 RtlInitUnicodeString(&DestinationRootPath, NULL);
1601 RtlInitUnicodeString(&SystemRootPath, NULL);
1602
1603
1604 Page = START_PAGE;
1605 while (Page != REBOOT_PAGE)
1606 {
1607 ClearScreen();
1608
1609 SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
1610
1611 switch (Page)
1612 {
1613 /* Start page */
1614 case START_PAGE:
1615 Page = StartPage(&Ir);
1616 break;
1617
1618 /* Intro page */
1619 case INTRO_PAGE:
1620 Page = IntroPage(&Ir);
1621 break;
1622
1623 /* Install pages */
1624 case INSTALL_INTRO_PAGE:
1625 Page = InstallIntroPage(&Ir);
1626 break;
1627
1628 #if 0
1629 case OEM_DRIVER_PAGE:
1630 Page = OemDriverPage(&Ir);
1631 break;
1632 #endif
1633
1634 #if 0
1635 case DEVICE_SETTINGS_PAGE:
1636 #endif
1637
1638 case SELECT_PARTITION_PAGE:
1639 Page = SelectPartitionPage(&Ir);
1640 break;
1641
1642 case SELECT_FILE_SYSTEM_PAGE:
1643 Page = SelectFileSystemPage(&Ir);
1644 break;
1645
1646 case CHECK_FILE_SYSTEM_PAGE:
1647 Page = CheckFileSystemPage(&Ir);
1648 break;
1649
1650 case INSTALL_DIRECTORY_PAGE:
1651 Page = InstallDirectoryPage(&Ir);
1652 break;
1653
1654 case PREPARE_COPY_PAGE:
1655 Page = PrepareCopyPage(&Ir);
1656 break;
1657
1658 case FILE_COPY_PAGE:
1659 Page = FileCopyPage(&Ir);
1660 break;
1661
1662 case REGISTRY_PAGE:
1663 Page = RegistryPage(&Ir);
1664 break;
1665
1666 case BOOT_LOADER_PAGE:
1667 Page = BootLoaderPage(&Ir);
1668 break;
1669
1670
1671 /* Repair pages */
1672 case REPAIR_INTRO_PAGE:
1673 Page = RepairIntroPage(&Ir);
1674 break;
1675
1676
1677 case SUCCESS_PAGE:
1678 Page = SuccessPage(&Ir);
1679 break;
1680
1681 case QUIT_PAGE:
1682 Page = QuitPage(&Ir);
1683 break;
1684 }
1685 }
1686
1687 /* Reboot */
1688 FreeConsole();
1689 NtShutdownSystem(ShutdownReboot);
1690 }
1691
1692 /* EOF */