3 * Copyright (C) 2002 ReactOS Team
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.
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.
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.
19 /* $Id: usetup.c,v 1.3 2002/09/25 14:48:35 ekohl Exp $
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS user-mode setup application
23 * FILE: subsys/system/usetup/usetup.c
24 * PURPOSE: setup application
25 * PROGRAMMERS: Eric Kohl (ekohl@rz-online.de)
28 #include <ddk/ntddk.h>
29 #include <ddk/ntddblue.h>
30 #include <ddk/ntddscsi.h>
32 #include <ntdll/rtl.h>
34 #include <ntos/keyboard.h>
40 #define INSTALL_INTRO_PAGE 1
42 #define CHOOSE_PARTITION_PAGE 3
43 #define SELECT_FILE_SYSTEM_PAGE 4
44 #define CHECK_FILE_SYSTEM_PAGE 5
45 #define PREPARE_COPY_PAGE 6
46 #define INSTALL_DIRECTORY_PAGE 7
47 #define FILE_COPY_PAGE 8
48 #define INIT_SYSTEM_PAGE 9
50 #define SUCCESS_PAGE 100
52 #define REBOOT_PAGE 102
57 /* FUNCTIONS ****************************************************************/
60 DisplayString(LPCWSTR lpwString
)
64 RtlInitUnicodeString(&us
, lpwString
);
70 PrintString(char* fmt
,...)
74 UNICODE_STRING UnicodeString
;
75 ANSI_STRING AnsiString
;
78 vsprintf(buffer
, fmt
, ap
);
81 RtlInitAnsiString(&AnsiString
, buffer
);
82 RtlAnsiStringToUnicodeString(&UnicodeString
,
85 NtDisplayString(&UnicodeString
);
86 RtlFreeUnicodeString(&UnicodeString
);
94 * FALSE: Don't quit setup.
97 ConfirmQuit(PINPUT_RECORD Ir
)
104 PUSHORT pAttributes
= NULL
;
105 PUCHAR pCharacters
= NULL
;
108 GetScreenSize(&xScreen
, &yScreen
);
109 yTop
= (yScreen
- 10) / 2;
110 xLeft
= (xScreen
- 52) / 2;
116 pAttributes
= (PUSHORT
)RtlAllocateHeap(ProcessHeap
,
118 xScreen
* yScreen
* sizeof(USHORT
));
120 DPRINT1("pAttributes %p\n", pAttributes
);
121 ReadConsoleOutputAttributes(pAttributes
,
126 pCharacters
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
128 xScreen
* yScreen
* sizeof(UCHAR
));
130 ReadConsoleOutputCharacters(pCharacters
,
137 /* Draw popup window */
138 SetTextXY(xLeft
, yTop
,
139 "+----------------------------------------------------+");
140 SetTextXY(xLeft
, yTop
+ 1,
141 "| ReactOS 0.0.20 is not completely installed on your |");
142 SetTextXY(xLeft
, yTop
+ 2,
143 "| computer. If you quit Setup now, you will need to |");
144 SetTextXY(xLeft
, yTop
+ 3,
145 "| run Setup again to install ReactOS. |");
146 SetTextXY(xLeft
, yTop
+ 4,
148 SetTextXY(xLeft
, yTop
+ 5,
149 "| * Press ENTER to continue Setup. |");
150 SetTextXY(xLeft
, yTop
+ 6,
151 "| * Press F3 to quit Setup. |");
152 SetTextXY(xLeft
, yTop
+ 7,
153 "+----------------------------------------------------+");
154 SetTextXY(xLeft
, yTop
+ 8,
155 "| F3= Quit ENTER = Continue |");
156 SetTextXY(xLeft
, yTop
+ 9,
157 "+----------------------------------------------------+");
163 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
164 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
169 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
179 WriteConsoleOutputAttributes(pAttributes
,
185 WriteConsoleOutputCharacters(pCharacters
,
190 RtlFreeHeap(ProcessHeap
,
193 RtlFreeHeap(ProcessHeap
,
209 RepairIntroPage(PINPUT_RECORD Ir
)
219 * TRUE: setup/repair completed successfully
220 * FALSE: setup/repair terminated by user
223 IntroPage(PINPUT_RECORD Ir
)
225 SetTextXY(6, 8, "Welcome to the ReactOS Setup");
227 SetTextXY(6, 11, "This part of the setup copies the ReactOS Operating System to your");
228 SetTextXY(6, 12, "computer and prepares the second part of the setup.");
230 SetTextXY(8, 15, "\xf9 Press ENTER to install ReactOS.");
233 SetTextXY(8, 17, "\xf9 Press R to repair ReactOS.");
234 SetTextXY(8, 19, "\xf9 Press F3 to quit without installing ReactOS.");
237 SetTextXY(8, 17, "\xf9 Press F3 to quit without installing ReactOS.");
239 SetStatusText(" ENTER = Continue F3 = Quit");
245 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
246 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
248 if (ConfirmQuit(Ir
) == TRUE
)
252 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
254 return(INSTALL_INTRO_PAGE
);
257 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R')
259 return(REPAIR_INTRO_PAGE
);
269 InstallIntroPage(PINPUT_RECORD Ir
)
271 SetTextXY(6, 8, "Install intro page");
274 SetTextXY(6, 10, "This part of the setup copies the ReactOS Operating System to your");
275 SetTextXY(6, 11, "computer and prepairs the second part of the setup.");
277 SetTextXY(8, 14, "\xf9 Press ENTER to start the ReactOS setup.");
279 SetTextXY(8, 17, "\xf9 Press F3 to quit without installing ReactOS.");
282 SetStatusText(" ENTER = Continue F3 = Quit");
288 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
289 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
291 if (ConfirmQuit(Ir
) == TRUE
)
295 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
297 /* FIXME: Preliminary exit */
298 return(CHOOSE_PARTITION_PAGE
);
302 return(INSTALL_INTRO_PAGE
);
307 ChoosePartitionPage(PINPUT_RECORD Ir
)
309 OBJECT_ATTRIBUTES ObjectAttributes
;
310 SYSTEM_DEVICE_INFORMATION Sdi
;
311 DISK_GEOMETRY DiskGeometry
;
315 IO_STATUS_BLOCK Iosb
;
316 WCHAR Buffer
[MAX_PATH
];
322 DRIVE_LAYOUT_INFORMATION
*LayoutBuffer
;
323 SCSI_ADDRESS ScsiAddress
;
330 SetTextXY(6, 8, "Choose install partition");
332 Status
= NtQuerySystemInformation(SystemDeviceInformation
,
334 sizeof(SYSTEM_DEVICE_INFORMATION
),
336 if (!NT_SUCCESS(Status
))
338 SetTextXY(8, 10, "NtQuerySystemInformation failed!");
341 PrintTextXY(6, 12, "Setup found %lu %s on this computer.",
342 Sdi
.NumberOfDisks
, (Sdi
.NumberOfDisks
== 1) ? "harddisk" : "harddisks");
345 for (DiskCount
= 0; DiskCount
< Sdi
.NumberOfDisks
; DiskCount
++)
348 L
"\\Device\\Harddisk%d\\Partition0",
350 RtlInitUnicodeString(&Name
,
353 InitializeObjectAttributes(&ObjectAttributes
,
359 Status
= NtOpenFile(&FileHandle
,
364 FILE_SYNCHRONOUS_IO_NONALERT
);
365 if (NT_SUCCESS(Status
))
367 Status
= NtDeviceIoControlFile(FileHandle
,
372 IOCTL_DISK_GET_DRIVE_GEOMETRY
,
376 sizeof(DISK_GEOMETRY
));
377 if (NT_SUCCESS(Status
))
379 Status
= NtDeviceIoControlFile(FileHandle
,
384 IOCTL_SCSI_GET_ADDRESS
,
388 sizeof(SCSI_ADDRESS
));
390 if (DiskGeometry
.MediaType
== FixedMedia
)
392 DiskSize
= DiskGeometry
.Cylinders
.QuadPart
*
393 (ULONGLONG
)DiskGeometry
.TracksPerCylinder
*
394 (ULONGLONG
)DiskGeometry
.SectorsPerTrack
*
395 (ULONGLONG
)DiskGeometry
.BytesPerSector
;
397 if (DiskSize
>= 0x120000000ULL
) /* 10 GB */
405 DiskSize
= (DiskSize
+ (1 << 19)) >> 20;
409 PrintTextXY(8, Line
++,
410 "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)",
414 ScsiAddress
.PortNumber
,
416 ScsiAddress
.TargetId
);
418 LayoutBuffer
= (DRIVE_LAYOUT_INFORMATION
*)RtlAllocateHeap(ProcessHeap
, 0, 8192);
420 Status
= NtDeviceIoControlFile(FileHandle
,
425 IOCTL_DISK_GET_DRIVE_LAYOUT
,
430 if (NT_SUCCESS(Status
))
432 for (i
= 0; i
< LayoutBuffer
->PartitionCount
; i
++)
434 if ((LayoutBuffer
->PartitionEntry
[i
].PartitionType
!= PARTITION_ENTRY_UNUSED
) &&
435 !IsContainerPartition(LayoutBuffer
->PartitionEntry
[i
].PartitionType
))
437 if ((LayoutBuffer
->PartitionEntry
[i
].PartitionType
== PARTITION_FAT_12
) ||
438 (LayoutBuffer
->PartitionEntry
[i
].PartitionType
== PARTITION_FAT_16
) ||
439 (LayoutBuffer
->PartitionEntry
[i
].PartitionType
== PARTITION_HUGE
) ||
440 (LayoutBuffer
->PartitionEntry
[i
].PartitionType
== PARTITION_XINT13
))
444 else if ((LayoutBuffer
->PartitionEntry
[i
].PartitionType
== PARTITION_FAT32
) ||
445 (LayoutBuffer
->PartitionEntry
[i
].PartitionType
== PARTITION_FAT32_XINT13
))
449 else if (LayoutBuffer
->PartitionEntry
[i
].PartitionType
== PARTITION_IFS
)
451 PartType
= "NTFS"; /* FIXME: Not quite correct! */
455 PartType
= "Unknown";
458 PrintTextXY(10, Line
++,
459 "%d: nr: %d type: %x (%s) %I64u MB",
461 LayoutBuffer
->PartitionEntry
[i
].PartitionNumber
,
462 LayoutBuffer
->PartitionEntry
[i
].PartitionType
,
464 (LayoutBuffer
->PartitionEntry
[i
].PartitionLength
.QuadPart
+ (1 << 19)) >>20);
472 RtlFreeHeap(ProcessHeap
, 0, LayoutBuffer
);
477 PrintTextXY(8, Line
++,
478 "Harddisk %lu: Failed to retrieve drive geometry (Status %lx)",
487 PrintTextXY(8, Line
++,
488 "Harddisk %lu: Failed to open (Status %lx)",
493 SetStatusText(" ENTER = Continue F3 = Quit");
499 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
500 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
502 if (ConfirmQuit(Ir
) == TRUE
)
506 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
508 return(SELECT_FILE_SYSTEM_PAGE
);
512 return(CHOOSE_PARTITION_PAGE
);
517 SelectFileSystemPage(PINPUT_RECORD Ir
)
520 SetTextXY(6, 8, "Select a file system");
522 SetTextXY(6, 10, "At present, ReactOS can not be installed on unformatted partitions.");
525 SetStatusText(" ENTER = Continue F3 = Quit");
531 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
532 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
534 if (ConfirmQuit(Ir
) == TRUE
)
538 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
540 return(CHECK_FILE_SYSTEM_PAGE
);
544 return(SELECT_FILE_SYSTEM_PAGE
);
549 CheckFileSystemPage(PINPUT_RECORD Ir
)
552 SetTextXY(6, 8, "Check file system");
554 SetTextXY(6, 10, "At present, ReactOS can not check file systems.");
557 SetStatusText(" ENTER = Continue F3 = Quit");
563 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
564 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
566 if (ConfirmQuit(Ir
) == TRUE
)
570 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
572 return(INSTALL_DIRECTORY_PAGE
);
576 return(CHECK_FILE_SYSTEM_PAGE
);
581 InstallDirectoryPage(PINPUT_RECORD Ir
)
584 SetTextXY(6, 8, "Enter the install directory");
586 SetTextXY(6, 12, "Install directory: \reactos");
589 SetStatusText(" ENTER = Continue F3 = Quit");
595 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
596 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
598 if (ConfirmQuit(Ir
) == TRUE
)
602 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
604 return(PREPARE_COPY_PAGE
);
608 return(INSTALL_DIRECTORY_PAGE
);
613 PrepareCopyPage(PINPUT_RECORD Ir
)
616 SetTextXY(6, 8, "Preparing to copy files");
619 SetTextXY(6, 12, "Build file copy list");
621 SetTextXY(6, 14, "Create directories");
624 SetStatusText(" ENTER = Continue F3 = Quit");
630 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
631 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
633 if (ConfirmQuit(Ir
) == TRUE
)
637 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
639 return(FILE_COPY_PAGE
);
643 return(PREPARE_COPY_PAGE
);
648 FileCopyPage(PINPUT_RECORD Ir
)
651 SetTextXY(6, 8, "Copying files");
654 SetStatusText(" ENTER = Continue F3 = Quit");
660 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
661 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
663 if (ConfirmQuit(Ir
) == TRUE
)
667 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
669 return(INIT_SYSTEM_PAGE
);
673 return(FILE_COPY_PAGE
);
678 InitSystemPage(PINPUT_RECORD Ir
)
681 SetTextXY(6, 8, "Initializing system settings");
684 SetTextXY(6, 12, "Create registry hives");
686 SetTextXY(6, 14, "Update registry hives");
688 SetTextXY(6, 16, "Install/update boot manager");
691 SetStatusText(" ENTER = Continue F3 = Quit");
697 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
698 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
700 if (ConfirmQuit(Ir
) == TRUE
)
704 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
706 return(SUCCESS_PAGE
);
710 return(INIT_SYSTEM_PAGE
);
715 QuitPage(PINPUT_RECORD Ir
)
717 SetTextXY(10, 6, "ReactOS is not completely installed");
719 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
720 SetTextXY(10, 9, "all CD-ROMs from CD-Drive.");
722 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
724 SetStatusText(" ENTER = Reboot computer");
730 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
739 SuccessPage(PINPUT_RECORD Ir
)
741 SetTextXY(10, 6, "The basic components of ReactOS have been installed successfully.");
743 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
744 SetTextXY(10, 9, "all CD-ROMs from CD-Drive.");
746 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
748 SetStatusText(" ENTER = Reboot computer");
754 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
763 NtProcessStartup(PPEB Peb
)
769 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
771 ProcessHeap
= Peb
->ProcessHeap
;
773 Status
= AllocConsole();
774 if (!NT_SUCCESS(Status
))
776 PrintString("Console initialization failed! (Status %lx)\n", Status
);
778 /* Raise a hard error (crash the system/BSOD) */
779 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
784 while (Page
!= REBOOT_PAGE
)
788 SetTextXY(4, 3, " ReactOS 0.0.20 Setup ");
789 SetTextXY(4, 4, "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD");
794 Page
= IntroPage(&Ir
);
797 case INSTALL_INTRO_PAGE
:
798 Page
= InstallIntroPage(&Ir
);
802 case OEM_DRIVER_PAGE
:
803 Page
= OemDriverPage(&Ir
);
808 case DEVICE_SETTINGS_PAGE
:
811 case CHOOSE_PARTITION_PAGE
:
812 Page
= ChoosePartitionPage(&Ir
);
815 case SELECT_FILE_SYSTEM_PAGE
:
816 Page
= SelectFileSystemPage(&Ir
);
819 case CHECK_FILE_SYSTEM_PAGE
:
820 Page
= CheckFileSystemPage(&Ir
);
823 case INSTALL_DIRECTORY_PAGE
:
824 Page
= InstallDirectoryPage(&Ir
);
827 case PREPARE_COPY_PAGE
:
828 Page
= PrepareCopyPage(&Ir
);
832 Page
= FileCopyPage(&Ir
);
835 case INIT_SYSTEM_PAGE
:
836 Page
= InitSystemPage(&Ir
);
841 Page
= SuccessPage(&Ir
);
845 Page
= QuitPage(&Ir
);
852 NtShutdownSystem(ShutdownReboot
);