diff --git a/reactos/subsys/system/usetup/console.c b/reactos/subsys/system/usetup/console.c index c96f36769d5..f0f9fa74957 100644 --- a/reactos/subsys/system/usetup/console.c +++ b/reactos/subsys/system/usetup/console.c @@ -830,6 +830,11 @@ ClearScreen(VOID) coPos.X = 0; coPos.Y = 0; + FillConsoleOutputAttribute(0x17, + xScreen * yScreen, + coPos, + &Written); + FillConsoleOutputCharacter(' ', xScreen * yScreen, coPos, @@ -876,6 +881,114 @@ SetTextXY(SHORT x, SHORT y, PCHAR Text) } +VOID +SetInputTextXY(SHORT x, SHORT y, SHORT len, PCHAR Text) +{ + COORD coPos; + ULONG Length; + ULONG Written; + + coPos.X = x; + coPos.Y = y; + + Length = strlen(Text); + + FillConsoleOutputAttribute(0x70, + len, + coPos, + &Written); + + WriteConsoleOutputCharacters(Text, + Length, + coPos); + + coPos.X += Length; + FillConsoleOutputCharacter('_', + 1, + coPos, + &Written); + + if (len > Length + 1) + { + coPos.X++; + FillConsoleOutputCharacter(' ', + len - Length - 1, + coPos, + &Written); + } +} + + +VOID +SetUnderlinedTextXY(SHORT x, SHORT y, PCHAR Text) +{ + COORD coPos; + ULONG Length; + ULONG Written; + + coPos.X = x; + coPos.Y = y; + + Length = strlen(Text); + + WriteConsoleOutputCharacters(Text, + Length, + coPos); + + coPos.Y++; + FillConsoleOutputCharacter(0xCD, + Length, + coPos, + &Written); +} + + +VOID +SetInvertedTextXY(SHORT x, SHORT y, PCHAR Text) +{ + COORD coPos; + ULONG Length; + ULONG Written; + + coPos.X = x; + coPos.Y = y; + + Length = strlen(Text); + + FillConsoleOutputAttribute(0x71, + Length, + coPos, + &Written); + + WriteConsoleOutputCharacters(Text, + Length, + coPos); +} + + +VOID +SetHighlightedTextXY(SHORT x, SHORT y, PCHAR Text) +{ + COORD coPos; + ULONG Length; + ULONG Written; + + coPos.X = x; + coPos.Y = y; + + Length = strlen(Text); + + FillConsoleOutputAttribute(0x1F, + Length, + coPos, + &Written); + + WriteConsoleOutputCharacters(Text, + Length, + coPos); +} + + VOID PrintTextXY(SHORT x, SHORT y, char* fmt,...) { diff --git a/reactos/subsys/system/usetup/makefile b/reactos/subsys/system/usetup/makefile index 6b16ce7e0e6..42dae1779fa 100644 --- a/reactos/subsys/system/usetup/makefile +++ b/reactos/subsys/system/usetup/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.1 2002/09/08 18:28:43 ekohl Exp $ +# $Id: makefile,v 1.2 2002/10/18 20:04:00 ekohl Exp $ PATH_TO_TOP = ../../.. @@ -12,7 +12,7 @@ TARGET_INSTALLDIR = system32 TARGET_CFLAGS = -D__NTAPP__ -TARGET_OBJECTS = $(TARGET_NAME).o console.o +TARGET_OBJECTS = $(TARGET_NAME).o console.o partlist.o include $(PATH_TO_TOP)/rules.mak diff --git a/reactos/subsys/system/usetup/partlist.c b/reactos/subsys/system/usetup/partlist.c new file mode 100644 index 00000000000..b3f1fce67ab --- /dev/null +++ b/reactos/subsys/system/usetup/partlist.c @@ -0,0 +1,621 @@ +/* + * partlist.c + */ + +#include +#include + +#include + +#include +#include + +#include "usetup.h" +#include "partlist.h" + + + + +PPARTLIST +CreatePartitionList(SHORT Left, + SHORT Top, + SHORT Right, + SHORT Bottom) +{ + PPARTLIST List; + OBJECT_ATTRIBUTES ObjectAttributes; + SYSTEM_DEVICE_INFORMATION Sdi; + DISK_GEOMETRY DiskGeometry; + ULONG ReturnSize; + NTSTATUS Status; + ULONG DiskCount; + IO_STATUS_BLOCK Iosb; + WCHAR Buffer[MAX_PATH]; + UNICODE_STRING Name; + HANDLE FileHandle; + DRIVE_LAYOUT_INFORMATION *LayoutBuffer; + SCSI_ADDRESS ScsiAddress; + ULONG i; + + List = (PPARTLIST)RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTLIST)); + if (List == NULL) + return(NULL); + + List->Left = Left; + List->Top = Top; + List->Right = Right; + List->Bottom = Bottom; + + List->TopDisk = (ULONG)-1; + List->TopPartition = (ULONG)-1; + + List->CurrentDisk = (ULONG)-1; + List->CurrentPartition = (ULONG)-1; + + List->DiskCount = 0; + List->DiskArray = NULL; + + + Status = NtQuerySystemInformation(SystemDeviceInformation, + &Sdi, + sizeof(SYSTEM_DEVICE_INFORMATION), + &ReturnSize); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, List); + return(NULL); + } + + List->DiskArray = (PDISKENTRY)RtlAllocateHeap(ProcessHeap, + 0, + Sdi.NumberOfDisks * sizeof(DISKENTRY)); + List->DiskCount = Sdi.NumberOfDisks; + + for (DiskCount = 0; DiskCount < Sdi.NumberOfDisks; DiskCount++) + { + swprintf(Buffer, + L"\\Device\\Harddisk%d\\Partition0", + DiskCount); + RtlInitUnicodeString(&Name, + Buffer); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + 0x10001, + &ObjectAttributes, + &Iosb, + 1, + FILE_SYNCHRONOUS_IO_NONALERT); + if (NT_SUCCESS(Status)) + { + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_GET_DRIVE_GEOMETRY, + NULL, + 0, + &DiskGeometry, + sizeof(DISK_GEOMETRY)); + if (NT_SUCCESS(Status)) + { + if (DiskGeometry.MediaType == FixedMedia) + { + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_SCSI_GET_ADDRESS, + NULL, + 0, + &ScsiAddress, + sizeof(SCSI_ADDRESS)); + + + List->DiskArray[DiskCount].DiskSize = + DiskGeometry.Cylinders.QuadPart * + (ULONGLONG)DiskGeometry.TracksPerCylinder * + (ULONGLONG)DiskGeometry.SectorsPerTrack * + (ULONGLONG)DiskGeometry.BytesPerSector; + List->DiskArray[DiskCount].DiskNumber = DiskCount; + List->DiskArray[DiskCount].Port = ScsiAddress.PortNumber; + List->DiskArray[DiskCount].Bus = ScsiAddress.PathId; + List->DiskArray[DiskCount].Id = ScsiAddress.TargetId; + + List->DiskArray[DiskCount].FixedDisk = TRUE; + + + LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192); + + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_GET_DRIVE_LAYOUT, + NULL, + 0, + LayoutBuffer, + 8192); + if (NT_SUCCESS(Status)) + { + + List->DiskArray[DiskCount].PartArray = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, + 0, + LayoutBuffer->PartitionCount * sizeof(PARTENTRY)); + List->DiskArray[DiskCount].PartCount = LayoutBuffer->PartitionCount; + + for (i = 0; i < LayoutBuffer->PartitionCount; i++) + { + if ((LayoutBuffer->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED) && + !IsContainerPartition(LayoutBuffer->PartitionEntry[i].PartitionType)) + { + List->DiskArray[DiskCount].PartArray[i].PartSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart; + List->DiskArray[DiskCount].PartArray[i].PartNumber = LayoutBuffer->PartitionEntry[i].PartitionNumber, + List->DiskArray[DiskCount].PartArray[i].PartType = LayoutBuffer->PartitionEntry[i].PartitionType; + List->DiskArray[DiskCount].PartArray[i].Used = TRUE; + } + else + { + List->DiskArray[DiskCount].PartArray[i].Used = FALSE; + } + } + } + + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + } + else + { + /* mark removable disk entry */ + List->DiskArray[DiskCount].FixedDisk = FALSE; + List->DiskArray[DiskCount].PartCount = 0; + List->DiskArray[DiskCount].PartArray = NULL; + } + } + + NtClose(FileHandle); + } + } + + List->TopDisk = 0; + List->TopPartition = 0; + + /* FIXME: search for first usable disk and partition */ + List->CurrentDisk = 0; + List->CurrentPartition = 0; + + DrawPartitionList(List); + + return(List); +} + + +VOID +DestroyPartitionList(PPARTLIST List) +{ + ULONG i; +#if 0 + COORD coPos; + USHORT Width; + + /* clear occupied screen area */ + coPos.X = List->Left; + Width = List->Right - List->Left + 1; + for (coPos.Y = List->Top; coPos.Y <= List->Bottom; coPos.Y++) + { + FillConsoleOutputAttribute(0x17, + Width, + coPos, + &i); + + FillConsoleOutputCharacter(' ', + Width, + coPos, + &i); + } +#endif + + /* free disk and partition info */ + if (List->DiskArray != NULL) + { + /* free partition arrays */ + for (i = 0; i < List->DiskCount; i++) + { + if (List->DiskArray[i].PartArray != NULL) + { + RtlFreeHeap(ProcessHeap, 0, List->DiskArray[i].PartArray); + List->DiskArray[i].PartCount = 0; + List->DiskArray[i].PartArray = NULL; + } + } + + /* free disk array */ + RtlFreeHeap(ProcessHeap, 0, List->DiskArray); + List->DiskCount = 0; + List->DiskArray = NULL; + } + + /* free list head */ + RtlFreeHeap(ProcessHeap, 0, List); +} + + +static VOID +PrintEmptyLine(PPARTLIST List, USHORT Line) +{ + COORD coPos; + ULONG Written; + USHORT Width; + USHORT Height; + + Width = List->Right - List->Left - 1; + Height = List->Bottom - List->Top - 1; + + if (Line > Height) + return; + + coPos.X = List->Left + 1; + coPos.Y = List->Top + 1 + Line; + + + FillConsoleOutputAttribute(0x17, + Width, + coPos, + &Written); + + FillConsoleOutputCharacter(' ', + Width, + coPos, + &Written); +} + + +static VOID +PrintDiskLine(PPARTLIST List, USHORT Line, PCHAR Text) +{ + COORD coPos; + ULONG Written; + USHORT Width; + USHORT Height; + + Width = List->Right - List->Left - 1; + Height = List->Bottom - List->Top - 1; + + if (Line > Height) + return; + + coPos.X = List->Left + 1; + coPos.Y = List->Top + 1 + Line; + + + FillConsoleOutputAttribute(0x17, + Width, + coPos, + &Written); + + FillConsoleOutputCharacter(' ', + Width, + coPos, + &Written); + + if (Text != NULL) + { + coPos.X++; + WriteConsoleOutputCharacters(Text, + min(strlen(Text), Width - 2), + coPos); + } +} + + +static VOID +PrintPartitionLine(PPARTLIST List, USHORT Line, PCHAR Text, BOOL Selected) +{ + COORD coPos; + ULONG Written; + USHORT Width; + USHORT Height; + + Width = List->Right - List->Left - 1; + Height = List->Bottom - List->Top - 1; + + if (Line > Height) + return; + + coPos.X = List->Left + 1; + coPos.Y = List->Top + 1 + Line; + + FillConsoleOutputCharacter(' ', + Width, + coPos, + &Written); + + coPos.X += 4; + Width -= 8; + FillConsoleOutputAttribute((Selected == TRUE)? 0x71 : 0x17, + Width, + coPos, + &Written); + + coPos.X++; + Width -= 2; + WriteConsoleOutputCharacters(Text, + min(strlen(Text), Width), + coPos); +} + + + +VOID +DrawPartitionList(PPARTLIST List) +{ + CHAR LineBuffer[128]; + COORD coPos; + ULONG Written; + SHORT i; + SHORT j; + ULONGLONG DiskSize; + PCHAR Unit; + USHORT Line; + PCHAR PartType; + + /* draw upper left corner */ + coPos.X = List->Left; + coPos.Y = List->Top; + FillConsoleOutputCharacter(0xDA, // '+', + 1, + coPos, + &Written); + + /* draw upper edge */ + coPos.X = List->Left + 1; + coPos.Y = List->Top; + FillConsoleOutputCharacter(0xC4, // '-', + List->Right - List->Left - 1, + coPos, + &Written); + + /* draw upper right corner */ + coPos.X = List->Right; + coPos.Y = List->Top; + FillConsoleOutputCharacter(0xBF, // '+', + 1, + coPos, + &Written); + + /* draw left and right edge */ + for (i = List->Top + 1; i < List->Bottom; i++) + { + coPos.X = List->Left; + coPos.Y = i; + FillConsoleOutputCharacter(0xB3, // '|', + 1, + coPos, + &Written); + + coPos.X = List->Right; + FillConsoleOutputCharacter(0xB3, //'|', + 1, + coPos, + &Written); + } + + /* draw lower left corner */ + coPos.X = List->Left; + coPos.Y = List->Bottom; + FillConsoleOutputCharacter(0xC0, // '+', + 1, + coPos, + &Written); + + /* draw lower edge */ + coPos.X = List->Left + 1; + coPos.Y = List->Bottom; + FillConsoleOutputCharacter(0xC4, // '-', + List->Right - List->Left - 1, + coPos, + &Written); + + /* draw upper right corner */ + coPos.X = List->Right; + coPos.Y = List->Bottom; + FillConsoleOutputCharacter(0xD9, // '+', + 1, + coPos, + &Written); + + /* print list entries */ + Line = 0; + for (i = 0; i < List->DiskCount; i++) + { + if (List->DiskArray[i].FixedDisk == TRUE) + { + /* print disk entry */ + if (List->DiskArray[i].DiskSize >= 0x280000000ULL) /* 10 GB */ + { + DiskSize = (List->DiskArray[i].DiskSize + (1 << 29)) >> 30; + Unit = "GB"; + } + else + { + DiskSize = (List->DiskArray[i].DiskSize + (1 << 19)) >> 20; + Unit = "MB"; + } + + sprintf(LineBuffer, + "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)", + DiskSize, + Unit, + List->DiskArray[i].DiskNumber, + List->DiskArray[i].Port, + List->DiskArray[i].Bus, + List->DiskArray[i].Id); + PrintDiskLine(List, Line, LineBuffer); + Line++; + + /* print separator line */ + PrintEmptyLine(List, Line); + Line++; + + /* print partition lines*/ + for (j = 0; j < List->DiskArray[i].PartCount; j++) + { + if (List->DiskArray[i].PartArray[j].Used == TRUE) + { + if ((List->DiskArray[i].PartArray[j].PartType == PARTITION_FAT_12) || + (List->DiskArray[i].PartArray[j].PartType == PARTITION_FAT_16) || + (List->DiskArray[i].PartArray[j].PartType == PARTITION_HUGE) || + (List->DiskArray[i].PartArray[j].PartType == PARTITION_XINT13)) + { + PartType = "FAT"; + } + else if ((List->DiskArray[i].PartArray[j].PartType == PARTITION_FAT32) || + (List->DiskArray[i].PartArray[j].PartType == PARTITION_FAT32_XINT13)) + { + PartType = "FAT32"; + } + else if (List->DiskArray[i].PartArray[j].PartType == PARTITION_IFS) + { + PartType = "NTFS"; /* FIXME: Not quite correct! */ + } + else + { + PartType = "Unknown"; + } + + sprintf(LineBuffer, + "%d: nr: %d type: %x (%s) %I64u MB", + j, + List->DiskArray[i].PartArray[j].PartNumber, + List->DiskArray[i].PartArray[j].PartType, + PartType, + (List->DiskArray[i].PartArray[j].PartSize + (1 << 19)) >> 20); + PrintPartitionLine(List, Line, LineBuffer, + (List->CurrentDisk == i && List->CurrentPartition == j)); // FALSE); + Line++; + + + } + } + + /* print separator line */ + PrintEmptyLine(List, Line); + Line++; + } + } + +} + + +VOID +ScrollDownPartitionList(PPARTLIST List) +{ + ULONG i; + ULONG j; + + /* check for available disks */ + if (List->DiskCount == 0) + return; + + /* check for next usable entry on current disk */ + for (i = List->CurrentPartition + 1; i < List->DiskArray[List->CurrentDisk].PartCount; i++) + { + if (List->DiskArray[List->CurrentDisk].PartArray[i].Used == TRUE) + { + List->CurrentPartition = i; + DrawPartitionList(List); + return; + } + } + + /* check for first usable entry on next disk */ + for (j = List->CurrentDisk + 1; j < List->DiskCount; j++) + { + for (i = 0; i < List->DiskArray[j].PartCount; i++) + { + if (List->DiskArray[j].PartArray[i].Used == TRUE) + { + List->CurrentDisk = j; + List->CurrentPartition = i; + DrawPartitionList(List); + return; + } + } + } +} + + +VOID +ScrollUpPartitionList(PPARTLIST List) +{ + ULONG i; + ULONG j; + + /* check for available disks */ + if (List->DiskCount == 0) + return; + + /* check for previous usable entry on current disk */ + for (i = List->CurrentPartition - 1; i != (ULONG)-1; i--) + { + if (List->DiskArray[List->CurrentDisk].PartArray[i].Used == TRUE) + { + List->CurrentPartition = i; + DrawPartitionList(List); + return; + } + } + + /* check for last usable entry on previous disk */ + for (j = List->CurrentDisk - 1; j != (ULONG)-1; j--) + { + for (i = List->DiskArray[j].PartCount - 1; i != (ULONG)-1; i--) + { + if (List->DiskArray[j].PartArray[i].Used == TRUE) + { + List->CurrentDisk = j; + List->CurrentPartition = i; + DrawPartitionList(List); + return; + } + } + } +} + + +BOOL +GetPartitionData(PPARTLIST List, PPARTDATA Data) +{ + if (List->CurrentDisk >= List->DiskCount) + return(FALSE); + + if (List->DiskArray[List->CurrentDisk].FixedDisk == FALSE) + return(FALSE); + + if (List->CurrentPartition >= List->DiskArray[List->CurrentDisk].PartCount) + return(FALSE); + + if (List->DiskArray[List->CurrentDisk].PartArray[List->CurrentPartition].Used == FALSE) + return(FALSE); + + Data->DiskSize = List->DiskArray[List->CurrentDisk].DiskSize; + Data->DiskNumber = List->DiskArray[List->CurrentDisk].DiskNumber; + Data->Port = List->DiskArray[List->CurrentDisk].Port; + Data->Bus = List->DiskArray[List->CurrentDisk].Bus; + Data->Id = List->DiskArray[List->CurrentDisk].Id; + + Data->PartSize = List->DiskArray[List->CurrentDisk].PartArray[List->CurrentPartition].PartSize; + Data->PartNumber = List->DiskArray[List->CurrentDisk].PartArray[List->CurrentPartition].PartNumber; + Data->PartType = List->DiskArray[List->CurrentDisk].PartArray[List->CurrentPartition].PartType; + + return(TRUE); +} + +/* EOF */ diff --git a/reactos/subsys/system/usetup/partlist.h b/reactos/subsys/system/usetup/partlist.h new file mode 100644 index 00000000000..ecd16d34b53 --- /dev/null +++ b/reactos/subsys/system/usetup/partlist.h @@ -0,0 +1,84 @@ +/* + * partlist.h + */ + + +typedef struct _PARTDATA +{ + ULONGLONG DiskSize; + ULONG DiskNumber; + USHORT Port; + USHORT Bus; + USHORT Id; + ULONGLONG PartSize; + ULONG PartNumber; + ULONG PartType; +} PARTDATA, *PPARTDATA; + + +typedef struct _PARTENTRY +{ + ULONGLONG PartSize; + ULONG PartNumber; + ULONG PartType; + BOOL Used; +} PARTENTRY, *PPARTENTRY; + +typedef struct _DISKENTRY +{ + ULONGLONG DiskSize; + ULONG DiskNumber; + USHORT Port; + USHORT Bus; + USHORT Id; + BOOL FixedDisk; + + ULONG PartCount; + PPARTENTRY PartArray; + +} DISKENTRY, *PDISKENTRY; + + +typedef struct _PARTLIST +{ + SHORT Left; + SHORT Top; + SHORT Right; + SHORT Bottom; + + ULONG TopDisk; + ULONG TopPartition; + + ULONG CurrentDisk; + ULONG CurrentPartition; + + ULONG DiskCount; + PDISKENTRY DiskArray; + +} PARTLIST, *PPARTLIST; + + + + +PPARTLIST +CreatePartitionList(SHORT Left, + SHORT Top, + SHORT Right, + SHORT Bottom); + +VOID +DestroyPartitionList(PPARTLIST List); + +VOID +DrawPartitionList(PPARTLIST List); + +VOID +ScrollDownPartitionList(PPARTLIST List); + +VOID +ScrollUpPartitionList(PPARTLIST List); + +BOOL +GetPartitionData(PPARTLIST List, PPARTDATA Data); + +/* EOF */ \ No newline at end of file diff --git a/reactos/subsys/system/usetup/usetup.c b/reactos/subsys/system/usetup/usetup.c index 06d5cef606c..9726e7c2a90 100644 --- a/reactos/subsys/system/usetup/usetup.c +++ b/reactos/subsys/system/usetup/usetup.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: usetup.c,v 1.3 2002/09/25 14:48:35 ekohl Exp $ +/* $Id: usetup.c,v 1.4 2002/10/18 20:04:00 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user-mode setup application @@ -34,12 +34,13 @@ #include #include "usetup.h" +#include "partlist.h" #define INTRO_PAGE 0 #define INSTALL_INTRO_PAGE 1 -#define CHOOSE_PARTITION_PAGE 3 +#define SELECT_PARTITION_PAGE 3 #define SELECT_FILE_SYSTEM_PAGE 4 #define CHECK_FILE_SYSTEM_PAGE 5 #define PREPARE_COPY_PAGE 6 @@ -52,8 +53,16 @@ #define REBOOT_PAGE 102 +/* GLOBALS ******************************************************************/ + HANDLE ProcessHeap; +BOOL PartDataValid = FALSE; +PARTDATA PartData; + +CHAR InstallDir[51]; + + /* FUNCTIONS ****************************************************************/ void @@ -222,7 +231,7 @@ RepairIntroPage(PINPUT_RECORD Ir) static ULONG IntroPage(PINPUT_RECORD Ir) { - SetTextXY(6, 8, "Welcome to the ReactOS Setup"); + SetHighlightedTextXY(6, 8, "Welcome to the ReactOS Setup"); SetTextXY(6, 11, "This part of the setup copies the ReactOS Operating System to your"); SetTextXY(6, 12, "computer and prepares the second part of the setup."); @@ -294,8 +303,7 @@ InstallIntroPage(PINPUT_RECORD Ir) } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) { - /* FIXME: Preliminary exit */ - return(CHOOSE_PARTITION_PAGE); + return(SELECT_PARTITION_PAGE); } } @@ -304,190 +312,29 @@ InstallIntroPage(PINPUT_RECORD Ir) static ULONG -ChoosePartitionPage(PINPUT_RECORD Ir) +SelectPartitionPage(PINPUT_RECORD Ir) { - OBJECT_ATTRIBUTES ObjectAttributes; - SYSTEM_DEVICE_INFORMATION Sdi; - DISK_GEOMETRY DiskGeometry; - ULONG ReturnSize; - NTSTATUS Status; - ULONG DiskCount; - IO_STATUS_BLOCK Iosb; - WCHAR Buffer[MAX_PATH]; - UNICODE_STRING Name; - HANDLE FileHandle; - ULONG Line; - ULONG i; + PPARTLIST PartList; + SHORT xScreen; + SHORT yScreen; - DRIVE_LAYOUT_INFORMATION *LayoutBuffer; - SCSI_ADDRESS ScsiAddress; - ULONGLONG DiskSize; - char *Scale; - char *PartType; + SetTextXY(6, 8, "The list below shows existing partitions and unused disk"); + SetTextXY(6, 9, "space for new partitions."); + SetTextXY(8, 11, "\xf9 Press UP or DOWN to select a list entry."); + SetTextXY(8, 13, "\xf9 Press ENTER to install ReactOS onto the selected partition."); + SetTextXY(8, 15, "\xf9 Press C to create a new partition."); + SetTextXY(8, 17, "\xf9 Press D to delete an existing partition."); + SetStatusText(" Please wait..."); - SetTextXY(6, 8, "Choose install partition"); + GetScreenSize(&xScreen, &yScreen); - Status = NtQuerySystemInformation(SystemDeviceInformation, - &Sdi, - sizeof(SYSTEM_DEVICE_INFORMATION), - &ReturnSize); - if (!NT_SUCCESS(Status)) + PartList = CreatePartitionList(2, 19, xScreen - 3, yScreen - 3); + if (PartList == NULL) { - SetTextXY(8, 10, "NtQuerySystemInformation failed!"); - } - - PrintTextXY(6, 12, "Setup found %lu %s on this computer.", - Sdi.NumberOfDisks, (Sdi.NumberOfDisks == 1) ? "harddisk" : "harddisks"); - - Line = 14; - for (DiskCount = 0; DiskCount < Sdi.NumberOfDisks; DiskCount++) - { - swprintf(Buffer, - L"\\Device\\Harddisk%d\\Partition0", - DiskCount); - RtlInitUnicodeString(&Name, - Buffer); - - InitializeObjectAttributes(&ObjectAttributes, - &Name, - 0, - NULL, - NULL); - - Status = NtOpenFile(&FileHandle, - 0x10001, - &ObjectAttributes, - &Iosb, - 1, - FILE_SYNCHRONOUS_IO_NONALERT); - if (NT_SUCCESS(Status)) - { - Status = NtDeviceIoControlFile(FileHandle, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_DISK_GET_DRIVE_GEOMETRY, - NULL, - 0, - &DiskGeometry, - sizeof(DISK_GEOMETRY)); - if (NT_SUCCESS(Status)) - { - Status = NtDeviceIoControlFile(FileHandle, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_SCSI_GET_ADDRESS, - NULL, - 0, - &ScsiAddress, - sizeof(SCSI_ADDRESS)); - - if (DiskGeometry.MediaType == FixedMedia) - { - DiskSize = DiskGeometry.Cylinders.QuadPart * - (ULONGLONG)DiskGeometry.TracksPerCylinder * - (ULONGLONG)DiskGeometry.SectorsPerTrack * - (ULONGLONG)DiskGeometry.BytesPerSector; -#if 0 - if (DiskSize >= 0x120000000ULL) /* 10 GB */ - { - DiskSize - Scale = "GB"; - } - else -#endif - { - DiskSize = (DiskSize + (1 << 19)) >> 20; - Scale = "MB"; - } - - PrintTextXY(8, Line++, - "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)", - DiskSize, - Scale, - DiskCount, - ScsiAddress.PortNumber, - ScsiAddress.PathId, - ScsiAddress.TargetId); - - LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192); - - Status = NtDeviceIoControlFile(FileHandle, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_DISK_GET_DRIVE_LAYOUT, - NULL, - 0, - LayoutBuffer, - 8192); - if (NT_SUCCESS(Status)) - { - for (i = 0; i < LayoutBuffer->PartitionCount; i++) - { - if ((LayoutBuffer->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED) && - !IsContainerPartition(LayoutBuffer->PartitionEntry[i].PartitionType)) - { - if ((LayoutBuffer->PartitionEntry[i].PartitionType == PARTITION_FAT_12) || - (LayoutBuffer->PartitionEntry[i].PartitionType == PARTITION_FAT_16) || - (LayoutBuffer->PartitionEntry[i].PartitionType == PARTITION_HUGE) || - (LayoutBuffer->PartitionEntry[i].PartitionType == PARTITION_XINT13)) - { - PartType = "FAT"; - } - else if ((LayoutBuffer->PartitionEntry[i].PartitionType == PARTITION_FAT32) || - (LayoutBuffer->PartitionEntry[i].PartitionType == PARTITION_FAT32_XINT13)) - { - PartType = "FAT32"; - } - else if (LayoutBuffer->PartitionEntry[i].PartitionType == PARTITION_IFS) - { - PartType = "NTFS"; /* FIXME: Not quite correct! */ - } - else - { - PartType = "Unknown"; - } - - PrintTextXY(10, Line++, - "%d: nr: %d type: %x (%s) %I64u MB", - i, - LayoutBuffer->PartitionEntry[i].PartitionNumber, - LayoutBuffer->PartitionEntry[i].PartitionType, - PartType, - (LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart + (1 << 19)) >>20); - - - - } - } - } - - RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); - } - } - else - { - PrintTextXY(8, Line++, - "Harddisk %lu: Failed to retrieve drive geometry (Status %lx)", - DiskCount, Status); - } - - NtClose(FileHandle); - Line++; - } - else - { - PrintTextXY(8, Line++, - "Harddisk %lu: Failed to open (Status %lx)", - DiskCount, Status); - } + /* FIXME: show an error dialog */ + return(QUIT_PAGE); } SetStatusText(" ENTER = Continue F3 = Quit"); @@ -500,29 +347,127 @@ ChoosePartitionPage(PINPUT_RECORD Ir) (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) { if (ConfirmQuit(Ir) == TRUE) - return(QUIT_PAGE); + { + DestroyPartitionList(PartList); + return(QUIT_PAGE); + } break; } + else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && + (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) + { + ScrollDownPartitionList(PartList); + } + else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && + (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) + { + ScrollUpPartitionList(PartList); + } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) { + PartDataValid = GetPartitionData(PartList, &PartData); + DestroyPartitionList(PartList); return(SELECT_FILE_SYSTEM_PAGE); } + + /* FIXME: Update status text */ + } - return(CHOOSE_PARTITION_PAGE); + DestroyPartitionList(PartList); + + return(SELECT_PARTITION_PAGE); } static ULONG SelectFileSystemPage(PINPUT_RECORD Ir) { + ULONGLONG DiskSize; + ULONGLONG PartSize; + PCHAR DiskUnit; + PCHAR PartUnit; + PCHAR PartType; - SetTextXY(6, 8, "Select a file system"); + if (PartDataValid == FALSE) + { + /* FIXME: show an error dialog */ + return(QUIT_PAGE); + } - SetTextXY(6, 10, "At present, ReactOS can not be installed on unformatted partitions."); + /* adjust disk size */ + if (PartData.DiskSize >= 0x280000000ULL) /* 10 GB */ + { + DiskSize = (PartData.DiskSize + (1 << 29)) >> 30; + DiskUnit = "GB"; + } + else + { + DiskSize = (PartData.DiskSize + (1 << 19)) >> 20; + DiskUnit = "MB"; + } + + /* adjust partition size */ + if (PartData.PartSize >= 0x280000000ULL) /* 10 GB */ + { + PartSize = (PartData.PartSize + (1 << 29)) >> 30; + PartUnit = "GB"; + } + else + { + PartSize = (PartData.PartSize + (1 << 19)) >> 20; + PartUnit = "MB"; + } + + /* adjust partition type */ + if ((PartData.PartType == PARTITION_FAT_12) || + (PartData.PartType == PARTITION_FAT_16) || + (PartData.PartType == PARTITION_HUGE) || + (PartData.PartType == PARTITION_XINT13)) + { + PartType = "FAT"; + } + else if ((PartData.PartType == PARTITION_FAT32) || + (PartData.PartType == PARTITION_FAT32_XINT13)) + { + PartType = "FAT32"; + } + else if (PartData.PartType == PARTITION_IFS) + { + PartType = "NTFS"; /* FIXME: Not quite correct! */ + } + else + { + PartType = "Unknown"; + } + + SetTextXY(6, 8, "ReactOS will be installed"); + + PrintTextXY(8, 9, "on Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu.", + PartData.DiskNumber, + DiskSize, + DiskUnit, + PartData.Port, + PartData.Bus, + PartData.Id); + + PrintTextXY(8, 10, "on Partition %lu (%I64u %s) %s", + PartData.PartNumber, + PartSize, + PartUnit, + PartType); + + SetTextXY(6, 13, "Select a file system for the partition from the list below."); + + SetTextXY(8, 15, "\xf9 Press UP or DOWN to select a file system."); + SetTextXY(8, 17, "\xf9 Press ENTER to format the partition."); + SetTextXY(8, 19, "\xf9 Press ESC to select another partition."); + + /* FIXME: use a real list later */ + SetInvertedTextXY(6, 22, " Keep current file system (no changes) "); - SetStatusText(" ENTER = Continue F3 = Quit"); + SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit"); while(TRUE) { @@ -535,6 +480,10 @@ SelectFileSystemPage(PINPUT_RECORD Ir) return(QUIT_PAGE); break; } + else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x1B) /* ESC */ + { + return(SELECT_PARTITION_PAGE); + } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) { return(CHECK_FILE_SYSTEM_PAGE); @@ -580,10 +529,19 @@ CheckFileSystemPage(PINPUT_RECORD Ir) static ULONG InstallDirectoryPage(PINPUT_RECORD Ir) { + ULONG Length; - SetTextXY(6, 8, "Enter the install directory"); + SetTextXY(6, 8, "Setup installs ReactOS files onto the selected partition. Choose a"); + SetTextXY(6, 9, "directory where you want ReactOS to be installed:"); - SetTextXY(6, 12, "Install directory: \reactos"); + strcpy(InstallDir, "\\reactos"); + Length = strlen(InstallDir); + + SetInputTextXY(8, 11, 51, InstallDir); + + SetTextXY(6, 14, "To change the suggested directory, press BACKSPACE to delete"); + SetTextXY(6, 15, "characters and then type the directory where you want ReactOS to"); + SetTextXY(6, 16, "be installed."); SetStatusText(" ENTER = Continue F3 = Quit"); @@ -599,10 +557,29 @@ InstallDirectoryPage(PINPUT_RECORD Ir) return(QUIT_PAGE); break; } - else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) + else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* Return */ { return(PREPARE_COPY_PAGE); } + else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* Backspace */ + { + if (Length > 0) + { + Length--; + InstallDir[Length] = 0; + SetInputTextXY(8, 11, 51, InstallDir); + } + } + else if (isprint(Ir->Event.KeyEvent.uChar.AsciiChar)) + { + if (Length < 50) + { + InstallDir[Length] = Ir->Event.KeyEvent.uChar.AsciiChar; + Length++; + InstallDir[Length] = 0; + SetInputTextXY(8, 11, 51, InstallDir); + } + } } return(INSTALL_DIRECTORY_PAGE); @@ -620,6 +597,10 @@ PrepareCopyPage(PINPUT_RECORD Ir) SetTextXY(6, 14, "Create directories"); + SetStatusText(" Please wait..."); + + + SetStatusText(" ENTER = Continue F3 = Quit"); @@ -785,8 +766,7 @@ NtProcessStartup(PPEB Peb) { ClearScreen(); - SetTextXY(4, 3, " ReactOS 0.0.20 Setup "); - 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"); + SetUnderlinedTextXY(4, 3, " ReactOS 0.0.20 Setup "); switch (Page) { @@ -808,8 +788,8 @@ NtProcessStartup(PPEB Peb) case DEVICE_SETTINGS_PAGE: #endif - case CHOOSE_PARTITION_PAGE: - Page = ChoosePartitionPage(&Ir); + case SELECT_PARTITION_PAGE: + Page = SelectPartitionPage(&Ir); break; case SELECT_FILE_SYSTEM_PAGE: diff --git a/reactos/subsys/system/usetup/usetup.h b/reactos/subsys/system/usetup/usetup.h index 4b459300ba7..56617e659d9 100644 --- a/reactos/subsys/system/usetup/usetup.h +++ b/reactos/subsys/system/usetup/usetup.h @@ -1,8 +1,8 @@ /* */ -#ifndef __CONSOLE_H__ -#define __CONSOLE_H__ +#ifndef __USETUP_H__ +#define __USETUP_H__ #define DPRINT1(args...) do { DbgPrint("(%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0); @@ -94,9 +94,21 @@ SetStatusText(PCHAR Text); VOID SetTextXY(SHORT x, SHORT y, PCHAR Text); +VOID +SetInputTextXY(SHORT x, SHORT y, SHORT len, PCHAR Text); + +VOID +SetUnderlinedTextXY(SHORT x, SHORT y, PCHAR Text); + +VOID +SetInvertedTextXY(SHORT x, SHORT y, PCHAR Text); + +VOID +SetHighlightedTextXY(SHORT x, SHORT y, PCHAR Text); + VOID PrintTextXY(SHORT x, SHORT y, char* fmt,...); -#endif /* __CONSOLE_H__*/ +#endif /* __USETUP_H__*/ /* EOF */