2002-10-18 20:04:00 +00:00
|
|
|
/*
|
2002-10-29 18:40:02 +00:00
|
|
|
* ReactOS kernel
|
2003-08-04 15:54:05 +00:00
|
|
|
* Copyright (C) 2002, 2003 ReactOS Team
|
2002-10-29 18:40:02 +00:00
|
|
|
*
|
|
|
|
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
2003-08-09 16:32:26 +00:00
|
|
|
/* $Id: partlist.c,v 1.16 2003/08/09 16:32:25 ekohl Exp $
|
2002-10-29 18:40:02 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS text-mode setup
|
|
|
|
* FILE: subsys/system/usetup/partlist.c
|
|
|
|
* PURPOSE: Partition list functions
|
|
|
|
* PROGRAMMER: Eric Kohl
|
2003-04-28 19:44:13 +00:00
|
|
|
* Casper S. Hornstrup (chorns@users.sourceforge.net)
|
2002-10-18 20:04:00 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <ddk/ntddk.h>
|
|
|
|
#include <ddk/ntddscsi.h>
|
|
|
|
|
|
|
|
#include <ntdll/rtl.h>
|
|
|
|
|
|
|
|
#include <ntos/minmax.h>
|
|
|
|
|
|
|
|
#include "usetup.h"
|
2002-10-29 18:40:02 +00:00
|
|
|
#include "console.h"
|
2002-10-18 20:04:00 +00:00
|
|
|
#include "partlist.h"
|
2002-11-02 23:17:06 +00:00
|
|
|
#include "drivesup.h"
|
2002-10-18 20:04:00 +00:00
|
|
|
|
|
|
|
|
2002-10-29 18:40:02 +00:00
|
|
|
/* FUNCTIONS ****************************************************************/
|
2002-10-18 20:04:00 +00:00
|
|
|
|
2002-11-13 18:25:18 +00:00
|
|
|
static VOID
|
2003-08-02 16:49:36 +00:00
|
|
|
GetDriverName(PDISKENTRY DiskEntry)
|
|
|
|
{
|
|
|
|
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
|
|
|
WCHAR KeyName[32];
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2003-08-05 20:39:24 +00:00
|
|
|
#if 0
|
|
|
|
RtlCreateUnicodeString (&DiskEntry->DriverName,
|
|
|
|
L"atapi");
|
|
|
|
#endif
|
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
RtlInitUnicodeString(&DiskEntry->DriverName,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
swprintf(KeyName,
|
|
|
|
L"\\Scsi\\Scsi Port %lu",
|
|
|
|
DiskEntry->Port);
|
|
|
|
|
|
|
|
RtlZeroMemory(&QueryTable,
|
|
|
|
sizeof(QueryTable));
|
|
|
|
|
|
|
|
QueryTable[0].Name = L"Driver";
|
|
|
|
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
|
|
QueryTable[0].EntryContext = &DiskEntry->DriverName;
|
|
|
|
|
|
|
|
Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
|
|
|
|
KeyName,
|
|
|
|
QueryTable,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-08-09 16:32:26 +00:00
|
|
|
static VOID
|
|
|
|
AssignDriverLetters (PPARTLIST List)
|
|
|
|
{
|
|
|
|
PDISKENTRY DiskEntry;
|
|
|
|
PPARTENTRY PartEntry;
|
|
|
|
PLIST_ENTRY Entry1;
|
|
|
|
PLIST_ENTRY Entry2;
|
|
|
|
CHAR Letter;
|
|
|
|
|
|
|
|
Letter = 'C';
|
|
|
|
|
|
|
|
/* Assign drive letters to primary partitions */
|
|
|
|
Entry1 = List->DiskListHead.Flink;
|
|
|
|
while (Entry1 != &List->DiskListHead)
|
|
|
|
{
|
|
|
|
DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry);
|
|
|
|
|
|
|
|
if (!IsListEmpty (&DiskEntry->PartListHead))
|
|
|
|
{
|
|
|
|
PartEntry = CONTAINING_RECORD (DiskEntry->PartListHead.Flink,
|
|
|
|
PARTENTRY,
|
|
|
|
ListEntry);
|
|
|
|
|
|
|
|
PartEntry->DriveLetter = 0;
|
|
|
|
|
|
|
|
if (PartEntry->Unpartitioned == FALSE &&
|
|
|
|
!IsContainerPartition(PartEntry->PartInfo[0].PartitionType))
|
|
|
|
{
|
|
|
|
if (IsRecognizedPartition(PartEntry->PartInfo[0].PartitionType) ||
|
|
|
|
(PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED &&
|
|
|
|
PartEntry->PartInfo[0].PartitionLength.QuadPart != 0LL))
|
|
|
|
{
|
|
|
|
if (Letter <= 'Z')
|
|
|
|
{
|
|
|
|
PartEntry->DriveLetter = Letter;
|
|
|
|
Letter++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Entry1 = Entry1->Flink;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Assign drive letters to logical drives */
|
|
|
|
Entry1 = List->DiskListHead.Flink;
|
|
|
|
while (Entry1 != &List->DiskListHead)
|
|
|
|
{
|
|
|
|
DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry);
|
|
|
|
|
|
|
|
Entry2 = DiskEntry->PartListHead.Flink;
|
|
|
|
if (Entry2 != &DiskEntry->PartListHead)
|
|
|
|
{
|
|
|
|
Entry2 = Entry2->Flink;
|
|
|
|
while (Entry2 != &DiskEntry->PartListHead)
|
|
|
|
{
|
|
|
|
PartEntry = CONTAINING_RECORD (Entry2,
|
|
|
|
PARTENTRY,
|
|
|
|
ListEntry);
|
|
|
|
|
|
|
|
PartEntry->DriveLetter = 0;
|
|
|
|
|
|
|
|
if (PartEntry->Unpartitioned == FALSE &&
|
|
|
|
!IsContainerPartition(PartEntry->PartInfo[0].PartitionType))
|
|
|
|
{
|
|
|
|
if (IsRecognizedPartition(PartEntry->PartInfo[0].PartitionType) ||
|
|
|
|
(PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED &&
|
|
|
|
PartEntry->PartInfo[0].PartitionLength.QuadPart != 0LL))
|
|
|
|
{
|
|
|
|
if (Letter <= 'Z')
|
|
|
|
{
|
|
|
|
PartEntry->DriveLetter = Letter;
|
|
|
|
Letter++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Entry2 = Entry2->Flink;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Entry1 = Entry1->Flink;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static VOID
|
|
|
|
UpdatePartitionNumbers (PDISKENTRY DiskEntry)
|
|
|
|
{
|
|
|
|
PPARTENTRY PartEntry;
|
|
|
|
PLIST_ENTRY Entry;
|
|
|
|
ULONG PartNumber;
|
|
|
|
ULONG i;
|
|
|
|
|
|
|
|
PartNumber = 1;
|
|
|
|
Entry = DiskEntry->PartListHead.Flink;
|
|
|
|
while (Entry != &DiskEntry->PartListHead)
|
|
|
|
{
|
|
|
|
PartEntry = CONTAINING_RECORD (Entry,
|
|
|
|
PARTENTRY,
|
|
|
|
ListEntry);
|
|
|
|
|
|
|
|
if (PartEntry->Unpartitioned == TRUE)
|
|
|
|
{
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
PartEntry->PartInfo[i].PartitionNumber = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
if (IsContainerPartition(PartEntry->PartInfo[i].PartitionType))
|
|
|
|
{
|
|
|
|
PartEntry->PartInfo[i].PartitionNumber = 0;
|
|
|
|
}
|
|
|
|
else if (PartEntry->PartInfo[i].PartitionType == PARTITION_ENTRY_UNUSED &&
|
|
|
|
PartEntry->PartInfo[i].PartitionLength.QuadPart == 0ULL)
|
|
|
|
{
|
|
|
|
PartEntry->PartInfo[i].PartitionNumber = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PartEntry->PartInfo[i].PartitionNumber = PartNumber;
|
|
|
|
PartNumber++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Entry = Entry->Flink;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
static VOID
|
|
|
|
AddPartitionToList (ULONG DiskNumber,
|
|
|
|
PDISKENTRY DiskEntry,
|
|
|
|
DRIVE_LAYOUT_INFORMATION *LayoutBuffer)
|
2002-11-13 18:25:18 +00:00
|
|
|
{
|
|
|
|
PPARTENTRY PartEntry;
|
|
|
|
ULONG i;
|
2003-08-03 12:20:22 +00:00
|
|
|
ULONG j;
|
|
|
|
|
|
|
|
for (i = 0; i < LayoutBuffer->PartitionCount; i += 4)
|
2002-11-13 18:25:18 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
PartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
sizeof(PARTENTRY));
|
|
|
|
if (PartEntry == NULL)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
RtlZeroMemory (PartEntry,
|
|
|
|
sizeof(PARTENTRY));
|
|
|
|
|
|
|
|
PartEntry->Unpartitioned = FALSE;
|
2002-11-13 18:25:18 +00:00
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
for (j = 0; j < 4; j++)
|
|
|
|
{
|
|
|
|
RtlCopyMemory (&PartEntry->PartInfo[j],
|
|
|
|
&LayoutBuffer->PartitionEntry[i+j],
|
|
|
|
sizeof(PARTITION_INFORMATION));
|
|
|
|
}
|
|
|
|
|
|
|
|
InsertTailList (&DiskEntry->PartListHead,
|
|
|
|
&PartEntry->ListEntry);
|
|
|
|
}
|
|
|
|
}
|
2002-11-13 18:25:18 +00:00
|
|
|
|
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
static VOID
|
|
|
|
ScanForUnpartitionedDiskSpace (PDISKENTRY DiskEntry)
|
|
|
|
{
|
|
|
|
ULONGLONG LastStartingOffset;
|
|
|
|
ULONGLONG LastPartitionLength;
|
|
|
|
ULONGLONG LastUnusedPartitionLength;
|
|
|
|
PPARTENTRY PartEntry;
|
|
|
|
PPARTENTRY NewPartEntry;
|
|
|
|
PLIST_ENTRY Entry;
|
|
|
|
ULONG i;
|
|
|
|
ULONG j;
|
2002-11-13 18:25:18 +00:00
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
if (IsListEmpty (&DiskEntry->PartListHead))
|
2002-11-13 18:25:18 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
/* Create a partition table that represents the empty disk */
|
|
|
|
PartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
sizeof(PARTENTRY));
|
|
|
|
if (PartEntry == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
RtlZeroMemory (PartEntry,
|
|
|
|
sizeof(PARTENTRY));
|
2002-11-13 18:25:18 +00:00
|
|
|
|
|
|
|
PartEntry->Unpartitioned = TRUE;
|
2003-08-03 12:20:22 +00:00
|
|
|
PartEntry->UnpartitionedOffset = 0ULL;
|
|
|
|
PartEntry->UnpartitionedLength = DiskEntry->DiskSize;
|
|
|
|
|
|
|
|
InsertTailList (&DiskEntry->PartListHead,
|
|
|
|
&PartEntry->ListEntry);
|
2002-11-13 18:25:18 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
/* Start partition at head 1, cylinder 0 */
|
|
|
|
LastStartingOffset = DiskEntry->TrackSize;
|
|
|
|
LastPartitionLength = 0ULL;
|
|
|
|
LastUnusedPartitionLength = 0ULL;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
Entry = DiskEntry->PartListHead.Flink;
|
|
|
|
while (Entry != &DiskEntry->PartListHead)
|
2002-11-13 18:25:18 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
PartEntry = CONTAINING_RECORD (Entry, PARTENTRY, ListEntry);
|
2002-11-13 18:25:18 +00:00
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
for (j = 0; j < 4; j++)
|
2002-11-13 18:25:18 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
if ((!IsContainerPartition(PartEntry->PartInfo[j].PartitionType)) &&
|
|
|
|
(PartEntry->PartInfo[j].PartitionType != PARTITION_ENTRY_UNUSED ||
|
|
|
|
PartEntry->PartInfo[j].PartitionLength.QuadPart != 0LL))
|
|
|
|
{
|
|
|
|
LastUnusedPartitionLength =
|
|
|
|
PartEntry->PartInfo[j].StartingOffset.QuadPart -
|
|
|
|
(LastStartingOffset + LastPartitionLength);
|
|
|
|
|
|
|
|
if (LastUnusedPartitionLength >= DiskEntry->CylinderSize)
|
|
|
|
{
|
|
|
|
DPRINT ("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength);
|
|
|
|
|
|
|
|
NewPartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
sizeof(PARTENTRY));
|
|
|
|
if (NewPartEntry == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
RtlZeroMemory (NewPartEntry,
|
|
|
|
sizeof(PARTENTRY));
|
|
|
|
|
|
|
|
NewPartEntry->Unpartitioned = TRUE;
|
|
|
|
NewPartEntry->UnpartitionedOffset = LastStartingOffset + LastPartitionLength;
|
|
|
|
NewPartEntry->UnpartitionedLength = LastUnusedPartitionLength;
|
|
|
|
if (j == 0)
|
|
|
|
NewPartEntry->UnpartitionedLength -= DiskEntry->TrackSize;
|
|
|
|
|
|
|
|
/* Insert the table into the list */
|
|
|
|
InsertTailList (&PartEntry->ListEntry,
|
|
|
|
&NewPartEntry->ListEntry);
|
|
|
|
}
|
|
|
|
|
|
|
|
LastStartingOffset = PartEntry->PartInfo[j].StartingOffset.QuadPart;
|
|
|
|
LastPartitionLength = PartEntry->PartInfo[j].PartitionLength.QuadPart;
|
|
|
|
}
|
2002-11-13 18:25:18 +00:00
|
|
|
}
|
2003-08-03 12:20:22 +00:00
|
|
|
|
|
|
|
i += 4;
|
|
|
|
Entry = Entry->Flink;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for trailing unpartitioned disk space */
|
|
|
|
if (DiskEntry->DiskSize > (LastStartingOffset + LastPartitionLength))
|
|
|
|
{
|
2003-08-09 16:32:26 +00:00
|
|
|
/* Round-down to cylinder size */
|
2003-08-05 20:39:24 +00:00
|
|
|
LastUnusedPartitionLength =
|
|
|
|
ROUND_DOWN (DiskEntry->DiskSize - (LastStartingOffset + LastPartitionLength),
|
|
|
|
DiskEntry->CylinderSize);
|
2003-08-03 12:20:22 +00:00
|
|
|
|
|
|
|
if (LastUnusedPartitionLength >= DiskEntry->CylinderSize)
|
2002-11-13 18:25:18 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
DPRINT ("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength);
|
|
|
|
|
|
|
|
NewPartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
sizeof(PARTENTRY));
|
|
|
|
if (NewPartEntry == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
RtlZeroMemory (NewPartEntry,
|
|
|
|
sizeof(PARTENTRY));
|
|
|
|
|
|
|
|
NewPartEntry->Unpartitioned = TRUE;
|
|
|
|
NewPartEntry->UnpartitionedOffset = LastStartingOffset + LastPartitionLength;
|
|
|
|
NewPartEntry->UnpartitionedLength = LastUnusedPartitionLength;
|
|
|
|
|
|
|
|
/* Append the table to the list */
|
|
|
|
InsertTailList (&DiskEntry->PartListHead,
|
|
|
|
&NewPartEntry->ListEntry);
|
2002-11-13 18:25:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-11-28 19:20:38 +00:00
|
|
|
static VOID
|
2003-08-02 16:49:36 +00:00
|
|
|
AddDiskToList (HANDLE FileHandle,
|
|
|
|
ULONG DiskNumber,
|
|
|
|
PPARTLIST List)
|
2002-11-28 19:20:38 +00:00
|
|
|
{
|
2003-08-02 16:49:36 +00:00
|
|
|
DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
|
|
|
|
DISK_GEOMETRY DiskGeometry;
|
|
|
|
SCSI_ADDRESS ScsiAddress;
|
|
|
|
PDISKENTRY DiskEntry;
|
|
|
|
IO_STATUS_BLOCK Iosb;
|
2002-11-28 19:20:38 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
Status = NtDeviceIoControlFile (FileHandle,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&Iosb,
|
|
|
|
IOCTL_DISK_GET_DRIVE_GEOMETRY,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
&DiskGeometry,
|
|
|
|
sizeof(DISK_GEOMETRY));
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2002-11-28 19:20:38 +00:00
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
if (DiskGeometry.MediaType != FixedMedia)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2002-11-28 19:20:38 +00:00
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
Status = NtDeviceIoControlFile (FileHandle,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&Iosb,
|
|
|
|
IOCTL_SCSI_GET_ADDRESS,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
&ScsiAddress,
|
|
|
|
sizeof(SCSI_ADDRESS));
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2002-11-28 19:20:38 +00:00
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
DiskEntry = (PDISKENTRY)RtlAllocateHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
sizeof(DISKENTRY));
|
|
|
|
if (DiskEntry == NULL)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2002-11-28 19:20:38 +00:00
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
InitializeListHead (&DiskEntry->PartListHead);
|
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
|
|
|
|
DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
|
|
|
|
DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
|
|
|
|
DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
|
|
|
|
|
|
|
|
DPRINT("Cylinders %d\n", DiskEntry->Cylinders);
|
|
|
|
DPRINT("TracksPerCylinder %d\n", DiskEntry->TracksPerCylinder);
|
|
|
|
DPRINT("SectorsPerTrack %d\n", DiskEntry->SectorsPerTrack);
|
|
|
|
DPRINT("BytesPerSector %d\n", DiskEntry->BytesPerSector);
|
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
DiskEntry->DiskSize =
|
2003-08-02 16:49:36 +00:00
|
|
|
DiskGeometry.Cylinders.QuadPart *
|
|
|
|
(ULONGLONG)DiskGeometry.TracksPerCylinder *
|
|
|
|
(ULONGLONG)DiskGeometry.SectorsPerTrack *
|
|
|
|
(ULONGLONG)DiskGeometry.BytesPerSector;
|
2003-08-03 12:20:22 +00:00
|
|
|
DiskEntry->CylinderSize =
|
|
|
|
(ULONGLONG)DiskGeometry.TracksPerCylinder *
|
|
|
|
(ULONGLONG)DiskGeometry.SectorsPerTrack *
|
|
|
|
(ULONGLONG)DiskGeometry.BytesPerSector;
|
|
|
|
DiskEntry->TrackSize =
|
|
|
|
(ULONGLONG)DiskGeometry.SectorsPerTrack *
|
|
|
|
(ULONGLONG)DiskGeometry.BytesPerSector;
|
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
DiskEntry->DiskNumber = DiskNumber;
|
|
|
|
DiskEntry->Port = ScsiAddress.PortNumber;
|
|
|
|
DiskEntry->Bus = ScsiAddress.PathId;
|
|
|
|
DiskEntry->Id = ScsiAddress.TargetId;
|
|
|
|
|
2003-08-09 16:32:26 +00:00
|
|
|
DiskEntry->UseLba = (DiskEntry->DiskSize > (1024ULL * 255ULL * 63ULL * 512ULL));
|
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
GetDriverName (DiskEntry);
|
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
InsertTailList (&List->DiskListHead,
|
|
|
|
&DiskEntry->ListEntry);
|
2003-08-02 16:49:36 +00:00
|
|
|
|
|
|
|
LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
8192);
|
|
|
|
if (LayoutBuffer == NULL)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = NtDeviceIoControlFile (FileHandle,
|
2002-11-28 19:20:38 +00:00
|
|
|
NULL,
|
2003-08-02 16:49:36 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&Iosb,
|
|
|
|
IOCTL_DISK_GET_DRIVE_LAYOUT,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
LayoutBuffer,
|
|
|
|
8192);
|
|
|
|
if (NT_SUCCESS (Status))
|
2002-11-28 19:20:38 +00:00
|
|
|
{
|
2003-08-02 16:49:36 +00:00
|
|
|
AddPartitionToList (DiskNumber,
|
|
|
|
DiskEntry,
|
|
|
|
LayoutBuffer);
|
2003-08-03 12:20:22 +00:00
|
|
|
|
|
|
|
ScanForUnpartitionedDiskSpace (DiskEntry);
|
2002-11-28 19:20:38 +00:00
|
|
|
}
|
2003-08-02 16:49:36 +00:00
|
|
|
|
|
|
|
RtlFreeHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
LayoutBuffer);
|
2002-11-28 19:20:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-18 20:04:00 +00:00
|
|
|
PPARTLIST
|
2003-08-02 16:49:36 +00:00
|
|
|
InitializePartitionList(VOID)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
|
|
|
PPARTLIST List;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
SYSTEM_DEVICE_INFORMATION Sdi;
|
|
|
|
DISK_GEOMETRY DiskGeometry;
|
2002-11-13 18:25:18 +00:00
|
|
|
IO_STATUS_BLOCK Iosb;
|
2002-10-18 20:04:00 +00:00
|
|
|
ULONG ReturnSize;
|
|
|
|
NTSTATUS Status;
|
2002-11-13 18:25:18 +00:00
|
|
|
ULONG DiskNumber;
|
2002-10-18 20:04:00 +00:00
|
|
|
WCHAR Buffer[MAX_PATH];
|
|
|
|
UNICODE_STRING Name;
|
|
|
|
HANDLE FileHandle;
|
|
|
|
|
2003-08-05 20:39:24 +00:00
|
|
|
List = (PPARTLIST)RtlAllocateHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
sizeof (PARTLIST));
|
2002-10-18 20:04:00 +00:00
|
|
|
if (List == NULL)
|
2003-08-05 20:39:24 +00:00
|
|
|
return NULL;
|
2002-10-18 20:04:00 +00:00
|
|
|
|
2003-04-05 15:36:34 +00:00
|
|
|
List->Left = 0;
|
|
|
|
List->Top = 0;
|
|
|
|
List->Right = 0;
|
|
|
|
List->Bottom = 0;
|
2002-10-18 20:04:00 +00:00
|
|
|
|
2002-10-29 18:40:02 +00:00
|
|
|
List->Line = 0;
|
|
|
|
|
2002-10-18 20:04:00 +00:00
|
|
|
List->TopDisk = (ULONG)-1;
|
|
|
|
List->TopPartition = (ULONG)-1;
|
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
List->CurrentDisk = NULL;
|
2003-08-03 12:20:22 +00:00
|
|
|
List->CurrentPartition = NULL;
|
2002-10-18 20:04:00 +00:00
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
InitializeListHead (&List->DiskListHead);
|
2002-10-18 20:04:00 +00:00
|
|
|
|
|
|
|
Status = NtQuerySystemInformation(SystemDeviceInformation,
|
|
|
|
&Sdi,
|
|
|
|
sizeof(SYSTEM_DEVICE_INFORMATION),
|
|
|
|
&ReturnSize);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
RtlFreeHeap(ProcessHeap, 0, List);
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
2002-11-13 18:25:18 +00:00
|
|
|
for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
|
|
|
swprintf(Buffer,
|
|
|
|
L"\\Device\\Harddisk%d\\Partition0",
|
2002-11-13 18:25:18 +00:00
|
|
|
DiskNumber);
|
2002-10-18 20:04:00 +00:00
|
|
|
RtlInitUnicodeString(&Name,
|
|
|
|
Buffer);
|
|
|
|
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&Name,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
Status = NtOpenFile(&FileHandle,
|
|
|
|
0x10001,
|
|
|
|
&ObjectAttributes,
|
|
|
|
&Iosb,
|
|
|
|
1,
|
|
|
|
FILE_SYNCHRONOUS_IO_NONALERT);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2003-08-02 16:49:36 +00:00
|
|
|
AddDiskToList (FileHandle,
|
|
|
|
DiskNumber,
|
|
|
|
List);
|
2002-10-18 20:04:00 +00:00
|
|
|
|
|
|
|
NtClose(FileHandle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-08-09 16:32:26 +00:00
|
|
|
AssignDriverLetters (List);
|
|
|
|
|
2002-10-18 20:04:00 +00:00
|
|
|
List->TopDisk = 0;
|
|
|
|
List->TopPartition = 0;
|
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
/* Search for first usable disk and partition */
|
2003-08-03 12:20:22 +00:00
|
|
|
if (IsListEmpty (&List->DiskListHead))
|
2003-08-02 16:49:36 +00:00
|
|
|
{
|
|
|
|
List->CurrentDisk = NULL;
|
2003-08-03 12:20:22 +00:00
|
|
|
List->CurrentPartition = NULL;
|
2003-08-02 16:49:36 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-08-05 20:39:24 +00:00
|
|
|
List->CurrentDisk =
|
|
|
|
CONTAINING_RECORD (List->DiskListHead.Flink,
|
|
|
|
DISKENTRY,
|
|
|
|
ListEntry);
|
2003-08-03 12:20:22 +00:00
|
|
|
|
|
|
|
if (IsListEmpty (&List->CurrentDisk->PartListHead))
|
|
|
|
{
|
|
|
|
List->CurrentPartition = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-08-05 20:39:24 +00:00
|
|
|
List->CurrentPartition =
|
|
|
|
CONTAINING_RECORD (List->CurrentDisk->PartListHead.Flink,
|
|
|
|
PARTENTRY,
|
|
|
|
ListEntry);
|
2003-08-03 12:20:22 +00:00
|
|
|
}
|
2003-08-02 16:49:36 +00:00
|
|
|
}
|
2002-10-18 20:04:00 +00:00
|
|
|
|
2003-08-05 20:39:24 +00:00
|
|
|
return List;
|
2003-04-05 15:36:34 +00:00
|
|
|
}
|
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
|
2003-04-05 15:36:34 +00:00
|
|
|
PPARTLIST
|
|
|
|
CreatePartitionList(SHORT Left,
|
|
|
|
SHORT Top,
|
|
|
|
SHORT Right,
|
|
|
|
SHORT Bottom)
|
|
|
|
{
|
|
|
|
PPARTLIST List;
|
|
|
|
|
2003-08-05 20:39:24 +00:00
|
|
|
List = InitializePartitionList ();
|
2003-04-05 15:36:34 +00:00
|
|
|
if (List == NULL)
|
2003-08-05 20:39:24 +00:00
|
|
|
return NULL;
|
2003-04-05 15:36:34 +00:00
|
|
|
|
|
|
|
List->Left = Left;
|
|
|
|
List->Top = Top;
|
|
|
|
List->Right = Right;
|
|
|
|
List->Bottom = Bottom;
|
|
|
|
|
2003-08-05 20:39:24 +00:00
|
|
|
DrawPartitionList (List);
|
2003-04-05 15:36:34 +00:00
|
|
|
|
2003-08-05 20:39:24 +00:00
|
|
|
return List;
|
2003-04-05 15:36:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-18 20:04:00 +00:00
|
|
|
VOID
|
|
|
|
DestroyPartitionList(PPARTLIST List)
|
|
|
|
{
|
2003-08-02 16:49:36 +00:00
|
|
|
PDISKENTRY DiskEntry;
|
2003-08-03 12:20:22 +00:00
|
|
|
PPARTENTRY PartEntry;
|
|
|
|
PLIST_ENTRY Entry;
|
2002-10-18 20:04:00 +00:00
|
|
|
#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
|
|
|
|
|
2002-11-28 19:20:38 +00:00
|
|
|
/* Release disk and partition info */
|
2003-08-03 12:20:22 +00:00
|
|
|
while (!IsListEmpty (&List->DiskListHead))
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
Entry = RemoveHeadList (&List->DiskListHead);
|
2003-08-02 16:49:36 +00:00
|
|
|
DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry);
|
2002-11-28 19:20:38 +00:00
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
/* Release driver name */
|
|
|
|
RtlFreeUnicodeString(&DiskEntry->DriverName);
|
|
|
|
|
|
|
|
/* Release partition array */
|
2003-08-03 12:20:22 +00:00
|
|
|
while (!IsListEmpty (&DiskEntry->PartListHead))
|
2003-08-02 16:49:36 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
Entry = RemoveHeadList (&DiskEntry->PartListHead);
|
|
|
|
PartEntry = CONTAINING_RECORD (Entry, PARTENTRY, ListEntry);
|
|
|
|
|
|
|
|
RtlFreeHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
PartEntry);
|
2002-10-18 20:04:00 +00:00
|
|
|
}
|
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
/* Release disk entry */
|
|
|
|
RtlFreeHeap (ProcessHeap, 0, DiskEntry);
|
2002-10-18 20:04:00 +00:00
|
|
|
}
|
|
|
|
|
2002-11-28 19:20:38 +00:00
|
|
|
/* Release list head */
|
2003-08-02 16:49:36 +00:00
|
|
|
RtlFreeHeap (ProcessHeap, 0, List);
|
2002-10-18 20:04:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static VOID
|
2002-10-29 18:40:02 +00:00
|
|
|
PrintEmptyLine(PPARTLIST List)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
|
|
|
COORD coPos;
|
|
|
|
ULONG Written;
|
|
|
|
USHORT Width;
|
|
|
|
USHORT Height;
|
|
|
|
|
|
|
|
Width = List->Right - List->Left - 1;
|
|
|
|
Height = List->Bottom - List->Top - 1;
|
|
|
|
|
2002-10-29 18:40:02 +00:00
|
|
|
if (List->Line < 0 || List->Line > Height)
|
2002-10-18 20:04:00 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
coPos.X = List->Left + 1;
|
2002-10-29 18:40:02 +00:00
|
|
|
coPos.Y = List->Top + 1 + List->Line;
|
2002-10-18 20:04:00 +00:00
|
|
|
|
|
|
|
FillConsoleOutputAttribute(0x17,
|
|
|
|
Width,
|
|
|
|
coPos,
|
|
|
|
&Written);
|
|
|
|
|
|
|
|
FillConsoleOutputCharacter(' ',
|
|
|
|
Width,
|
|
|
|
coPos,
|
|
|
|
&Written);
|
2002-10-29 18:40:02 +00:00
|
|
|
|
|
|
|
List->Line++;
|
2002-10-18 20:04:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static VOID
|
2002-10-29 18:40:02 +00:00
|
|
|
PrintPartitionData(PPARTLIST List,
|
2003-08-02 16:49:36 +00:00
|
|
|
PDISKENTRY DiskEntry,
|
2003-08-03 12:20:22 +00:00
|
|
|
PPARTENTRY PartEntry)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
2002-10-29 18:40:02 +00:00
|
|
|
CHAR LineBuffer[128];
|
2002-10-18 20:04:00 +00:00
|
|
|
COORD coPos;
|
|
|
|
ULONG Written;
|
|
|
|
USHORT Width;
|
|
|
|
USHORT Height;
|
|
|
|
|
2002-10-29 18:40:02 +00:00
|
|
|
ULONGLONG PartSize;
|
|
|
|
PCHAR Unit;
|
|
|
|
UCHAR Attribute;
|
2002-11-13 18:25:18 +00:00
|
|
|
PCHAR PartType;
|
2002-10-29 18:40:02 +00:00
|
|
|
|
2002-10-18 20:04:00 +00:00
|
|
|
Width = List->Right - List->Left - 1;
|
|
|
|
Height = List->Bottom - List->Top - 1;
|
|
|
|
|
2002-10-29 18:40:02 +00:00
|
|
|
if (List->Line < 0 || List->Line > Height)
|
2002-10-18 20:04:00 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
coPos.X = List->Left + 1;
|
2002-10-29 18:40:02 +00:00
|
|
|
coPos.Y = List->Top + 1 + List->Line;
|
2002-10-18 20:04:00 +00:00
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
if (PartEntry->Unpartitioned == TRUE)
|
2002-10-29 18:40:02 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
#if 0
|
|
|
|
if (PartEntry->UnpartitionledLength >= 0x280000000ULL) /* 10 GB */
|
2002-11-13 18:25:18 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
PartSize = (PartEntry->UnpartitionedLength + (1 << 29)) >> 30;
|
|
|
|
Unit = "GB";
|
2002-11-13 18:25:18 +00:00
|
|
|
}
|
2003-08-03 12:20:22 +00:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
if (PartEntry->UnpartitionedLength >= 0xA00000ULL) /* 10 MB */
|
2002-11-13 18:25:18 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
PartSize = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20;
|
|
|
|
Unit = "MB";
|
2002-11-13 18:25:18 +00:00
|
|
|
}
|
2003-08-03 12:20:22 +00:00
|
|
|
else
|
2002-11-13 18:25:18 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
PartSize = (PartEntry->UnpartitionedLength + (1 << 9)) >> 10;
|
|
|
|
Unit = "KB";
|
2002-11-13 18:25:18 +00:00
|
|
|
}
|
|
|
|
|
2002-11-02 23:17:06 +00:00
|
|
|
sprintf(LineBuffer,
|
2003-08-03 12:20:22 +00:00
|
|
|
" Unpartitioned space %6I64u %s",
|
2002-11-13 18:25:18 +00:00
|
|
|
PartSize,
|
|
|
|
Unit);
|
|
|
|
}
|
2003-08-03 12:20:22 +00:00
|
|
|
else
|
2002-11-13 18:25:18 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
|
|
|
|
/* Determine partition type */
|
|
|
|
PartType = NULL;
|
2003-08-05 20:39:24 +00:00
|
|
|
if (PartEntry->New == TRUE)
|
|
|
|
{
|
|
|
|
PartType = "New (Unformatted)";
|
|
|
|
}
|
|
|
|
else if (PartEntry->Unpartitioned == FALSE)
|
2002-11-13 18:25:18 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_12) ||
|
|
|
|
(PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_16) ||
|
|
|
|
(PartEntry->PartInfo[0].PartitionType == PARTITION_HUGE) ||
|
|
|
|
(PartEntry->PartInfo[0].PartitionType == PARTITION_XINT13))
|
|
|
|
{
|
|
|
|
PartType = "FAT";
|
|
|
|
}
|
|
|
|
else if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32) ||
|
|
|
|
(PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
|
|
|
|
{
|
|
|
|
PartType = "FAT32";
|
|
|
|
}
|
|
|
|
else if (PartEntry->PartInfo[0].PartitionType == PARTITION_IFS)
|
|
|
|
{
|
|
|
|
PartType = "NTFS"; /* FIXME: Not quite correct! */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0x280000000ULL) /* 10 GB */
|
|
|
|
{
|
|
|
|
PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 29)) >> 30;
|
|
|
|
Unit = "GB";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0xA00000ULL) /* 10 MB */
|
|
|
|
{
|
|
|
|
PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 19)) >> 20;
|
|
|
|
Unit = "MB";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 9)) >> 10;
|
|
|
|
Unit = "KB";
|
|
|
|
}
|
|
|
|
|
2003-08-05 20:39:24 +00:00
|
|
|
if (PartType == NULL)
|
2003-08-03 12:20:22 +00:00
|
|
|
{
|
2003-08-05 20:39:24 +00:00
|
|
|
sprintf (LineBuffer,
|
2003-08-06 16:37:46 +00:00
|
|
|
"%c%c Type %-3lu %6I64u %s",
|
2003-08-05 20:39:24 +00:00
|
|
|
(PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
|
|
|
|
(PartEntry->DriveLetter == 0) ? '-' : ':',
|
|
|
|
PartEntry->PartInfo[0].PartitionType,
|
|
|
|
PartSize,
|
|
|
|
Unit);
|
2002-11-13 18:25:18 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-08-05 20:39:24 +00:00
|
|
|
sprintf (LineBuffer,
|
|
|
|
"%c%c %-24s %6I64u %s",
|
|
|
|
(PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
|
|
|
|
(PartEntry->DriveLetter == 0) ? '-' : ':',
|
|
|
|
PartType,
|
|
|
|
PartSize,
|
|
|
|
Unit);
|
2002-11-13 18:25:18 +00:00
|
|
|
}
|
2002-11-02 23:17:06 +00:00
|
|
|
}
|
2002-10-29 18:40:02 +00:00
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
Attribute = (List->CurrentDisk == DiskEntry &&
|
2003-08-03 12:20:22 +00:00
|
|
|
List->CurrentPartition == PartEntry) ? 0x71 : 0x17;
|
2002-10-29 18:40:02 +00:00
|
|
|
|
|
|
|
FillConsoleOutputCharacter(' ',
|
2002-10-18 20:04:00 +00:00
|
|
|
Width,
|
|
|
|
coPos,
|
|
|
|
&Written);
|
|
|
|
|
2002-10-29 18:40:02 +00:00
|
|
|
coPos.X += 4;
|
|
|
|
Width -= 8;
|
|
|
|
FillConsoleOutputAttribute(Attribute,
|
2002-10-18 20:04:00 +00:00
|
|
|
Width,
|
|
|
|
coPos,
|
|
|
|
&Written);
|
|
|
|
|
2002-10-29 18:40:02 +00:00
|
|
|
coPos.X++;
|
|
|
|
Width -= 2;
|
|
|
|
WriteConsoleOutputCharacters(LineBuffer,
|
|
|
|
min(strlen(LineBuffer), Width),
|
|
|
|
coPos);
|
|
|
|
|
|
|
|
List->Line++;
|
2002-10-18 20:04:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static VOID
|
2002-10-29 18:40:02 +00:00
|
|
|
PrintDiskData(PPARTLIST List,
|
2003-08-02 16:49:36 +00:00
|
|
|
PDISKENTRY DiskEntry)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
PPARTENTRY PartEntry;
|
|
|
|
PLIST_ENTRY Entry;
|
2002-10-29 18:40:02 +00:00
|
|
|
CHAR LineBuffer[128];
|
2002-10-18 20:04:00 +00:00
|
|
|
COORD coPos;
|
|
|
|
ULONG Written;
|
|
|
|
USHORT Width;
|
|
|
|
USHORT Height;
|
2002-10-29 18:40:02 +00:00
|
|
|
ULONGLONG DiskSize;
|
|
|
|
PCHAR Unit;
|
|
|
|
SHORT PartIndex;
|
|
|
|
|
2002-10-18 20:04:00 +00:00
|
|
|
Width = List->Right - List->Left - 1;
|
|
|
|
Height = List->Bottom - List->Top - 1;
|
|
|
|
|
2002-10-29 18:40:02 +00:00
|
|
|
if (List->Line < 0 || List->Line > Height)
|
2002-10-18 20:04:00 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
coPos.X = List->Left + 1;
|
2002-10-29 18:40:02 +00:00
|
|
|
coPos.Y = List->Top + 1 + List->Line;
|
2002-10-18 20:04:00 +00:00
|
|
|
|
2002-11-13 18:25:18 +00:00
|
|
|
#if 0
|
2002-10-29 18:40:02 +00:00
|
|
|
if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
|
|
|
|
{
|
|
|
|
DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
|
|
|
|
Unit = "GB";
|
|
|
|
}
|
2002-11-13 18:25:18 +00:00
|
|
|
else
|
|
|
|
#endif
|
2002-10-29 18:40:02 +00:00
|
|
|
{
|
|
|
|
DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
|
2002-11-13 18:25:18 +00:00
|
|
|
if (DiskSize == 0)
|
|
|
|
DiskSize = 1;
|
2002-10-29 18:40:02 +00:00
|
|
|
Unit = "MB";
|
|
|
|
}
|
|
|
|
|
2002-11-28 19:20:38 +00:00
|
|
|
if (DiskEntry->DriverName.Length > 0)
|
|
|
|
{
|
|
|
|
sprintf(LineBuffer,
|
2003-08-04 15:54:05 +00:00
|
|
|
"%6I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) on %wZ",
|
2002-11-28 19:20:38 +00:00
|
|
|
DiskSize,
|
|
|
|
Unit,
|
|
|
|
DiskEntry->DiskNumber,
|
|
|
|
DiskEntry->Port,
|
|
|
|
DiskEntry->Bus,
|
|
|
|
DiskEntry->Id,
|
|
|
|
&DiskEntry->DriverName);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sprintf(LineBuffer,
|
2003-08-04 15:54:05 +00:00
|
|
|
"%6I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)",
|
2002-11-28 19:20:38 +00:00
|
|
|
DiskSize,
|
|
|
|
Unit,
|
|
|
|
DiskEntry->DiskNumber,
|
|
|
|
DiskEntry->Port,
|
|
|
|
DiskEntry->Bus,
|
|
|
|
DiskEntry->Id);
|
|
|
|
}
|
2002-10-29 18:40:02 +00:00
|
|
|
|
|
|
|
FillConsoleOutputAttribute(0x17,
|
2002-10-18 20:04:00 +00:00
|
|
|
Width,
|
|
|
|
coPos,
|
|
|
|
&Written);
|
|
|
|
|
2002-10-29 18:40:02 +00:00
|
|
|
FillConsoleOutputCharacter(' ',
|
2002-10-18 20:04:00 +00:00
|
|
|
Width,
|
|
|
|
coPos,
|
|
|
|
&Written);
|
|
|
|
|
|
|
|
coPos.X++;
|
2002-10-29 18:40:02 +00:00
|
|
|
WriteConsoleOutputCharacters(LineBuffer,
|
|
|
|
min(strlen(LineBuffer), Width - 2),
|
2002-10-18 20:04:00 +00:00
|
|
|
coPos);
|
|
|
|
|
2002-10-29 18:40:02 +00:00
|
|
|
List->Line++;
|
|
|
|
|
|
|
|
/* Print separator line */
|
|
|
|
PrintEmptyLine(List);
|
|
|
|
|
|
|
|
/* Print partition lines*/
|
2003-08-03 12:20:22 +00:00
|
|
|
Entry = DiskEntry->PartListHead.Flink;
|
|
|
|
while (Entry != &DiskEntry->PartListHead)
|
2002-10-29 18:40:02 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
PartEntry = CONTAINING_RECORD (Entry, PARTENTRY, ListEntry);
|
|
|
|
|
|
|
|
/* Print disk entry */
|
|
|
|
PrintPartitionData (List,
|
|
|
|
DiskEntry,
|
|
|
|
PartEntry);
|
|
|
|
|
|
|
|
Entry = Entry->Flink;
|
2002-10-29 18:40:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Print separator line */
|
2002-11-13 18:25:18 +00:00
|
|
|
PrintEmptyLine(List);
|
2002-10-29 18:40:02 +00:00
|
|
|
}
|
2002-10-18 20:04:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
|
|
DrawPartitionList(PPARTLIST List)
|
|
|
|
{
|
2003-08-02 16:49:36 +00:00
|
|
|
PLIST_ENTRY Entry;
|
|
|
|
PDISKENTRY DiskEntry;
|
2002-10-18 20:04:00 +00:00
|
|
|
CHAR LineBuffer[128];
|
|
|
|
COORD coPos;
|
|
|
|
ULONG Written;
|
|
|
|
SHORT i;
|
2002-10-29 18:40:02 +00:00
|
|
|
SHORT DiskIndex;
|
2002-10-18 20:04:00 +00:00
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
2002-11-13 18:25:18 +00:00
|
|
|
/* draw lower right corner */
|
2002-10-18 20:04:00 +00:00
|
|
|
coPos.X = List->Right;
|
|
|
|
coPos.Y = List->Bottom;
|
|
|
|
FillConsoleOutputCharacter(0xD9, // '+',
|
|
|
|
1,
|
|
|
|
coPos,
|
|
|
|
&Written);
|
|
|
|
|
|
|
|
/* print list entries */
|
2002-10-29 18:40:02 +00:00
|
|
|
List->Line = 0;
|
2003-08-02 16:49:36 +00:00
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
Entry = List->DiskListHead.Flink;
|
|
|
|
while (Entry != &List->DiskListHead)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
2003-08-02 16:49:36 +00:00
|
|
|
DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry);
|
|
|
|
|
|
|
|
/* Print disk entry */
|
|
|
|
PrintDiskData (List,
|
|
|
|
DiskEntry);
|
|
|
|
|
|
|
|
Entry = Entry->Flink;
|
2002-10-18 20:04:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
|
|
ScrollDownPartitionList(PPARTLIST List)
|
|
|
|
{
|
2003-08-02 16:49:36 +00:00
|
|
|
PDISKENTRY DiskEntry;
|
2003-08-03 12:20:22 +00:00
|
|
|
PPARTENTRY PartEntry;
|
|
|
|
PLIST_ENTRY Entry1;
|
|
|
|
PLIST_ENTRY Entry2;
|
2002-10-18 20:04:00 +00:00
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
/* Check for empty disks */
|
2003-08-03 12:20:22 +00:00
|
|
|
if (IsListEmpty (&List->DiskListHead))
|
2002-10-18 20:04:00 +00:00
|
|
|
return;
|
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
/* Check for next usable entry on current disk */
|
|
|
|
if (List->CurrentPartition != NULL)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
Entry2 = List->CurrentPartition->ListEntry.Flink;
|
|
|
|
while (Entry2 != &List->CurrentDisk->PartListHead)
|
2003-08-02 16:49:36 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);
|
|
|
|
|
|
|
|
// if (PartEntry->HidePartEntry == FALSE)
|
|
|
|
{
|
|
|
|
List->CurrentPartition = PartEntry;
|
|
|
|
DrawPartitionList (List);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Entry2 = Entry2->Flink;
|
2003-08-02 16:49:36 +00:00
|
|
|
}
|
2002-10-18 20:04:00 +00:00
|
|
|
}
|
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
/* Check for first usable entry on next disk */
|
|
|
|
if (List->CurrentDisk != NULL)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
Entry1 = List->CurrentDisk->ListEntry.Flink;
|
|
|
|
while (Entry1 != &List->DiskListHead)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry);
|
|
|
|
|
|
|
|
Entry2 = DiskEntry->PartListHead.Flink;
|
|
|
|
while (Entry2 != &DiskEntry->PartListHead)
|
2003-08-02 16:49:36 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);
|
|
|
|
|
|
|
|
// if (PartEntry->HidePartEntry == FALSE)
|
|
|
|
{
|
|
|
|
List->CurrentDisk = DiskEntry;
|
|
|
|
List->CurrentPartition = PartEntry;
|
|
|
|
DrawPartitionList (List);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Entry2 = Entry2->Flink;
|
2003-08-02 16:49:36 +00:00
|
|
|
}
|
2003-08-03 12:20:22 +00:00
|
|
|
|
|
|
|
Entry1 = Entry1->Flink;
|
2002-10-18 20:04:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
|
|
ScrollUpPartitionList(PPARTLIST List)
|
|
|
|
{
|
2003-08-02 16:49:36 +00:00
|
|
|
PDISKENTRY DiskEntry;
|
2003-08-03 12:20:22 +00:00
|
|
|
PPARTENTRY PartEntry;
|
|
|
|
PLIST_ENTRY Entry1;
|
|
|
|
PLIST_ENTRY Entry2;
|
2002-10-18 20:04:00 +00:00
|
|
|
ULONG i;
|
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
/* Check for empty disks */
|
2003-08-03 12:20:22 +00:00
|
|
|
if (IsListEmpty (&List->DiskListHead))
|
2002-10-18 20:04:00 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* check for previous usable entry on current disk */
|
2003-08-03 12:20:22 +00:00
|
|
|
if (List->CurrentPartition != NULL)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
Entry2 = List->CurrentPartition->ListEntry.Blink;
|
|
|
|
while (Entry2 != &List->CurrentDisk->PartListHead)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);
|
|
|
|
|
|
|
|
// if (PartEntry->HidePartEntry == FALSE)
|
|
|
|
{
|
|
|
|
List->CurrentPartition = PartEntry;
|
|
|
|
DrawPartitionList (List);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Entry2 = Entry2->Blink;
|
2002-10-18 20:04:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
|
2002-10-18 20:04:00 +00:00
|
|
|
/* check for last usable entry on previous disk */
|
2003-08-03 12:20:22 +00:00
|
|
|
if (List->CurrentDisk != NULL)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
Entry1 = List->CurrentDisk->ListEntry.Blink;
|
|
|
|
while (Entry1 != &List->DiskListHead)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry);
|
|
|
|
|
|
|
|
Entry2 = DiskEntry->PartListHead.Blink;
|
|
|
|
while (Entry2 != &DiskEntry->PartListHead)
|
2002-10-18 20:04:00 +00:00
|
|
|
{
|
2003-08-03 12:20:22 +00:00
|
|
|
PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);
|
|
|
|
|
|
|
|
// if (PartEntry->HidePartEntry == FALSE)
|
|
|
|
{
|
|
|
|
List->CurrentDisk = DiskEntry;
|
|
|
|
List->CurrentPartition = PartEntry;
|
|
|
|
DrawPartitionList (List);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Entry2 = Entry2->Blink;
|
2002-10-18 20:04:00 +00:00
|
|
|
}
|
2003-08-03 12:20:22 +00:00
|
|
|
|
|
|
|
Entry1 = Entry1->Blink;
|
2002-10-18 20:04:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-08-04 15:54:05 +00:00
|
|
|
VOID
|
2003-01-17 13:18:15 +00:00
|
|
|
GetActiveBootPartition(PPARTLIST List,
|
2003-08-04 15:54:05 +00:00
|
|
|
PDISKENTRY *DiskEntry,
|
|
|
|
PPARTENTRY *PartEntry)
|
2003-01-17 13:18:15 +00:00
|
|
|
{
|
2003-08-04 15:54:05 +00:00
|
|
|
PDISKENTRY LocalDiskEntry;
|
|
|
|
PPARTENTRY LocalPartEntry;
|
2003-08-03 12:20:22 +00:00
|
|
|
PLIST_ENTRY Entry;
|
2003-01-17 13:18:15 +00:00
|
|
|
ULONG i;
|
|
|
|
|
2003-08-04 15:54:05 +00:00
|
|
|
*DiskEntry = NULL;
|
|
|
|
*PartEntry = NULL;
|
|
|
|
|
|
|
|
/* Check for empty disk list */
|
2003-08-03 12:20:22 +00:00
|
|
|
if (IsListEmpty (&List->DiskListHead))
|
2003-08-04 15:54:05 +00:00
|
|
|
return;
|
2003-01-17 13:18:15 +00:00
|
|
|
|
2003-08-03 12:20:22 +00:00
|
|
|
/* Get first disk entry from the disk list */
|
|
|
|
Entry = List->DiskListHead.Flink;
|
2003-08-04 15:54:05 +00:00
|
|
|
LocalDiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry);
|
2003-01-17 13:18:15 +00:00
|
|
|
|
2003-08-04 15:54:05 +00:00
|
|
|
/* Check for empty partition list */
|
|
|
|
if (IsListEmpty (&LocalDiskEntry->PartListHead))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Search for active partition */
|
|
|
|
Entry = LocalDiskEntry->PartListHead.Flink;
|
|
|
|
while (Entry != &LocalDiskEntry->PartListHead)
|
2003-01-17 13:18:15 +00:00
|
|
|
{
|
2003-08-04 15:54:05 +00:00
|
|
|
LocalPartEntry = CONTAINING_RECORD (Entry, PARTENTRY, ListEntry);
|
2003-01-17 13:18:15 +00:00
|
|
|
|
2003-08-04 15:54:05 +00:00
|
|
|
if (LocalPartEntry->PartInfo[0].BootIndicator)
|
2003-08-03 12:20:22 +00:00
|
|
|
{
|
2003-08-04 15:54:05 +00:00
|
|
|
*DiskEntry = LocalDiskEntry;
|
|
|
|
*PartEntry = LocalPartEntry;
|
|
|
|
return;
|
2003-01-17 13:18:15 +00:00
|
|
|
}
|
2003-08-03 12:20:22 +00:00
|
|
|
|
|
|
|
Entry = Entry->Flink;
|
2003-01-17 13:18:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-08-06 16:37:46 +00:00
|
|
|
VOID
|
|
|
|
CreateNewPartition (PPARTLIST List,
|
2003-08-09 16:32:26 +00:00
|
|
|
ULONGLONG PartitionSize,
|
|
|
|
BOOLEAN AutoCreate)
|
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
2003-04-18 14:00:17 +00:00
|
|
|
{
|
|
|
|
PDISKENTRY DiskEntry;
|
|
|
|
PPARTENTRY PartEntry;
|
2003-08-06 16:37:46 +00:00
|
|
|
PPARTENTRY PrevPartEntry;
|
|
|
|
PPARTENTRY NextPartEntry;
|
|
|
|
PPARTENTRY NewPartEntry;
|
|
|
|
|
|
|
|
if (List == NULL ||
|
|
|
|
List->CurrentDisk == NULL ||
|
|
|
|
List->CurrentPartition == NULL ||
|
|
|
|
List->CurrentPartition->Unpartitioned == FALSE)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
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
2003-04-18 14:00:17 +00:00
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
DiskEntry = List->CurrentDisk;
|
2003-08-03 12:20:22 +00:00
|
|
|
PartEntry = List->CurrentPartition;
|
|
|
|
|
2003-08-09 16:32:26 +00:00
|
|
|
if (AutoCreate == TRUE ||
|
|
|
|
PartitionSize == PartEntry->UnpartitionedLength)
|
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
2003-04-18 14:00:17 +00:00
|
|
|
{
|
2003-08-06 16:37:46 +00:00
|
|
|
/* Convert current entry to 'new (unformatted)' */
|
|
|
|
PartEntry->PartInfo[0].StartingOffset.QuadPart =
|
|
|
|
PartEntry->UnpartitionedOffset + DiskEntry->TrackSize;
|
|
|
|
PartEntry->PartInfo[0].PartitionLength.QuadPart =
|
|
|
|
PartEntry->UnpartitionedLength - DiskEntry->TrackSize;
|
|
|
|
PartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED;
|
|
|
|
PartEntry->PartInfo[0].BootIndicator = FALSE; /* FIXME */
|
|
|
|
PartEntry->PartInfo[0].RewritePartition = TRUE;
|
|
|
|
|
|
|
|
/* Check for previous partition entry */
|
|
|
|
if (PartEntry->ListEntry.Blink != &DiskEntry->PartListHead)
|
|
|
|
{
|
|
|
|
PrevPartEntry = CONTAINING_RECORD (PartEntry->ListEntry.Blink,
|
|
|
|
PARTENTRY,
|
|
|
|
ListEntry);
|
|
|
|
|
|
|
|
|
|
|
|
/* FIXME: Update extended partition entries */
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-08-09 16:32:26 +00:00
|
|
|
PartEntry->AutoCreate = AutoCreate;
|
2003-08-06 16:37:46 +00:00
|
|
|
PartEntry->New = TRUE;
|
|
|
|
PartEntry->Unpartitioned = FALSE;
|
|
|
|
PartEntry->UnpartitionedOffset = 0ULL;
|
|
|
|
PartEntry->UnpartitionedLength = 0ULL;
|
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
2003-04-18 14:00:17 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-08-06 16:37:46 +00:00
|
|
|
/* Insert an initialize a new partition entry */
|
|
|
|
NewPartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
sizeof(PARTENTRY));
|
|
|
|
if (NewPartEntry == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
RtlZeroMemory (NewPartEntry,
|
|
|
|
sizeof(PARTENTRY));
|
|
|
|
|
|
|
|
/* Insert the new entry into the list */
|
|
|
|
InsertTailList (&PartEntry->ListEntry,
|
|
|
|
&NewPartEntry->ListEntry);
|
|
|
|
|
|
|
|
NewPartEntry->New = TRUE;
|
|
|
|
|
|
|
|
NewPartEntry->PartInfo[0].StartingOffset.QuadPart =
|
|
|
|
PartEntry->UnpartitionedOffset + DiskEntry->TrackSize;
|
|
|
|
NewPartEntry->PartInfo[0].PartitionLength.QuadPart =
|
|
|
|
PartitionSize - DiskEntry->TrackSize;
|
|
|
|
NewPartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED;
|
|
|
|
NewPartEntry->PartInfo[0].BootIndicator = FALSE; /* FIXME */
|
|
|
|
NewPartEntry->PartInfo[0].RewritePartition = TRUE;
|
|
|
|
|
|
|
|
/* FIXME: Update extended partition entries */
|
|
|
|
|
|
|
|
/* Update offset and size of the remaining unpartitioned disk space */
|
|
|
|
PartEntry->UnpartitionedOffset += PartitionSize;
|
|
|
|
PartEntry->UnpartitionedLength -= PartitionSize;
|
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
2003-04-18 14:00:17 +00:00
|
|
|
}
|
|
|
|
|
2003-08-06 16:37:46 +00:00
|
|
|
DiskEntry->Modified = TRUE;
|
|
|
|
|
2003-08-09 16:32:26 +00:00
|
|
|
UpdatePartitionNumbers (DiskEntry);
|
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
2003-04-18 14:00:17 +00:00
|
|
|
|
2003-08-09 16:32:26 +00:00
|
|
|
AssignDriverLetters (List);
|
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
2003-04-18 14:00:17 +00:00
|
|
|
}
|
|
|
|
|
2003-04-28 19:44:13 +00:00
|
|
|
|
2003-08-06 16:37:46 +00:00
|
|
|
VOID
|
|
|
|
DeleteCurrentPartition (PPARTLIST List)
|
2003-04-28 19:44:13 +00:00
|
|
|
{
|
|
|
|
PDISKENTRY DiskEntry;
|
|
|
|
PPARTENTRY PartEntry;
|
2003-08-06 16:37:46 +00:00
|
|
|
PPARTENTRY PrevPartEntry;
|
|
|
|
PPARTENTRY NextPartEntry;
|
|
|
|
|
|
|
|
if (List == NULL ||
|
|
|
|
List->CurrentDisk == NULL ||
|
|
|
|
List->CurrentPartition == NULL ||
|
|
|
|
List->CurrentPartition->Unpartitioned == TRUE)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2003-04-28 19:44:13 +00:00
|
|
|
|
2003-08-02 16:49:36 +00:00
|
|
|
DiskEntry = List->CurrentDisk;
|
2003-08-03 12:20:22 +00:00
|
|
|
PartEntry = List->CurrentPartition;
|
2003-08-06 16:37:46 +00:00
|
|
|
|
|
|
|
/* Get pointer to previous partition entry */
|
|
|
|
PrevPartEntry = NULL;
|
|
|
|
if (PartEntry->ListEntry.Blink != &DiskEntry->PartListHead)
|
2003-04-28 19:44:13 +00:00
|
|
|
{
|
2003-08-06 16:37:46 +00:00
|
|
|
PrevPartEntry = CONTAINING_RECORD (PartEntry->ListEntry.Blink,
|
|
|
|
PARTENTRY,
|
|
|
|
ListEntry);
|
2003-04-28 19:44:13 +00:00
|
|
|
}
|
2003-08-06 16:37:46 +00:00
|
|
|
|
|
|
|
/* Get pointer to previous partition entry */
|
|
|
|
NextPartEntry = NULL;
|
|
|
|
if (PartEntry->ListEntry.Flink != &DiskEntry->PartListHead)
|
2003-04-28 19:44:13 +00:00
|
|
|
{
|
2003-08-06 16:37:46 +00:00
|
|
|
NextPartEntry = CONTAINING_RECORD (PartEntry->ListEntry.Flink,
|
|
|
|
PARTENTRY,
|
|
|
|
ListEntry);
|
2003-04-28 19:44:13 +00:00
|
|
|
}
|
|
|
|
|
2003-08-06 16:37:46 +00:00
|
|
|
if ((PrevPartEntry != NULL && PrevPartEntry->Unpartitioned == TRUE) &&
|
|
|
|
(NextPartEntry != NULL && NextPartEntry->Unpartitioned == TRUE))
|
|
|
|
{
|
|
|
|
/* Merge previous, current and next entry */
|
2003-04-28 19:44:13 +00:00
|
|
|
|
2003-08-06 16:37:46 +00:00
|
|
|
/* Adjust the previous entries length */
|
|
|
|
PrevPartEntry->UnpartitionedLength +=
|
|
|
|
(PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize +
|
|
|
|
NextPartEntry->UnpartitionedLength);
|
2003-04-28 19:44:13 +00:00
|
|
|
|
2003-08-06 16:37:46 +00:00
|
|
|
/* FIXME: Container entries ?? */
|
2003-08-02 16:49:36 +00:00
|
|
|
|
2003-08-06 16:37:46 +00:00
|
|
|
/* Remove the current entry */
|
|
|
|
RemoveEntryList (&PartEntry->ListEntry);
|
|
|
|
RtlFreeHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
PartEntry);
|
2003-08-02 16:49:36 +00:00
|
|
|
|
2003-08-06 16:37:46 +00:00
|
|
|
/* Remove the next entry */
|
|
|
|
RemoveEntryList (&NextPartEntry->ListEntry);
|
|
|
|
RtlFreeHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
NextPartEntry);
|
|
|
|
|
|
|
|
/* Update current partition */
|
|
|
|
List->CurrentPartition = PrevPartEntry;
|
2003-08-02 16:49:36 +00:00
|
|
|
}
|
2003-08-06 16:37:46 +00:00
|
|
|
else if (PrevPartEntry != NULL && PrevPartEntry->Unpartitioned == TRUE)
|
|
|
|
{
|
|
|
|
/* Merge current and previous entry */
|
|
|
|
|
|
|
|
/* Adjust the previous entries length */
|
|
|
|
PrevPartEntry->UnpartitionedLength +=
|
|
|
|
(PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize);
|
2003-08-02 16:49:36 +00:00
|
|
|
|
2003-08-06 16:37:46 +00:00
|
|
|
/* FIXME: Container entries ?? */
|
2003-08-02 16:49:36 +00:00
|
|
|
|
2003-08-06 16:37:46 +00:00
|
|
|
/* Remove the current entry */
|
|
|
|
RemoveEntryList (&PartEntry->ListEntry);
|
|
|
|
RtlFreeHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
PartEntry);
|
|
|
|
|
|
|
|
/* Update current partition */
|
|
|
|
List->CurrentPartition = PrevPartEntry;
|
|
|
|
}
|
|
|
|
else if (NextPartEntry != NULL && NextPartEntry->Unpartitioned == TRUE)
|
2003-08-02 16:49:36 +00:00
|
|
|
{
|
2003-08-06 16:37:46 +00:00
|
|
|
/* Merge current and next entry */
|
|
|
|
|
|
|
|
/* Adjust the next entries offset and length */
|
|
|
|
NextPartEntry->UnpartitionedOffset =
|
|
|
|
PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
|
|
|
|
NextPartEntry->UnpartitionedLength +=
|
|
|
|
(PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize);
|
|
|
|
|
|
|
|
/* FIXME: Container entries ?? */
|
|
|
|
|
|
|
|
/* Remove the current entry */
|
|
|
|
RemoveEntryList (&PartEntry->ListEntry);
|
|
|
|
RtlFreeHeap (ProcessHeap,
|
|
|
|
0,
|
|
|
|
PartEntry);
|
|
|
|
|
|
|
|
/* Update current partition */
|
|
|
|
List->CurrentPartition = NextPartEntry;
|
2003-08-02 16:49:36 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-08-06 16:37:46 +00:00
|
|
|
/* Nothing to merge but change current entry */
|
|
|
|
PartEntry->New = FALSE;
|
|
|
|
PartEntry->Unpartitioned = TRUE;
|
|
|
|
PartEntry->UnpartitionedOffset =
|
|
|
|
PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
|
|
|
|
PartEntry->UnpartitionedLength =
|
|
|
|
PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize;
|
2003-08-02 16:49:36 +00:00
|
|
|
|
2003-08-06 16:37:46 +00:00
|
|
|
/* FIXME: Container entries ?? */
|
2003-08-02 16:49:36 +00:00
|
|
|
|
2003-08-06 16:37:46 +00:00
|
|
|
/* Wipe the partition table */
|
|
|
|
RtlZeroMemory (&PartEntry->PartInfo,
|
|
|
|
sizeof(PartEntry->PartInfo));
|
|
|
|
}
|
2003-08-02 16:49:36 +00:00
|
|
|
|
2003-08-06 16:37:46 +00:00
|
|
|
DiskEntry->Modified = TRUE;
|
|
|
|
|
2003-08-09 16:32:26 +00:00
|
|
|
UpdatePartitionNumbers (DiskEntry);
|
2003-08-02 16:49:36 +00:00
|
|
|
|
2003-08-09 16:32:26 +00:00
|
|
|
AssignDriverLetters (List);
|
2003-08-02 16:49:36 +00:00
|
|
|
}
|
|
|
|
|
2002-10-18 20:04:00 +00:00
|
|
|
/* EOF */
|