Implemented selection of install partition and directory.
authorEric Kohl <eric.kohl@reactos.org>
Fri, 18 Oct 2002 20:04:00 +0000 (20:04 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Fri, 18 Oct 2002 20:04:00 +0000 (20:04 +0000)
svn path=/trunk/; revision=3635

reactos/subsys/system/usetup/console.c
reactos/subsys/system/usetup/makefile
reactos/subsys/system/usetup/partlist.c [new file with mode: 0644]
reactos/subsys/system/usetup/partlist.h [new file with mode: 0644]
reactos/subsys/system/usetup/usetup.c
reactos/subsys/system/usetup/usetup.h

index c96f367..f0f9fa7 100644 (file)
@@ -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,...)
 {
index 6b16ce7..42dae17 100644 (file)
@@ -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 (file)
index 0000000..b3f1fce
--- /dev/null
@@ -0,0 +1,621 @@
+/*
+ *  partlist.c
+ */
+
+#include <ddk/ntddk.h>
+#include <ddk/ntddscsi.h>
+
+#include <ntdll/rtl.h>
+
+#include <ntos/minmax.h>
+#include <ntos/keyboard.h>
+
+#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 (file)
index 0000000..ecd16d3
--- /dev/null
@@ -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
index 06d5cef..9726e7c 100644 (file)
@@ -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
 #include <ntos/keyboard.h>
 
 #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
 #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;
-
-  DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
-  SCSI_ADDRESS ScsiAddress;
-  ULONGLONG DiskSize;
-  char *Scale;
-  char *PartType;
-
+  PPARTLIST PartList;
+  SHORT xScreen;
+  SHORT yScreen;
 
+  SetTextXY(6, 8, "The list below shows existing partitions and unused disk");
+  SetTextXY(6, 9, "space for new partitions.");
 
-  SetTextXY(6, 8, "Choose install partition");
+  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.");
 
-  Status = NtQuerySystemInformation(SystemDeviceInformation,
-                                   &Sdi,
-                                   sizeof(SYSTEM_DEVICE_INFORMATION),
-                                   &ReturnSize);
-  if (!NT_SUCCESS(Status))
-    {
-      SetTextXY(8, 10, "NtQuerySystemInformation failed!");
-    }
+  SetStatusText("   Please wait...");
 
-  PrintTextXY(6, 12, "Setup found %lu %s on this computer.",
-           Sdi.NumberOfDisks, (Sdi.NumberOfDisks == 1) ? "harddisk" : "harddisks");
+  GetScreenSize(&xScreen, &yScreen);
 
-  Line = 14;
-  for (DiskCount = 0; DiskCount < Sdi.NumberOfDisks; DiskCount++)
+  PartList = CreatePartitionList(2, 19, xScreen - 3, yScreen - 3);
+  if (PartList == NULL)
     {
-      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";
+    }
 
-  SetStatusText("   ENTER = Continue   F3 = Quit");
+  /* 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   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:
index 4b45930..56617e6 100644 (file)
@@ -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 */