2003-04-18 Casper S. Hornstrup <chorns@users.sourceforge.net>

* subsys/system/usetup/partlist.c (AddPartitionList): Create
	unpartitioned areas.
	(CreatePartitionListNoGUI): Save disk geometry.
	(PrintDiskData): Do not print hidden partition list entries.
	(ScrollDownPartitionList, ScrollUpPartitionList): Skip hidden partition
	list entries.
	(GetActiveBootPartition): Use CurrentDisk as index.
	(CreateSelectedPartition): New function.
	* subsys/system/usetup/partlist.h (PARTDATA): Add field NewPartSize.
	(PARTENTRY): Add fields StartingOffset and HidePartEntry.
	(DISKENTRY): Add fields Cylinders, TracksPerCylinder, SectorsPerTrack,
	and BytesPerSector;
	(CreateSelectedPartition): Add Prototype.
	* subsys/system/usetup/usetup.c (PAGE_NUMBER): Add CREATE_PARTITION_PAGE
	and FORMAT_PARTITION_PAGE
	(CurrentPartitionList, CurrentFileSystemList): New globals.
	(SelectPartitionPage): Set CurrentPartitionList.
	(PARTITION_SIZE_INPUT_FIELD_LENGTH): Define as 6.
	(DrawInputField, ShowPartitionSizeInputBox, CreatePartitionPage,
	CreateFileSystemList, DestroyFileSystemList, DrawFileSystemList,
	ScrollDownFileSystemList, ScrollUpFileSystemList, FormatPartitionPage):
	New functions.
	(SelectFileSystemPage): Draw partition screen.
	(CheckFileSystemPage): Handle CREATE_PARTITION_PAGE and
	FORMAT_PARTITION_PAGE.
	* subsys/system/usetup/usetup.h (FILE_SYSTEM, FILE_SYSTEM_LIST): Add enums.

svn path=/trunk/; revision=4552
This commit is contained in:
Casper Hornstrup 2003-04-18 14:00:17 +00:00
parent 9acdb61c4b
commit 569a7a02b6
5 changed files with 863 additions and 89 deletions

View file

