coPos.X = 0;
coPos.Y = 0;
+ FillConsoleOutputAttribute(0x17,
+ xScreen * yScreen,
+ coPos,
+ &Written);
+
FillConsoleOutputCharacter(' ',
xScreen * yScreen,
coPos,
}
+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,...)
{
-# $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 = ../../..
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
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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
* 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
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.");
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)
{
- /* FIXME: Preliminary exit */
- return(CHOOSE_PARTITION_PAGE);
+ return(SELECT_PARTITION_PAGE);
}
}
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");
(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)
{
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);
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");
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);
SetTextXY(6, 14, "Create directories");
+ SetStatusText(" Please wait...");
+
+
+
SetStatusText(" ENTER = Continue F3 = Quit");
{
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)
{
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:
/*
*/
-#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);
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 */