mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
3c616b625d
- Also, reserve a new field to display whether the disk is MBR or GPT-initialized. - Adjust the code that used the "STRING_HDDINFOUNKx" string labels. The extra slot added to some of the strings is to indicate whether the disk is MBR or GPT. As attentive readers will notice, the code that "determines" whether the disk is either MBR or GPT is of course just temporary: it's just a placeholder code that should currently just show "MBR". Having the NoMbr flag mostly signifies that the disk is uninitialized. A GPT disk also has a MBR but it's for "backcompatibility" / "protective" reasons (so that MBR-only tools would see the disk as just a big 1-partitioned only disk with which they could barely do anything). A real involved test for the nature of the disk should involve calling the correct IOCTLs in the disk detection code in partlist.c . This is for the future (and when ReactOS will better support GPT disks). svn path=/branches/setup_improvements/; revision=74614 svn path=/branches/setup_improvements/; revision=74615
805 lines
24 KiB
C
805 lines
24 KiB
C
/*
|
|
* ReactOS kernel
|
|
* Copyright (C) 2002, 2003, 2004, 2005 ReactOS Team
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
/* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS text-mode setup
|
|
* FILE: base/setup/usetup/partlist.c
|
|
* PURPOSE: Partition list functions
|
|
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
|
*/
|
|
|
|
#include "usetup.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* HELPERS FOR PARTITION TYPES **********************************************/
|
|
|
|
typedef struct _PARTITION_TYPE
|
|
{
|
|
UCHAR Type;
|
|
PCHAR Description;
|
|
} PARTITION_TYPE, *PPARTITION_TYPE;
|
|
|
|
/*
|
|
* This partition type list was ripped off the kernelDisk.c module from:
|
|
*
|
|
* Visopsys Operating System
|
|
* Copyright (C) 1998-2015 J. Andrew McLaughlin
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*
|
|
* See also https://en.wikipedia.org/wiki/Partition_type#List_of_partition_IDs
|
|
* and http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
|
|
* for a complete list.
|
|
*/
|
|
|
|
/* This is a table for keeping known partition type codes and descriptions */
|
|
static PARTITION_TYPE PartitionTypes[] =
|
|
{
|
|
{ 0x00, "(Empty)" },
|
|
{ 0x01, "FAT12" },
|
|
{ 0x02, "XENIX root" },
|
|
{ 0x03, "XENIX /usr" },
|
|
{ 0x04, "FAT16 (small)" },
|
|
{ 0x05, "Extended" },
|
|
{ 0x06, "FAT16" },
|
|
{ 0x07, "NTFS/HPFS/exFAT" },
|
|
{ 0x08, "OS/2 or AIX boot" },
|
|
{ 0x09, "AIX data" },
|
|
{ 0x0A, "OS/2 Boot Manager" },
|
|
{ 0x0B, "FAT32" },
|
|
{ 0x0C, "FAT32 (LBA)" },
|
|
{ 0x0E, "FAT16 (LBA)" },
|
|
{ 0x0F, "Extended (LBA)" },
|
|
{ 0x11, "Hidden FAT12" },
|
|
{ 0x12, "FAT diagnostic" },
|
|
{ 0x14, "Hidden FAT16 (small)" },
|
|
{ 0x16, "Hidden FAT16" },
|
|
{ 0x17, "Hidden HPFS or NTFS" },
|
|
{ 0x1B, "Hidden FAT32" },
|
|
{ 0x1C, "Hidden FAT32 (LBA)" },
|
|
{ 0x1E, "Hidden FAT16 (LBA)" },
|
|
{ 0x35, "JFS" },
|
|
{ 0x39, "Plan 9" },
|
|
{ 0x3C, "PartitionMagic" },
|
|
{ 0x3D, "Hidden Netware" },
|
|
{ 0x41, "PowerPC PReP" },
|
|
{ 0x42, "Win2K dynamic extended" },
|
|
{ 0x43, "Old Linux" },
|
|
{ 0x44, "GoBack" },
|
|
{ 0x4D, "QNX4.x" },
|
|
{ 0x4D, "QNX4.x 2nd" },
|
|
{ 0x4D, "QNX4.x 3rd" },
|
|
{ 0x50, "Ontrack R/O" },
|
|
{ 0x51, "Ontrack R/W or Novell" },
|
|
{ 0x52, "CP/M" },
|
|
{ 0x63, "GNU HURD or UNIX SysV" },
|
|
{ 0x64, "Netware 2" },
|
|
{ 0x65, "Netware 3/4" },
|
|
{ 0x66, "Netware SMS" },
|
|
{ 0x67, "Novell" },
|
|
{ 0x68, "Novell" },
|
|
{ 0x69, "Netware 5+" },
|
|
{ 0x7E, "Veritas VxVM public" },
|
|
{ 0x7F, "Veritas VxVM private" },
|
|
{ 0x80, "Minix" },
|
|
{ 0x81, "Linux or Minix" },
|
|
{ 0x82, "Linux swap or Solaris" },
|
|
{ 0x83, "Linux" },
|
|
{ 0x84, "Hibernation" },
|
|
{ 0x85, "Linux extended" },
|
|
{ 0x86, "HPFS or NTFS mirrored" },
|
|
{ 0x87, "HPFS or NTFS mirrored" },
|
|
{ 0x8E, "Linux LVM" },
|
|
{ 0x93, "Hidden Linux" },
|
|
{ 0x96, "CDFS/ISO-9660" },
|
|
{ 0x9F, "BSD/OS" },
|
|
{ 0xA0, "Laptop hibernation" },
|
|
{ 0xA1, "Laptop hibernation" },
|
|
{ 0xA5, "BSD, NetBSD, FreeBSD" },
|
|
{ 0xA6, "OpenBSD" },
|
|
{ 0xA7, "NeXTSTEP" },
|
|
{ 0xA8, "OS-X UFS" },
|
|
{ 0xA9, "NetBSD" },
|
|
{ 0xAB, "OS-X boot" },
|
|
{ 0xAF, "OS-X HFS" },
|
|
{ 0xB6, "NT corrupt mirror" },
|
|
{ 0xB7, "BSDI" },
|
|
{ 0xB8, "BSDI swap" },
|
|
{ 0xBE, "Solaris 8 boot" },
|
|
{ 0xBF, "Solaris x86" },
|
|
{ 0xC0, "NTFT" },
|
|
{ 0xC1, "DR-DOS FAT12" },
|
|
{ 0xC2, "Hidden Linux" },
|
|
{ 0xC3, "Hidden Linux swap" },
|
|
{ 0xC4, "DR-DOS FAT16 (small)" },
|
|
{ 0xC5, "DR-DOS Extended" },
|
|
{ 0xC6, "DR-DOS FAT16" },
|
|
{ 0xC7, "HPFS mirrored" },
|
|
{ 0xCB, "DR-DOS FAT32" },
|
|
{ 0xCC, "DR-DOS FAT32 (LBA)" },
|
|
{ 0xCE, "DR-DOS FAT16 (LBA)" },
|
|
{ 0xD0, "MDOS" },
|
|
{ 0xD1, "MDOS FAT12" },
|
|
{ 0xD4, "MDOS FAT16 (small)" },
|
|
{ 0xD5, "MDOS Extended" },
|
|
{ 0xD6, "MDOS FAT16" },
|
|
{ 0xD8, "CP/M-86" },
|
|
{ 0xDF, "BootIt EMBRM(FAT16/32)" },
|
|
{ 0xEB, "BeOS BFS" },
|
|
{ 0xEE, "EFI GPT protective" },
|
|
{ 0xEF, "EFI filesystem" },
|
|
{ 0xF0, "Linux/PA-RISC boot" },
|
|
{ 0xF2, "DOS 3.3+ second" },
|
|
{ 0xFA, "Bochs" },
|
|
{ 0xFB, "VmWare" },
|
|
{ 0xFC, "VmWare swap" },
|
|
{ 0xFD, "Linux RAID" },
|
|
{ 0xFE, "NT hidden" },
|
|
};
|
|
|
|
VOID
|
|
GetPartTypeStringFromPartitionType(
|
|
IN UCHAR partitionType,
|
|
OUT PCHAR strPartType,
|
|
IN ULONG cchPartType)
|
|
{
|
|
/* Determine partition type */
|
|
|
|
if (IsContainerPartition(partitionType))
|
|
{
|
|
RtlStringCchCopyA(strPartType, cchPartType, MUIGetString(STRING_EXTENDED_PARTITION));
|
|
}
|
|
else if (partitionType == PARTITION_ENTRY_UNUSED)
|
|
{
|
|
RtlStringCchCopyA(strPartType, cchPartType, MUIGetString(STRING_FORMATUNUSED));
|
|
}
|
|
else
|
|
{
|
|
UINT i;
|
|
|
|
/* Do the table lookup */
|
|
for (i = 0; i < ARRAYSIZE(PartitionTypes); i++)
|
|
{
|
|
if (partitionType == PartitionTypes[i].Type)
|
|
{
|
|
RtlStringCchCopyA(strPartType, cchPartType, PartitionTypes[i].Description);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* We are here because the partition type is unknown */
|
|
RtlStringCchCopyA(strPartType, cchPartType, MUIGetString(STRING_FORMATUNKNOWN));
|
|
}
|
|
}
|
|
|
|
|
|
/* FUNCTIONS ****************************************************************/
|
|
|
|
VOID
|
|
InitPartitionListUi(
|
|
IN OUT PPARTLIST_UI ListUi,
|
|
IN PPARTLIST List,
|
|
IN SHORT Left,
|
|
IN SHORT Top,
|
|
IN SHORT Right,
|
|
IN SHORT Bottom)
|
|
{
|
|
ListUi->List = List;
|
|
// ListUi->FirstShown = NULL;
|
|
// ListUi->LastShown = NULL;
|
|
|
|
ListUi->Left = Left;
|
|
ListUi->Top = Top;
|
|
ListUi->Right = Right;
|
|
ListUi->Bottom = Bottom;
|
|
|
|
ListUi->Line = 0;
|
|
ListUi->Offset = 0;
|
|
|
|
// ListUi->Redraw = TRUE;
|
|
}
|
|
|
|
static
|
|
VOID
|
|
PrintEmptyLine(
|
|
IN PPARTLIST_UI ListUi)
|
|
{
|
|
COORD coPos;
|
|
ULONG Written;
|
|
USHORT Width;
|
|
USHORT Height;
|
|
|
|
Width = ListUi->Right - ListUi->Left - 1;
|
|
Height = ListUi->Bottom - ListUi->Top - 2;
|
|
|
|
coPos.X = ListUi->Left + 1;
|
|
coPos.Y = ListUi->Top + 1 + ListUi->Line;
|
|
|
|
if (ListUi->Line >= 0 && ListUi->Line <= Height)
|
|
{
|
|
FillConsoleOutputAttribute(StdOutput,
|
|
FOREGROUND_WHITE | BACKGROUND_BLUE,
|
|
Width,
|
|
coPos,
|
|
&Written);
|
|
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
' ',
|
|
Width,
|
|
coPos,
|
|
&Written);
|
|
}
|
|
|
|
ListUi->Line++;
|
|
}
|
|
|
|
static
|
|
VOID
|
|
PrintPartitionData(
|
|
IN PPARTLIST_UI ListUi,
|
|
IN PDISKENTRY DiskEntry,
|
|
IN PPARTENTRY PartEntry)
|
|
{
|
|
PPARTLIST List = ListUi->List;
|
|
CHAR LineBuffer[128];
|
|
COORD coPos;
|
|
ULONG Written;
|
|
USHORT Width;
|
|
USHORT Height;
|
|
LARGE_INTEGER PartSize;
|
|
PCHAR Unit;
|
|
UCHAR Attribute;
|
|
CHAR PartTypeString[32];
|
|
PCHAR PartType = PartTypeString;
|
|
|
|
Width = ListUi->Right - ListUi->Left - 1;
|
|
Height = ListUi->Bottom - ListUi->Top - 2;
|
|
|
|
coPos.X = ListUi->Left + 1;
|
|
coPos.Y = ListUi->Top + 1 + ListUi->Line;
|
|
|
|
if (PartEntry->IsPartitioned == FALSE)
|
|
{
|
|
PartSize.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
|
|
#if 0
|
|
if (PartSize.QuadPart >= 10737418240) /* 10 GB */
|
|
{
|
|
PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1073741824);
|
|
Unit = MUIGetString(STRING_GB);
|
|
}
|
|
else
|
|
#endif
|
|
if (PartSize.QuadPart >= 10485760) /* 10 MB */
|
|
{
|
|
PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1048576);
|
|
Unit = MUIGetString(STRING_MB);
|
|
}
|
|
else
|
|
{
|
|
PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1024);
|
|
Unit = MUIGetString(STRING_KB);
|
|
}
|
|
|
|
sprintf(LineBuffer,
|
|
MUIGetString(STRING_UNPSPACE),
|
|
PartEntry->LogicalPartition ? " " : "",
|
|
PartEntry->LogicalPartition ? "" : " ",
|
|
PartSize.u.LowPart,
|
|
Unit);
|
|
}
|
|
else
|
|
{
|
|
/* Determine partition type */
|
|
PartTypeString[0] = '\0';
|
|
if (PartEntry->New != FALSE)
|
|
{
|
|
PartType = MUIGetString(STRING_UNFORMATTED);
|
|
}
|
|
else if (PartEntry->IsPartitioned != FALSE)
|
|
{
|
|
GetPartTypeStringFromPartitionType(PartEntry->PartitionType,
|
|
PartTypeString,
|
|
ARRAYSIZE(PartTypeString));
|
|
PartType = PartTypeString;
|
|
}
|
|
|
|
PartSize.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
|
|
#if 0
|
|
if (PartSize.QuadPart >= 10737418240) /* 10 GB */
|
|
{
|
|
PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1073741824);
|
|
Unit = MUIGetString(STRING_GB);
|
|
}
|
|
else
|
|
#endif
|
|
if (PartSize.QuadPart >= 10485760) /* 10 MB */
|
|
{
|
|
PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1048576);
|
|
Unit = MUIGetString(STRING_MB);
|
|
}
|
|
else
|
|
{
|
|
PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1024);
|
|
Unit = MUIGetString(STRING_KB);
|
|
}
|
|
|
|
if (strcmp(PartType, MUIGetString(STRING_FORMATUNKNOWN)) == 0)
|
|
{
|
|
sprintf(LineBuffer,
|
|
MUIGetString(STRING_HDDINFOUNK5),
|
|
(PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
|
|
(PartEntry->DriveLetter == 0) ? '-' : ':',
|
|
PartEntry->BootIndicator ? '*' : ' ',
|
|
PartEntry->LogicalPartition ? " " : "",
|
|
PartEntry->PartitionType,
|
|
PartEntry->LogicalPartition ? "" : " ",
|
|
PartSize.u.LowPart,
|
|
Unit);
|
|
}
|
|
else
|
|
{
|
|
sprintf(LineBuffer,
|
|
"%c%c %c %s%-24s%s %6lu %s",
|
|
(PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
|
|
(PartEntry->DriveLetter == 0) ? '-' : ':',
|
|
PartEntry->BootIndicator ? '*' : ' ',
|
|
PartEntry->LogicalPartition ? " " : "",
|
|
PartType,
|
|
PartEntry->LogicalPartition ? "" : " ",
|
|
PartSize.u.LowPart,
|
|
Unit);
|
|
}
|
|
}
|
|
|
|
Attribute = (List->CurrentDisk == DiskEntry &&
|
|
List->CurrentPartition == PartEntry) ?
|
|
FOREGROUND_BLUE | BACKGROUND_WHITE :
|
|
FOREGROUND_WHITE | BACKGROUND_BLUE;
|
|
|
|
if (ListUi->Line >= 0 && ListUi->Line <= Height)
|
|
{
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
' ',
|
|
Width,
|
|
coPos,
|
|
&Written);
|
|
}
|
|
coPos.X += 4;
|
|
Width -= 8;
|
|
if (ListUi->Line >= 0 && ListUi->Line <= Height)
|
|
{
|
|
FillConsoleOutputAttribute(StdOutput,
|
|
Attribute,
|
|
Width,
|
|
coPos,
|
|
&Written);
|
|
}
|
|
coPos.X++;
|
|
Width -= 2;
|
|
if (ListUi->Line >= 0 && ListUi->Line <= Height)
|
|
{
|
|
WriteConsoleOutputCharacterA(StdOutput,
|
|
LineBuffer,
|
|
min(strlen(LineBuffer), Width),
|
|
coPos,
|
|
&Written);
|
|
}
|
|
|
|
ListUi->Line++;
|
|
}
|
|
|
|
static
|
|
VOID
|
|
PrintDiskData(
|
|
IN PPARTLIST_UI ListUi,
|
|
IN PDISKENTRY DiskEntry)
|
|
{
|
|
// PPARTLIST List = ListUi->List;
|
|
PPARTENTRY PrimaryPartEntry, LogicalPartEntry;
|
|
PLIST_ENTRY PrimaryEntry, LogicalEntry;
|
|
CHAR LineBuffer[128];
|
|
COORD coPos;
|
|
ULONG Written;
|
|
USHORT Width;
|
|
USHORT Height;
|
|
ULARGE_INTEGER DiskSize;
|
|
PCHAR Unit;
|
|
|
|
Width = ListUi->Right - ListUi->Left - 1;
|
|
Height = ListUi->Bottom - ListUi->Top - 2;
|
|
|
|
coPos.X = ListUi->Left + 1;
|
|
coPos.Y = ListUi->Top + 1 + ListUi->Line;
|
|
|
|
DiskSize.QuadPart = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
|
|
if (DiskSize.QuadPart >= 10737418240) /* 10 GB */
|
|
{
|
|
DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, 1073741824);
|
|
Unit = MUIGetString(STRING_GB);
|
|
}
|
|
else
|
|
{
|
|
DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, 1048576);
|
|
if (DiskSize.QuadPart == 0)
|
|
DiskSize.QuadPart = 1;
|
|
Unit = MUIGetString(STRING_MB);
|
|
}
|
|
|
|
if (DiskEntry->DriverName.Length > 0)
|
|
{
|
|
sprintf(LineBuffer,
|
|
MUIGetString(STRING_HDINFOPARTSELECT_1),
|
|
DiskSize.u.LowPart,
|
|
Unit,
|
|
DiskEntry->DiskNumber,
|
|
DiskEntry->Port,
|
|
DiskEntry->Bus,
|
|
DiskEntry->Id,
|
|
&DiskEntry->DriverName,
|
|
DiskEntry->NoMbr ? "GPT" : "MBR");
|
|
}
|
|
else
|
|
{
|
|
sprintf(LineBuffer,
|
|
MUIGetString(STRING_HDINFOPARTSELECT_2),
|
|
DiskSize.u.LowPart,
|
|
Unit,
|
|
DiskEntry->DiskNumber,
|
|
DiskEntry->Port,
|
|
DiskEntry->Bus,
|
|
DiskEntry->Id,
|
|
DiskEntry->NoMbr ? "GPT" : "MBR");
|
|
}
|
|
|
|
if (ListUi->Line >= 0 && ListUi->Line <= Height)
|
|
{
|
|
FillConsoleOutputAttribute(StdOutput,
|
|
FOREGROUND_WHITE | BACKGROUND_BLUE,
|
|
Width,
|
|
coPos,
|
|
&Written);
|
|
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
' ',
|
|
Width,
|
|
coPos,
|
|
&Written);
|
|
}
|
|
|
|
coPos.X++;
|
|
if (ListUi->Line >= 0 && ListUi->Line <= Height)
|
|
{
|
|
WriteConsoleOutputCharacterA(StdOutput,
|
|
LineBuffer,
|
|
min((USHORT)strlen(LineBuffer), Width - 2),
|
|
coPos,
|
|
&Written);
|
|
}
|
|
|
|
ListUi->Line++;
|
|
|
|
/* Print separator line */
|
|
PrintEmptyLine(ListUi);
|
|
|
|
/* Print partition lines */
|
|
PrimaryEntry = DiskEntry->PrimaryPartListHead.Flink;
|
|
while (PrimaryEntry != &DiskEntry->PrimaryPartListHead)
|
|
{
|
|
PrimaryPartEntry = CONTAINING_RECORD(PrimaryEntry, PARTENTRY, ListEntry);
|
|
|
|
PrintPartitionData(ListUi,
|
|
DiskEntry,
|
|
PrimaryPartEntry);
|
|
|
|
if (IsContainerPartition(PrimaryPartEntry->PartitionType))
|
|
{
|
|
LogicalEntry = DiskEntry->LogicalPartListHead.Flink;
|
|
while (LogicalEntry != &DiskEntry->LogicalPartListHead)
|
|
{
|
|
LogicalPartEntry = CONTAINING_RECORD(LogicalEntry, PARTENTRY, ListEntry);
|
|
|
|
PrintPartitionData(ListUi,
|
|
DiskEntry,
|
|
LogicalPartEntry);
|
|
|
|
LogicalEntry = LogicalEntry->Flink;
|
|
}
|
|
}
|
|
|
|
PrimaryEntry = PrimaryEntry->Flink;
|
|
}
|
|
|
|
/* Print separator line */
|
|
PrintEmptyLine(ListUi);
|
|
}
|
|
|
|
VOID
|
|
DrawPartitionList(
|
|
IN PPARTLIST_UI ListUi)
|
|
{
|
|
PPARTLIST List = ListUi->List;
|
|
PLIST_ENTRY Entry, Entry2;
|
|
PDISKENTRY DiskEntry;
|
|
PPARTENTRY PartEntry = NULL;
|
|
COORD coPos;
|
|
ULONG Written;
|
|
SHORT i;
|
|
SHORT CurrentDiskLine;
|
|
SHORT CurrentPartLine;
|
|
SHORT LastLine;
|
|
BOOLEAN CurrentPartLineFound = FALSE;
|
|
BOOLEAN CurrentDiskLineFound = FALSE;
|
|
|
|
/* Calculate the line of the current disk and partition */
|
|
CurrentDiskLine = 0;
|
|
CurrentPartLine = 0;
|
|
LastLine = 0;
|
|
|
|
Entry = List->DiskListHead.Flink;
|
|
while (Entry != &List->DiskListHead)
|
|
{
|
|
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
|
|
|
|
LastLine += 2;
|
|
if (CurrentPartLineFound == FALSE)
|
|
{
|
|
CurrentPartLine += 2;
|
|
}
|
|
|
|
Entry2 = DiskEntry->PrimaryPartListHead.Flink;
|
|
while (Entry2 != &DiskEntry->PrimaryPartListHead)
|
|
{
|
|
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
|
|
if (PartEntry == List->CurrentPartition)
|
|
{
|
|
CurrentPartLineFound = TRUE;
|
|
}
|
|
|
|
Entry2 = Entry2->Flink;
|
|
if (CurrentPartLineFound == FALSE)
|
|
{
|
|
CurrentPartLine++;
|
|
}
|
|
|
|
LastLine++;
|
|
}
|
|
|
|
if (CurrentPartLineFound == FALSE)
|
|
{
|
|
Entry2 = DiskEntry->LogicalPartListHead.Flink;
|
|
while (Entry2 != &DiskEntry->LogicalPartListHead)
|
|
{
|
|
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
|
|
if (PartEntry == List->CurrentPartition)
|
|
{
|
|
CurrentPartLineFound = TRUE;
|
|
}
|
|
|
|
Entry2 = Entry2->Flink;
|
|
if (CurrentPartLineFound == FALSE)
|
|
{
|
|
CurrentPartLine++;
|
|
}
|
|
|
|
LastLine++;
|
|
}
|
|
}
|
|
|
|
if (DiskEntry == List->CurrentDisk)
|
|
{
|
|
CurrentDiskLineFound = TRUE;
|
|
}
|
|
|
|
Entry = Entry->Flink;
|
|
if (Entry != &List->DiskListHead)
|
|
{
|
|
if (CurrentDiskLineFound == FALSE)
|
|
{
|
|
CurrentPartLine ++;
|
|
CurrentDiskLine = CurrentPartLine;
|
|
}
|
|
|
|
LastLine++;
|
|
}
|
|
else
|
|
{
|
|
LastLine--;
|
|
}
|
|
}
|
|
|
|
/* If it possible, make the disk name visible */
|
|
if (CurrentPartLine < ListUi->Offset)
|
|
{
|
|
ListUi->Offset = CurrentPartLine;
|
|
}
|
|
else if (CurrentPartLine - ListUi->Offset > ListUi->Bottom - ListUi->Top - 2)
|
|
{
|
|
ListUi->Offset = CurrentPartLine - (ListUi->Bottom - ListUi->Top - 2);
|
|
}
|
|
|
|
if (CurrentDiskLine < ListUi->Offset && CurrentPartLine - CurrentDiskLine < ListUi->Bottom - ListUi->Top - 2)
|
|
{
|
|
ListUi->Offset = CurrentDiskLine;
|
|
}
|
|
|
|
/* Draw upper left corner */
|
|
coPos.X = ListUi->Left;
|
|
coPos.Y = ListUi->Top;
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
0xDA, // '+',
|
|
1,
|
|
coPos,
|
|
&Written);
|
|
|
|
/* Draw upper edge */
|
|
coPos.X = ListUi->Left + 1;
|
|
coPos.Y = ListUi->Top;
|
|
if (ListUi->Offset == 0)
|
|
{
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
0xC4, // '-',
|
|
ListUi->Right - ListUi->Left - 1,
|
|
coPos,
|
|
&Written);
|
|
}
|
|
else
|
|
{
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
0xC4, // '-',
|
|
ListUi->Right - ListUi->Left - 5,
|
|
coPos,
|
|
&Written);
|
|
coPos.X = ListUi->Right - 5;
|
|
WriteConsoleOutputCharacterA(StdOutput,
|
|
"(\x18)", // "(up)"
|
|
3,
|
|
coPos,
|
|
&Written);
|
|
coPos.X = ListUi->Right - 2;
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
0xC4, // '-',
|
|
2,
|
|
coPos,
|
|
&Written);
|
|
}
|
|
|
|
/* Draw upper right corner */
|
|
coPos.X = ListUi->Right;
|
|
coPos.Y = ListUi->Top;
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
0xBF, // '+',
|
|
1,
|
|
coPos,
|
|
&Written);
|
|
|
|
/* Draw left and right edge */
|
|
for (i = ListUi->Top + 1; i < ListUi->Bottom; i++)
|
|
{
|
|
coPos.X = ListUi->Left;
|
|
coPos.Y = i;
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
0xB3, // '|',
|
|
1,
|
|
coPos,
|
|
&Written);
|
|
|
|
coPos.X = ListUi->Right;
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
0xB3, //'|',
|
|
1,
|
|
coPos,
|
|
&Written);
|
|
}
|
|
|
|
/* Draw lower left corner */
|
|
coPos.X = ListUi->Left;
|
|
coPos.Y = ListUi->Bottom;
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
0xC0, // '+',
|
|
1,
|
|
coPos,
|
|
&Written);
|
|
|
|
/* Draw lower edge */
|
|
coPos.X = ListUi->Left + 1;
|
|
coPos.Y = ListUi->Bottom;
|
|
if (LastLine - ListUi->Offset <= ListUi->Bottom - ListUi->Top - 2)
|
|
{
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
0xC4, // '-',
|
|
ListUi->Right - ListUi->Left - 1,
|
|
coPos,
|
|
&Written);
|
|
}
|
|
else
|
|
{
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
0xC4, // '-',
|
|
ListUi->Right - ListUi->Left - 5,
|
|
coPos,
|
|
&Written);
|
|
coPos.X = ListUi->Right - 5;
|
|
WriteConsoleOutputCharacterA(StdOutput,
|
|
"(\x19)", // "(down)"
|
|
3,
|
|
coPos,
|
|
&Written);
|
|
coPos.X = ListUi->Right - 2;
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
0xC4, // '-',
|
|
2,
|
|
coPos,
|
|
&Written);
|
|
}
|
|
|
|
/* Draw lower right corner */
|
|
coPos.X = ListUi->Right;
|
|
coPos.Y = ListUi->Bottom;
|
|
FillConsoleOutputCharacterA(StdOutput,
|
|
0xD9, // '+',
|
|
1,
|
|
coPos,
|
|
&Written);
|
|
|
|
/* print list entries */
|
|
ListUi->Line = - ListUi->Offset;
|
|
|
|
Entry = List->DiskListHead.Flink;
|
|
while (Entry != &List->DiskListHead)
|
|
{
|
|
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
|
|
|
|
/* Print disk entry */
|
|
PrintDiskData(ListUi, DiskEntry);
|
|
|
|
Entry = Entry->Flink;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ScrollDownPartitionList(
|
|
IN PPARTLIST_UI ListUi)
|
|
{
|
|
if (GetNextPartition(ListUi->List))
|
|
DrawPartitionList(ListUi);
|
|
}
|
|
|
|
VOID
|
|
ScrollUpPartitionList(
|
|
IN PPARTLIST_UI ListUi)
|
|
{
|
|
if (GetPrevPartition(ListUi->List))
|
|
DrawPartitionList(ListUi);
|
|
}
|
|
|
|
/* EOF */
|