@ -1,3 +1,32 @@
2003-04-18 Casper S. Hornstrup <chorns@users.sourceforge.net>
* subsys/system/usetup/partlist.c (AddPartitionList): Create
unpartitioned areas.
(CreatePartitionListNoGUI): Save disk geometry.
(PrintDiskData): Do not print hidden partition list entries.
(ScrollDownPartitionList, ScrollUpPartitionList): Skip hidden partition
list entries.
(GetActiveBootPartition): Use CurrentDisk as index.
(CreateSelectedPartition): New function.
* subsys/system/usetup/partlist.h (PARTDATA): Add field NewPartSize.
(PARTENTRY): Add fields StartingOffset and HidePartEntry.
(DISKENTRY): Add fields Cylinders, TracksPerCylinder, SectorsPerTrack,
and BytesPerSector;
(CreateSelectedPartition): Add Prototype.
* subsys/system/usetup/usetup.c (PAGE_NUMBER): Add CREATE_PARTITION_PAGE
and FORMAT_PARTITION_PAGE
(CurrentPartitionList, CurrentFileSystemList): New globals.
(SelectPartitionPage): Set CurrentPartitionList.
(PARTITION_SIZE_INPUT_FIELD_LENGTH): Define as 6.
(DrawInputField, ShowPartitionSizeInputBox, CreatePartitionPage,
CreateFileSystemList, DestroyFileSystemList, DrawFileSystemList,
ScrollDownFileSystemList, ScrollUpFileSystemList, FormatPartitionPage):
New functions.
(SelectFileSystemPage): Draw partition screen.
(CheckFileSystemPage): Handle CREATE_PARTITION_PAGE and
FORMAT_PARTITION_PAGE.
* subsys/system/usetup/usetup.h (FILE_SYSTEM, FILE_SYSTEM_LIST): Add enums.
2003-04-17 Casper S. Hornstrup <chorns@users.sourceforge.net>
* tools/mkhive/infcache.c (InfpCacheFindSection, InfpCacheFindKeyLine,

View 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: partlist.c,v 1.7 2003/04/05 15:36:34 chorns Exp $
/* $Id: partlist.c,v 1.8 2003/04/18 14:00:17 chorns Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/partlist.c
@ -47,7 +47,11 @@ AddPartitionList(ULONG DiskNumber,
PPARTENTRY PartEntry;
ULONG i;
ULONG EntryCount;
BOOLEAN LastEntryWasUnused;
ULONGLONG LastStartingOffset;
ULONGLONG LastPartitionSize;
ULONGLONG LastUnusedPartitionSize;
ULONG LastUnusedEntry;
/*
* FIXME:
@ -62,14 +66,6 @@ AddPartitionList(ULONG DiskNumber,
}
else
{
#if 0
for (i = 0; i < LayoutBuffer->PartitionCount; i++)
{
}
#endif
EntryCount = LayoutBuffer->PartitionCount;
}
@ -88,12 +84,20 @@ AddPartitionList(ULONG DiskNumber,
PartEntry = &DiskEntry->PartArray[0];
PartEntry->Unpartitioned = TRUE;
PartEntry->PartSize = 0; /* ?? */
PartEntry->Used = TRUE;
// Start partition at head 1, cylinder 0
PartEntry->StartingOffset = DiskEntry->SectorsPerTrack * DiskEntry->BytesPerSector;
PartEntry->PartSize = DiskEntry->DiskSize - PartEntry->StartingOffset;
PartEntry->Used = FALSE;
PartEntry->HidePartEntry = FALSE;
}
else
{
LastEntryWasUnused = FALSE;
// Start partition at head 1, cylinder 0
LastStartingOffset = DiskEntry->SectorsPerTrack * DiskEntry->BytesPerSector;
LastPartitionSize = 0;
LastUnusedEntry = -1;
LastUnusedPartitionSize = 0;
for (i = 0; i < LayoutBuffer->PartitionCount; i++)
{
PartEntry = &DiskEntry->PartArray[i];
@ -101,6 +105,17 @@ AddPartitionList(ULONG DiskNumber,
if ((LayoutBuffer->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED) &&
(!IsContainerPartition(LayoutBuffer->PartitionEntry[i].PartitionType)))
{
LastUnusedPartitionSize = LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart
- (LastStartingOffset + LastPartitionSize);
if (LastUnusedEntry != -1)
{
DiskEntry->PartArray[LastUnusedEntry].StartingOffset = LastStartingOffset + LastPartitionSize;
DiskEntry->PartArray[LastUnusedEntry].PartSize = LastUnusedPartitionSize;
}
LastStartingOffset = LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart;
LastPartitionSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart;
PartEntry->StartingOffset = LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart;
PartEntry->PartSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart;
PartEntry->PartNumber = LayoutBuffer->PartitionEntry[i].PartitionNumber,
PartEntry->PartType = LayoutBuffer->PartitionEntry[i].PartitionType;
@ -112,12 +127,36 @@ AddPartitionList(ULONG DiskNumber,
PartEntry->Unpartitioned = FALSE;
PartEntry->Used = TRUE;
PartEntry->HidePartEntry = FALSE;
LastEntryWasUnused = FALSE;
LastUnusedEntry = -1;
}
else
{
if (LastEntryWasUnused)
{
/* Group unused entries into one unpartitioned disk space area */
PartEntry->HidePartEntry = TRUE;
PartEntry->PartSize = 0;
}
else
{
LastUnusedEntry = i;
}
PartEntry->Unpartitioned = TRUE;
PartEntry->Used = FALSE;
LastEntryWasUnused = TRUE;
}
}
LastUnusedPartitionSize = DiskEntry->DiskSize
- (LastStartingOffset + LastPartitionSize);
if (LastUnusedEntry != -1)
{
DiskEntry->PartArray[LastUnusedEntry].StartingOffset = LastStartingOffset + LastPartitionSize;
DiskEntry->PartArray[LastUnusedEntry].PartSize = LastUnusedPartitionSize;
}
}
}
@ -256,6 +295,16 @@ CreatePartitionListNoGUI()
sizeof(SCSI_ADDRESS));
List->DiskArray[DiskNumber].Cylinders = DiskGeometry.Cylinders.QuadPart;
List->DiskArray[DiskNumber].TracksPerCylinder = DiskGeometry.TracksPerCylinder;
List->DiskArray[DiskNumber].SectorsPerTrack = DiskGeometry.SectorsPerTrack;
List->DiskArray[DiskNumber].BytesPerSector = DiskGeometry.BytesPerSector;
DPRINT("Cylinders %d\n", List->DiskArray[DiskNumber].Cylinders);
DPRINT("TracksPerCylinder %d\n", List->DiskArray[DiskNumber].TracksPerCylinder);
DPRINT("SectorsPerTrack %d\n", List->DiskArray[DiskNumber].SectorsPerTrack);
DPRINT("BytesPerSector %d\n", List->DiskArray[DiskNumber].BytesPerSector);
List->DiskArray[DiskNumber].DiskSize =
DiskGeometry.Cylinders.QuadPart *
(ULONGLONG)DiskGeometry.TracksPerCylinder *
@ -654,7 +703,7 @@ PrintPartitionData(PPARTLIST List,
if (PartEntry->Unpartitioned == TRUE)
{
sprintf(LineBuffer,
" Unpartitioned space %I64u %s",
" Unpartitioned space %I64u %s",
PartSize,
Unit);
}
@ -816,12 +865,12 @@ PrintDiskData(PPARTLIST List,
/* Print partition lines*/
for (PartIndex = 0; PartIndex < DiskEntry->PartCount; PartIndex++)
{
if (DiskEntry->PartArray[PartIndex].Used == TRUE)
{
PrintPartitionData(List,
DiskIndex,
PartIndex);
}
if (!DiskEntry->PartArray[PartIndex].HidePartEntry)
{
PrintPartitionData(List,
DiskIndex,
PartIndex);
}
}
/* Print separator line */
@ -930,12 +979,12 @@ ScrollDownPartitionList(PPARTLIST List)
/* 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;
}
if (!List->DiskArray[List->CurrentDisk].PartArray[i].HidePartEntry)
{
List->CurrentPartition = i;
DrawPartitionList(List);
return;
}
}
/* check for first usable entry on next disk */
@ -943,13 +992,13 @@ ScrollDownPartitionList(PPARTLIST List)
{
for (i = 0; i < List->DiskArray[j].PartCount; i++)
{
if (List->DiskArray[j].PartArray[i].Used == TRUE)
{
if (!List->DiskArray[j].PartArray[i].HidePartEntry)
{
List->CurrentDisk = j;
List->CurrentPartition = i;
DrawPartitionList(List);
return;
}
}
}
}
}
@ -968,7 +1017,7 @@ ScrollUpPartitionList(PPARTLIST List)
/* 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)
if (!List->DiskArray[List->CurrentDisk].PartArray[i].HidePartEntry)
{
List->CurrentPartition = i;
DrawPartitionList(List);
@ -981,7 +1030,7 @@ ScrollUpPartitionList(PPARTLIST List)
{
for (i = List->DiskArray[j].PartCount - 1; i != (ULONG)-1; i--)
{
if (List->DiskArray[j].PartArray[i].Used == TRUE)
if (!List->DiskArray[j].PartArray[i].HidePartEntry)
{
List->CurrentDisk = j;
List->CurrentPartition = i;
@ -1063,7 +1112,7 @@ GetActiveBootPartition(PPARTLIST List,
if (List->CurrentDisk >= List->DiskCount)
return(FALSE);
DiskEntry = &List->DiskArray[0];
DiskEntry = &List->DiskArray[List->CurrentDisk];
if (DiskEntry->FixedDisk == FALSE)
{
@ -1120,4 +1169,113 @@ GetActiveBootPartition(PPARTLIST List,
}
BOOL
CreateSelectedPartition(PPARTLIST List,
ULONG PartType,
ULONGLONG NewPartSize)
{
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
ULONG PartEntryNumber;
OBJECT_ATTRIBUTES ObjectAttributes;
DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
WCHAR Buffer[MAX_PATH];
UNICODE_STRING Name;
HANDLE FileHandle;
LARGE_INTEGER li;
DiskEntry = &List->DiskArray[List->CurrentDisk];
PartEntry = &DiskEntry->PartArray[List->CurrentPartition];
PartEntry->PartType = PartType;
PartEntryNumber = PartEntry->PartNumber;
DPRINT("NewPartSize %d (%d MB)\n", NewPartSize, NewPartSize / (1024 * 1024));
DPRINT("PartEntry->StartingOffset %d\n", PartEntry->StartingOffset);
DPRINT("PartEntry->PartSize %d\n", PartEntry->PartSize);
DPRINT("PartEntry->PartNumber %d\n", PartEntry->PartNumber);
DPRINT("PartEntry->PartType 0x%x\n", PartEntry->PartType);
DPRINT("PartEntry->FileSystemName %s\n", PartEntry->FileSystemName);
swprintf(Buffer,
L"\\Device\\Harddisk%d\\Partition0",
DiskEntry->DiskNumber);
RtlInitUnicodeString(&Name, Buffer);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
0,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
0x10001,
&ObjectAttributes,
&Iosb,
1,
FILE_SYNCHRONOUS_IO_NONALERT);
if (NT_SUCCESS(Status))
{
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))
{
DPRINT("IOCTL_DISK_GET_DRIVE_LAYOUT failed() 0x%.08x\n", Status);
NtClose(FileHandle);
RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
return FALSE;
}
li.QuadPart = PartEntry->StartingOffset;
LayoutBuffer->PartitionEntry[PartEntryNumber].StartingOffset = li;
li.QuadPart = NewPartSize;
LayoutBuffer->PartitionEntry[PartEntryNumber].PartitionLength = li;
LayoutBuffer->PartitionEntry[PartEntryNumber].HiddenSectors = 0; /* FIXME: ? */
LayoutBuffer->PartitionEntry[PartEntryNumber].PartitionType = PartType;
LayoutBuffer->PartitionEntry[PartEntryNumber].RecognizedPartition = TRUE;
LayoutBuffer->PartitionEntry[PartEntryNumber].RewritePartition = TRUE;
Status = NtDeviceIoControlFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_DISK_SET_DRIVE_LAYOUT,
LayoutBuffer,
8192,
NULL,
0);
if (!NT_SUCCESS(Status))
{
DPRINT("IOCTL_DISK_SET_DRIVE_LAYOUT failed() 0x%.08x\n", Status);
NtClose(FileHandle);
RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
return FALSE;
}
}
else
{
DPRINT("NtOpenFile failed() 0x%.08x\n", Status);
NtClose(FileHandle);
RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
return FALSE;
}
NtClose(FileHandle);
RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
return TRUE;
}
/* EOF */

