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.5 2002/10/25 22:08:21 chorns 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>
41 #define INSTALL_INTRO_PAGE 1
43 #define SELECT_PARTITION_PAGE 3
44 #define SELECT_FILE_SYSTEM_PAGE 4
45 #define CHECK_FILE_SYSTEM_PAGE 5
46 #define PREPARE_COPY_PAGE 6
47 #define INSTALL_DIRECTORY_PAGE 7
48 #define FILE_COPY_PAGE 8
49 #define INIT_SYSTEM_PAGE 9
51 #define SUCCESS_PAGE 100
53 #define REBOOT_PAGE 102
56 /* GLOBALS ******************************************************************/
60 BOOL PartDataValid
= FALSE
;
66 /* FUNCTIONS ****************************************************************/
69 DisplayString(LPCWSTR lpwString
)
73 RtlInitUnicodeString(&us
, lpwString
);
79 PrintString(char* fmt
,...)
83 UNICODE_STRING UnicodeString
;
84 ANSI_STRING AnsiString
;
87 vsprintf(buffer
, fmt
, ap
);
90 RtlInitAnsiString(&AnsiString
, buffer
);
91 RtlAnsiStringToUnicodeString(&UnicodeString
,
94 NtDisplayString(&UnicodeString
);
95 RtlFreeUnicodeString(&UnicodeString
);
103 * FALSE: Don't quit setup.
106 ConfirmQuit(PINPUT_RECORD Ir
)
113 PUSHORT pAttributes
= NULL
;
114 PUCHAR pCharacters
= NULL
;
117 GetScreenSize(&xScreen
, &yScreen
);
118 yTop
= (yScreen
- 10) / 2;
119 xLeft
= (xScreen
- 52) / 2;
125 pAttributes
= (PUSHORT
)RtlAllocateHeap(ProcessHeap
,
127 xScreen
* yScreen
* sizeof(USHORT
));
129 DPRINT1("pAttributes %p\n", pAttributes
);
130 ReadConsoleOutputAttributes(pAttributes
,
135 pCharacters
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
137 xScreen
* yScreen
* sizeof(UCHAR
));
139 ReadConsoleOutputCharacters(pCharacters
,
146 /* Draw popup window */
147 SetTextXY(xLeft
, yTop
,
148 "+----------------------------------------------------+");
149 SetTextXY(xLeft
, yTop
+ 1,
150 "| ReactOS 0.0.20 is not completely installed on your |");
151 SetTextXY(xLeft
, yTop
+ 2,
152 "| computer. If you quit Setup now, you will need to |");
153 SetTextXY(xLeft
, yTop
+ 3,
154 "| run Setup again to install ReactOS. |");
155 SetTextXY(xLeft
, yTop
+ 4,
157 SetTextXY(xLeft
, yTop
+ 5,
158 "| * Press ENTER to continue Setup. |");
159 SetTextXY(xLeft
, yTop
+ 6,
160 "| * Press F3 to quit Setup. |");
161 SetTextXY(xLeft
, yTop
+ 7,
162 "+----------------------------------------------------+");
163 SetTextXY(xLeft
, yTop
+ 8,
164 "| F3= Quit ENTER = Continue |");
165 SetTextXY(xLeft
, yTop
+ 9,
166 "+----------------------------------------------------+");
172 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
173 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
178 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
188 WriteConsoleOutputAttributes(pAttributes
,
194 WriteConsoleOutputCharacters(pCharacters
,
199 RtlFreeHeap(ProcessHeap
,
202 RtlFreeHeap(ProcessHeap
,
218 RepairIntroPage(PINPUT_RECORD Ir
)
228 * TRUE: setup/repair completed successfully
229 * FALSE: setup/repair terminated by user
232 IntroPage(PINPUT_RECORD Ir
)
234 SetHighlightedTextXY(6, 8, "Welcome to the ReactOS Setup");
236 SetTextXY(6, 11, "This part of the setup copies the ReactOS Operating System to your");
237 SetTextXY(6, 12, "computer and prepares the second part of the setup.");
239 SetTextXY(8, 15, "\xf9 Press ENTER to install ReactOS.");
242 SetTextXY(8, 17, "\xf9 Press R to repair ReactOS.");
243 SetTextXY(8, 19, "\xf9 Press F3 to quit without installing ReactOS.");
246 SetTextXY(8, 17, "\xf9 Press F3 to quit without installing ReactOS.");
248 SetStatusText(" ENTER = Continue F3 = Quit");
254 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
255 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
257 if (ConfirmQuit(Ir
) == TRUE
)
261 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
263 return(INSTALL_INTRO_PAGE
);
266 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R')
268 return(REPAIR_INTRO_PAGE
);
278 InstallIntroPage(PINPUT_RECORD Ir
)
280 SetTextXY(6, 8, "Install intro page");
283 SetTextXY(6, 10, "This part of the setup copies the ReactOS Operating System to your");
284 SetTextXY(6, 11, "computer and prepairs the second part of the setup.");
286 SetTextXY(8, 14, "\xf9 Press ENTER to start the ReactOS setup.");
288 SetTextXY(8, 17, "\xf9 Press F3 to quit without installing ReactOS.");
291 SetStatusText(" ENTER = Continue F3 = Quit");
297 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
298 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
300 if (ConfirmQuit(Ir
) == TRUE
)
304 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
306 return(SELECT_PARTITION_PAGE
);
310 return(INSTALL_INTRO_PAGE
);
315 SelectPartitionPage(PINPUT_RECORD Ir
)
321 SetTextXY(6, 8, "The list below shows existing partitions and unused disk");
322 SetTextXY(6, 9, "space for new partitions.");
324 SetTextXY(8, 11, "\xf9 Press UP or DOWN to select a list entry.");
325 SetTextXY(8, 13, "\xf9 Press ENTER to install ReactOS onto the selected partition.");
326 SetTextXY(8, 15, "\xf9 Press C to create a new partition.");
327 SetTextXY(8, 17, "\xf9 Press D to delete an existing partition.");
329 SetStatusText(" Please wait...");
331 GetScreenSize(&xScreen
, &yScreen
);
333 PartList
= CreatePartitionList(2, 19, xScreen
- 3, yScreen
- 3);
334 if (PartList
== NULL
)
336 /* FIXME: show an error dialog */
340 SetStatusText(" ENTER = Continue F3 = Quit");
346 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
347 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
349 if (ConfirmQuit(Ir
) == TRUE
)
351 DestroyPartitionList(PartList
);
356 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
357 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
))
359 ScrollDownPartitionList(PartList
);
361 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
362 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
))
364 ScrollUpPartitionList(PartList
);
366 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
368 PartDataValid
= GetPartitionData(PartList
, &PartData
);
369 DestroyPartitionList(PartList
);
370 return(SELECT_FILE_SYSTEM_PAGE
);
373 /* FIXME: Update status text */
377 DestroyPartitionList(PartList
);
379 return(SELECT_PARTITION_PAGE
);
384 SelectFileSystemPage(PINPUT_RECORD Ir
)
392 if (PartDataValid
== FALSE
)
394 /* FIXME: show an error dialog */
398 /* adjust disk size */
399 if (PartData
.DiskSize
>= 0x280000000ULL
) /* 10 GB */
401 DiskSize
= (PartData
.DiskSize
+ (1 << 29)) >> 30;
406 DiskSize
= (PartData
.DiskSize
+ (1 << 19)) >> 20;
410 /* adjust partition size */
411 if (PartData
.PartSize
>= 0x280000000ULL
) /* 10 GB */
413 PartSize
= (PartData
.PartSize
+ (1 << 29)) >> 30;
418 PartSize
= (PartData
.PartSize
+ (1 << 19)) >> 20;
422 /* adjust partition type */
423 if ((PartData
.PartType
== PARTITION_FAT_12
) ||
424 (PartData
.PartType
== PARTITION_FAT_16
) ||
425 (PartData
.PartType
== PARTITION_HUGE
) ||
426 (PartData
.PartType
== PARTITION_XINT13
))
430 else if ((PartData
.PartType
== PARTITION_FAT32
) ||
431 (PartData
.PartType
== PARTITION_FAT32_XINT13
))
435 else if (PartData
.PartType
== PARTITION_IFS
)
437 PartType
= "NTFS"; /* FIXME: Not quite correct! */
441 PartType
= "Unknown";
444 SetTextXY(6, 8, "ReactOS will be installed");
446 PrintTextXY(8, 9, "on Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu.",
454 PrintTextXY(8, 10, "on Partition %lu (%I64u %s) %s",
460 SetTextXY(6, 13, "Select a file system for the partition from the list below.");
462 SetTextXY(8, 15, "\xf9 Press UP or DOWN to select a file system.");
463 SetTextXY(8, 17, "\xf9 Press ENTER to format the partition.");
464 SetTextXY(8, 19, "\xf9 Press ESC to select another partition.");
466 /* FIXME: use a real list later */
467 SetInvertedTextXY(6, 22, " Keep current file system (no changes) ");
470 SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit");
476 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
477 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
479 if (ConfirmQuit(Ir
) == TRUE
)
483 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x1B) /* ESC */
485 return(SELECT_PARTITION_PAGE
);
487 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
489 return(CHECK_FILE_SYSTEM_PAGE
);
493 return(SELECT_FILE_SYSTEM_PAGE
);
498 CheckFileSystemPage(PINPUT_RECORD Ir
)
501 SetTextXY(6, 8, "Check file system");
503 SetTextXY(6, 10, "At present, ReactOS can not check file systems.");
506 SetStatusText(" ENTER = Continue F3 = Quit");
512 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
513 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
515 if (ConfirmQuit(Ir
) == TRUE
)
519 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
521 return(INSTALL_DIRECTORY_PAGE
);
525 return(CHECK_FILE_SYSTEM_PAGE
);
530 InstallDirectoryPage(PINPUT_RECORD Ir
)
534 SetTextXY(6, 8, "Setup installs ReactOS files onto the selected partition. Choose a");
535 SetTextXY(6, 9, "directory where you want ReactOS to be installed:");
537 strcpy(InstallDir
, "\\reactos");
538 Length
= strlen(InstallDir
);
540 SetInputTextXY(8, 11, 51, InstallDir
);
542 SetTextXY(6, 14, "To change the suggested directory, press BACKSPACE to delete");
543 SetTextXY(6, 15, "characters and then type the directory where you want ReactOS to");
544 SetTextXY(6, 16, "be installed.");
547 SetStatusText(" ENTER = Continue F3 = Quit");
553 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
554 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
556 if (ConfirmQuit(Ir
) == TRUE
)
560 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* Return */
562 return(PREPARE_COPY_PAGE
);
564 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* Backspace */
569 InstallDir
[Length
] = 0;
570 SetInputTextXY(8, 11, 51, InstallDir
);
573 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
577 InstallDir
[Length
] = Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
579 InstallDir
[Length
] = 0;
580 SetInputTextXY(8, 11, 51, InstallDir
);
585 return(INSTALL_DIRECTORY_PAGE
);
590 PrepareCopyPage(PINPUT_RECORD Ir
)
593 SetTextXY(6, 8, "Preparing to copy files");
596 SetTextXY(6, 12, "Build file copy list");
598 SetTextXY(6, 14, "Create directories");
600 SetStatusText(" Please wait...");
605 SetStatusText(" ENTER = Continue F3 = Quit");
611 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
612 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
614 if (ConfirmQuit(Ir
) == TRUE
)
618 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
620 return(FILE_COPY_PAGE
);
624 return(PREPARE_COPY_PAGE
);
629 FileCopyPage(PINPUT_RECORD Ir
)
632 SetTextXY(6, 8, "Copying files");
635 SetStatusText(" ENTER = Continue F3 = Quit");
641 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
642 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
644 if (ConfirmQuit(Ir
) == TRUE
)
648 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
650 return(INIT_SYSTEM_PAGE
);
654 return(FILE_COPY_PAGE
);
659 InitSystemPage(PINPUT_RECORD Ir
)
662 SetTextXY(6, 8, "Initializing system settings");
665 SetTextXY(6, 12, "Create registry hives");
667 SetTextXY(6, 14, "Update registry hives");
669 SetTextXY(6, 16, "Install/update boot manager");
672 SetStatusText(" ENTER = Continue F3 = Quit");
678 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
679 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
))
681 if (ConfirmQuit(Ir
) == TRUE
)
685 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
687 return(SUCCESS_PAGE
);
691 return(INIT_SYSTEM_PAGE
);
696 QuitPage(PINPUT_RECORD Ir
)
698 SetTextXY(10, 6, "ReactOS is not completely installed");
700 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
701 SetTextXY(10, 9, "all CD-ROMs from CD-Drive.");
703 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
705 SetStatusText(" ENTER = Reboot computer");
711 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
720 SuccessPage(PINPUT_RECORD Ir
)
722 SetTextXY(10, 6, "The basic components of ReactOS have been installed successfully.");
724 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
725 SetTextXY(10, 9, "all CD-ROMs from CD-Drive.");
727 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
729 SetStatusText(" ENTER = Reboot computer");
735 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
744 NtProcessStartup(PPEB Peb
)
750 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
752 ProcessHeap
= Peb
->ProcessHeap
;
754 Status
= AllocConsole();
755 if (!NT_SUCCESS(Status
))
757 PrintString("Console initialization failed! (Status %lx)\n", Status
);
759 /* Raise a hard error (crash the system/BSOD) */
760 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
765 while (Page
!= REBOOT_PAGE
)
769 SetUnderlinedTextXY(4, 3, " ReactOS 0.0.20 Setup ");
774 Page
= IntroPage(&Ir
);
777 case INSTALL_INTRO_PAGE
:
778 Page
= InstallIntroPage(&Ir
);
782 case OEM_DRIVER_PAGE
:
783 Page
= OemDriverPage(&Ir
);
788 case DEVICE_SETTINGS_PAGE
:
791 case SELECT_PARTITION_PAGE
:
792 Page
= SelectPartitionPage(&Ir
);
795 case SELECT_FILE_SYSTEM_PAGE
:
796 Page
= SelectFileSystemPage(&Ir
);
799 case CHECK_FILE_SYSTEM_PAGE
:
800 Page
= CheckFileSystemPage(&Ir
);
803 case INSTALL_DIRECTORY_PAGE
:
804 Page
= InstallDirectoryPage(&Ir
);
807 case PREPARE_COPY_PAGE
:
808 Page
= PrepareCopyPage(&Ir
);
812 Page
= FileCopyPage(&Ir
);
815 case INIT_SYSTEM_PAGE
:
816 Page
= InitSystemPage(&Ir
);
821 Page
= SuccessPage(&Ir
);
825 Page
= QuitPage(&Ir
);
832 NtShutdownSystem(ShutdownReboot
);