reactos/base/setup/lib/utils/partlist.c

4153 lines
137 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS Setup Library
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Partition list functions
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
* Copyright 2018-2019 Hermes Belusca-Maito
*/
#include "precomp.h"
#include <ntddscsi.h>
#include "partlist.h"
#include "fsrec.h"
#include "registry.h"
#define NDEBUG
#include <debug.h>
//#define DUMP_PARTITION_TABLE
#include <pshpack1.h>
typedef struct _REG_DISK_MOUNT_INFO
{
ULONG Signature;
LARGE_INTEGER StartingOffset;
} REG_DISK_MOUNT_INFO, *PREG_DISK_MOUNT_INFO;
#include <poppack.h>
/* FUNCTIONS ****************************************************************/
#ifdef DUMP_PARTITION_TABLE
static
VOID
DumpPartitionTable(
PDISKENTRY DiskEntry)
{
PPARTITION_INFORMATION PartitionInfo;
ULONG i;
DbgPrint("\n");
DbgPrint("Index Start Length Hidden Nr Type Boot RW\n");
DbgPrint("----- ------------ ------------ ---------- -- ---- ---- --\n");
for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++)
{
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[i];
DbgPrint(" %3lu %12I64u %12I64u %10lu %2lu %2x %c %c\n",
i,
PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector,
PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector,
PartitionInfo->HiddenSectors,
PartitionInfo->PartitionNumber,
PartitionInfo->PartitionType,
PartitionInfo->BootIndicator ? '*': ' ',
PartitionInfo->RewritePartition ? 'Y': 'N');
}
DbgPrint("\n");
}
#endif
ULONGLONG
AlignDown(
IN ULONGLONG Value,
IN ULONG Alignment)
{
ULONGLONG Temp;
Temp = Value / Alignment;
return Temp * Alignment;
}
ULONGLONG
AlignUp(
IN ULONGLONG Value,
IN ULONG Alignment)
{
ULONGLONG Temp, Result;
Temp = Value / Alignment;
Result = Temp * Alignment;
if (Value % Alignment)
Result += Alignment;
return Result;
}
ULONGLONG
RoundingDivide(
IN ULONGLONG Dividend,
IN ULONGLONG Divisor)
{
return (Dividend + Divisor / 2) / Divisor;
}
static
VOID
GetDriverName(
IN PDISKENTRY DiskEntry)
{
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
WCHAR KeyName[32];
NTSTATUS Status;
RtlInitUnicodeString(&DiskEntry->DriverName, NULL);
RtlStringCchPrintfW(KeyName, ARRAYSIZE(KeyName),
L"\\Scsi\\Scsi Port %hu",
DiskEntry->Port);
RtlZeroMemory(&QueryTable, sizeof(QueryTable));
QueryTable[0].Name = L"Driver";
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
QueryTable[0].EntryContext = &DiskEntry->DriverName;
/* This will allocate DiskEntry->DriverName if needed */
Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
KeyName,
QueryTable,
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
}
}
static
VOID
AssignDriveLetters(
IN PPARTLIST List)
{
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
PLIST_ENTRY Entry1;
PLIST_ENTRY Entry2;
WCHAR Letter;
Letter = L'C';
/* Assign drive letters to primary partitions */
for (Entry1 = List->DiskListHead.Flink;
Entry1 != &List->DiskListHead;
Entry1 = Entry1->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
Entry2 != &DiskEntry->PrimaryPartListHead;
Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
PartEntry->DriveLetter = 0;
if (PartEntry->IsPartitioned &&
!IsContainerPartition(PartEntry->PartitionType))
{
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
if (IsRecognizedPartition(PartEntry->PartitionType) ||
PartEntry->SectorCount.QuadPart != 0LL)
{
if (Letter <= L'Z')
{
PartEntry->DriveLetter = Letter;
Letter++;
}
}
}
}
}
/* Assign drive letters to logical drives */
for (Entry1 = List->DiskListHead.Flink;
Entry1 != &List->DiskListHead;
Entry1 = Entry1->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
Entry2 != &DiskEntry->LogicalPartListHead;
Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
PartEntry->DriveLetter = 0;
if (PartEntry->IsPartitioned)
{
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
if (IsRecognizedPartition(PartEntry->PartitionType) ||
PartEntry->SectorCount.QuadPart != 0LL)
{
if (Letter <= L'Z')
{
PartEntry->DriveLetter = Letter;
Letter++;
}
}
}
}
}
}
static NTSTATUS
NTAPI
DiskIdentifierQueryRoutine(
PWSTR ValueName,
ULONG ValueType,
PVOID ValueData,
ULONG ValueLength,
PVOID Context,
PVOID EntryContext)
{
PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
UNICODE_STRING NameU;
if (ValueType == REG_SZ &&
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
ValueLength == 20 * sizeof(WCHAR) &&
((PWCHAR)ValueData)[8] == L'-')
{
NameU.Buffer = (PWCHAR)ValueData;
NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
NameU.Buffer = (PWCHAR)ValueData + 9;
RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
static NTSTATUS
NTAPI
DiskConfigurationDataQueryRoutine(
PWSTR ValueName,
ULONG ValueType,
PVOID ValueData,
ULONG ValueLength,
PVOID Context,
PVOID EntryContext)
{
PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
ULONG i;
if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
return STATUS_UNSUCCESSFUL;
FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
/* Hm. Version and Revision are not set on Microsoft Windows XP... */
#if 0
if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
FullResourceDescriptor->PartialResourceList.Revision != 1)
return STATUS_UNSUCCESSFUL;
#endif
for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
{
if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA))
continue;
DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
BiosDiskEntry->DiskGeometry = *DiskGeometry;
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
static NTSTATUS
NTAPI
SystemConfigurationDataQueryRoutine(
PWSTR ValueName,
ULONG ValueType,
PVOID ValueData,
ULONG ValueLength,
PVOID Context,
PVOID EntryContext)
{
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context;
ULONG i;
if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
return STATUS_UNSUCCESSFUL;
FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
/* Hm. Version and Revision are not set on Microsoft Windows XP... */
#if 0
if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
FullResourceDescriptor->PartialResourceList.Revision != 1)
return STATUS_UNSUCCESSFUL;
#endif
for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
{
if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
continue;
*Int13Drives = (CM_INT13_DRIVE_PARAMETER*)RtlAllocateHeap(ProcessHeap, 0,
FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
if (*Int13Drives == NULL)
return STATUS_NO_MEMORY;
memcpy(*Int13Drives,
&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1],
FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
static VOID
EnumerateBiosDiskEntries(
IN PPARTLIST PartList)
{
RTL_QUERY_REGISTRY_TABLE QueryTable[3];
WCHAR Name[120];
ULONG AdapterCount;
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
ULONG ControllerCount;
ULONG DiskCount;
NTSTATUS Status;
PCM_INT13_DRIVE_PARAMETER Int13Drives;
PBIOSDISKENTRY BiosDiskEntry;
#define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
memset(QueryTable, 0, sizeof(QueryTable));
QueryTable[1].Name = L"Configuration Data";
QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine;
Int13Drives = NULL;
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
&QueryTable[1],
(PVOID)&Int13Drives,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
return;
}
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
for (AdapterCount = 0; ; ++AdapterCount)
{
RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
L"%s\\%lu",
ROOT_NAME, AdapterCount);
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
Name,
&QueryTable[2],
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
break;
}
RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
L"%s\\%lu\\DiskController",
ROOT_NAME, AdapterCount);
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
Name,
&QueryTable[2],
NULL,
NULL);
if (NT_SUCCESS(Status))
{
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
for (ControllerCount = 0; ; ++ControllerCount)
{
RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
L"%s\\%lu\\DiskController\\%lu",
ROOT_NAME, AdapterCount, ControllerCount);
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
Name,
&QueryTable[2],
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap(ProcessHeap, 0, Int13Drives);
return;
}
RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral",
ROOT_NAME, AdapterCount, ControllerCount);
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
Name,
&QueryTable[2],
NULL,
NULL);
if (NT_SUCCESS(Status))
{
QueryTable[0].Name = L"Identifier";
QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine;
QueryTable[1].Name = L"Configuration Data";
QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine;
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
for (DiskCount = 0; ; ++DiskCount)
{
BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
if (BiosDiskEntry == NULL)
{
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
RtlFreeHeap(ProcessHeap, 0, Int13Drives);
return;
}
RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral\\%lu",
ROOT_NAME, AdapterCount, ControllerCount, DiskCount);
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
Name,
QueryTable,
(PVOID)BiosDiskEntry,
NULL);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
RtlFreeHeap(ProcessHeap, 0, Int13Drives);
return;
}
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
BiosDiskEntry->AdapterNumber = 0; // And NOT "AdapterCount" as it needs to be hardcoded for BIOS!
BiosDiskEntry->ControllerNumber = ControllerCount;
BiosDiskEntry->DiskNumber = DiskCount;
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
BiosDiskEntry->DiskEntry = NULL;
if (DiskCount < Int13Drives[0].NumberDrives)
{
BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
}
else
{
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
DPRINT1("Didn't find Int13 drive data for disk %u\n", DiskCount);
}
InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry);
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
DPRINT("--->\n");
DPRINT("AdapterNumber: %lu\n", BiosDiskEntry->AdapterNumber);
DPRINT("ControllerNumber: %lu\n", BiosDiskEntry->ControllerNumber);
DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber);
DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature);
DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum);
DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
DPRINT("<---\n");
}
}
}
}
}
RtlFreeHeap(ProcessHeap, 0, Int13Drives);
#undef ROOT_NAME
}
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
/*
* Detects whether a disk reports as a "super-floppy", i.e. an unpartitioned
* disk with a valid VBR, following the criteria used by IoReadPartitionTable()
* and IoWritePartitionTable():
* only one single partition starting at the beginning of the disk; the reported
* defaults are: partition number being zero and its type being FAT16 non-bootable.
* Note also that accessing \Device\HarddiskN\Partition0 or Partition1 returns
* the same data.
*/
// static
BOOLEAN
IsSuperFloppy(
IN PDISKENTRY DiskEntry)
{
PPARTITION_INFORMATION PartitionInfo;
ULONGLONG PartitionLengthEstimate;
/* No layout buffer: we cannot say anything yet */
if (DiskEntry->LayoutBuffer == NULL)
return FALSE;
/* We must have only one partition */
if (DiskEntry->LayoutBuffer->PartitionCount != 1)
return FALSE;
/* Get the single partition entry */
PartitionInfo = DiskEntry->LayoutBuffer->PartitionEntry;
/* The single partition must start at the beginning of the disk */
if (!(PartitionInfo->StartingOffset.QuadPart == 0 &&
PartitionInfo->HiddenSectors == 0))
{
return FALSE;
}
/* The disk signature is usually set to one; warn in case it's not */
if (DiskEntry->LayoutBuffer->Signature != 1)
{
DPRINT1("Super-Floppy disk %lu signature %08x != 1!\n",
DiskEntry->DiskNumber, DiskEntry->LayoutBuffer->Signature);
}
/*
* The partition number must be zero or one, be recognized,
* have FAT16 type and report as non-bootable.
*/
if ((PartitionInfo->PartitionNumber != 0 &&
PartitionInfo->PartitionNumber != 1) ||
PartitionInfo->RecognizedPartition != TRUE ||
PartitionInfo->PartitionType != PARTITION_FAT_16 ||
PartitionInfo->BootIndicator != FALSE)
{
DPRINT1("Super-Floppy disk %lu does not return default settings!\n"
" PartitionNumber = %lu, expected 0\n"
" RecognizedPartition = %s, expected TRUE\n"
" PartitionType = 0x%02x, expected 0x04 (PARTITION_FAT_16)\n"
" BootIndicator = %s, expected FALSE\n",
DiskEntry->DiskNumber,
PartitionInfo->PartitionNumber,
PartitionInfo->RecognizedPartition ? "TRUE" : "FALSE",
PartitionInfo->PartitionType,
PartitionInfo->BootIndicator ? "TRUE" : "FALSE");
}
/* The partition lengths should agree */
PartitionLengthEstimate = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
if (PartitionInfo->PartitionLength.QuadPart != PartitionLengthEstimate)
{
DPRINT1("PartitionLength = %I64u is different from PartitionLengthEstimate = %I64u\n",
PartitionInfo->PartitionLength.QuadPart, PartitionLengthEstimate);
}
return TRUE;
}
/*
* Inserts the disk region represented by PartEntry into either the primary
* or the logical partition list of the given disk.
* The lists are kept sorted by increasing order of start sectors.
* Of course no disk region should overlap at all with one another.
*/
static
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
BOOLEAN
InsertDiskRegion(
IN PDISKENTRY DiskEntry,
IN PPARTENTRY PartEntry,
IN BOOLEAN LogicalPartition)
{
PLIST_ENTRY List;
PLIST_ENTRY Entry;
PPARTENTRY PartEntry2;
/* Use the correct partition list */
if (LogicalPartition)
List = &DiskEntry->LogicalPartListHead;
else
List = &DiskEntry->PrimaryPartListHead;
/* Find the first disk region before which we need to insert the new one */
for (Entry = List->Flink; Entry != List; Entry = Entry->Flink)
{
PartEntry2 = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
/* Ignore any unused empty region */
if ((PartEntry2->PartitionType == PARTITION_ENTRY_UNUSED &&
PartEntry2->StartSector.QuadPart == 0) || PartEntry2->SectorCount.QuadPart == 0)
{
continue;
}
/* If the current region ends before the one to be inserted, try again */
if (PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1 < PartEntry->StartSector.QuadPart)
continue;
/*
* One of the disk region boundaries crosses the desired region
* (it starts after the desired region, or ends before the end
* of the desired region): this is an impossible situation because
* disk regions (partitions) cannot overlap!
* Throw an error and bail out.
*/
if (max(PartEntry->StartSector.QuadPart, PartEntry2->StartSector.QuadPart)
<=
min( PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1,
PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1))
{
DPRINT1("Disk region overlap problem, stopping there!\n"
"Partition to be inserted:\n"
" StartSector = %I64u ; EndSector = %I64u\n"
"Existing disk region:\n"
" StartSector = %I64u ; EndSector = %I64u\n",
PartEntry->StartSector.QuadPart,
PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1,
PartEntry2->StartSector.QuadPart,
PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1);
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
return FALSE;
}
/* We have found the first region before which the new one has to be inserted */
break;
}
/* Insert the disk region */
InsertTailList(Entry, &PartEntry->ListEntry);
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
return TRUE;
}
static
PPARTENTRY
CreateInsertBlankRegion(
IN PDISKENTRY DiskEntry,
IN OUT PLIST_ENTRY ListHead,
IN ULONGLONG StartSector,
IN ULONGLONG SectorCount,
IN BOOLEAN LogicalSpace)
{
PPARTENTRY NewPartEntry;
NewPartEntry = RtlAllocateHeap(ProcessHeap,
HEAP_ZERO_MEMORY,
sizeof(PARTENTRY));
if (NewPartEntry == NULL)
return NULL;
NewPartEntry->DiskEntry = DiskEntry;
NewPartEntry->StartSector.QuadPart = StartSector;
NewPartEntry->SectorCount.QuadPart = SectorCount;
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
NewPartEntry->LogicalPartition = LogicalSpace;
NewPartEntry->IsPartitioned = FALSE;
NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem[0] = L'\0';
DPRINT1("First Sector : %I64u\n", NewPartEntry->StartSector.QuadPart);
DPRINT1("Last Sector : %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
/* Insert the new entry into the list */
InsertTailList(ListHead, &NewPartEntry->ListEntry);
return NewPartEntry;
}
static
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
BOOLEAN
InitializePartitionEntry(
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
IN OUT PPARTENTRY PartEntry,
IN ULONGLONG SectorCount,
IN BOOLEAN AutoCreate)
{
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
PDISKENTRY DiskEntry = PartEntry->DiskEntry;
DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
/* Fail if we try to initialize this partition entry with more sectors than what it actually contains */
if (SectorCount > PartEntry->SectorCount.QuadPart)
return FALSE;
/* Fail if the partition is already in use */
ASSERT(!PartEntry->IsPartitioned);
if ((AutoCreate != FALSE) ||
(AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart))
{
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
PartEntry->AutoCreate = AutoCreate;
}
else
{
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
ULONGLONG StartSector;
ULONGLONG SectorCount2;
PPARTENTRY NewPartEntry;
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
/* Create a partition entry that represents the remaining space after the partition to be initialized */
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
StartSector = AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment);
SectorCount2 = PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - StartSector;
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
NewPartEntry = CreateInsertBlankRegion(DiskEntry,
PartEntry->ListEntry.Flink,
StartSector,
SectorCount2,
PartEntry->LogicalPartition);
if (NewPartEntry == NULL)
{
DPRINT1("Failed to create a new empty region for disk space!\n");
return FALSE;
}
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
/* Resize down the partition entry; its StartSector remains the same */
PartEntry->SectorCount.QuadPart = StartSector - PartEntry->StartSector.QuadPart;
}
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
/* Convert the partition entry to 'New (Unformatted)' */
PartEntry->New = TRUE;
PartEntry->IsPartitioned = TRUE;
// FIXME: Use FileSystemToMBRPartitionType() only for MBR, otherwise use PARTITION_BASIC_DATA_GUID.
PartEntry->PartitionType = FileSystemToMBRPartitionType(L"RAW",
PartEntry->StartSector.QuadPart,
PartEntry->SectorCount.QuadPart);
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
PartEntry->FormatState = Unformatted;
PartEntry->FileSystem[0] = L'\0';
// PartEntry->AutoCreate = AutoCreate;
PartEntry->BootIndicator = FALSE;
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
DPRINT1("First Sector : %I64u\n", PartEntry->StartSector.QuadPart);
DPRINT1("Last Sector : %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
return TRUE;
}
static
VOID
AddPartitionToDisk(
IN ULONG DiskNumber,
IN PDISKENTRY DiskEntry,
IN ULONG PartitionIndex,
IN BOOLEAN LogicalPartition)
{
NTSTATUS Status;
PPARTITION_INFORMATION PartitionInfo;
PPARTENTRY PartEntry;
HANDLE PartitionHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
WCHAR PathBuffer[MAX_PATH];
UNICODE_STRING Name;
UCHAR LabelBuffer[sizeof(FILE_FS_VOLUME_INFORMATION) + 256 * sizeof(WCHAR)];
PFILE_FS_VOLUME_INFORMATION LabelInfo = (PFILE_FS_VOLUME_INFORMATION)LabelBuffer;
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
if (PartitionInfo->PartitionType == PARTITION_ENTRY_UNUSED ||
((LogicalPartition != FALSE) && IsContainerPartition(PartitionInfo->PartitionType)))
{
return;
}
PartEntry = RtlAllocateHeap(ProcessHeap,
HEAP_ZERO_MEMORY,
sizeof(PARTENTRY));
if (PartEntry == NULL)
return;
PartEntry->DiskEntry = DiskEntry;
PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
PartEntry->BootIndicator = PartitionInfo->BootIndicator;
PartEntry->PartitionType = PartitionInfo->PartitionType;
PartEntry->LogicalPartition = LogicalPartition;
PartEntry->IsPartitioned = TRUE;
PartEntry->OnDiskPartitionNumber = PartitionInfo->PartitionNumber;
PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
PartEntry->PartitionIndex = PartitionIndex;
/* Specify the partition as initially unformatted */
PartEntry->FormatState = Unformatted;
PartEntry->FileSystem[0] = L'\0';
/* Initialize the partition volume label */
RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
if (IsContainerPartition(PartEntry->PartitionType))
{
PartEntry->FormatState = Unformatted;
if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
DiskEntry->ExtendedPartition = PartEntry;
}
else if (IsRecognizedPartition(PartEntry->PartitionType))
{
ASSERT(PartitionInfo->RecognizedPartition);
ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
/* Try to open the volume so as to mount it */
RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
L"\\Device\\Harddisk%lu\\Partition%lu",
DiskEntry->DiskNumber,
PartEntry->PartitionNumber);
RtlInitUnicodeString(&Name, PathBuffer);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
PartitionHandle = NULL;
Status = NtOpenFile(&PartitionHandle,
FILE_READ_DATA | SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
}
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
if (PartitionHandle)
{
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
ASSERT(NT_SUCCESS(Status));
/* We don't have a FS, try to guess one */
Status = InferFileSystem(NULL, PartitionHandle,
PartEntry->FileSystem,
sizeof(PartEntry->FileSystem));
if (!NT_SUCCESS(Status))
DPRINT1("InferFileSystem() failed, Status 0x%08lx\n", Status);
}
if (*PartEntry->FileSystem)
{
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
ASSERT(PartitionHandle);
/*
* Handle partition mounted with RawFS: it is
* either unformatted or has an unknown format.
*/
if (wcsicmp(PartEntry->FileSystem, L"RAW") == 0)
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
{
/*
* True unformatted partitions on NT are created with their
* partition type set to either one of the following values,
* and are mounted with RawFS. This is done this way since we
* are assured to have FAT support, which is the only FS that
* uses these partition types. Therefore, having a partition
* mounted with RawFS and with these partition types means that
* the FAT FS was unable to mount it beforehand and thus the
* partition is unformatted.
* However, any partition mounted by RawFS that does NOT have
* any of these partition types must be considered as having
* an unknown format.
*/
if (PartEntry->PartitionType == PARTITION_FAT_12 ||
PartEntry->PartitionType == PARTITION_FAT_16 ||
PartEntry->PartitionType == PARTITION_HUGE ||
PartEntry->PartitionType == PARTITION_XINT13 ||
PartEntry->PartitionType == PARTITION_FAT32 ||
PartEntry->PartitionType == PARTITION_FAT32_XINT13)
{
PartEntry->FormatState = Unformatted;
}
else
{
/* Close the partition before dismounting */
NtClose(PartitionHandle);
PartitionHandle = NULL;
/*
* Dismount the partition since RawFS owns it, and set its
* format to unknown (may or may not be actually formatted).
*/
DismountVolume(PartEntry);
PartEntry->FormatState = UnknownFormat;
PartEntry->FileSystem[0] = L'\0';
}
}
else
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
{
PartEntry->FormatState = Preformatted;
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
}
}
else
{
PartEntry->FormatState = UnknownFormat;
}
/* Retrieve the partition volume label */
if (PartitionHandle)
{
Status = NtQueryVolumeInformationFile(PartitionHandle,
&IoStatusBlock,
&LabelBuffer,
sizeof(LabelBuffer),
FileFsVolumeInformation);
if (NT_SUCCESS(Status))
{
/* Copy the (possibly truncated) volume label and NULL-terminate it */
RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
}
else
{
DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
}
}
/* Close the partition */
if (PartitionHandle)
NtClose(PartitionHandle);
}
else
{
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
/* Unknown partition, hence unknown format (may or may not be actually formatted) */
PartEntry->FormatState = UnknownFormat;
}
InsertDiskRegion(DiskEntry, PartEntry, LogicalPartition);
}
static
VOID
ScanForUnpartitionedDiskSpace(
IN PDISKENTRY DiskEntry)
{
ULONGLONG StartSector;
ULONGLONG SectorCount;
ULONGLONG LastStartSector;
ULONGLONG LastSectorCount;
ULONGLONG LastUnusedSectorCount;
PPARTENTRY PartEntry;
PPARTENTRY NewPartEntry;
PLIST_ENTRY Entry;
DPRINT("ScanForUnpartitionedDiskSpace()\n");
if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
{
DPRINT1("No primary partition!\n");
/* Create a partition entry that represents the empty disk */
if (DiskEntry->SectorAlignment < 2048)
StartSector = 2048ULL;
else
StartSector = (ULONGLONG)DiskEntry->SectorAlignment;
SectorCount = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) - StartSector;
NewPartEntry = CreateInsertBlankRegion(DiskEntry,
&DiskEntry->PrimaryPartListHead,
StartSector,
SectorCount,
FALSE);
if (NewPartEntry == NULL)
DPRINT1("Failed to create a new empty region for full disk space!\n");
return;
}
/* Start partition at head 1, cylinder 0 */
if (DiskEntry->SectorAlignment < 2048)
LastStartSector = 2048ULL;
else
LastStartSector = (ULONGLONG)DiskEntry->SectorAlignment;
LastSectorCount = 0ULL;
LastUnusedSectorCount = 0ULL;
for (Entry = DiskEntry->PrimaryPartListHead.Flink;
Entry != &DiskEntry->PrimaryPartListHead;
Entry = Entry->Flink)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
PartEntry->SectorCount.QuadPart != 0ULL)
{
LastUnusedSectorCount =
PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
{
DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
StartSector = LastStartSector + LastSectorCount;
SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
/* Insert the table into the list */
NewPartEntry = CreateInsertBlankRegion(DiskEntry,
&PartEntry->ListEntry,
StartSector,
SectorCount,
FALSE);
if (NewPartEntry == NULL)
{
DPRINT1("Failed to create a new empty region for disk space!\n");
return;
}
}
LastStartSector = PartEntry->StartSector.QuadPart;
LastSectorCount = PartEntry->SectorCount.QuadPart;
}
}
/* Check for trailing unpartitioned disk space */
if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
{
LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
{
DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
StartSector = LastStartSector + LastSectorCount;
SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
/* Append the table to the list */
NewPartEntry = CreateInsertBlankRegion(DiskEntry,
&DiskEntry->PrimaryPartListHead,
StartSector,
SectorCount,
FALSE);
if (NewPartEntry == NULL)
{
DPRINT1("Failed to create a new empty region for trailing disk space!\n");
return;
}
}
}
if (DiskEntry->ExtendedPartition != NULL)
{
if (IsListEmpty(&DiskEntry->LogicalPartListHead))
{
DPRINT1("No logical partition!\n");
/* Create a partition entry that represents the empty extended partition */
StartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
SectorCount = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
NewPartEntry = CreateInsertBlankRegion(DiskEntry,
&DiskEntry->LogicalPartListHead,
StartSector,
SectorCount,
TRUE);
if (NewPartEntry == NULL)
{
DPRINT1("Failed to create a new empty region for full extended partition space!\n");
return;
}
return;
}
/* Start partition at head 1, cylinder 0 */
LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
LastSectorCount = 0ULL;
LastUnusedSectorCount = 0ULL;
for (Entry = DiskEntry->LogicalPartListHead.Flink;
Entry != &DiskEntry->LogicalPartListHead;
Entry = Entry->Flink)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
PartEntry->SectorCount.QuadPart != 0ULL)
{
LastUnusedSectorCount =
PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);
if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) &&
LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
{
DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
StartSector = LastStartSector + LastSectorCount;
SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
/* Insert the table into the list */
NewPartEntry = CreateInsertBlankRegion(DiskEntry,
&PartEntry->ListEntry,
StartSector,
SectorCount,
TRUE);
if (NewPartEntry == NULL)
{
DPRINT1("Failed to create a new empty region for extended partition space!\n");
return;
}
}
LastStartSector = PartEntry->StartSector.QuadPart;
LastSectorCount = PartEntry->SectorCount.QuadPart;
}
}
/* Check for trailing unpartitioned disk space */
if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
{
LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart +
DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount),
DiskEntry->SectorAlignment);
if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
{
DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
StartSector = LastStartSector + LastSectorCount;
SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
/* Append the table to the list */
NewPartEntry = CreateInsertBlankRegion(DiskEntry,
&DiskEntry->LogicalPartListHead,
StartSector,
SectorCount,
TRUE);
if (NewPartEntry == NULL)
{
DPRINT1("Failed to create a new empty region for extended partition space!\n");
return;
}
}
}
}
DPRINT("ScanForUnpartitionedDiskSpace() done\n");
}
static
VOID
SetDiskSignature(
IN PPARTLIST List,
IN PDISKENTRY DiskEntry)
{
LARGE_INTEGER SystemTime;
TIME_FIELDS TimeFields;
PLIST_ENTRY Entry2;
PDISKENTRY DiskEntry2;
PUCHAR Buffer;
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
return;
}
Buffer = (PUCHAR)&DiskEntry->LayoutBuffer->Signature;
while (TRUE)
{
NtQuerySystemTime(&SystemTime);
RtlTimeToTimeFields(&SystemTime, &TimeFields);
Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);
if (DiskEntry->LayoutBuffer->Signature == 0)
{
continue;
}
/* Check if the signature already exist */
/* FIXME:
* Check also signatures from disks, which are
* not visible (bootable) by the bios.
*/
for (Entry2 = List->DiskListHead.Flink;
Entry2 != &List->DiskListHead;
Entry2 = Entry2->Flink)
{
DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry);
if (DiskEntry2->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
continue;
}
if (DiskEntry != DiskEntry2 &&
DiskEntry->LayoutBuffer->Signature == DiskEntry2->LayoutBuffer->Signature)
break;
}
if (Entry2 == &List->DiskListHead)
break;
}
}
static
VOID
UpdateDiskSignatures(
IN PPARTLIST List)
{
PLIST_ENTRY Entry;
PDISKENTRY DiskEntry;
/* Update each disk */
for (Entry = List->DiskListHead.Flink;
Entry != &List->DiskListHead;
Entry = Entry->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
continue;
}
if (DiskEntry->LayoutBuffer &&
DiskEntry->LayoutBuffer->Signature == 0)
{
SetDiskSignature(List, DiskEntry);
DiskEntry->LayoutBuffer->PartitionEntry[0].RewritePartition = TRUE;
}
}
}
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
static
VOID
UpdateHwDiskNumbers(
IN PPARTLIST List)
{
PLIST_ENTRY ListEntry;
PBIOSDISKENTRY BiosDiskEntry;
PDISKENTRY DiskEntry;
ULONG HwAdapterNumber = 0;
ULONG HwControllerNumber = 0;
ULONG RemovableDiskCount = 0;
/*
* Enumerate the disks recognized by the BIOS and recompute the disk
* numbers on the system when *ALL* removable disks are not connected.
* The entries are inserted in increasing order of AdapterNumber,
* ControllerNumber and DiskNumber.
*/
for (ListEntry = List->BiosDiskListHead.Flink;
ListEntry != &List->BiosDiskListHead;
ListEntry = ListEntry->Flink)
{
BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
DiskEntry = BiosDiskEntry->DiskEntry;
/*
* If the adapter or controller numbers change, update them and reset
* the number of removable disks on this adapter/controller.
*/
if (HwAdapterNumber != BiosDiskEntry->AdapterNumber ||
HwControllerNumber != BiosDiskEntry->ControllerNumber)
{
HwAdapterNumber = BiosDiskEntry->AdapterNumber;
HwControllerNumber = BiosDiskEntry->ControllerNumber;
RemovableDiskCount = 0;
}
/* Adjust the actual hardware disk number */
if (DiskEntry)
{
ASSERT(DiskEntry->HwDiskNumber == BiosDiskEntry->DiskNumber);
if (DiskEntry->MediaType == RemovableMedia)
{
/* Increase the number of removable disks and set the disk number to zero */
++RemovableDiskCount;
DiskEntry->HwFixedDiskNumber = 0;
}
else // if (DiskEntry->MediaType == FixedMedia)
{
/* Adjust the fixed disk number, offset by the number of removable disks found before this one */
DiskEntry->HwFixedDiskNumber = BiosDiskEntry->DiskNumber - RemovableDiskCount;
}
}
else
{
DPRINT1("BIOS disk %lu is not recognized by NTOS!\n", BiosDiskEntry->DiskNumber);
}
}
}
static
VOID
AddDiskToList(
IN HANDLE FileHandle,
IN ULONG DiskNumber,
IN PPARTLIST List)
{
DISK_GEOMETRY DiskGeometry;
SCSI_ADDRESS ScsiAddress;
PDISKENTRY DiskEntry;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
PPARTITION_SECTOR Mbr;
PULONG Buffer;
LARGE_INTEGER FileOffset;
WCHAR Identifier[20];
ULONG Checksum;
ULONG Signature;
ULONG i;
PLIST_ENTRY ListEntry;
PBIOSDISKENTRY BiosDiskEntry;
ULONG LayoutBufferSize;
PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
/* Retrieve the drive geometry */
Status = NtDeviceIoControlFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&DiskGeometry,
sizeof(DiskGeometry));
if (!NT_SUCCESS(Status))
return;
if (DiskGeometry.MediaType != FixedMedia &&
DiskGeometry.MediaType != RemovableMedia)
{
return;
}
/*
* FIXME: Here we suppose the disk is always SCSI. What if it is
* of another type? To check this we need to retrieve the name of
* the driver the disk device belongs to.
*/
Status = NtDeviceIoControlFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_SCSI_GET_ADDRESS,
NULL,
0,
&ScsiAddress,
sizeof(ScsiAddress));
if (!NT_SUCCESS(Status))
return;
/*
* Check whether the disk is initialized, by looking at its MBR.
* NOTE that this must be generalized to GPT disks as well!
*/
Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(ProcessHeap,
0,
DiskGeometry.BytesPerSector);
if (Mbr == NULL)
return;
FileOffset.QuadPart = 0;
Status = NtReadFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
(PVOID)Mbr,
DiskGeometry.BytesPerSector,
&FileOffset,
NULL);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap(ProcessHeap, 0, Mbr);
DPRINT1("NtReadFile failed, status=%x\n", Status);
return;
}
Signature = Mbr->Signature;
/* Calculate the MBR checksum */
Checksum = 0;
Buffer = (PULONG)Mbr;
for (i = 0; i < 128; i++)
{
Checksum += Buffer[i];
}
Checksum = ~Checksum + 1;
RtlStringCchPrintfW(Identifier, ARRAYSIZE(Identifier),
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
L"%08x-%08x-%c",
Checksum, Signature,
(Mbr->Magic == PARTITION_MAGIC) ? L'A' : L'X');
DPRINT("Identifier: %S\n", Identifier);
DiskEntry = RtlAllocateHeap(ProcessHeap,
HEAP_ZERO_MEMORY,
sizeof(DISKENTRY));
if (DiskEntry == NULL)
{
RtlFreeHeap(ProcessHeap, 0, Mbr);
DPRINT1("Failed to allocate a new disk entry.\n");
return;
}
DiskEntry->PartList = List;
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
#if 0
{
FILE_FS_DEVICE_INFORMATION FileFsDevice;
/* Query the device for its type */
Status = NtQueryVolumeInformationFile(FileHandle,
&Iosb,
&FileFsDevice,
sizeof(FileFsDevice),
FileFsDeviceInformation);
if (!NT_SUCCESS(Status))
{
DPRINT1("Couldn't detect device type for disk %lu of identifier '%S'...\n", DiskNumber, Identifier);
}
else
{
DPRINT1("Disk %lu : DeviceType: 0x%08x ; Characteristics: 0x%08x\n", DiskNumber, FileFsDevice.DeviceType, FileFsDevice.Characteristics);
}
}
// NOTE: We may also use NtQueryVolumeInformationFile(FileFsDeviceInformation).
#endif
DiskEntry->MediaType = DiskGeometry.MediaType;
if (DiskEntry->MediaType == RemovableMedia)
{
DPRINT1("Disk %lu of identifier '%S' is removable\n", DiskNumber, Identifier);
}
else // if (DiskEntry->MediaType == FixedMedia)
{
DPRINT1("Disk %lu of identifier '%S' is fixed\n", DiskNumber, Identifier);
}
// DiskEntry->Checksum = Checksum;
// DiskEntry->Signature = Signature;
DiskEntry->BiosFound = FALSE;
/*
* Check if this disk has a valid MBR: verify its signature,
* and whether its two first bytes are a valid instruction
* (related to this, see IsThereAValidBootSector() in partlist.c).
*
* See also ntoskrnl/fstub/fstubex.c!FstubDetectPartitionStyle().
*/
// DiskEntry->NoMbr = (Mbr->Magic != PARTITION_MAGIC || (*(PUSHORT)Mbr->BootCode) == 0x0000);
/* If we have not the 0xAA55 then it's raw partition */
if (Mbr->Magic != PARTITION_MAGIC)
{
DiskEntry->DiskStyle = PARTITION_STYLE_RAW;
}
/* Check partitions types: if first is 0xEE and all the others 0, we have GPT */
else if (Mbr->Partition[0].PartitionType == EFI_PMBR_OSTYPE_EFI &&
Mbr->Partition[1].PartitionType == 0 &&
Mbr->Partition[2].PartitionType == 0 &&
Mbr->Partition[3].PartitionType == 0)
{
DiskEntry->DiskStyle = PARTITION_STYLE_GPT;
}
/* Otherwise, partition table is in MBR */
else
{
DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
}
/* Free the MBR sector buffer */
RtlFreeHeap(ProcessHeap, 0, Mbr);
for (ListEntry = List->BiosDiskListHead.Flink;
ListEntry != &List->BiosDiskListHead;
ListEntry = ListEntry->Flink)
{
BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
/* FIXME:
* Compare the size from bios and the reported size from driver.
* If we have more than one disk with a zero or with the same signature
* we must create new signatures and reboot. After the reboot,
* it is possible to identify the disks.
*/
if (BiosDiskEntry->Signature == Signature &&
BiosDiskEntry->Checksum == Checksum &&
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
BiosDiskEntry->DiskEntry == NULL)
{
if (!DiskEntry->BiosFound)
{
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
DiskEntry->HwAdapterNumber = BiosDiskEntry->AdapterNumber;
DiskEntry->HwControllerNumber = BiosDiskEntry->ControllerNumber;
DiskEntry->HwDiskNumber = BiosDiskEntry->DiskNumber;
if (DiskEntry->MediaType == RemovableMedia)
{
/* Set the removable disk number to zero */
DiskEntry->HwFixedDiskNumber = 0;
}
else // if (DiskEntry->MediaType == FixedMedia)
{
/* The fixed disk number will later be adjusted using the number of removable disks */
DiskEntry->HwFixedDiskNumber = BiosDiskEntry->DiskNumber;
}
DiskEntry->BiosFound = TRUE;
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
BiosDiskEntry->DiskEntry = DiskEntry;
break;
}
else
{
// FIXME: What to do?
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
DPRINT1("Disk %lu of identifier '%S' has already been found?!\n", DiskNumber, Identifier);
}
}
}
if (!DiskEntry->BiosFound)
{
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %lu may not be bootable by the BIOS!\n", DiskNumber);
}
DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
DPRINT("TracksPerCylinder %lu\n", DiskEntry->TracksPerCylinder);
DPRINT("SectorsPerTrack %lu\n", DiskEntry->SectorsPerTrack);
DPRINT("BytesPerSector %lu\n", DiskEntry->BytesPerSector);
DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
(ULONGLONG)DiskGeometry.TracksPerCylinder *
(ULONGLONG)DiskGeometry.SectorsPerTrack;
DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
DiskEntry->CylinderAlignment = DiskGeometry.TracksPerCylinder *
DiskGeometry.SectorsPerTrack;
DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount.QuadPart);
DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment);
DiskEntry->DiskNumber = DiskNumber;
DiskEntry->Port = ScsiAddress.PortNumber;
DiskEntry->Bus = ScsiAddress.PathId;
DiskEntry->Id = ScsiAddress.TargetId;
GetDriverName(DiskEntry);
/*
* Actually it would be more correct somehow to use:
*
* OBJECT_NAME_INFORMATION NameInfo; // ObjectNameInfo;
* ULONG ReturnedLength;
*
* Status = NtQueryObject(SomeHandleToTheDisk,
* ObjectNameInformation,
* &NameInfo,
* sizeof(NameInfo),
* &ReturnedLength);
* etc...
*
* See examples in https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/ntoskrnl/io/iomgr/error.c;hb=2f3a93ee9cec8322a86bf74b356f1ad83fc912dc#l267
*/
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
InitializeListHead(&DiskEntry->PrimaryPartListHead);
InitializeListHead(&DiskEntry->LogicalPartListHead);
InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
/*
* We now retrieve the disk partition layout
*/
/*
* Stop there now if the disk is GPT-partitioned,
* since we currently do not support such disks.
*/
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
return;
}
/* Allocate a layout buffer with 4 partition entries first */
LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
DiskEntry->LayoutBuffer = RtlAllocateHeap(ProcessHeap,
HEAP_ZERO_MEMORY,
LayoutBufferSize);
if (DiskEntry->LayoutBuffer == NULL)
{
DPRINT1("Failed to allocate the disk layout buffer!\n");
return;
}
/* Keep looping while the drive layout buffer is too small */
for (;;)
{
DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
Status = NtDeviceIoControlFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_DISK_GET_DRIVE_LAYOUT,
NULL,
0,
DiskEntry->LayoutBuffer,
LayoutBufferSize);
if (NT_SUCCESS(Status))
break;
if (Status != STATUS_BUFFER_TOO_SMALL)
{
DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
return;
}
LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
HEAP_ZERO_MEMORY,
DiskEntry->LayoutBuffer,
LayoutBufferSize);
if (NewLayoutBuffer == NULL)
{
DPRINT1("Failed to reallocate the disk layout buffer!\n");
return;
}
DiskEntry->LayoutBuffer = NewLayoutBuffer;
}
DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
#ifdef DUMP_PARTITION_TABLE
DumpPartitionTable(DiskEntry);
#endif
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
if (IsSuperFloppy(DiskEntry))
DPRINT1("Disk %lu is a super-floppy\n", DiskNumber);
if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != PARTITION_ENTRY_UNUSED)
{
if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
{
DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
}
else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
{
DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
}
else
{
DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
}
}
else
{
DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
}
if (DiskEntry->LayoutBuffer->PartitionCount == 0)
{
DiskEntry->NewDisk = TRUE;
DiskEntry->LayoutBuffer->PartitionCount = 4;
for (i = 0; i < 4; i++)
{
DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
}
}
else
{
/* Enumerate and add the first four primary partitions */
for (i = 0; i < 4; i++)
{
AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
}
/* Enumerate and add the remaining partitions as logical ones */
for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
{
AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
}
}
ScanForUnpartitionedDiskSpace(DiskEntry);
}
/*
* Retrieve the system disk, i.e. the fixed disk that is accessible by the
* firmware during boot time and where the system partition resides.
* If no system partition has been determined, we retrieve the first disk
* that verifies the mentioned criteria above.
*/
static
PDISKENTRY
GetSystemDisk(
IN PPARTLIST List)
{
PLIST_ENTRY Entry;
PDISKENTRY DiskEntry;
/* Check for empty disk list */
if (IsListEmpty(&List->DiskListHead))
return NULL;
/*
* If we already have a system partition, the system disk
* is the one on which the system partition resides.
*/
if (List->SystemPartition)
return List->SystemPartition->DiskEntry;
/* Loop over the disks and find the correct one */
for (Entry = List->DiskListHead.Flink;
Entry != &List->DiskListHead;
Entry = Entry->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
/* The disk must be a fixed disk and be found by the firmware */
if (DiskEntry->MediaType == FixedMedia && DiskEntry->BiosFound)
{
break;
}
}
if (Entry == &List->DiskListHead)
{
/* We haven't encountered any suitable disk */
return NULL;
}
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT1("System disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
}
return DiskEntry;
}
/*
* Retrieve the actual "active" partition of the given disk.
* On MBR disks, partition with the Active/Boot flag set;
* on GPT disks, partition with the correct GUID.
*/
BOOLEAN
IsPartitionActive(
IN PPARTENTRY PartEntry)
{
// TODO: Support for GPT disks!
if (IsContainerPartition(PartEntry->PartitionType))
return FALSE;
/* Check if the partition is partitioned, used and active */
if (PartEntry->IsPartitioned &&
// !IsContainerPartition(PartEntry->PartitionType) &&
PartEntry->BootIndicator)
{
/* Yes it is */
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
return TRUE;
}
return FALSE;
}
static
PPARTENTRY
GetActiveDiskPartition(
IN PDISKENTRY DiskEntry)
{
PLIST_ENTRY ListEntry;
PPARTENTRY PartEntry;
PPARTENTRY ActivePartition = NULL;
/* Check for empty disk list */
// ASSERT(DiskEntry);
if (!DiskEntry)
return NULL;
/* Check for empty partition list */
if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
return NULL;
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
return NULL;
}
/* Scan all (primary) partitions to find the active disk partition */
for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
ListEntry != &DiskEntry->PrimaryPartListHead;
ListEntry = ListEntry->Flink)
{
/* Retrieve the partition */
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
if (IsPartitionActive(PartEntry))
{
/* Yes, we've found it */
ASSERT(DiskEntry == PartEntry->DiskEntry);
ASSERT(PartEntry->IsPartitioned);
ActivePartition = PartEntry;
DPRINT1("Found active system partition %lu in disk %lu, drive letter %C\n",
PartEntry->PartitionNumber, DiskEntry->DiskNumber,
(PartEntry->DriveLetter == 0) ? L'-' : PartEntry->DriveLetter);
break;
}
}
/* Check if the disk is new and if so, use its first partition as the active system partition */
if (DiskEntry->NewDisk && ActivePartition != NULL)
{
// FIXME: What to do??
DPRINT1("NewDisk TRUE but already existing active partition?\n");
}
/* Return the active partition found (or none) */
return ActivePartition;
}
PPARTLIST
CreatePartitionList(VOID)
{
PPARTLIST List;
PDISKENTRY SystemDisk;
OBJECT_ATTRIBUTES ObjectAttributes;
SYSTEM_DEVICE_INFORMATION Sdi;
IO_STATUS_BLOCK Iosb;
ULONG ReturnSize;
NTSTATUS Status;
ULONG DiskNumber;
HANDLE FileHandle;
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
UNICODE_STRING Name;
WCHAR Buffer[MAX_PATH];
List = (PPARTLIST)RtlAllocateHeap(ProcessHeap,
0,
sizeof(PARTLIST));
if (List == NULL)
return NULL;
List->SystemPartition = NULL;
InitializeListHead(&List->DiskListHead);
InitializeListHead(&List->BiosDiskListHead);
/*
* Enumerate the disks seen by the BIOS; this will be used later
* to map drives seen by NTOS with their corresponding BIOS names.
*/
EnumerateBiosDiskEntries(List);
/* Enumerate disks seen by NTOS */
Status = NtQuerySystemInformation(SystemDeviceInformation,
&Sdi,
sizeof(Sdi),
&ReturnSize);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx", Status);
RtlFreeHeap(ProcessHeap, 0, List);
return NULL;
}
for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
{
RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
L"\\Device\\Harddisk%lu\\Partition0",
DiskNumber);
RtlInitUnicodeString(&Name, Buffer);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
&ObjectAttributes,
&Iosb,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
if (NT_SUCCESS(Status))
{
AddDiskToList(FileHandle, DiskNumber, List);
NtClose(FileHandle);
}
}
UpdateDiskSignatures(List);
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
UpdateHwDiskNumbers(List);
AssignDriveLetters(List);
/*
* Retrieve the system partition: the active partition on the system
* disk (the one that will be booted by default by the hardware).
*/
SystemDisk = GetSystemDisk(List);
List->SystemPartition = (SystemDisk ? GetActiveDiskPartition(SystemDisk) : NULL);
return List;
}
VOID
DestroyPartitionList(
IN PPARTLIST List)
{
PDISKENTRY DiskEntry;
PBIOSDISKENTRY BiosDiskEntry;
PPARTENTRY PartEntry;
PLIST_ENTRY Entry;
/* Release disk and partition info */
while (!IsListEmpty(&List->DiskListHead))
{
Entry = RemoveHeadList(&List->DiskListHead);
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
/* Release driver name */
RtlFreeUnicodeString(&DiskEntry->DriverName);
/* Release primary partition list */
while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
{
Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead);
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
RtlFreeHeap(ProcessHeap, 0, PartEntry);
}
/* Release logical partition list */
while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
{
Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
RtlFreeHeap(ProcessHeap, 0, PartEntry);
}
/* Release layout buffer */
if (DiskEntry->LayoutBuffer != NULL)
RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
/* Release disk entry */
RtlFreeHeap(ProcessHeap, 0, DiskEntry);
}
/* Release the bios disk info */
while (!IsListEmpty(&List->BiosDiskListHead))
{
Entry = RemoveHeadList(&List->BiosDiskListHead);
BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
}
/* Release list head */
RtlFreeHeap(ProcessHeap, 0, List);
}
PDISKENTRY
GetDiskByBiosNumber(
IN PPARTLIST List,
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
IN ULONG HwDiskNumber)
{
PDISKENTRY DiskEntry;
PLIST_ENTRY Entry;
/* Loop over the disks and find the correct one */
for (Entry = List->DiskListHead.Flink;
Entry != &List->DiskListHead;
Entry = Entry->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
if (DiskEntry->HwDiskNumber == HwDiskNumber)
{
/* Disk found */
return DiskEntry;
}
}
/* Disk not found, stop there */
return NULL;
}
PDISKENTRY
GetDiskByNumber(
IN PPARTLIST List,
IN ULONG DiskNumber)
{
PDISKENTRY DiskEntry;
PLIST_ENTRY Entry;
/* Loop over the disks and find the correct one */
for (Entry = List->DiskListHead.Flink;
Entry != &List->DiskListHead;
Entry = Entry->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
if (DiskEntry->DiskNumber == DiskNumber)
{
/* Disk found */
return DiskEntry;
}
}
/* Disk not found, stop there */
return NULL;
}
PDISKENTRY
GetDiskBySCSI(
IN PPARTLIST List,
IN USHORT Port,
IN USHORT Bus,
IN USHORT Id)
{
PDISKENTRY DiskEntry;
PLIST_ENTRY Entry;
/* Loop over the disks and find the correct one */
for (Entry = List->DiskListHead.Flink;
Entry != &List->DiskListHead;
Entry = Entry->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
if (DiskEntry->Port == Port &&
DiskEntry->Bus == Bus &&
DiskEntry->Id == Id)
{
/* Disk found */
return DiskEntry;
}
}
/* Disk not found, stop there */
return NULL;
}
PDISKENTRY
GetDiskBySignature(
IN PPARTLIST List,
IN ULONG Signature)
{
PDISKENTRY DiskEntry;
PLIST_ENTRY Entry;
/* Loop over the disks and find the correct one */
for (Entry = List->DiskListHead.Flink;
Entry != &List->DiskListHead;
Entry = Entry->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
if (DiskEntry->LayoutBuffer->Signature == Signature)
{
/* Disk found */
return DiskEntry;
}
}
/* Disk not found, stop there */
return NULL;
}
PPARTENTRY
GetPartition(
// IN PPARTLIST List,
IN PDISKENTRY DiskEntry,
IN ULONG PartitionNumber)
{
PPARTENTRY PartEntry;
PLIST_ENTRY Entry;
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
return NULL;
}
/* Disk found, loop over the primary partitions first... */
for (Entry = DiskEntry->PrimaryPartListHead.Flink;
Entry != &DiskEntry->PrimaryPartListHead;
Entry = Entry->Flink)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->PartitionNumber == PartitionNumber)
{
/* Partition found */
return PartEntry;
}
}
/* ... then over the logical partitions if needed */
for (Entry = DiskEntry->LogicalPartListHead.Flink;
Entry != &DiskEntry->LogicalPartListHead;
Entry = Entry->Flink)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->PartitionNumber == PartitionNumber)
{
/* Partition found */
return PartEntry;
}
}
/* The partition was not found on the disk, stop there */
return NULL;
}
BOOLEAN
GetDiskOrPartition(
IN PPARTLIST List,
IN ULONG DiskNumber,
IN ULONG PartitionNumber OPTIONAL,
OUT PDISKENTRY* pDiskEntry,
OUT PPARTENTRY* pPartEntry OPTIONAL)
{
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry = NULL;
/* Find the disk */
DiskEntry = GetDiskByNumber(List, DiskNumber);
if (!DiskEntry)
return FALSE;
/* If we have a partition (PartitionNumber != 0), find it */
if (PartitionNumber != 0)
{
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
return FALSE;
}
PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
if (!PartEntry)
return FALSE;
ASSERT(PartEntry->DiskEntry == DiskEntry);
}
/* Return the disk (and optionally the partition) */
*pDiskEntry = DiskEntry;
if (pPartEntry) *pPartEntry = PartEntry;
return TRUE;
}
//
// NOTE: Was introduced broken in r6258 by Casper
//
PPARTENTRY
SelectPartition(
IN PPARTLIST List,
IN ULONG DiskNumber,
IN ULONG PartitionNumber)
{
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
DiskEntry = GetDiskByNumber(List, DiskNumber);
if (!DiskEntry)
return NULL;
PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
if (!PartEntry)
return NULL;
ASSERT(PartEntry->DiskEntry == DiskEntry);
ASSERT(DiskEntry->DiskNumber == DiskNumber);
ASSERT(PartEntry->PartitionNumber == PartitionNumber);
return PartEntry;
}
PPARTENTRY
GetNextPartition(
IN PPARTLIST List,
IN PPARTENTRY CurrentPart OPTIONAL)
{
PLIST_ENTRY DiskListEntry;
PLIST_ENTRY PartListEntry;
PDISKENTRY CurrentDisk;
/* Fail if no disks are available */
if (IsListEmpty(&List->DiskListHead))
return NULL;
/* Check for the next usable entry on the current partition's disk */
if (CurrentPart != NULL)
{
CurrentDisk = CurrentPart->DiskEntry;
if (CurrentPart->LogicalPartition)
{
/* Logical partition */
PartListEntry = CurrentPart->ListEntry.Flink;
if (PartListEntry != &CurrentDisk->LogicalPartListHead)
{
/* Next logical partition */
CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
return CurrentPart;
}
else
{
PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink;
if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
{
CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
return CurrentPart;
}
}
}
else
{
/* Primary or extended partition */
if (CurrentPart->IsPartitioned &&
IsContainerPartition(CurrentPart->PartitionType))
{
/* First logical partition */
PartListEntry = CurrentDisk->LogicalPartListHead.Flink;
if (PartListEntry != &CurrentDisk->LogicalPartListHead)
{
CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
return CurrentPart;
}
}
else
{
/* Next primary partition */
PartListEntry = CurrentPart->ListEntry.Flink;
if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
{
CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
return CurrentPart;
}
}
}
}
/* Search for the first partition entry on the next disk */
for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink
: List->DiskListHead.Flink);
DiskListEntry != &List->DiskListHead;
DiskListEntry = DiskListEntry->Flink)
{
CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
if (CurrentDisk->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
continue;
}
PartListEntry = CurrentDisk->PrimaryPartListHead.Flink;
if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
{
CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
return CurrentPart;
}
}
return NULL;
}
PPARTENTRY
GetPrevPartition(
IN PPARTLIST List,
IN PPARTENTRY CurrentPart OPTIONAL)
{
PLIST_ENTRY DiskListEntry;
PLIST_ENTRY PartListEntry;
PDISKENTRY CurrentDisk;
/* Fail if no disks are available */
if (IsListEmpty(&List->DiskListHead))
return NULL;
/* Check for the previous usable entry on the current partition's disk */
if (CurrentPart != NULL)
{
CurrentDisk = CurrentPart->DiskEntry;
if (CurrentPart->LogicalPartition)
{
/* Logical partition */
PartListEntry = CurrentPart->ListEntry.Blink;
if (PartListEntry != &CurrentDisk->LogicalPartListHead)
{
/* Previous logical partition */
CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
}
else
{
/* Extended partition */
CurrentPart = CurrentDisk->ExtendedPartition;
}
return CurrentPart;
}
else
{
/* Primary or extended partition */
PartListEntry = CurrentPart->ListEntry.Blink;
if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
{
CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
if (CurrentPart->IsPartitioned &&
IsContainerPartition(CurrentPart->PartitionType))
{
PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
}
return CurrentPart;
}
}
}
/* Search for the last partition entry on the previous disk */
for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
: List->DiskListHead.Blink);
DiskListEntry != &List->DiskListHead;
DiskListEntry = DiskListEntry->Blink)
{
CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
if (CurrentDisk->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
continue;
}
PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
{
CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
if (CurrentPart->IsPartitioned &&
IsContainerPartition(CurrentPart->PartitionType))
{
PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
if (PartListEntry != &CurrentDisk->LogicalPartListHead)
{
CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
return CurrentPart;
}
}
else
{
return CurrentPart;
}
}
}
return NULL;
}
// static
FORCEINLINE
BOOLEAN
IsEmptyLayoutEntry(
IN PPARTITION_INFORMATION PartitionInfo)
{
if (PartitionInfo->StartingOffset.QuadPart == 0 &&
PartitionInfo->PartitionLength.QuadPart == 0)
{
return TRUE;
}
return FALSE;
}
// static
FORCEINLINE
BOOLEAN
IsSamePrimaryLayoutEntry(
IN PPARTITION_INFORMATION PartitionInfo,
IN PDISKENTRY DiskEntry,
IN PPARTENTRY PartEntry)
{
if (PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector &&
PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector)
// PartitionInfo->PartitionType == PartEntry->PartitionType
{
return TRUE;
}
return FALSE;
}
static
ULONG
GetPrimaryPartitionCount(
IN PDISKENTRY DiskEntry)
{
PLIST_ENTRY Entry;
PPARTENTRY PartEntry;
ULONG Count = 0;
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
return 0;
}
for (Entry = DiskEntry->PrimaryPartListHead.Flink;
Entry != &DiskEntry->PrimaryPartListHead;
Entry = Entry->Flink)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
Count++;
}
return Count;
}
static
ULONG
GetLogicalPartitionCount(
IN PDISKENTRY DiskEntry)
{
PLIST_ENTRY ListEntry;
PPARTENTRY PartEntry;
ULONG Count = 0;
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
return 0;
}
for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
ListEntry != &DiskEntry->LogicalPartListHead;
ListEntry = ListEntry->Flink)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
Count++;
}
return Count;
}
static
BOOLEAN
ReAllocateLayoutBuffer(
IN PDISKENTRY DiskEntry)
{
PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
ULONG NewPartitionCount;
ULONG CurrentPartitionCount = 0;
ULONG LayoutBufferSize;
ULONG i;
DPRINT1("ReAllocateLayoutBuffer()\n");
NewPartitionCount = 4 + GetLogicalPartitionCount(DiskEntry) * 4;
if (DiskEntry->LayoutBuffer)
CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
DPRINT1("CurrentPartitionCount: %lu ; NewPartitionCount: %lu\n",
CurrentPartitionCount, NewPartitionCount);
if (CurrentPartitionCount == NewPartitionCount)
return TRUE;
LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
((NewPartitionCount - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
HEAP_ZERO_MEMORY,
DiskEntry->LayoutBuffer,
LayoutBufferSize);
if (NewLayoutBuffer == NULL)
{
DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize);
return FALSE;
}
NewLayoutBuffer->PartitionCount = NewPartitionCount;
/* If the layout buffer grows, make sure the new (empty) entries are written to the disk */
if (NewPartitionCount > CurrentPartitionCount)
{
for (i = CurrentPartitionCount; i < NewPartitionCount; i++)
{
NewLayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
}
}
DiskEntry->LayoutBuffer = NewLayoutBuffer;
return TRUE;
}
static
VOID
UpdateDiskLayout(
IN PDISKENTRY DiskEntry)
{
PPARTITION_INFORMATION PartitionInfo;
PPARTITION_INFORMATION LinkInfo = NULL;
PLIST_ENTRY ListEntry;
PPARTENTRY PartEntry;
LARGE_INTEGER HiddenSectors64;
ULONG Index;
ULONG PartitionNumber = 1;
DPRINT1("UpdateDiskLayout()\n");
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
return;
}
/* Resize the layout buffer if necessary */
if (ReAllocateLayoutBuffer(DiskEntry) == FALSE)
{
DPRINT("ReAllocateLayoutBuffer() failed.\n");
return;
}
/* Update the primary partition table */
Index = 0;
for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
ListEntry != &DiskEntry->PrimaryPartListHead;
ListEntry = ListEntry->Flink)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
{
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
PartEntry->PartitionIndex = Index;
/* Reset the current partition number only for newly-created (unmounted) partitions */
if (PartEntry->New)
PartEntry->PartitionNumber = 0;
PartEntry->OnDiskPartitionNumber = (!IsContainerPartition(PartEntry->PartitionType) ? PartitionNumber : 0);
if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry))
{
DPRINT1("Updating primary partition entry %lu\n", Index);
PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
PartitionInfo->HiddenSectors = PartEntry->StartSector.LowPart;
PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
PartitionInfo->PartitionType = PartEntry->PartitionType;
PartitionInfo->BootIndicator = PartEntry->BootIndicator;
PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
PartitionInfo->RewritePartition = TRUE;
}
if (!IsContainerPartition(PartEntry->PartitionType))
PartitionNumber++;
Index++;
}
}
ASSERT(Index <= 4);
/* Update the logical partition table */
Index = 4;
for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
ListEntry != &DiskEntry->LogicalPartListHead;
ListEntry = ListEntry->Flink)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
{
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
PartEntry->PartitionIndex = Index;
/* Reset the current partition number only for newly-created (unmounted) partitions */
if (PartEntry->New)
PartEntry->PartitionNumber = 0;
PartEntry->OnDiskPartitionNumber = PartitionNumber;
DPRINT1("Updating logical partition entry %lu\n", Index);
PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
PartitionInfo->HiddenSectors = DiskEntry->SectorAlignment;
PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
PartitionInfo->PartitionType = PartEntry->PartitionType;
PartitionInfo->BootIndicator = FALSE;
PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
PartitionInfo->RewritePartition = TRUE;
/* Fill the link entry of the previous partition entry */
if (LinkInfo != NULL)
{
LinkInfo->StartingOffset.QuadPart = (PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
LinkInfo->PartitionLength.QuadPart = (PartEntry->StartSector.QuadPart + DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart;
LinkInfo->HiddenSectors = HiddenSectors64.LowPart;
LinkInfo->PartitionNumber = 0;
LinkInfo->PartitionType = PARTITION_EXTENDED;
LinkInfo->BootIndicator = FALSE;
LinkInfo->RecognizedPartition = FALSE;
LinkInfo->RewritePartition = TRUE;
}
/* Save a pointer to the link entry of the current partition entry */
LinkInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index + 1];
PartitionNumber++;
Index += 4;
}
}
/* Wipe unused primary partition entries */
for (Index = GetPrimaryPartitionCount(DiskEntry); Index < 4; Index++)
{
DPRINT1("Primary partition entry %lu\n", Index);
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
if (!IsEmptyLayoutEntry(PartitionInfo))
{
DPRINT1("Wiping primary partition entry %lu\n", Index);
PartitionInfo->StartingOffset.QuadPart = 0;
PartitionInfo->PartitionLength.QuadPart = 0;
PartitionInfo->HiddenSectors = 0;
PartitionInfo->PartitionNumber = 0;
PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
PartitionInfo->BootIndicator = FALSE;
PartitionInfo->RecognizedPartition = FALSE;
PartitionInfo->RewritePartition = TRUE;
}
}
/* Wipe unused logical partition entries */
for (Index = 4; Index < DiskEntry->LayoutBuffer->PartitionCount; Index++)
{
if (Index % 4 >= 2)
{
DPRINT1("Logical partition entry %lu\n", Index);
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
if (!IsEmptyLayoutEntry(PartitionInfo))
{
DPRINT1("Wiping partition entry %lu\n", Index);
PartitionInfo->StartingOffset.QuadPart = 0;
PartitionInfo->PartitionLength.QuadPart = 0;
PartitionInfo->HiddenSectors = 0;
PartitionInfo->PartitionNumber = 0;
PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
PartitionInfo->BootIndicator = FALSE;
PartitionInfo->RecognizedPartition = FALSE;
PartitionInfo->RewritePartition = TRUE;
}
}
}
// HACK: See the FIXMEs in WritePartitions(): (Re)set the PartitionStyle to MBR.
DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
DiskEntry->Dirty = TRUE;
#ifdef DUMP_PARTITION_TABLE
DumpPartitionTable(DiskEntry);
#endif
}
static
PPARTENTRY
GetPrevUnpartitionedEntry(
IN PPARTENTRY PartEntry)
{
PDISKENTRY DiskEntry = PartEntry->DiskEntry;
PPARTENTRY PrevPartEntry;
PLIST_ENTRY ListHead;
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
return NULL;
}
if (PartEntry->LogicalPartition)
ListHead = &DiskEntry->LogicalPartListHead;
else
ListHead = &DiskEntry->PrimaryPartListHead;
if (PartEntry->ListEntry.Blink != ListHead)
{
PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
PARTENTRY,
ListEntry);
if (!PrevPartEntry->IsPartitioned)
{
ASSERT(PrevPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
return PrevPartEntry;
}
}
return NULL;
}
static
PPARTENTRY
GetNextUnpartitionedEntry(
IN PPARTENTRY PartEntry)
{
PDISKENTRY DiskEntry = PartEntry->DiskEntry;
PPARTENTRY NextPartEntry;
PLIST_ENTRY ListHead;
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
return NULL;
}
if (PartEntry->LogicalPartition)
ListHead = &DiskEntry->LogicalPartListHead;
else
ListHead = &DiskEntry->PrimaryPartListHead;
if (PartEntry->ListEntry.Flink != ListHead)
{
NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
PARTENTRY,
ListEntry);
if (!NextPartEntry->IsPartitioned)
{
ASSERT(NextPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
return NextPartEntry;
}
}
return NULL;
}
BOOLEAN
CreatePrimaryPartition(
IN PPARTLIST List,
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
IN OUT PPARTENTRY PartEntry,
IN ULONGLONG SectorCount,
IN BOOLEAN AutoCreate)
{
ERROR_NUMBER Error;
DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount);
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
if (List == NULL || PartEntry == NULL ||
PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
{
return FALSE;
}
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
Error = PrimaryPartitionCreationChecks(PartEntry);
if (Error != NOT_AN_ERROR)
{
DPRINT1("PrimaryPartitionCreationChecks() failed with error %lu\n", Error);
return FALSE;
}
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
/* Initialize the partition entry, inserting a new blank region if needed */
if (!InitializePartitionEntry(PartEntry, SectorCount, AutoCreate))
return FALSE;
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
ASSERT(PartEntry->LogicalPartition == FALSE);
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
UpdateDiskLayout(PartEntry->DiskEntry);
AssignDriveLetters(List);
return TRUE;
}
static
VOID
AddLogicalDiskSpace(
IN PDISKENTRY DiskEntry)
{
ULONGLONG StartSector;
ULONGLONG SectorCount;
PPARTENTRY NewPartEntry;
DPRINT1("AddLogicalDiskSpace()\n");
/* Create a partition entry that represents the empty space in the container partition */
StartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
SectorCount = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
NewPartEntry = CreateInsertBlankRegion(DiskEntry,
&DiskEntry->LogicalPartListHead,
StartSector,
SectorCount,
TRUE);
if (NewPartEntry == NULL)
{
DPRINT1("Failed to create a new empty region for extended partition space!\n");
return;
}
}
BOOLEAN
CreateExtendedPartition(
IN PPARTLIST List,
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
IN OUT PPARTENTRY PartEntry,
IN ULONGLONG SectorCount)
{
ERROR_NUMBER Error;
DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount);
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
if (List == NULL || PartEntry == NULL ||
PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
{
return FALSE;
}
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
Error = ExtendedPartitionCreationChecks(PartEntry);
if (Error != NOT_AN_ERROR)
{
DPRINT1("ExtendedPartitionCreationChecks() failed with error %lu\n", Error);
return FALSE;
}
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
/* Initialize the partition entry, inserting a new blank region if needed */
if (!InitializePartitionEntry(PartEntry, SectorCount, FALSE))
return FALSE;
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
ASSERT(PartEntry->LogicalPartition == FALSE);
if (PartEntry->StartSector.QuadPart < 1450560)
{
/* Partition starts below the 8.4GB boundary ==> CHS partition */
PartEntry->PartitionType = PARTITION_EXTENDED;
}
else
{
/* Partition starts above the 8.4GB boundary ==> LBA partition */
PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
}
// FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
PartEntry->New = FALSE;
PartEntry->FormatState = Formatted;
PartEntry->DiskEntry->ExtendedPartition = PartEntry;
AddLogicalDiskSpace(PartEntry->DiskEntry);
UpdateDiskLayout(PartEntry->DiskEntry);
AssignDriveLetters(List);
return TRUE;
}
BOOLEAN
CreateLogicalPartition(
IN PPARTLIST List,
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
IN OUT PPARTENTRY PartEntry,
IN ULONGLONG SectorCount,
IN BOOLEAN AutoCreate)
{
ERROR_NUMBER Error;
DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount);
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
if (List == NULL || PartEntry == NULL ||
PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
{
return FALSE;
}
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
Error = LogicalPartitionCreationChecks(PartEntry);
if (Error != NOT_AN_ERROR)
{
DPRINT1("LogicalPartitionCreationChecks() failed with error %lu\n", Error);
return FALSE;
}
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
/* Initialize the partition entry, inserting a new blank region if needed */
if (!InitializePartitionEntry(PartEntry, SectorCount, AutoCreate))
return FALSE;
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
ASSERT(PartEntry->LogicalPartition == TRUE);
UpdateDiskLayout(PartEntry->DiskEntry);
AssignDriveLetters(List);
return TRUE;
}
NTSTATUS
DismountVolume(
IN PPARTENTRY PartEntry)
{
NTSTATUS Status;
NTSTATUS LockStatus;
UNICODE_STRING Name;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE PartitionHandle;
WCHAR Buffer[MAX_PATH];
/* Check whether the partition is valid and was mounted by the system */
if (!PartEntry->IsPartitioned ||
IsContainerPartition(PartEntry->PartitionType) ||
!IsRecognizedPartition(PartEntry->PartitionType) ||
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
PartEntry->FormatState == UnknownFormat ||
// NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
// it has been usually mounted with RawFS and thus needs to be dismounted.
!*PartEntry->FileSystem ||
PartEntry->PartitionNumber == 0)
{
/* The partition is not mounted, so just return success */
return STATUS_SUCCESS;
}
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
/* Open the volume */
RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
L"\\Device\\Harddisk%lu\\Partition%lu",
PartEntry->DiskEntry->DiskNumber,
PartEntry->PartitionNumber);
RtlInitUnicodeString(&Name, Buffer);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&PartitionHandle,
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
return Status;
}
/* Lock the volume */
LockStatus = NtFsControlFile(PartitionHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
FSCTL_LOCK_VOLUME,
NULL,
0,
NULL,
0);
if (!NT_SUCCESS(LockStatus))
{
DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
}
/* Dismount the volume */
Status = NtFsControlFile(PartitionHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
FSCTL_DISMOUNT_VOLUME,
NULL,
0,
NULL,
0);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
}
/* Unlock the volume */
LockStatus = NtFsControlFile(PartitionHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
FSCTL_UNLOCK_VOLUME,
NULL,
0,
NULL,
0);
if (!NT_SUCCESS(LockStatus))
{
DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
}
/* Close the volume */
NtClose(PartitionHandle);
return Status;
}
BOOLEAN
DeletePartition(
IN PPARTLIST List,
IN PPARTENTRY PartEntry,
OUT PPARTENTRY* FreeRegion OPTIONAL)
{
PDISKENTRY DiskEntry;
PPARTENTRY PrevPartEntry;
PPARTENTRY NextPartEntry;
PPARTENTRY LogicalPartEntry;
PLIST_ENTRY Entry;
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
if (List == NULL || PartEntry == NULL ||
PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned == FALSE)
{
return FALSE;
}
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
/* Clear the system partition if it is being deleted */
if (List->SystemPartition == PartEntry)
{
ASSERT(List->SystemPartition);
List->SystemPartition = NULL;
}
DiskEntry = PartEntry->DiskEntry;
/* Check which type of partition (primary/logical or extended) is being deleted */
if (DiskEntry->ExtendedPartition == PartEntry)
{
/* An extended partition is being deleted: delete all logical partition entries */
while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
{
Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
/* Dismount the logical partition */
DismountVolume(LogicalPartEntry);
/* Delete it */
RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
}
DiskEntry->ExtendedPartition = NULL;
}
else
{
/* A primary partition is being deleted: dismount it */
DismountVolume(PartEntry);
}
/* Adjust the unpartitioned disk space entries */
/* Get pointer to previous and next unpartitioned entries */
PrevPartEntry = GetPrevUnpartitionedEntry(PartEntry);
NextPartEntry = GetNextUnpartitionedEntry(PartEntry);
if (PrevPartEntry != NULL && NextPartEntry != NULL)
{
/* Merge the previous, current and next unpartitioned entries */
/* Adjust the previous entry length */
PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
/* Remove the current and next entries */
RemoveEntryList(&PartEntry->ListEntry);
RtlFreeHeap(ProcessHeap, 0, PartEntry);
RemoveEntryList(&NextPartEntry->ListEntry);
RtlFreeHeap(ProcessHeap, 0, NextPartEntry);
/* Optionally return the freed region */
if (FreeRegion)
*FreeRegion = PrevPartEntry;
}
else if (PrevPartEntry != NULL && NextPartEntry == NULL)
{
/* Merge the current and the previous unpartitioned entries */
/* Adjust the previous entry length */
PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
/* Remove the current entry */
RemoveEntryList(&PartEntry->ListEntry);
RtlFreeHeap(ProcessHeap, 0, PartEntry);
/* Optionally return the freed region */
if (FreeRegion)
*FreeRegion = PrevPartEntry;
}
else if (PrevPartEntry == NULL && NextPartEntry != NULL)
{
/* Merge the current and the next unpartitioned entries */
/* Adjust the next entry offset and length */
NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
/* Remove the current entry */
RemoveEntryList(&PartEntry->ListEntry);
RtlFreeHeap(ProcessHeap, 0, PartEntry);
/* Optionally return the freed region */
if (FreeRegion)
*FreeRegion = NextPartEntry;
}
else
{
/* Nothing to merge but change the current entry */
PartEntry->IsPartitioned = FALSE;
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
PartEntry->OnDiskPartitionNumber = 0;
PartEntry->PartitionNumber = 0;
// PartEntry->PartitionIndex = 0;
PartEntry->BootIndicator = FALSE;
PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
PartEntry->FormatState = Unformatted;
PartEntry->FileSystem[0] = L'\0';
PartEntry->DriveLetter = 0;
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
/* Optionally return the freed region */
if (FreeRegion)
*FreeRegion = PartEntry;
}
UpdateDiskLayout(DiskEntry);
AssignDriveLetters(List);
return TRUE;
}
static
BOOLEAN
IsSupportedActivePartition(
IN PPARTENTRY PartEntry)
{
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
/* Check the type and the file system of this partition */
/*
* We do not support extended partition containers (on MBR disks) marked
* as active, and containing code inside their extended boot records.
*/
if (IsContainerPartition(PartEntry->PartitionType))
{
DPRINT1("System partition %lu in disk %lu is an extended partition container?!\n",
PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
return FALSE;
}
/*
* ADDITIONAL CHECKS / BIG HACK:
*
* Retrieve its file system and check whether we have
* write support for it. If that is the case we are fine
* and we can use it directly. However if we don't have
* write support we will need to change the active system
* partition.
*
* NOTE that this is completely useless on architectures
* where a real system partition is required, as on these
* architectures the partition uses the FAT FS, for which
* we do have write support.
* NOTE also that for those architectures looking for a
* partition boot indicator is insufficient.
*/
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
if (PartEntry->FormatState == Unformatted)
{
/* If this partition is mounted, it would use RawFS ("RAW") */
return TRUE;
}
else if ((PartEntry->FormatState == Preformatted) ||
(PartEntry->FormatState == Formatted))
{
ASSERT(*PartEntry->FileSystem);
/* NOTE: Please keep in sync with the RegisteredFileSystems list! */
if (wcsicmp(PartEntry->FileSystem, L"FAT") == 0 ||
wcsicmp(PartEntry->FileSystem, L"FAT32") == 0 ||
// wcsicmp(PartEntry->FileSystem, L"NTFS") == 0 ||
[SETUPLIB][USETUP] Code simplifications & fixes. SETUPLIB: ========= - Remove useless HiddenSectors member in PARTENTRY structure. - InsertDiskRegion() helper returns a BOOLEAN success. - CreateInsertBlankRegion() helper sets LogicalPartition. - Simplify the InitializePartitionEntry() helper so that its PartEntry parameter is clearly the one that is being initialized (i.e. converted from a blank region to) an actual partition, and use the helper CreateInsertBlankRegion(). The calculations for the StartSector and SectorCount are exactly equivalent with the old version of this function. Also make it return a BOOLEAN success instead. + Add some extra validation checks. + Adjust CreatePrimaryPartition(), CreateExtendedPartition() and CreateLogicalPartition() in this regard. - Better handling of "RAW"-mounted partitions: treat them as "Unformatted" only if they are RAW *AND* their PartitionType is one of those associated with FAT file-system. Otherwise we cannot decide whether they are indeed unformatted or have an unknown file-system on them, therefore treat them as the latter. In this regard, the IsSupportedActivePartition() helper should not look for FileSystem == RAW but instead only look whether the partition is Unformatted. This should help with situations similar to the one described in CORE-16274 where a partition with a genuine file-system but not recognized by ReactOS (because we currently do not have the EXT2/3/4 filesystem driver loaded during 1st-stage setup due to commit 5a650f6b) and therefore mounted as RAW, was thought to be unformatted. USETUP: ======= - Use the "global" SystemPartition pointer: this is the "system" partition we will actually use. It can be different from the actual one of the computer, for example when we install ReactOS on a removable disk. This allows also to simplify the code. - Remove the single-used DestinationDriveLetter variable. - Remove BuildInstallPaths() helper and use InitDestinationPaths() directly instead. - Always mention the disk where the partition being formatted is. - Cleanup old code comments, add assertions here & there...
2019-08-24 23:32:46 +00:00
wcsicmp(PartEntry->FileSystem, L"BTRFS") == 0)
{
return TRUE;
}
else
{
// WARNING: We cannot write on this FS yet!
DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
PartEntry->FileSystem);
return FALSE;
}
}
else // if (PartEntry->FormatState == UnknownFormat)
{
ASSERT(!*PartEntry->FileSystem);
DPRINT1("System partition %lu in disk %lu with no or unknown FS?!\n",
PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
return FALSE;
}
// HACK: WARNING: We cannot write on this FS yet!
// See fsutil.c:InferFileSystem()
if (PartEntry->PartitionType == PARTITION_IFS)
{
DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
PartEntry->FileSystem);
return FALSE;
}
return TRUE;
}
PPARTENTRY
FindSupportedSystemPartition(
IN PPARTLIST List,
IN BOOLEAN ForceSelect,
IN PDISKENTRY AlternativeDisk OPTIONAL,
IN PPARTENTRY AlternativePart OPTIONAL)
{
PLIST_ENTRY ListEntry;
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
PPARTENTRY ActivePartition;
PPARTENTRY CandidatePartition = NULL;
/* Check for empty disk list */
if (IsListEmpty(&List->DiskListHead))
{
/* No system partition! */
ASSERT(List->SystemPartition == NULL);
goto NoSystemPartition;
}
/* Adjust the optional alternative disk if needed */
if (!AlternativeDisk && AlternativePart)
AlternativeDisk = AlternativePart->DiskEntry;
/* Ensure that the alternative partition is on the alternative disk */
if (AlternativePart)
ASSERT(AlternativeDisk && (AlternativePart->DiskEntry == AlternativeDisk));
/* Ensure that the alternative disk is in the list */
if (AlternativeDisk)
ASSERT(AlternativeDisk->PartList == List);
/* Start fresh */
CandidatePartition = NULL;
//
// Step 1 : Check the system disk.
//
/*
* First, check whether the system disk, i.e. the one that will be booted
* by default by the hardware, contains an active partition. If so this
* should be our system partition.
*/
DiskEntry = GetSystemDisk(List);
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT1("System disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
goto UseAlternativeDisk;
}
/* If we have a system partition (in the system disk), validate it */
ActivePartition = List->SystemPartition;
if (ActivePartition && IsSupportedActivePartition(ActivePartition))
{
CandidatePartition = ActivePartition;
DPRINT1("Use the current system partition %lu in disk %lu, drive letter %C\n",
CandidatePartition->PartitionNumber,
CandidatePartition->DiskEntry->DiskNumber,
(CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
/* Return the candidate system partition */
return CandidatePartition;
}
/* If the system disk is not the optional alternative disk, perform the minimal checks */
if (DiskEntry != AlternativeDisk)
{
/*
* No active partition has been recognized. Enumerate all the (primary)
* partitions in the system disk, excluding the possible current active
* partition, to find a new candidate.
*/
for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
ListEntry != &DiskEntry->PrimaryPartListHead;
ListEntry = ListEntry->Flink)
{
/* Retrieve the partition */
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
/* Skip the current active partition */
if (PartEntry == ActivePartition)
continue;
/* Check if the partition is partitioned and used */
if (PartEntry->IsPartitioned &&
!IsContainerPartition(PartEntry->PartitionType))
{
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
/* If we get a candidate active partition in the disk, validate it */
if (IsSupportedActivePartition(PartEntry))
{
CandidatePartition = PartEntry;
goto UseAlternativePartition;
}
}
#if 0
/* Check if the partition is partitioned and used */
if (!PartEntry->IsPartitioned)
{
ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
// TODO: Check for minimal size!!
CandidatePartition = PartEntry;
goto UseAlternativePartition;
}
#endif
}
/*
* Still nothing, look whether there is some free space that we can use
* for the new system partition. We must be sure that the total number
* of partition is less than the maximum allowed, and that the minimal
* size is fine.
*/
//
// TODO: Fix the handling of system partition being created in unpartitioned space!!
// --> When to partition it? etc...
//
if (GetPrimaryPartitionCount(DiskEntry) < 4)
{
for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
ListEntry != &DiskEntry->PrimaryPartListHead;
ListEntry = ListEntry->Flink)
{
/* Retrieve the partition */
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
/* Skip the current active partition */
if (PartEntry == ActivePartition)
continue;
/* Check for unpartitioned space */
if (!PartEntry->IsPartitioned)
{
ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
// TODO: Check for minimal size!!
CandidatePartition = PartEntry;
goto UseAlternativePartition;
}
}
}
}
//
// Step 2 : No active partition found: Check the alternative disk if specified.
//
UseAlternativeDisk:
if (!AlternativeDisk || (!ForceSelect && (DiskEntry != AlternativeDisk)))
goto NoSystemPartition;
if (AlternativeDisk->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT1("Alternative disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
goto NoSystemPartition;
}
if (DiskEntry != AlternativeDisk)
{
/* Choose the alternative disk */
DiskEntry = AlternativeDisk;
/* If we get a candidate active partition, validate it */
ActivePartition = GetActiveDiskPartition(DiskEntry);
if (ActivePartition && IsSupportedActivePartition(ActivePartition))
{
CandidatePartition = ActivePartition;
goto UseAlternativePartition;
}
}
/* We now may have an unsupported active partition, or none */
/***
*** TODO: Improve the selection:
*** - If we want a really separate system partition from the partition where
*** we install, do something similar to what's done below in the code.
*** - Otherwise if we allow for the system partition to be also the partition
*** where we install, just directly fall down to using AlternativePart.
***/
/* Retrieve the first partition of the disk */
PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink,
PARTENTRY, ListEntry);
ASSERT(DiskEntry == PartEntry->DiskEntry);
CandidatePartition = PartEntry;
//
// See: https://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/partlist.c?r1=63355&r2=63354&pathrev=63355#l2318
//
/* Check if the disk is new and if so, use its first partition as the active system partition */
if (DiskEntry->NewDisk)
{
// !IsContainerPartition(PartEntry->PartitionType);
if (!CandidatePartition->IsPartitioned || !CandidatePartition->BootIndicator) /* CandidatePartition != ActivePartition */
{
ASSERT(DiskEntry == CandidatePartition->DiskEntry);
DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %C\n",
CandidatePartition->PartitionNumber,
CandidatePartition->DiskEntry->DiskNumber,
(CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
/* Return the candidate system partition */
return CandidatePartition;
}
// FIXME: What to do??
DPRINT1("NewDisk TRUE but first partition is used?\n");
}
/*
* The disk is not new, check if any partition is initialized;
* if not, the first one becomes the system partition.
*/
for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
ListEntry != &DiskEntry->PrimaryPartListHead;
ListEntry = ListEntry->Flink)
{
/* Retrieve the partition */
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
/* Check if the partition is partitioned and is used */
// !IsContainerPartition(PartEntry->PartitionType);
if (/* PartEntry->IsPartitioned && */
PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator)
{
break;
}
}
if (ListEntry == &DiskEntry->PrimaryPartListHead)
{
/*
* OK we haven't encountered any used and active partition,
* so use the first one as the system partition.
*/
ASSERT(DiskEntry == CandidatePartition->DiskEntry);
DPRINT1("Use first active system partition %lu in disk %lu, drive letter %C\n",
CandidatePartition->PartitionNumber,
CandidatePartition->DiskEntry->DiskNumber,
(CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
/* Return the candidate system partition */
return CandidatePartition;
}
/*
* The disk is not new, we did not find any actual active partition,
* or the one we found was not supported, or any possible other candidate
* is not supported. We then use the alternative partition if specified.
*/
if (AlternativePart)
{
DPRINT1("No valid or supported system partition has been found, use the alternative partition!\n");
CandidatePartition = AlternativePart;
goto UseAlternativePartition;
}
else
{
NoSystemPartition:
DPRINT1("No valid or supported system partition has been found on this system!\n");
return NULL;
}
UseAlternativePartition:
/*
* We are here because we did not find any (active) candidate system
* partition that we know how to support. What we are going to do is
* to change the existing system partition and use the alternative partition
* (e.g. on which we install ReactOS) as the new system partition.
* Then we will need to add in FreeLdr's boot menu an entry for booting
* from the original system partition.
*/
ASSERT(CandidatePartition);
DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %C\n",
CandidatePartition->PartitionNumber,
CandidatePartition->DiskEntry->DiskNumber,
(CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
/* Return the candidate system partition */
return CandidatePartition;
}
BOOLEAN
SetActivePartition(
IN PPARTLIST List,
IN PPARTENTRY PartEntry,
IN PPARTENTRY OldActivePart OPTIONAL)
{
/* Check for empty disk list */
if (IsListEmpty(&List->DiskListHead))
return FALSE;
/* Validate the partition entry */
if (!PartEntry)
return FALSE;
/*
* If the partition entry is already the system partition, or if it is
* the same as the old active partition hint the user provided (and if
* it is already active), just return success.
*/
if ((PartEntry == List->SystemPartition) ||
((PartEntry == OldActivePart) && IsPartitionActive(OldActivePart)))
{
return TRUE;
}
ASSERT(PartEntry->DiskEntry);
/* Ensure that the partition's disk is in the list */
ASSERT(PartEntry->DiskEntry->PartList == List);
/*
* If the user provided an old active partition hint, verify that it is
* indeeed active and belongs to the same disk where the new partition
* belongs. Otherwise determine the current active partition on the disk
* where the new partition belongs.
*/
if (!(OldActivePart && IsPartitionActive(OldActivePart) && (OldActivePart->DiskEntry == PartEntry->DiskEntry)))
{
/* It's not, determine the current active partition for the disk */
OldActivePart = GetActiveDiskPartition(PartEntry->DiskEntry);
}
/* Unset the old active partition if it exists */
if (OldActivePart)
{
OldActivePart->BootIndicator = FALSE;
OldActivePart->DiskEntry->LayoutBuffer->PartitionEntry[OldActivePart->PartitionIndex].BootIndicator = FALSE;
OldActivePart->DiskEntry->LayoutBuffer->PartitionEntry[OldActivePart->PartitionIndex].RewritePartition = TRUE;
OldActivePart->DiskEntry->Dirty = TRUE;
}
/* Modify the system partition if the new partition is on the system disk */
if (PartEntry->DiskEntry == GetSystemDisk(List))
List->SystemPartition = PartEntry;
/* Set the new active partition */
PartEntry->BootIndicator = TRUE;
PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].BootIndicator = TRUE;
PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
PartEntry->DiskEntry->Dirty = TRUE;
return TRUE;
}
NTSTATUS
WritePartitions(
IN PDISKENTRY DiskEntry)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name;
HANDLE FileHandle;
IO_STATUS_BLOCK Iosb;
ULONG BufferSize;
PPARTITION_INFORMATION PartitionInfo;
ULONG PartitionCount;
PLIST_ENTRY ListEntry;
PPARTENTRY PartEntry;
WCHAR DstPath[MAX_PATH];
DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
/* If the disk is not dirty, there is nothing to do */
if (!DiskEntry->Dirty)
return STATUS_SUCCESS;
RtlStringCchPrintfW(DstPath, ARRAYSIZE(DstPath),
L"\\Device\\Harddisk%lu\\Partition0",
DiskEntry->DiskNumber);
RtlInitUnicodeString(&Name, DstPath);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
&ObjectAttributes,
&Iosb,
0,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
return Status;
}
#ifdef DUMP_PARTITION_TABLE
DumpPartitionTable(DiskEntry);
#endif
//
// FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
// the disk in MBR or GPT format in case the disk was not initialized!!
// For this we must ask the user which format to use.
//
/* Save the original partition count to be restored later (see comment below) */
PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
/* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
((PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
Status = NtDeviceIoControlFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_DISK_SET_DRIVE_LAYOUT,
DiskEntry->LayoutBuffer,
BufferSize,
DiskEntry->LayoutBuffer,
BufferSize);
NtClose(FileHandle);
/*
* IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
* DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
* where such a table is expected to enumerate up to 4 partitions:
* partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
* Due to this we need to restore the original PartitionCount number.
*/
DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
/* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
if (!NT_SUCCESS(Status))
{
DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
return Status;
}
#ifdef DUMP_PARTITION_TABLE
DumpPartitionTable(DiskEntry);
#endif
/* Update the partition numbers */
/* Update the primary partition table */
for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
ListEntry != &DiskEntry->PrimaryPartListHead;
ListEntry = ListEntry->Flink)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
{
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
}
}
/* Update the logical partition table */
for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
ListEntry != &DiskEntry->LogicalPartListHead;
ListEntry = ListEntry->Flink)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
{
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
}
}
//
// NOTE: Originally (see r40437), we used to install here also a new MBR
// for this disk (by calling InstallMbrBootCodeToDisk), only if:
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
// DiskEntry->NewDisk == TRUE and DiskEntry->HwDiskNumber == 0.
// Then after that, both DiskEntry->NewDisk and DiskEntry->NoMbr were set
// to FALSE. In the other place (in usetup.c) where InstallMbrBootCodeToDisk
// was called too, the installation test was modified by checking whether
// DiskEntry->NoMbr was TRUE (instead of NewDisk).
//
// HACK: Parts of FIXMEs described above: (Re)set the PartitionStyle to MBR.
DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
/* The layout has been successfully updated, the disk is not dirty anymore */
DiskEntry->Dirty = FALSE;
return Status;
}
BOOLEAN
WritePartitionsToDisk(
IN PPARTLIST List)
{
NTSTATUS Status;
PLIST_ENTRY Entry;
PDISKENTRY DiskEntry;
if (List == NULL)
return TRUE;
for (Entry = List->DiskListHead.Flink;
Entry != &List->DiskListHead;
Entry = Entry->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
continue;
}
if (DiskEntry->Dirty != FALSE)
{
Status = WritePartitions(DiskEntry);
if (!NT_SUCCESS(Status))
{
DPRINT1("WritePartitionsToDisk() failed to update disk %lu, Status 0x%08lx\n",
DiskEntry->DiskNumber, Status);
}
}
}
return TRUE;
}
BOOLEAN
SetMountedDeviceValue(
IN WCHAR Letter,
IN ULONG Signature,
IN LARGE_INTEGER StartingOffset)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"SYSTEM\\MountedDevices");
UNICODE_STRING ValueName;
WCHAR ValueNameBuffer[16];
HANDLE KeyHandle;
REG_DISK_MOUNT_INFO MountInfo;
RtlStringCchPrintfW(ValueNameBuffer, ARRAYSIZE(ValueNameBuffer),
L"\\DosDevices\\%c:", Letter);
RtlInitUnicodeString(&ValueName, ValueNameBuffer);
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE, NULL),
NULL);
Status = NtOpenKey(&KeyHandle,
KEY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
Status = NtCreateKey(&KeyHandle,
KEY_ALL_ACCESS,
&ObjectAttributes,
0,
NULL,
REG_OPTION_NON_VOLATILE,
NULL);
}
if (!NT_SUCCESS(Status))
{
DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
return FALSE;
}
MountInfo.Signature = Signature;
MountInfo.StartingOffset = StartingOffset;
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_BINARY,
(PVOID)&MountInfo,
sizeof(MountInfo));
NtClose(KeyHandle);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
return FALSE;
}
return TRUE;
}
BOOLEAN
SetMountedDeviceValues(
IN PPARTLIST List)
{
PLIST_ENTRY Entry1, Entry2;
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
LARGE_INTEGER StartingOffset;
if (List == NULL)
return FALSE;
for (Entry1 = List->DiskListHead.Flink;
Entry1 != &List->DiskListHead;
Entry1 = Entry1->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry1,
DISKENTRY,
ListEntry);
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
continue;
}
for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
Entry2 != &DiskEntry->PrimaryPartListHead;
Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
{
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
/* Assign a "\DosDevices\#:" mount point to this partition */
if (PartEntry->DriveLetter)
{
StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
if (!SetMountedDeviceValue(PartEntry->DriveLetter,
DiskEntry->LayoutBuffer->Signature,
StartingOffset))
{
return FALSE;
}
}
}
}
for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
Entry2 != &DiskEntry->LogicalPartListHead;
Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
{
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
/* Assign a "\DosDevices\#:" mount point to this partition */
if (PartEntry->DriveLetter)
{
StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
if (!SetMountedDeviceValue(PartEntry->DriveLetter,
DiskEntry->LayoutBuffer->Signature,
StartingOffset))
{
return FALSE;
}
}
}
}
}
return TRUE;
}
VOID
SetMBRPartitionType(
IN PPARTENTRY PartEntry,
IN UCHAR PartitionType)
{
PDISKENTRY DiskEntry = PartEntry->DiskEntry;
ASSERT(DiskEntry->DiskStyle == PARTITION_STYLE_MBR);
PartEntry->PartitionType = PartitionType;
DiskEntry->Dirty = TRUE;
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartitionType;
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RecognizedPartition = IsRecognizedPartition(PartitionType);
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
}
ERROR_NUMBER
PrimaryPartitionCreationChecks(
IN PPARTENTRY PartEntry)
{
PDISKENTRY DiskEntry = PartEntry->DiskEntry;
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
return ERROR_WARN_PARTITION;
}
/* Fail if the partition is already in use */
if (PartEntry->IsPartitioned)
return ERROR_NEW_PARTITION;
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
/* Only one primary partition is allowed on super-floppy */
if (IsSuperFloppy(DiskEntry))
return ERROR_PARTITION_TABLE_FULL;
/* Fail if there are already 4 primary partitions in the list */
if (GetPrimaryPartitionCount(DiskEntry) >= 4)
return ERROR_PARTITION_TABLE_FULL;
return ERROR_SUCCESS;
}
ERROR_NUMBER
ExtendedPartitionCreationChecks(
IN PPARTENTRY PartEntry)
{
PDISKENTRY DiskEntry = PartEntry->DiskEntry;
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
return ERROR_WARN_PARTITION;
}
/* Fail if the partition is already in use */
if (PartEntry->IsPartitioned)
return ERROR_NEW_PARTITION;
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
/* Only one primary partition is allowed on super-floppy */
if (IsSuperFloppy(DiskEntry))
return ERROR_PARTITION_TABLE_FULL;
/* Fail if there are already 4 primary partitions in the list */
if (GetPrimaryPartitionCount(DiskEntry) >= 4)
return ERROR_PARTITION_TABLE_FULL;
/* Fail if there is another extended partition in the list */
if (DiskEntry->ExtendedPartition != NULL)
return ERROR_ONLY_ONE_EXTENDED;
return ERROR_SUCCESS;
}
ERROR_NUMBER
LogicalPartitionCreationChecks(
IN PPARTENTRY PartEntry)
{
PDISKENTRY DiskEntry = PartEntry->DiskEntry;
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
return ERROR_WARN_PARTITION;
}
/* Fail if the partition is already in use */
if (PartEntry->IsPartitioned)
return ERROR_NEW_PARTITION;
[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super-floppy" partitioning. Nowadays more and more people try to install ReactOS from removable drives (e.g. USB sticks) onto fixed HDDs, or try to install it into USB sticks too. Both fixed and removable drives, as well as partitions on these, are represented in NT using the same device name format: \Device\HarddiskM\PartitionN , with an increasing disk number M. Using this number for building the corresponding firmware-specific ARC multi(x)disk(y)rdisk(z) path used by the NT/ROS loader (FreeLdr, ...) is then prone to error since there may have been removable drives inserted and accounted for in the calculation of the disk number. These drives must be correctly subtracted in order to generate the correct ARC path, valid once all the removable drives have been ejected (which should also be the situation seen from the BIOS when booting up, except of course if you boot on a USB stick). This problem is now solved. Note that it matters only for the disks that have also been enumerated by the firmware (BIOS; Int 13h). We don't have to care about the other drives, since the ARC path will be of a different format and will not use the disk number (instead, the SCSI coordinates are used). We also try to enumerate all the disks found in all the possible disk adapters and controllers enumerated in the Hardware registry tree (and that are visible by FreeLdr) in order to cover all. Finally, we detect whether a disk reports as a "super-floppy", i.e. an unpartitioned disk with a valid VBR. This is indeed how a standard floppy disk looks like, or how USB sticks are partitioned on Windows. Such disk is reported has having only one single partition starting at the beginning of the disk, with partition number == 0, its type being FAT16 non-bootable. This allows us to forbid creating any new partitions on such disks. Note that accessing either \Device\HarddiskN\Partition0 or Partition1 on such a disk returns the same data. Note also that on the contrary, regular MBR-partitioned disks would report at least four partitions entries, instead of just one. The other improvements are: - Do *NOT* write any MBR on a disk partitioned as "super-floppy". CORE-13703 - Fix the computed disk identifier, of format: %08x-%08x-%c . The numbers are respectively the checksum of the first sector, and the disk signature. The terminating letter is A or X, depending whether the first sector ends with 0x55AA/0xAA55 or not (see also commit 5053f1f5). - Warn if the user attempts to install ReactOS on a disk that is not visible by the firmware of his computer, because it may not be bootable.
2019-03-11 23:13:25 +00:00
/* Only one primary partition is allowed on super-floppy */
if (IsSuperFloppy(DiskEntry))
return ERROR_PARTITION_TABLE_FULL;
return ERROR_SUCCESS;
}
BOOLEAN
GetNextUnformattedPartition(
IN PPARTLIST List,
OUT PDISKENTRY *pDiskEntry OPTIONAL,
OUT PPARTENTRY *pPartEntry)
{
PLIST_ENTRY Entry1, Entry2;
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
for (Entry1 = List->DiskListHead.Flink;
Entry1 != &List->DiskListHead;
Entry1 = Entry1->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry1,
DISKENTRY,
ListEntry);
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
continue;
}
for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
Entry2 != &DiskEntry->PrimaryPartListHead;
Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned && PartEntry->New)
{
ASSERT(DiskEntry == PartEntry->DiskEntry);
if (pDiskEntry) *pDiskEntry = DiskEntry;
*pPartEntry = PartEntry;
return TRUE;
}
}
for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
Entry2 != &DiskEntry->LogicalPartListHead;
Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned && PartEntry->New)
{
ASSERT(DiskEntry == PartEntry->DiskEntry);
if (pDiskEntry) *pDiskEntry = DiskEntry;
*pPartEntry = PartEntry;
return TRUE;
}
}
}
if (pDiskEntry) *pDiskEntry = NULL;
*pPartEntry = NULL;
return FALSE;
}
BOOLEAN
GetNextUncheckedPartition(
IN PPARTLIST List,
OUT PDISKENTRY *pDiskEntry OPTIONAL,
OUT PPARTENTRY *pPartEntry)
{
PLIST_ENTRY Entry1, Entry2;
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
for (Entry1 = List->DiskListHead.Flink;
Entry1 != &List->DiskListHead;
Entry1 = Entry1->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry1,
DISKENTRY,
ListEntry);
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
continue;
}
for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
Entry2 != &DiskEntry->PrimaryPartListHead;
Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
{
ASSERT(DiskEntry == PartEntry->DiskEntry);
if (pDiskEntry) *pDiskEntry = DiskEntry;
*pPartEntry = PartEntry;
return TRUE;
}
}
for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
Entry2 != &DiskEntry->LogicalPartListHead;
Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
{
ASSERT(DiskEntry == PartEntry->DiskEntry);
if (pDiskEntry) *pDiskEntry = DiskEntry;
*pPartEntry = PartEntry;
return TRUE;
}
}
}
if (pDiskEntry) *pDiskEntry = NULL;
*pPartEntry = NULL;
return FALSE;
}
/* EOF */