View 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: partlist.h,v 1.8 2003/04/05 15:36:34 chorns Exp $
/* $Id: partlist.h,v 1.9 2003/04/18 14:00:17 chorns Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/partlist.h
@ -36,6 +36,7 @@ typedef struct _PARTDATA
USHORT Id;
ULONGLONG PartSize;
ULONGLONG NewPartSize;
ULONG PartNumber;
ULONG PartType;
@ -47,6 +48,7 @@ typedef struct _PARTDATA
typedef struct _PARTENTRY
{
ULONGLONG StartingOffset;
ULONGLONG PartSize;
ULONG PartNumber;
ULONG PartType;
@ -59,11 +61,17 @@ typedef struct _PARTENTRY
BOOL Unpartitioned;
BOOL Used;
BOOLEAN HidePartEntry;
} PARTENTRY, *PPARTENTRY;
typedef struct _DISKENTRY
{
ULONGLONG DiskSize;
ULONGLONG Cylinders;
ULONGLONG TracksPerCylinder;
ULONGLONG SectorsPerTrack;
ULONGLONG BytesPerSector;
ULONG DiskNumber;
USHORT Port;
USHORT Bus;
@ -132,6 +140,11 @@ BOOL
GetActiveBootPartition(PPARTLIST List,
PPARTDATA Data);
BOOL
CreateSelectedPartition(PPARTLIST List,
ULONG PartType,
ULONGLONG NewPartSize);
#endif /* __PARTLIST_H__ */
/* EOF */

View file

@ -40,6 +40,8 @@
#include "bootsup.h"
#include "registry.h"
#define NDEBUG
#include <debug.h>
typedef enum _PAGE_NUMBER
{
@ -48,7 +50,9 @@ typedef enum _PAGE_NUMBER
INSTALL_INTRO_PAGE,
SELECT_PARTITION_PAGE,
CREATE_PARTITION_PAGE,
SELECT_FILE_SYSTEM_PAGE,
FORMAT_PARTITION_PAGE,
CHECK_FILE_SYSTEM_PAGE,
PREPARE_COPY_PAGE,
INSTALL_DIRECTORY_PAGE,
@ -74,26 +78,31 @@ typedef struct _COPYCONTEXT
/* GLOBALS ******************************************************************/
HANDLE ProcessHeap;
BOOLEAN PartDataValid;
PARTDATA PartData;
BOOLEAN ActivePartitionValid;
PARTDATA ActivePartition;
UNICODE_STRING SourcePath;
UNICODE_STRING SourceRootPath;
UNICODE_STRING InstallPath;
UNICODE_STRING DestinationPath;
UNICODE_STRING DestinationArcPath;
UNICODE_STRING DestinationRootPath;
/* LOCALS *******************************************************************/
UNICODE_STRING SystemRootPath; /* Path to the active partition */
static BOOLEAN PartDataValid;
static PARTDATA PartData;
HINF SetupInf;
static BOOLEAN ActivePartitionValid;
static PARTDATA ActivePartition;
HSPFILEQ SetupFileQueue = NULL;
static UNICODE_STRING SourcePath;
static UNICODE_STRING InstallPath;
static UNICODE_STRING DestinationPath;
static UNICODE_STRING DestinationArcPath;
static UNICODE_STRING DestinationRootPath;
static UNICODE_STRING SystemRootPath; /* Path to the active partition */
static HINF SetupInf;
static HSPFILEQ SetupFileQueue = NULL;
static PPARTLIST CurrentPartitionList = NULL;
static PFILE_SYSTEM_LIST CurrentFileSystemList;
/* FUNCTIONS ****************************************************************/
@ -644,6 +653,12 @@ SelectPartitionPage(PINPUT_RECORD Ir)
return(QUIT_PAGE);
}
if (CurrentPartitionList != NULL)
{
DestroyPartitionList(CurrentPartitionList);
}
CurrentPartitionList = PartList;
SetStatusText(" ENTER = Continue F3 = Quit");
while(TRUE)
@ -670,58 +685,486 @@ SelectPartitionPage(PINPUT_RECORD Ir)
{
ScrollUpPartitionList(PartList);
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
{
PartDataValid = GetSelectedPartition(PartList,
&PartData);
ActivePartitionValid = GetActiveBootPartition(PartList,
&ActivePartition);
DestroyPartitionList(PartList);
RtlFreeUnicodeString(&DestinationRootPath);
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
PartData.DiskNumber,
PartData.PartNumber);
RtlCreateUnicodeString(&DestinationRootPath,
PathBuffer);
RtlFreeUnicodeString(&SystemRootPath);
if (ActivePartitionValid)
{
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
ActivePartition.DiskNumber,
ActivePartition.PartNumber);
}
else
{
/* We mark the selected partition as bootable */
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
PartData.DiskNumber,
PartData.PartNumber);
}
RtlCreateUnicodeString(&SystemRootPath,
PathBuffer);
return(SELECT_FILE_SYSTEM_PAGE);
if (PartDataValid)
{
ActivePartitionValid = GetActiveBootPartition(PartList,
&ActivePartition);
RtlFreeUnicodeString(&DestinationRootPath);
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
PartData.DiskNumber,
PartData.PartNumber);
RtlCreateUnicodeString(&DestinationRootPath,
PathBuffer);
RtlFreeUnicodeString(&SystemRootPath);
if (ActivePartitionValid)
{
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
ActivePartition.DiskNumber,
ActivePartition.PartNumber);
}
else
{
/* We mark the selected partition as bootable */
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
PartData.DiskNumber,
PartData.PartNumber);
}
RtlCreateUnicodeString(&SystemRootPath,
PathBuffer);
return(SELECT_FILE_SYSTEM_PAGE);
}
else
{
/* FIXME: show an error dialog */
return(SELECT_PARTITION_PAGE);
}
}
else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_C) /* C */
{
#ifdef ENABLE_FORMAT
/* Don't destroy the parition list here */;
return(CREATE_PARTITION_PAGE);
#endif
}
/* FIXME: Update status text */
}
DestroyPartitionList(PartList);
return(SELECT_PARTITION_PAGE);
}
static VOID
DrawInputField(ULONG FieldLength,
SHORT Left,
SHORT Top,
PCHAR FieldContent)
{
CHAR buf[100];
COORD coPos;
coPos.X = Left;
coPos.Y = Top;
memset(buf, '_', sizeof(buf));
buf[FieldLength - strlen(FieldContent)] = 0;
strcat(buf, FieldContent);
WriteConsoleOutputCharacters(buf,
strlen(buf),
coPos);
}
#define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
static VOID
ShowPartitionSizeInputBox(ULONG MaxSize,
PCHAR InputBuffer,
PBOOLEAN Quit,
PBOOLEAN Cancel)
{
SHORT Left;
SHORT Top;
SHORT Right;
SHORT Bottom;
INPUT_RECORD Ir;
COORD coPos;
ULONG Written;
SHORT i;
CHAR buf[100];
ULONG index;
CHAR ch;
SHORT iLeft;
SHORT iTop;
SHORT xScreen;
SHORT yScreen;
if (Quit != NULL)
*Quit = FALSE;
if (Cancel != NULL)
*Cancel = FALSE;
GetScreenSize(&xScreen, &yScreen);
Left = 12;
Top = 11;
Right = xScreen - 12;
Bottom = 15;
/* draw upper left corner */
coPos.X = Left;
coPos.Y = Top;
FillConsoleOutputCharacter(0xDA, // '+',
1,
coPos,
&Written);
/* draw upper edge */
coPos.X = Left + 1;
coPos.Y = Top;
FillConsoleOutputCharacter(0xC4, // '-',
Right - Left - 1,
coPos,
&Written);
/* draw upper right corner */
coPos.X = Right;
coPos.Y = Top;
FillConsoleOutputCharacter(0xBF, // '+',
1,
coPos,
&Written);
/* draw left and right edge */
for (i = Top + 1; i < Bottom; i++)
{
coPos.X = Left;
coPos.Y = i;
FillConsoleOutputCharacter(0xB3, // '|',
1,
coPos,
&Written);
coPos.X = Right;
FillConsoleOutputCharacter(0xB3, //'|',
1,
coPos,
&Written);
}
/* draw lower left corner */
coPos.X = Left;
coPos.Y = Bottom;
FillConsoleOutputCharacter(0xC0, // '+',
1,
coPos,
&Written);
/* draw lower edge */
coPos.X = Left + 1;
coPos.Y = Bottom;
FillConsoleOutputCharacter(0xC4, // '-',
Right - Left - 1,
coPos,
&Written);
/* draw lower right corner */
coPos.X = Right;
coPos.Y = Bottom;
FillConsoleOutputCharacter(0xD9, // '+',
1,
coPos,
&Written);
/* Print message */
coPos.X = Left + 2;
coPos.Y = Top + 2;
strcpy(buf, "Size of new partition:");
iLeft = coPos.X + strlen(buf) + 1;
iTop = coPos.Y;
WriteConsoleOutputCharacters(buf,
strlen(buf),
coPos);
sprintf(buf, "MB (max. %d MB)", MaxSize / (1024 * 1024));
coPos.X = iLeft + PARTITION_SIZE_INPUT_FIELD_LENGTH + 1;
coPos.Y = iTop;
WriteConsoleOutputCharacters(buf,
strlen(buf),
coPos);
buf[0] = 0;
index = 0;
DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, iLeft, iTop, buf);
while(TRUE)
{
ConInKey(&Ir);
if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
(Ir.Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
{
if (Quit != NULL)
*Quit = TRUE;
buf[0] = 0;
break;
}
else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
{
break;
}
else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESCAPE */
{
if (Cancel != NULL)
*Cancel = FALSE;
buf[0] = 0;
break;
}
else if ((Ir.Event.KeyEvent.wVirtualKeyCode == VK_BACK) && (index > 0)) /* BACKSPACE */
{
index--;
buf[index] = 0;
DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, iLeft, iTop, buf);
}
else if ((Ir.Event.KeyEvent.uChar.AsciiChar != 0x00)
&& (index < PARTITION_SIZE_INPUT_FIELD_LENGTH))
{
ch = Ir.Event.KeyEvent.uChar.AsciiChar;
if ((ch >= '0') && (ch <= '9'))
{
buf[index] = ch;
index++;
buf[index] = 0;
DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, iLeft, iTop, buf);
}
}
}
strcpy(InputBuffer, buf);
}
static PAGE_NUMBER
CreatePartitionPage(PINPUT_RECORD Ir)
{
BOOLEAN Valid;
WCHAR PathBuffer[MAX_PATH];
PPARTLIST PartList;
PPARTENTRY PartEntry;
SHORT xScreen;
SHORT yScreen;
BOOLEAN Quit;
BOOLEAN Cancel;
CHAR InputBuffer[50];
ULONG MaxSize;
ULONGLONG PartSize;
SetTextXY(6, 8, "You have chosen to create a new partition in the unused disk space.");
SetTextXY(6, 9, "Please enter the size of the new partition in megabytes.");
SetStatusText(" Please wait...");
GetScreenSize(&xScreen, &yScreen);
PartList = CurrentPartitionList;
SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit");
PartEntry = &PartList->DiskArray[PartList->CurrentDisk].PartArray[PartList->CurrentPartition];
while (TRUE)
{
MaxSize = PartEntry->PartSize;
ShowPartitionSizeInputBox(MaxSize, InputBuffer, &Quit, &Cancel);
if (Quit == TRUE)
{
if (ConfirmQuit(Ir) == TRUE)
{
DestroyPartitionList(PartList);
return(QUIT_PAGE);
}
}
else if (Cancel == TRUE)
{
break;
}
else
{
PartSize = atoi(InputBuffer);
if (PartSize < 1)
{
// Too small
continue;
}
/* Convert to bytes */
PartSize *= 1024 * 1024;
if (PartSize > PartEntry->PartSize)
{
// Too large
continue;
}
assert(PartEntry->Unpartitioned == TRUE);
PartEntry->PartType = PARTITION_ENTRY_UNUSED;
PartEntry->Used = TRUE;
PartDataValid = GetSelectedPartition(PartList,
&PartData);
if (PartDataValid)
{
PartData.NewPartSize = PartSize;
ActivePartitionValid = GetActiveBootPartition(PartList,
&ActivePartition);
RtlFreeUnicodeString(&DestinationRootPath);
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
PartData.DiskNumber,
PartData.PartNumber);
RtlCreateUnicodeString(&DestinationRootPath,
PathBuffer);
RtlFreeUnicodeString(&SystemRootPath);
if (ActivePartitionValid)
{
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
ActivePartition.DiskNumber,
ActivePartition.PartNumber);
}
else
{
/* We mark the selected partition as bootable */
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
PartData.DiskNumber,
PartData.PartNumber);
}
RtlCreateUnicodeString(&SystemRootPath,
PathBuffer);
return(SELECT_FILE_SYSTEM_PAGE);
}
else
{
/* FIXME: show an error dialog */
return(SELECT_PARTITION_PAGE);
}
}
}
return(SELECT_PARTITION_PAGE);
}
static PFILE_SYSTEM_LIST
CreateFileSystemList(SHORT Left,
SHORT Top,
BOOLEAN ForceFormat,
FILE_SYSTEM ForceFileSystem)
{
PFILE_SYSTEM_LIST List;
List = (PFILE_SYSTEM_LIST)RtlAllocateHeap(ProcessHeap, 0, sizeof(FILE_SYSTEM_LIST));
if (List == NULL)
return(NULL);
List->Left = Left;
List->Top = Top;
#if ENABLE_FORMAT
List->FileSystemCount = 1;
#else
List->FileSystemCount = 0;
#endif
if (ForceFormat)
{
List->CurrentFileSystem = ForceFileSystem;
}
else
{
List->FileSystemCount++;
List->CurrentFileSystem = FsKeep;
}
return(List);
}
static VOID
DestroyFileSystemList(PFILE_SYSTEM_LIST List)
{
RtlFreeHeap(ProcessHeap, 0, List);
}
static VOID
DrawFileSystemList(PFILE_SYSTEM_LIST List)
{
COORD coPos;
ULONG Written;
ULONG index;
index = 0;
#ifdef ENABLE_FORMAT
coPos.X = List->Left;
coPos.Y = List->Top + index;
FillConsoleOutputAttribute(0x17,
50,
coPos,
&Written);
FillConsoleOutputCharacter(' ',
50,
coPos,
&Written);
if (List->CurrentFileSystem == FsFat)
{
SetInvertedTextXY(List->Left, List->Top + index, " Format partition as FAT file system ");
}
else
{
SetTextXY(List->Left, List->Top + index, " Format partition as FAT file system ");
}
index++;
#endif
coPos.X = List->Left;
coPos.Y = List->Top + index;
FillConsoleOutputAttribute(0x17,
50,
coPos,
&Written);
FillConsoleOutputCharacter(' ',
50,
coPos,
&Written);
if (List->CurrentFileSystem == FsKeep)
{
SetInvertedTextXY(List->Left, List->Top + index, " Keep current file system (no changes) ");
}
else
{
SetTextXY(List->Left, List->Top + index, " Keep current file system (no changes) ");
}
}
static VOID
ScrollDownFileSystemList(PFILE_SYSTEM_LIST List)
{
if ((ULONG) List->CurrentFileSystem < List->FileSystemCount - 1)
{
(ULONG) List->CurrentFileSystem++;
DrawFileSystemList(List);
}
}
static VOID
ScrollUpFileSystemList(PFILE_SYSTEM_LIST List)
{
if ((ULONG) List->CurrentFileSystem > 0)
{
(ULONG) List->CurrentFileSystem--;
DrawFileSystemList(List);
}
}
static PAGE_NUMBER
SelectFileSystemPage(PINPUT_RECORD Ir)
{
PFILE_SYSTEM_LIST FileSystemList;
ULONGLONG DiskSize;
ULONGLONG PartSize;
PCHAR DiskUnit;
@ -775,6 +1218,10 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
{
PartType = "NTFS"; /* FIXME: Not quite correct! */
}
else if (PartData.PartType == PARTITION_ENTRY_UNUSED)
{
PartType = "Unused";
}
else
{
PartType = "Unknown";
@ -804,9 +1251,16 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
SetTextXY(8, 21, "\xfa Press ENTER to format the partition.");
SetTextXY(8, 23, "\xfa Press ESC to select another partition.");
/* FIXME: use a real list later */
SetInvertedTextXY(6, 26, " Keep current file system (no changes) ");
FileSystemList = CreateFileSystemList(6, 26, FALSE, FsKeep);
if (FileSystemList == NULL)
{
/* FIXME: show an error dialog */
return(QUIT_PAGE);
}
CurrentFileSystemList = FileSystemList;
DrawFileSystemList(FileSystemList);
SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit");
@ -824,18 +1278,111 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
(Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
{
DestroyFileSystemList(FileSystemList);
return(SELECT_PARTITION_PAGE);
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
(Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
{
return(CHECK_FILE_SYSTEM_PAGE);
ScrollDownFileSystemList(FileSystemList);
}
else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
(Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
{
ScrollUpFileSystemList(FileSystemList);
}
else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
{
if (FileSystemList->CurrentFileSystem == FsKeep)
{
return(CHECK_FILE_SYSTEM_PAGE);
}
else
{
return(FORMAT_PARTITION_PAGE);
}
}
}
}
static ULONG
FormatPartitionPage(PINPUT_RECORD Ir)
{
BOOLEAN CreatePartition;
ULONG PartType;
BOOLEAN Valid;
SetTextXY(6, 8, "Format partition");
SetTextXY(6, 10, "Setup will now format the partition. Press ENTER to continue.");
SetStatusText(" ENTER = Continue F3 = Quit");
while(TRUE)
{
ConInKey(Ir);
if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
(Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
{
if (ConfirmQuit(Ir) == TRUE)
{
return(QUIT_PAGE);
}
break;
}
else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
{
SetStatusText(" Please wait ...");
CreatePartition = FALSE;
switch (CurrentFileSystemList->CurrentFileSystem)
{
#ifdef ENABLE_FORMAT
case FsFat:
PartType = PARTITION_FAT32_XINT13;
CreatePartition = TRUE;
break;
#endif
case FsKeep:
CreatePartition = FALSE;
break;
default:
return QUIT_PAGE;
}
if (CreatePartition)
{
Valid = CreateSelectedPartition(CurrentPartitionList, PartType, PartData.NewPartSize);
if (Valid)
{
return(INSTALL_DIRECTORY_PAGE);
}
else
{
DPRINT("CreateSelectedPartition() failed\n");
/* FIXME: show an error dialog */
return(QUIT_PAGE);
}
}
switch (CurrentFileSystemList->CurrentFileSystem)
{
#ifdef ENABLE_FORMAT
case FsFat:
break;
#endif
case FsKeep:
break;
default:
return QUIT_PAGE;
}
}
}
return(SELECT_FILE_SYSTEM_PAGE);
return(INSTALL_DIRECTORY_PAGE);
}
static ULONG
CheckFileSystemPage(PINPUT_RECORD Ir)
{
@ -2190,10 +2737,18 @@ NtProcessStartup(PPEB Peb)
Page = SelectPartitionPage(&Ir);
break;
case CREATE_PARTITION_PAGE:
Page = CreatePartitionPage(&Ir);
break;
case SELECT_FILE_SYSTEM_PAGE:
Page = SelectFileSystemPage(&Ir);
break;
case FORMAT_PARTITION_PAGE:
Page = FormatPartitionPage(&Ir);
break;
case CHECK_FILE_SYSTEM_PAGE:
Page = CheckFileSystemPage(&Ir);
break;

View file

@ -27,6 +27,8 @@
#ifndef __USETUP_H__
#define __USETUP_H__
// Define to allow creating a new partition and format it
//#define ENABLE_FORMAT
#define DPRINT1(args...) do { DbgPrint("(%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0);
#define CHECKPOINT1 do { DbgPrint("%s:%d\n",__FILE__,__LINE__); } while(0);
@ -34,6 +36,23 @@
#define DPRINT(args...)
#define CHECKPOINT
typedef enum
{
#ifdef ENABLE_FORMAT
FsFat = 0,
FsKeep = 1
#else
FsKeep = 0
#endif
} FILE_SYSTEM;
typedef struct _FILE_SYSTEM_LIST
{
SHORT Left;
SHORT Top;
FILE_SYSTEM CurrentFileSystem;
ULONG FileSystemCount;
} FILE_SYSTEM_LIST, *PFILE_SYSTEM_LIST;
extern HANDLE ProcessHeap;