16f19c83bSHermès Bélusca-Maïto /*
26f19c83bSHermès Bélusca-Maïto * PROJECT: ReactOS Setup Library
36f15802aSHermès Bélusca-Maïto * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
46f19c83bSHermès Bélusca-Maïto * PURPOSE: Partition list functions
5c1fbc2d6SHermès Bélusca-Maïto * COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
66f15802aSHermès Bélusca-Maïto * Copyright 2018-2024 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
76f19c83bSHermès Bélusca-Maïto */
86f19c83bSHermès Bélusca-Maïto
96f19c83bSHermès Bélusca-Maïto #include "precomp.h"
106f19c83bSHermès Bélusca-Maïto #include <ntddscsi.h>
116f19c83bSHermès Bélusca-Maïto
126f19c83bSHermès Bélusca-Maïto #include "partlist.h"
136f15802aSHermès Bélusca-Maïto #include "volutil.h"
146f15802aSHermès Bélusca-Maïto #include "fsrec.h" // For FileSystemToMBRPartitionType()
156f15802aSHermès Bélusca-Maïto
1651cb3cc6SHermès Bélusca-Maïto #include "registry.h"
176f19c83bSHermès Bélusca-Maïto
186f19c83bSHermès Bélusca-Maïto #define NDEBUG
196f19c83bSHermès Bélusca-Maïto #include <debug.h>
206f19c83bSHermès Bélusca-Maïto
216f19c83bSHermès Bélusca-Maïto // #define DUMP_PARTITION_TABLE
226f19c83bSHermès Bélusca-Maïto
236f19c83bSHermès Bélusca-Maïto #include <pshpack1.h>
246f19c83bSHermès Bélusca-Maïto typedef struct _REG_DISK_MOUNT_INFO
256f19c83bSHermès Bélusca-Maïto {
266f19c83bSHermès Bélusca-Maïto ULONG Signature;
276f15802aSHermès Bélusca-Maïto ULONGLONG StartingOffset;
286f19c83bSHermès Bélusca-Maïto } REG_DISK_MOUNT_INFO, *PREG_DISK_MOUNT_INFO;
296f19c83bSHermès Bélusca-Maïto #include <poppack.h>
306f19c83bSHermès Bélusca-Maïto
316f19c83bSHermès Bélusca-Maïto
326f19c83bSHermès Bélusca-Maïto /* FUNCTIONS ****************************************************************/
336f19c83bSHermès Bélusca-Maïto
346f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
356f19c83bSHermès Bélusca-Maïto static
366f19c83bSHermès Bélusca-Maïto VOID
DumpPartitionTable(PDISKENTRY DiskEntry)376f19c83bSHermès Bélusca-Maïto DumpPartitionTable(
386f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry)
396f19c83bSHermès Bélusca-Maïto {
406f19c83bSHermès Bélusca-Maïto PPARTITION_INFORMATION PartitionInfo;
416f19c83bSHermès Bélusca-Maïto ULONG i;
426f19c83bSHermès Bélusca-Maïto
436f19c83bSHermès Bélusca-Maïto DbgPrint("\n");
446f19c83bSHermès Bélusca-Maïto DbgPrint("Index Start Length Hidden Nr Type Boot RW\n");
456f19c83bSHermès Bélusca-Maïto DbgPrint("----- ------------ ------------ ---------- -- ---- ---- --\n");
466f19c83bSHermès Bélusca-Maïto
476f19c83bSHermès Bélusca-Maïto for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++)
486f19c83bSHermès Bélusca-Maïto {
496f19c83bSHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[i];
506f19c83bSHermès Bélusca-Maïto DbgPrint(" %3lu %12I64u %12I64u %10lu %2lu %2x %c %c\n",
516f19c83bSHermès Bélusca-Maïto i,
526f19c83bSHermès Bélusca-Maïto PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector,
536f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector,
546f19c83bSHermès Bélusca-Maïto PartitionInfo->HiddenSectors,
556f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionNumber,
566f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionType,
576f19c83bSHermès Bélusca-Maïto PartitionInfo->BootIndicator ? '*': ' ',
586f19c83bSHermès Bélusca-Maïto PartitionInfo->RewritePartition ? 'Y': 'N');
596f19c83bSHermès Bélusca-Maïto }
606f19c83bSHermès Bélusca-Maïto
616f19c83bSHermès Bélusca-Maïto DbgPrint("\n");
626f19c83bSHermès Bélusca-Maïto }
636f19c83bSHermès Bélusca-Maïto #endif
646f19c83bSHermès Bélusca-Maïto
656f19c83bSHermès Bélusca-Maïto
666f19c83bSHermès Bélusca-Maïto ULONGLONG
AlignDown(IN ULONGLONG Value,IN ULONG Alignment)676f19c83bSHermès Bélusca-Maïto AlignDown(
686f19c83bSHermès Bélusca-Maïto IN ULONGLONG Value,
696f19c83bSHermès Bélusca-Maïto IN ULONG Alignment)
706f19c83bSHermès Bélusca-Maïto {
716f19c83bSHermès Bélusca-Maïto ULONGLONG Temp;
726f19c83bSHermès Bélusca-Maïto
736f19c83bSHermès Bélusca-Maïto Temp = Value / Alignment;
746f19c83bSHermès Bélusca-Maïto
756f19c83bSHermès Bélusca-Maïto return Temp * Alignment;
766f19c83bSHermès Bélusca-Maïto }
776f19c83bSHermès Bélusca-Maïto
786f19c83bSHermès Bélusca-Maïto ULONGLONG
AlignUp(IN ULONGLONG Value,IN ULONG Alignment)796f19c83bSHermès Bélusca-Maïto AlignUp(
806f19c83bSHermès Bélusca-Maïto IN ULONGLONG Value,
816f19c83bSHermès Bélusca-Maïto IN ULONG Alignment)
826f19c83bSHermès Bélusca-Maïto {
836f19c83bSHermès Bélusca-Maïto ULONGLONG Temp, Result;
846f19c83bSHermès Bélusca-Maïto
856f19c83bSHermès Bélusca-Maïto Temp = Value / Alignment;
866f19c83bSHermès Bélusca-Maïto
876f19c83bSHermès Bélusca-Maïto Result = Temp * Alignment;
886f19c83bSHermès Bélusca-Maïto if (Value % Alignment)
896f19c83bSHermès Bélusca-Maïto Result += Alignment;
906f19c83bSHermès Bélusca-Maïto
916f19c83bSHermès Bélusca-Maïto return Result;
926f19c83bSHermès Bélusca-Maïto }
936f19c83bSHermès Bélusca-Maïto
946f19c83bSHermès Bélusca-Maïto ULONGLONG
RoundingDivide(IN ULONGLONG Dividend,IN ULONGLONG Divisor)956f19c83bSHermès Bélusca-Maïto RoundingDivide(
966f19c83bSHermès Bélusca-Maïto IN ULONGLONG Dividend,
976f19c83bSHermès Bélusca-Maïto IN ULONGLONG Divisor)
986f19c83bSHermès Bélusca-Maïto {
996f19c83bSHermès Bélusca-Maïto return (Dividend + Divisor / 2) / Divisor;
1006f19c83bSHermès Bélusca-Maïto }
1016f19c83bSHermès Bélusca-Maïto
1026f19c83bSHermès Bélusca-Maïto
1036f19c83bSHermès Bélusca-Maïto static
1046f19c83bSHermès Bélusca-Maïto VOID
GetDriverName(IN PDISKENTRY DiskEntry)1056f19c83bSHermès Bélusca-Maïto GetDriverName(
1066f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry)
1076f19c83bSHermès Bélusca-Maïto {
1086f19c83bSHermès Bélusca-Maïto RTL_QUERY_REGISTRY_TABLE QueryTable[2];
1096f19c83bSHermès Bélusca-Maïto WCHAR KeyName[32];
1106f19c83bSHermès Bélusca-Maïto NTSTATUS Status;
1116f19c83bSHermès Bélusca-Maïto
1126f19c83bSHermès Bélusca-Maïto RtlInitUnicodeString(&DiskEntry->DriverName, NULL);
1136f19c83bSHermès Bélusca-Maïto
1146f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(KeyName, ARRAYSIZE(KeyName),
1156f19c83bSHermès Bélusca-Maïto L"\\Scsi\\Scsi Port %hu",
1166f19c83bSHermès Bélusca-Maïto DiskEntry->Port);
1176f19c83bSHermès Bélusca-Maïto
1186f19c83bSHermès Bélusca-Maïto RtlZeroMemory(&QueryTable, sizeof(QueryTable));
1196f19c83bSHermès Bélusca-Maïto
1206f19c83bSHermès Bélusca-Maïto QueryTable[0].Name = L"Driver";
1216f19c83bSHermès Bélusca-Maïto QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
1226f19c83bSHermès Bélusca-Maïto QueryTable[0].EntryContext = &DiskEntry->DriverName;
1236f19c83bSHermès Bélusca-Maïto
124f41750abSHermès Bélusca-Maïto /* This will allocate DiskEntry->DriverName if needed */
1256f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
1266f19c83bSHermès Bélusca-Maïto KeyName,
1276f19c83bSHermès Bélusca-Maïto QueryTable,
1286f19c83bSHermès Bélusca-Maïto NULL,
1296f19c83bSHermès Bélusca-Maïto NULL);
1306f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
1316f19c83bSHermès Bélusca-Maïto {
1326f19c83bSHermès Bélusca-Maïto DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
1336f19c83bSHermès Bélusca-Maïto }
1346f19c83bSHermès Bélusca-Maïto }
1356f19c83bSHermès Bélusca-Maïto
1366f19c83bSHermès Bélusca-Maïto static
1376f19c83bSHermès Bélusca-Maïto VOID
AssignDriveLetters(IN PPARTLIST List)1386f19c83bSHermès Bélusca-Maïto AssignDriveLetters(
1396f19c83bSHermès Bélusca-Maïto IN PPARTLIST List)
1406f19c83bSHermès Bélusca-Maïto {
1416f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
1426f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry;
1436f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry1;
1446f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry2;
145f41750abSHermès Bélusca-Maïto WCHAR Letter;
1466f19c83bSHermès Bélusca-Maïto
147f41750abSHermès Bélusca-Maïto Letter = L'C';
1486f19c83bSHermès Bélusca-Maïto
1496f19c83bSHermès Bélusca-Maïto /* Assign drive letters to primary partitions */
1508bed4adfSHermès Bélusca-Maïto for (Entry1 = List->DiskListHead.Flink;
1518bed4adfSHermès Bélusca-Maïto Entry1 != &List->DiskListHead;
1528bed4adfSHermès Bélusca-Maïto Entry1 = Entry1->Flink)
1536f19c83bSHermès Bélusca-Maïto {
1546f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
1556f19c83bSHermès Bélusca-Maïto
1568bed4adfSHermès Bélusca-Maïto for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
1578bed4adfSHermès Bélusca-Maïto Entry2 != &DiskEntry->PrimaryPartListHead;
1588bed4adfSHermès Bélusca-Maïto Entry2 = Entry2->Flink)
1596f19c83bSHermès Bélusca-Maïto {
1606f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
1616f19c83bSHermès Bélusca-Maïto
1626f15802aSHermès Bélusca-Maïto if (!PartEntry->Volume)
1636f15802aSHermès Bélusca-Maïto continue;
1646f15802aSHermès Bélusca-Maïto PartEntry->Volume->Info.DriveLetter = UNICODE_NULL;
1656f19c83bSHermès Bélusca-Maïto
1666f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned &&
1676f15802aSHermès Bélusca-Maïto !IsContainerPartition(PartEntry->PartitionType) &&
1686f15802aSHermès Bélusca-Maïto (IsRecognizedPartition(PartEntry->PartitionType) ||
1696f15802aSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart != 0LL))
1706f19c83bSHermès Bélusca-Maïto {
171f41750abSHermès Bélusca-Maïto if (Letter <= L'Z')
1726f15802aSHermès Bélusca-Maïto PartEntry->Volume->Info.DriveLetter = Letter++;
1736f19c83bSHermès Bélusca-Maïto }
1746f19c83bSHermès Bélusca-Maïto }
1756f19c83bSHermès Bélusca-Maïto }
1766f19c83bSHermès Bélusca-Maïto
1776f19c83bSHermès Bélusca-Maïto /* Assign drive letters to logical drives */
1788bed4adfSHermès Bélusca-Maïto for (Entry1 = List->DiskListHead.Flink;
1798bed4adfSHermès Bélusca-Maïto Entry1 != &List->DiskListHead;
1808bed4adfSHermès Bélusca-Maïto Entry1 = Entry1->Flink)
1816f19c83bSHermès Bélusca-Maïto {
1826f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
1836f19c83bSHermès Bélusca-Maïto
1848bed4adfSHermès Bélusca-Maïto for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
1858bed4adfSHermès Bélusca-Maïto Entry2 != &DiskEntry->LogicalPartListHead;
1868bed4adfSHermès Bélusca-Maïto Entry2 = Entry2->Flink)
1876f19c83bSHermès Bélusca-Maïto {
1886f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
1896f19c83bSHermès Bélusca-Maïto
1906f15802aSHermès Bélusca-Maïto if (!PartEntry->Volume)
1916f15802aSHermès Bélusca-Maïto continue;
1926f15802aSHermès Bélusca-Maïto PartEntry->Volume->Info.DriveLetter = UNICODE_NULL;
1936f19c83bSHermès Bélusca-Maïto
1946f15802aSHermès Bélusca-Maïto if (PartEntry->IsPartitioned &&
1956f15802aSHermès Bélusca-Maïto (IsRecognizedPartition(PartEntry->PartitionType) ||
1966f15802aSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart != 0LL))
1976f19c83bSHermès Bélusca-Maïto {
198f41750abSHermès Bélusca-Maïto if (Letter <= L'Z')
1996f15802aSHermès Bélusca-Maïto PartEntry->Volume->Info.DriveLetter = Letter++;
2006f19c83bSHermès Bélusca-Maïto }
2016f19c83bSHermès Bélusca-Maïto }
2026f19c83bSHermès Bélusca-Maïto }
2036f19c83bSHermès Bélusca-Maïto }
2046f19c83bSHermès Bélusca-Maïto
2056f19c83bSHermès Bélusca-Maïto static NTSTATUS
2066f19c83bSHermès Bélusca-Maïto NTAPI
DiskIdentifierQueryRoutine(PWSTR ValueName,ULONG ValueType,PVOID ValueData,ULONG ValueLength,PVOID Context,PVOID EntryContext)2076f19c83bSHermès Bélusca-Maïto DiskIdentifierQueryRoutine(
2086f19c83bSHermès Bélusca-Maïto PWSTR ValueName,
2096f19c83bSHermès Bélusca-Maïto ULONG ValueType,
2106f19c83bSHermès Bélusca-Maïto PVOID ValueData,
2116f19c83bSHermès Bélusca-Maïto ULONG ValueLength,
2126f19c83bSHermès Bélusca-Maïto PVOID Context,
2136f19c83bSHermès Bélusca-Maïto PVOID EntryContext)
2146f19c83bSHermès Bélusca-Maïto {
2156f19c83bSHermès Bélusca-Maïto PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
2166f19c83bSHermès Bélusca-Maïto UNICODE_STRING NameU;
2176f19c83bSHermès Bélusca-Maïto
2186f19c83bSHermès Bélusca-Maïto if (ValueType == REG_SZ &&
21947a1acedSHermès Bélusca-Maïto ValueLength == 20 * sizeof(WCHAR) &&
22047a1acedSHermès Bélusca-Maïto ((PWCHAR)ValueData)[8] == L'-')
2216f19c83bSHermès Bélusca-Maïto {
2226f19c83bSHermès Bélusca-Maïto NameU.Buffer = (PWCHAR)ValueData;
2236f19c83bSHermès Bélusca-Maïto NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
2246f19c83bSHermès Bélusca-Maïto RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
2256f19c83bSHermès Bélusca-Maïto
2266f19c83bSHermès Bélusca-Maïto NameU.Buffer = (PWCHAR)ValueData + 9;
2276f19c83bSHermès Bélusca-Maïto RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
2286f19c83bSHermès Bélusca-Maïto
2296f19c83bSHermès Bélusca-Maïto return STATUS_SUCCESS;
2306f19c83bSHermès Bélusca-Maïto }
2316f19c83bSHermès Bélusca-Maïto
2326f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL;
2336f19c83bSHermès Bélusca-Maïto }
2346f19c83bSHermès Bélusca-Maïto
2356f19c83bSHermès Bélusca-Maïto static NTSTATUS
2366f19c83bSHermès Bélusca-Maïto NTAPI
DiskConfigurationDataQueryRoutine(PWSTR ValueName,ULONG ValueType,PVOID ValueData,ULONG ValueLength,PVOID Context,PVOID EntryContext)2376f19c83bSHermès Bélusca-Maïto DiskConfigurationDataQueryRoutine(
2386f19c83bSHermès Bélusca-Maïto PWSTR ValueName,
2396f19c83bSHermès Bélusca-Maïto ULONG ValueType,
2406f19c83bSHermès Bélusca-Maïto PVOID ValueData,
2416f19c83bSHermès Bélusca-Maïto ULONG ValueLength,
2426f19c83bSHermès Bélusca-Maïto PVOID Context,
2436f19c83bSHermès Bélusca-Maïto PVOID EntryContext)
2446f19c83bSHermès Bélusca-Maïto {
2456f19c83bSHermès Bélusca-Maïto PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
2466f19c83bSHermès Bélusca-Maïto PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
2476f19c83bSHermès Bélusca-Maïto PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
2486f19c83bSHermès Bélusca-Maïto ULONG i;
2496f19c83bSHermès Bélusca-Maïto
2506f19c83bSHermès Bélusca-Maïto if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
2516f19c83bSHermès Bélusca-Maïto ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
2526f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL;
2536f19c83bSHermès Bélusca-Maïto
2546f19c83bSHermès Bélusca-Maïto FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
2556f19c83bSHermès Bélusca-Maïto
2566f19c83bSHermès Bélusca-Maïto /* Hm. Version and Revision are not set on Microsoft Windows XP... */
2576f19c83bSHermès Bélusca-Maïto #if 0
2586f19c83bSHermès Bélusca-Maïto if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
2596f19c83bSHermès Bélusca-Maïto FullResourceDescriptor->PartialResourceList.Revision != 1)
2606f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL;
2616f19c83bSHermès Bélusca-Maïto #endif
2626f19c83bSHermès Bélusca-Maïto
2636f19c83bSHermès Bélusca-Maïto for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
2646f19c83bSHermès Bélusca-Maïto {
2656f19c83bSHermès Bélusca-Maïto if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
2666f19c83bSHermès Bélusca-Maïto FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA))
2676f19c83bSHermès Bélusca-Maïto continue;
2686f19c83bSHermès Bélusca-Maïto
2696f19c83bSHermès Bélusca-Maïto DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
2706f19c83bSHermès Bélusca-Maïto BiosDiskEntry->DiskGeometry = *DiskGeometry;
2716f19c83bSHermès Bélusca-Maïto
2726f19c83bSHermès Bélusca-Maïto return STATUS_SUCCESS;
2736f19c83bSHermès Bélusca-Maïto }
2746f19c83bSHermès Bélusca-Maïto
2756f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL;
2766f19c83bSHermès Bélusca-Maïto }
2776f19c83bSHermès Bélusca-Maïto
2786f19c83bSHermès Bélusca-Maïto static NTSTATUS
2796f19c83bSHermès Bélusca-Maïto NTAPI
SystemConfigurationDataQueryRoutine(PWSTR ValueName,ULONG ValueType,PVOID ValueData,ULONG ValueLength,PVOID Context,PVOID EntryContext)2806f19c83bSHermès Bélusca-Maïto SystemConfigurationDataQueryRoutine(
2816f19c83bSHermès Bélusca-Maïto PWSTR ValueName,
2826f19c83bSHermès Bélusca-Maïto ULONG ValueType,
2836f19c83bSHermès Bélusca-Maïto PVOID ValueData,
2846f19c83bSHermès Bélusca-Maïto ULONG ValueLength,
2856f19c83bSHermès Bélusca-Maïto PVOID Context,
2866f19c83bSHermès Bélusca-Maïto PVOID EntryContext)
2876f19c83bSHermès Bélusca-Maïto {
2886f19c83bSHermès Bélusca-Maïto PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
2896f19c83bSHermès Bélusca-Maïto PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context;
2906f19c83bSHermès Bélusca-Maïto ULONG i;
2916f19c83bSHermès Bélusca-Maïto
2926f19c83bSHermès Bélusca-Maïto if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
2936f19c83bSHermès Bélusca-Maïto ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
2946f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL;
2956f19c83bSHermès Bélusca-Maïto
2966f19c83bSHermès Bélusca-Maïto FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
2976f19c83bSHermès Bélusca-Maïto
2986f19c83bSHermès Bélusca-Maïto /* Hm. Version and Revision are not set on Microsoft Windows XP... */
2996f19c83bSHermès Bélusca-Maïto #if 0
3006f19c83bSHermès Bélusca-Maïto if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
3016f19c83bSHermès Bélusca-Maïto FullResourceDescriptor->PartialResourceList.Revision != 1)
3026f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL;
3036f19c83bSHermès Bélusca-Maïto #endif
3046f19c83bSHermès Bélusca-Maïto
3056f19c83bSHermès Bélusca-Maïto for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
3066f19c83bSHermès Bélusca-Maïto {
3076f19c83bSHermès Bélusca-Maïto if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
3086f19c83bSHermès Bélusca-Maïto FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
3096f19c83bSHermès Bélusca-Maïto continue;
3106f19c83bSHermès Bélusca-Maïto
3116f19c83bSHermès Bélusca-Maïto *Int13Drives = (CM_INT13_DRIVE_PARAMETER*)RtlAllocateHeap(ProcessHeap, 0,
3126f19c83bSHermès Bélusca-Maïto FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
3136f19c83bSHermès Bélusca-Maïto if (*Int13Drives == NULL)
3146f19c83bSHermès Bélusca-Maïto return STATUS_NO_MEMORY;
3156f19c83bSHermès Bélusca-Maïto
3166f19c83bSHermès Bélusca-Maïto memcpy(*Int13Drives,
3176f19c83bSHermès Bélusca-Maïto &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1],
3186f19c83bSHermès Bélusca-Maïto FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
3196f19c83bSHermès Bélusca-Maïto return STATUS_SUCCESS;
3206f19c83bSHermès Bélusca-Maïto }
3216f19c83bSHermès Bélusca-Maïto
3226f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL;
3236f19c83bSHermès Bélusca-Maïto }
3246f19c83bSHermès Bélusca-Maïto
3256f19c83bSHermès Bélusca-Maïto
3266f19c83bSHermès Bélusca-Maïto static VOID
EnumerateBiosDiskEntries(IN PPARTLIST PartList)3276f19c83bSHermès Bélusca-Maïto EnumerateBiosDiskEntries(
3286f19c83bSHermès Bélusca-Maïto IN PPARTLIST PartList)
3296f19c83bSHermès Bélusca-Maïto {
3306f19c83bSHermès Bélusca-Maïto RTL_QUERY_REGISTRY_TABLE QueryTable[3];
3316f19c83bSHermès Bélusca-Maïto WCHAR Name[120];
3326f19c83bSHermès Bélusca-Maïto ULONG AdapterCount;
33347a1acedSHermès Bélusca-Maïto ULONG ControllerCount;
3346f19c83bSHermès Bélusca-Maïto ULONG DiskCount;
3356f19c83bSHermès Bélusca-Maïto NTSTATUS Status;
3366f19c83bSHermès Bélusca-Maïto PCM_INT13_DRIVE_PARAMETER Int13Drives;
3376f19c83bSHermès Bélusca-Maïto PBIOSDISKENTRY BiosDiskEntry;
3386f19c83bSHermès Bélusca-Maïto
339f41750abSHermès Bélusca-Maïto #define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
340f41750abSHermès Bélusca-Maïto
3416f19c83bSHermès Bélusca-Maïto memset(QueryTable, 0, sizeof(QueryTable));
3426f19c83bSHermès Bélusca-Maïto
3436f19c83bSHermès Bélusca-Maïto QueryTable[1].Name = L"Configuration Data";
3446f19c83bSHermès Bélusca-Maïto QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine;
3456f19c83bSHermès Bélusca-Maïto Int13Drives = NULL;
3466f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
3476f19c83bSHermès Bélusca-Maïto L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
3486f19c83bSHermès Bélusca-Maïto &QueryTable[1],
3496f19c83bSHermès Bélusca-Maïto (PVOID)&Int13Drives,
3506f19c83bSHermès Bélusca-Maïto NULL);
3516f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
3526f19c83bSHermès Bélusca-Maïto {
3536f19c83bSHermès Bélusca-Maïto DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
3546f19c83bSHermès Bélusca-Maïto return;
3556f19c83bSHermès Bélusca-Maïto }
3566f19c83bSHermès Bélusca-Maïto
35747a1acedSHermès Bélusca-Maïto for (AdapterCount = 0; ; ++AdapterCount)
3586f19c83bSHermès Bélusca-Maïto {
3596f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
3606f19c83bSHermès Bélusca-Maïto L"%s\\%lu",
3616f19c83bSHermès Bélusca-Maïto ROOT_NAME, AdapterCount);
3626f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
3636f19c83bSHermès Bélusca-Maïto Name,
3646f19c83bSHermès Bélusca-Maïto &QueryTable[2],
3656f19c83bSHermès Bélusca-Maïto NULL,
3666f19c83bSHermès Bélusca-Maïto NULL);
3676f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
3686f19c83bSHermès Bélusca-Maïto {
3696f19c83bSHermès Bélusca-Maïto break;
3706f19c83bSHermès Bélusca-Maïto }
3716f19c83bSHermès Bélusca-Maïto
3726f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
3736f19c83bSHermès Bélusca-Maïto L"%s\\%lu\\DiskController",
3746f19c83bSHermès Bélusca-Maïto ROOT_NAME, AdapterCount);
3756f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
3766f19c83bSHermès Bélusca-Maïto Name,
3776f19c83bSHermès Bélusca-Maïto &QueryTable[2],
3786f19c83bSHermès Bélusca-Maïto NULL,
3796f19c83bSHermès Bélusca-Maïto NULL);
3806f19c83bSHermès Bélusca-Maïto if (NT_SUCCESS(Status))
3816f19c83bSHermès Bélusca-Maïto {
38247a1acedSHermès Bélusca-Maïto for (ControllerCount = 0; ; ++ControllerCount)
3836f19c83bSHermès Bélusca-Maïto {
3846f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
38547a1acedSHermès Bélusca-Maïto L"%s\\%lu\\DiskController\\%lu",
38647a1acedSHermès Bélusca-Maïto ROOT_NAME, AdapterCount, ControllerCount);
3876f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
3886f19c83bSHermès Bélusca-Maïto Name,
3896f19c83bSHermès Bélusca-Maïto &QueryTable[2],
3906f19c83bSHermès Bélusca-Maïto NULL,
3916f19c83bSHermès Bélusca-Maïto NULL);
3926f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
3936f19c83bSHermès Bélusca-Maïto {
3946f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Int13Drives);
3956f19c83bSHermès Bélusca-Maïto return;
3966f19c83bSHermès Bélusca-Maïto }
3976f19c83bSHermès Bélusca-Maïto
3986f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
39947a1acedSHermès Bélusca-Maïto L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral",
40047a1acedSHermès Bélusca-Maïto ROOT_NAME, AdapterCount, ControllerCount);
4016f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
4026f19c83bSHermès Bélusca-Maïto Name,
4036f19c83bSHermès Bélusca-Maïto &QueryTable[2],
4046f19c83bSHermès Bélusca-Maïto NULL,
4056f19c83bSHermès Bélusca-Maïto NULL);
4066f19c83bSHermès Bélusca-Maïto if (NT_SUCCESS(Status))
4076f19c83bSHermès Bélusca-Maïto {
4086f19c83bSHermès Bélusca-Maïto QueryTable[0].Name = L"Identifier";
4096f19c83bSHermès Bélusca-Maïto QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine;
4106f19c83bSHermès Bélusca-Maïto QueryTable[1].Name = L"Configuration Data";
4116f19c83bSHermès Bélusca-Maïto QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine;
4126f19c83bSHermès Bélusca-Maïto
41347a1acedSHermès Bélusca-Maïto for (DiskCount = 0; ; ++DiskCount)
4146f19c83bSHermès Bélusca-Maïto {
4156f19c83bSHermès Bélusca-Maïto BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
4166f19c83bSHermès Bélusca-Maïto if (BiosDiskEntry == NULL)
4176f19c83bSHermès Bélusca-Maïto {
41847a1acedSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Int13Drives);
41947a1acedSHermès Bélusca-Maïto return;
4206f19c83bSHermès Bélusca-Maïto }
4216f19c83bSHermès Bélusca-Maïto
4226f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
42347a1acedSHermès Bélusca-Maïto L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral\\%lu",
42447a1acedSHermès Bélusca-Maïto ROOT_NAME, AdapterCount, ControllerCount, DiskCount);
4256f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
4266f19c83bSHermès Bélusca-Maïto Name,
4276f19c83bSHermès Bélusca-Maïto QueryTable,
4286f19c83bSHermès Bélusca-Maïto (PVOID)BiosDiskEntry,
4296f19c83bSHermès Bélusca-Maïto NULL);
4306f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
4316f19c83bSHermès Bélusca-Maïto {
4326f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
43347a1acedSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Int13Drives);
43447a1acedSHermès Bélusca-Maïto return;
4356f19c83bSHermès Bélusca-Maïto }
4366f19c83bSHermès Bélusca-Maïto
43747a1acedSHermès Bélusca-Maïto BiosDiskEntry->AdapterNumber = 0; // And NOT "AdapterCount" as it needs to be hardcoded for BIOS!
43847a1acedSHermès Bélusca-Maïto BiosDiskEntry->ControllerNumber = ControllerCount;
4396f19c83bSHermès Bélusca-Maïto BiosDiskEntry->DiskNumber = DiskCount;
44047a1acedSHermès Bélusca-Maïto BiosDiskEntry->DiskEntry = NULL;
4416f19c83bSHermès Bélusca-Maïto
4426f19c83bSHermès Bélusca-Maïto if (DiskCount < Int13Drives[0].NumberDrives)
4436f19c83bSHermès Bélusca-Maïto {
4446f19c83bSHermès Bélusca-Maïto BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
4456f19c83bSHermès Bélusca-Maïto }
4466f19c83bSHermès Bélusca-Maïto else
4476f19c83bSHermès Bélusca-Maïto {
44847a1acedSHermès Bélusca-Maïto DPRINT1("Didn't find Int13 drive data for disk %u\n", DiskCount);
4496f19c83bSHermès Bélusca-Maïto }
4506f19c83bSHermès Bélusca-Maïto
4516f19c83bSHermès Bélusca-Maïto InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry);
4526f19c83bSHermès Bélusca-Maïto
45347a1acedSHermès Bélusca-Maïto DPRINT("--->\n");
45447a1acedSHermès Bélusca-Maïto DPRINT("AdapterNumber: %lu\n", BiosDiskEntry->AdapterNumber);
45547a1acedSHermès Bélusca-Maïto DPRINT("ControllerNumber: %lu\n", BiosDiskEntry->ControllerNumber);
4566f19c83bSHermès Bélusca-Maïto DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber);
4576f19c83bSHermès Bélusca-Maïto DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature);
4586f19c83bSHermès Bélusca-Maïto DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum);
4596f19c83bSHermès Bélusca-Maïto DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
4606f19c83bSHermès Bélusca-Maïto DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
4616f19c83bSHermès Bélusca-Maïto DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
4626f19c83bSHermès Bélusca-Maïto DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
4636f19c83bSHermès Bélusca-Maïto DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
4646f19c83bSHermès Bélusca-Maïto DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
4656f19c83bSHermès Bélusca-Maïto DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
4666f19c83bSHermès Bélusca-Maïto DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
46747a1acedSHermès Bélusca-Maïto DPRINT("<---\n");
4686f19c83bSHermès Bélusca-Maïto }
4696f19c83bSHermès Bélusca-Maïto }
4706f19c83bSHermès Bélusca-Maïto }
4716f19c83bSHermès Bélusca-Maïto }
4726f19c83bSHermès Bélusca-Maïto }
4736f19c83bSHermès Bélusca-Maïto
4746f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Int13Drives);
475f41750abSHermès Bélusca-Maïto
476f41750abSHermès Bélusca-Maïto #undef ROOT_NAME
4776f19c83bSHermès Bélusca-Maïto }
4786f19c83bSHermès Bélusca-Maïto
4797df92966SHermès Bélusca-Maïto
48047a1acedSHermès Bélusca-Maïto /*
481*d6d3d0eaSHermès Bélusca-Maïto * Detects whether a disk is a "super-floppy", i.e. an unpartitioned
482*d6d3d0eaSHermès Bélusca-Maïto * disk with only a valid VBR, as reported by IoReadPartitionTable()
48347a1acedSHermès Bélusca-Maïto * and IoWritePartitionTable():
484*d6d3d0eaSHermès Bélusca-Maïto * only one single partition starting at offset zero and spanning the
485*d6d3d0eaSHermès Bélusca-Maïto * whole disk, without hidden sectors, whose type is FAT16 non-bootable.
486*d6d3d0eaSHermès Bélusca-Maïto *
487*d6d3d0eaSHermès Bélusca-Maïto * Accessing \Device\HarddiskN\Partition0 or Partition1 on such disks
488*d6d3d0eaSHermès Bélusca-Maïto * returns the same data.
48947a1acedSHermès Bélusca-Maïto */
49047a1acedSHermès Bélusca-Maïto BOOLEAN
IsDiskSuperFloppy2(_In_ const DISK_PARTITION_INFO * DiskInfo,_In_opt_ const ULONGLONG * DiskSize,_In_ const PARTITION_INFORMATION * PartitionInfo)491*d6d3d0eaSHermès Bélusca-Maïto IsDiskSuperFloppy2(
492*d6d3d0eaSHermès Bélusca-Maïto _In_ const DISK_PARTITION_INFO* DiskInfo,
493*d6d3d0eaSHermès Bélusca-Maïto _In_opt_ const ULONGLONG* DiskSize,
494*d6d3d0eaSHermès Bélusca-Maïto _In_ const PARTITION_INFORMATION* PartitionInfo)
49547a1acedSHermès Bélusca-Maïto {
496*d6d3d0eaSHermès Bélusca-Maïto /* Structure size must be valid */
497*d6d3d0eaSHermès Bélusca-Maïto if (DiskInfo->SizeOfPartitionInfo < RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr))
49847a1acedSHermès Bélusca-Maïto return FALSE;
49947a1acedSHermès Bélusca-Maïto
500*d6d3d0eaSHermès Bélusca-Maïto /* The layout must be MBR */
501*d6d3d0eaSHermès Bélusca-Maïto if (DiskInfo->PartitionStyle != PARTITION_STYLE_MBR)
50247a1acedSHermès Bélusca-Maïto return FALSE;
50347a1acedSHermès Bélusca-Maïto
50447a1acedSHermès Bélusca-Maïto /* The single partition must start at the beginning of the disk */
50547a1acedSHermès Bélusca-Maïto if (!(PartitionInfo->StartingOffset.QuadPart == 0 &&
50647a1acedSHermès Bélusca-Maïto PartitionInfo->HiddenSectors == 0))
50747a1acedSHermès Bélusca-Maïto {
50847a1acedSHermès Bélusca-Maïto return FALSE;
50947a1acedSHermès Bélusca-Maïto }
51047a1acedSHermès Bélusca-Maïto
511*d6d3d0eaSHermès Bélusca-Maïto /* The disk signature is usually set to 1; warn in case it's not */
512*d6d3d0eaSHermès Bélusca-Maïto if (DiskInfo->Mbr.Signature != 1)
51347a1acedSHermès Bélusca-Maïto {
514*d6d3d0eaSHermès Bélusca-Maïto DPRINT1("Super-Floppy signature %08x != 1\n", DiskInfo->Mbr.Signature);
51547a1acedSHermès Bélusca-Maïto }
51647a1acedSHermès Bélusca-Maïto
517*d6d3d0eaSHermès Bélusca-Maïto /* The partition must be recognized and report as FAT16 non-bootable */
518*d6d3d0eaSHermès Bélusca-Maïto if ((PartitionInfo->RecognizedPartition != TRUE) ||
519*d6d3d0eaSHermès Bélusca-Maïto (PartitionInfo->PartitionType != PARTITION_FAT_16) ||
520*d6d3d0eaSHermès Bélusca-Maïto (PartitionInfo->BootIndicator != FALSE))
52147a1acedSHermès Bélusca-Maïto {
522*d6d3d0eaSHermès Bélusca-Maïto DPRINT1("Super-Floppy does not return default settings:\n"
52347a1acedSHermès Bélusca-Maïto " RecognizedPartition = %s, expected TRUE\n"
52447a1acedSHermès Bélusca-Maïto " PartitionType = 0x%02x, expected 0x04 (PARTITION_FAT_16)\n"
52547a1acedSHermès Bélusca-Maïto " BootIndicator = %s, expected FALSE\n",
52647a1acedSHermès Bélusca-Maïto PartitionInfo->RecognizedPartition ? "TRUE" : "FALSE",
52747a1acedSHermès Bélusca-Maïto PartitionInfo->PartitionType,
52847a1acedSHermès Bélusca-Maïto PartitionInfo->BootIndicator ? "TRUE" : "FALSE");
52947a1acedSHermès Bélusca-Maïto }
53047a1acedSHermès Bélusca-Maïto
531*d6d3d0eaSHermès Bélusca-Maïto /* The partition and disk sizes should agree */
532*d6d3d0eaSHermès Bélusca-Maïto if (DiskSize && (PartitionInfo->PartitionLength.QuadPart != *DiskSize))
53347a1acedSHermès Bélusca-Maïto {
534*d6d3d0eaSHermès Bélusca-Maïto DPRINT1("PartitionLength = %I64u is different from DiskSize = %I64u\n",
535*d6d3d0eaSHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart, *DiskSize);
53647a1acedSHermès Bélusca-Maïto }
53747a1acedSHermès Bélusca-Maïto
53847a1acedSHermès Bélusca-Maïto return TRUE;
53947a1acedSHermès Bélusca-Maïto }
54047a1acedSHermès Bélusca-Maïto
541*d6d3d0eaSHermès Bélusca-Maïto BOOLEAN
IsDiskSuperFloppy(_In_ const DRIVE_LAYOUT_INFORMATION * Layout,_In_opt_ const ULONGLONG * DiskSize)542*d6d3d0eaSHermès Bélusca-Maïto IsDiskSuperFloppy(
543*d6d3d0eaSHermès Bélusca-Maïto _In_ const DRIVE_LAYOUT_INFORMATION* Layout,
544*d6d3d0eaSHermès Bélusca-Maïto _In_opt_ const ULONGLONG* DiskSize)
545*d6d3d0eaSHermès Bélusca-Maïto {
546*d6d3d0eaSHermès Bélusca-Maïto DISK_PARTITION_INFO DiskInfo;
547*d6d3d0eaSHermès Bélusca-Maïto
548*d6d3d0eaSHermès Bélusca-Maïto /* The layout must contain only one partition */
549*d6d3d0eaSHermès Bélusca-Maïto if (Layout->PartitionCount != 1)
550*d6d3d0eaSHermès Bélusca-Maïto return FALSE;
551*d6d3d0eaSHermès Bélusca-Maïto
552*d6d3d0eaSHermès Bélusca-Maïto /* Build the disk partition info */
553*d6d3d0eaSHermès Bélusca-Maïto DiskInfo.SizeOfPartitionInfo = RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr);
554*d6d3d0eaSHermès Bélusca-Maïto DiskInfo.PartitionStyle = PARTITION_STYLE_MBR;
555*d6d3d0eaSHermès Bélusca-Maïto DiskInfo.Mbr.Signature = Layout->Signature;
556*d6d3d0eaSHermès Bélusca-Maïto DiskInfo.Mbr.CheckSum = 0; // Dummy value
557*d6d3d0eaSHermès Bélusca-Maïto
558*d6d3d0eaSHermès Bélusca-Maïto /* Call the helper on the single partition entry */
559*d6d3d0eaSHermès Bélusca-Maïto return IsDiskSuperFloppy2(&DiskInfo, DiskSize, Layout->PartitionEntry);
560*d6d3d0eaSHermès Bélusca-Maïto }
561*d6d3d0eaSHermès Bélusca-Maïto
562*d6d3d0eaSHermès Bélusca-Maïto BOOLEAN
IsDiskSuperFloppyEx(_In_ const DRIVE_LAYOUT_INFORMATION_EX * LayoutEx,_In_opt_ const ULONGLONG * DiskSize)563*d6d3d0eaSHermès Bélusca-Maïto IsDiskSuperFloppyEx(
564*d6d3d0eaSHermès Bélusca-Maïto _In_ const DRIVE_LAYOUT_INFORMATION_EX* LayoutEx,
565*d6d3d0eaSHermès Bélusca-Maïto _In_opt_ const ULONGLONG* DiskSize)
566*d6d3d0eaSHermès Bélusca-Maïto {
567*d6d3d0eaSHermès Bélusca-Maïto DISK_PARTITION_INFO DiskInfo;
568*d6d3d0eaSHermès Bélusca-Maïto const PARTITION_INFORMATION_EX* PartitionInfoEx;
569*d6d3d0eaSHermès Bélusca-Maïto PARTITION_INFORMATION PartitionInfo;
570*d6d3d0eaSHermès Bélusca-Maïto
571*d6d3d0eaSHermès Bélusca-Maïto /* The layout must be MBR and contain only one partition */
572*d6d3d0eaSHermès Bélusca-Maïto if (LayoutEx->PartitionStyle != PARTITION_STYLE_MBR)
573*d6d3d0eaSHermès Bélusca-Maïto return FALSE;
574*d6d3d0eaSHermès Bélusca-Maïto if (LayoutEx->PartitionCount != 1)
575*d6d3d0eaSHermès Bélusca-Maïto return FALSE;
576*d6d3d0eaSHermès Bélusca-Maïto
577*d6d3d0eaSHermès Bélusca-Maïto /* Build the disk partition info */
578*d6d3d0eaSHermès Bélusca-Maïto DiskInfo.SizeOfPartitionInfo = RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr);
579*d6d3d0eaSHermès Bélusca-Maïto DiskInfo.PartitionStyle = PARTITION_STYLE_MBR; // LayoutEx->PartitionStyle;
580*d6d3d0eaSHermès Bélusca-Maïto DiskInfo.Mbr.Signature = LayoutEx->Mbr.Signature;
581*d6d3d0eaSHermès Bélusca-Maïto DiskInfo.Mbr.CheckSum = 0; // Dummy value
582*d6d3d0eaSHermès Bélusca-Maïto
583*d6d3d0eaSHermès Bélusca-Maïto /* Convert the single partition entry */
584*d6d3d0eaSHermès Bélusca-Maïto PartitionInfoEx = LayoutEx->PartitionEntry;
585*d6d3d0eaSHermès Bélusca-Maïto
586*d6d3d0eaSHermès Bélusca-Maïto PartitionInfo.StartingOffset = PartitionInfoEx->StartingOffset;
587*d6d3d0eaSHermès Bélusca-Maïto PartitionInfo.PartitionLength = PartitionInfoEx->PartitionLength;
588*d6d3d0eaSHermès Bélusca-Maïto PartitionInfo.HiddenSectors = PartitionInfoEx->Mbr.HiddenSectors;
589*d6d3d0eaSHermès Bélusca-Maïto PartitionInfo.PartitionNumber = PartitionInfoEx->PartitionNumber;
590*d6d3d0eaSHermès Bélusca-Maïto PartitionInfo.PartitionType = PartitionInfoEx->Mbr.PartitionType;
591*d6d3d0eaSHermès Bélusca-Maïto PartitionInfo.BootIndicator = PartitionInfoEx->Mbr.BootIndicator;
592*d6d3d0eaSHermès Bélusca-Maïto PartitionInfo.RecognizedPartition = PartitionInfoEx->Mbr.RecognizedPartition;
593*d6d3d0eaSHermès Bélusca-Maïto PartitionInfo.RewritePartition = PartitionInfoEx->RewritePartition;
594*d6d3d0eaSHermès Bélusca-Maïto
595*d6d3d0eaSHermès Bélusca-Maïto /* Call the helper on the single partition entry */
596*d6d3d0eaSHermès Bélusca-Maïto return IsDiskSuperFloppy2(&DiskInfo, DiskSize, &PartitionInfo);
597*d6d3d0eaSHermès Bélusca-Maïto }
598*d6d3d0eaSHermès Bélusca-Maïto
599*d6d3d0eaSHermès Bélusca-Maïto BOOLEAN
IsSuperFloppy(_In_ PDISKENTRY DiskEntry)600*d6d3d0eaSHermès Bélusca-Maïto IsSuperFloppy(
601*d6d3d0eaSHermès Bélusca-Maïto _In_ PDISKENTRY DiskEntry)
602*d6d3d0eaSHermès Bélusca-Maïto {
603*d6d3d0eaSHermès Bélusca-Maïto ULONGLONG DiskSize;
604*d6d3d0eaSHermès Bélusca-Maïto
605*d6d3d0eaSHermès Bélusca-Maïto /* No layout buffer: we cannot say anything yet */
606*d6d3d0eaSHermès Bélusca-Maïto if (!DiskEntry->LayoutBuffer)
607*d6d3d0eaSHermès Bélusca-Maïto return FALSE;
608*d6d3d0eaSHermès Bélusca-Maïto
609*d6d3d0eaSHermès Bélusca-Maïto /* The disk must be MBR */
610*d6d3d0eaSHermès Bélusca-Maïto if (DiskEntry->DiskStyle != PARTITION_STYLE_MBR)
611*d6d3d0eaSHermès Bélusca-Maïto return FALSE;
612*d6d3d0eaSHermès Bélusca-Maïto
613*d6d3d0eaSHermès Bélusca-Maïto DiskSize = GetDiskSizeInBytes(DiskEntry);
614*d6d3d0eaSHermès Bélusca-Maïto return IsDiskSuperFloppy(DiskEntry->LayoutBuffer, &DiskSize);
615*d6d3d0eaSHermès Bélusca-Maïto }
616*d6d3d0eaSHermès Bélusca-Maïto
6177df92966SHermès Bélusca-Maïto
6187df92966SHermès Bélusca-Maïto /*
6196f15802aSHermès Bélusca-Maïto * Inserts the disk region represented by PartEntry into either
6206f15802aSHermès Bélusca-Maïto * the primary or the logical partition list of the given disk.
6217df92966SHermès Bélusca-Maïto * The lists are kept sorted by increasing order of start sectors.
6227df92966SHermès Bélusca-Maïto * Of course no disk region should overlap at all with one another.
6237df92966SHermès Bélusca-Maïto */
6247df92966SHermès Bélusca-Maïto static
625626c654aSHermès Bélusca-Maïto BOOLEAN
InsertDiskRegion(IN PDISKENTRY DiskEntry,IN PPARTENTRY PartEntry,IN BOOLEAN LogicalPartition)6267df92966SHermès Bélusca-Maïto InsertDiskRegion(
6277df92966SHermès Bélusca-Maïto IN PDISKENTRY DiskEntry,
6287df92966SHermès Bélusca-Maïto IN PPARTENTRY PartEntry,
6297df92966SHermès Bélusca-Maïto IN BOOLEAN LogicalPartition)
6307df92966SHermès Bélusca-Maïto {
6317df92966SHermès Bélusca-Maïto PLIST_ENTRY List;
6327df92966SHermès Bélusca-Maïto PLIST_ENTRY Entry;
6337df92966SHermès Bélusca-Maïto PPARTENTRY PartEntry2;
6347df92966SHermès Bélusca-Maïto
6357df92966SHermès Bélusca-Maïto /* Use the correct partition list */
6367df92966SHermès Bélusca-Maïto if (LogicalPartition)
6377df92966SHermès Bélusca-Maïto List = &DiskEntry->LogicalPartListHead;
6387df92966SHermès Bélusca-Maïto else
6397df92966SHermès Bélusca-Maïto List = &DiskEntry->PrimaryPartListHead;
6407df92966SHermès Bélusca-Maïto
6417df92966SHermès Bélusca-Maïto /* Find the first disk region before which we need to insert the new one */
6427df92966SHermès Bélusca-Maïto for (Entry = List->Flink; Entry != List; Entry = Entry->Flink)
6437df92966SHermès Bélusca-Maïto {
6447df92966SHermès Bélusca-Maïto PartEntry2 = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
6457df92966SHermès Bélusca-Maïto
6467df92966SHermès Bélusca-Maïto /* Ignore any unused empty region */
6477df92966SHermès Bélusca-Maïto if ((PartEntry2->PartitionType == PARTITION_ENTRY_UNUSED &&
6487df92966SHermès Bélusca-Maïto PartEntry2->StartSector.QuadPart == 0) || PartEntry2->SectorCount.QuadPart == 0)
6497df92966SHermès Bélusca-Maïto {
6507df92966SHermès Bélusca-Maïto continue;
6517df92966SHermès Bélusca-Maïto }
6527df92966SHermès Bélusca-Maïto
6537df92966SHermès Bélusca-Maïto /* If the current region ends before the one to be inserted, try again */
6547df92966SHermès Bélusca-Maïto if (PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1 < PartEntry->StartSector.QuadPart)
6557df92966SHermès Bélusca-Maïto continue;
6567df92966SHermès Bélusca-Maïto
6577df92966SHermès Bélusca-Maïto /*
6587df92966SHermès Bélusca-Maïto * One of the disk region boundaries crosses the desired region
6597df92966SHermès Bélusca-Maïto * (it starts after the desired region, or ends before the end
6607df92966SHermès Bélusca-Maïto * of the desired region): this is an impossible situation because
6617df92966SHermès Bélusca-Maïto * disk regions (partitions) cannot overlap!
6627df92966SHermès Bélusca-Maïto * Throw an error and bail out.
6637df92966SHermès Bélusca-Maïto */
6647df92966SHermès Bélusca-Maïto if (max(PartEntry->StartSector.QuadPart, PartEntry2->StartSector.QuadPart)
6657df92966SHermès Bélusca-Maïto <=
6667df92966SHermès Bélusca-Maïto min( PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1,
6677df92966SHermès Bélusca-Maïto PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1))
6687df92966SHermès Bélusca-Maïto {
6697df92966SHermès Bélusca-Maïto DPRINT1("Disk region overlap problem, stopping there!\n"
6707df92966SHermès Bélusca-Maïto "Partition to be inserted:\n"
6717df92966SHermès Bélusca-Maïto " StartSector = %I64u ; EndSector = %I64u\n"
6727df92966SHermès Bélusca-Maïto "Existing disk region:\n"
6737df92966SHermès Bélusca-Maïto " StartSector = %I64u ; EndSector = %I64u\n",
6747df92966SHermès Bélusca-Maïto PartEntry->StartSector.QuadPart,
6757df92966SHermès Bélusca-Maïto PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1,
6767df92966SHermès Bélusca-Maïto PartEntry2->StartSector.QuadPart,
6777df92966SHermès Bélusca-Maïto PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1);
678626c654aSHermès Bélusca-Maïto return FALSE;
6797df92966SHermès Bélusca-Maïto }
6807df92966SHermès Bélusca-Maïto
6817df92966SHermès Bélusca-Maïto /* We have found the first region before which the new one has to be inserted */
6827df92966SHermès Bélusca-Maïto break;
6837df92966SHermès Bélusca-Maïto }
6847df92966SHermès Bélusca-Maïto
6857df92966SHermès Bélusca-Maïto /* Insert the disk region */
6867df92966SHermès Bélusca-Maïto InsertTailList(Entry, &PartEntry->ListEntry);
687626c654aSHermès Bélusca-Maïto return TRUE;
6887df92966SHermès Bélusca-Maïto }
6897df92966SHermès Bélusca-Maïto
6907df92966SHermès Bélusca-Maïto static
6917df92966SHermès Bélusca-Maïto PPARTENTRY
CreateInsertBlankRegion(IN PDISKENTRY DiskEntry,IN OUT PLIST_ENTRY ListHead,IN ULONGLONG StartSector,IN ULONGLONG SectorCount,IN BOOLEAN LogicalSpace)6927df92966SHermès Bélusca-Maïto CreateInsertBlankRegion(
6937df92966SHermès Bélusca-Maïto IN PDISKENTRY DiskEntry,
6947df92966SHermès Bélusca-Maïto IN OUT PLIST_ENTRY ListHead,
6957df92966SHermès Bélusca-Maïto IN ULONGLONG StartSector,
6967df92966SHermès Bélusca-Maïto IN ULONGLONG SectorCount,
6977df92966SHermès Bélusca-Maïto IN BOOLEAN LogicalSpace)
6987df92966SHermès Bélusca-Maïto {
6997df92966SHermès Bélusca-Maïto PPARTENTRY NewPartEntry;
7007df92966SHermès Bélusca-Maïto
7017df92966SHermès Bélusca-Maïto NewPartEntry = RtlAllocateHeap(ProcessHeap,
7027df92966SHermès Bélusca-Maïto HEAP_ZERO_MEMORY,
7037df92966SHermès Bélusca-Maïto sizeof(PARTENTRY));
7046f15802aSHermès Bélusca-Maïto if (!NewPartEntry)
7057df92966SHermès Bélusca-Maïto return NULL;
7067df92966SHermès Bélusca-Maïto
7077df92966SHermès Bélusca-Maïto NewPartEntry->DiskEntry = DiskEntry;
7087df92966SHermès Bélusca-Maïto
7097df92966SHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart = StartSector;
7107df92966SHermès Bélusca-Maïto NewPartEntry->SectorCount.QuadPart = SectorCount;
7117df92966SHermès Bélusca-Maïto
712626c654aSHermès Bélusca-Maïto NewPartEntry->LogicalPartition = LogicalSpace;
713c1fbc2d6SHermès Bélusca-Maïto NewPartEntry->IsPartitioned = FALSE;
714c1fbc2d6SHermès Bélusca-Maïto NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
7156f15802aSHermès Bélusca-Maïto NewPartEntry->Volume = NULL;
716c1fbc2d6SHermès Bélusca-Maïto
7177df92966SHermès Bélusca-Maïto DPRINT1("First Sector : %I64u\n", NewPartEntry->StartSector.QuadPart);
7187df92966SHermès Bélusca-Maïto DPRINT1("Last Sector : %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
7197df92966SHermès Bélusca-Maïto DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
7207df92966SHermès Bélusca-Maïto
721c1fbc2d6SHermès Bélusca-Maïto /* Insert the new entry into the list */
7227df92966SHermès Bélusca-Maïto InsertTailList(ListHead, &NewPartEntry->ListEntry);
7237df92966SHermès Bélusca-Maïto
7247df92966SHermès Bélusca-Maïto return NewPartEntry;
7257df92966SHermès Bélusca-Maïto }
7267df92966SHermès Bélusca-Maïto
7277df92966SHermès Bélusca-Maïto static
72899f0937fSHermès Bélusca-Maïto VOID
DestroyRegion(_Inout_ PPARTENTRY PartEntry)7296f15802aSHermès Bélusca-Maïto DestroyRegion(
7306f15802aSHermès Bélusca-Maïto _Inout_ PPARTENTRY PartEntry)
7316f15802aSHermès Bélusca-Maïto {
7326f15802aSHermès Bélusca-Maïto // RemoveEntryList(&PartEntry->Volume->ListEntry);
7336f15802aSHermès Bélusca-Maïto if (PartEntry->Volume)
7346f15802aSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, PartEntry->Volume);
7356f15802aSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, PartEntry);
7366f15802aSHermès Bélusca-Maïto }
7376f15802aSHermès Bélusca-Maïto
7386f15802aSHermès Bélusca-Maïto static
7396f15802aSHermès Bélusca-Maïto VOID
AddLogicalDiskSpace(_In_ PDISKENTRY DiskEntry)74099f0937fSHermès Bélusca-Maïto AddLogicalDiskSpace(
74199f0937fSHermès Bélusca-Maïto _In_ PDISKENTRY DiskEntry)
74299f0937fSHermès Bélusca-Maïto {
74399f0937fSHermès Bélusca-Maïto ULONGLONG StartSector;
74499f0937fSHermès Bélusca-Maïto ULONGLONG SectorCount;
74599f0937fSHermès Bélusca-Maïto PPARTENTRY NewPartEntry;
74699f0937fSHermès Bélusca-Maïto
74799f0937fSHermès Bélusca-Maïto DPRINT("AddLogicalDiskSpace()\n");
74899f0937fSHermès Bélusca-Maïto
74999f0937fSHermès Bélusca-Maïto /* Create a partition entry that represents the empty space in the container partition */
75099f0937fSHermès Bélusca-Maïto
75199f0937fSHermès Bélusca-Maïto StartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
75299f0937fSHermès Bélusca-Maïto SectorCount = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
75399f0937fSHermès Bélusca-Maïto
75499f0937fSHermès Bélusca-Maïto NewPartEntry = CreateInsertBlankRegion(DiskEntry,
75599f0937fSHermès Bélusca-Maïto &DiskEntry->LogicalPartListHead,
75699f0937fSHermès Bélusca-Maïto StartSector,
75799f0937fSHermès Bélusca-Maïto SectorCount,
75899f0937fSHermès Bélusca-Maïto TRUE);
75999f0937fSHermès Bélusca-Maïto if (!NewPartEntry)
76099f0937fSHermès Bélusca-Maïto DPRINT1("Failed to create a new empty region for full extended partition space!\n");
76199f0937fSHermès Bélusca-Maïto }
76299f0937fSHermès Bélusca-Maïto
76399f0937fSHermès Bélusca-Maïto // TODO: Improve upon the PartitionInfo parameter later
76499f0937fSHermès Bélusca-Maïto // (see VDS::CREATE_PARTITION_PARAMETERS and PPARTITION_INFORMATION_MBR/GPT for example)
76599f0937fSHermès Bélusca-Maïto // So far we only use it as the optional type of the partition to create.
76699f0937fSHermès Bélusca-Maïto //
76799f0937fSHermès Bélusca-Maïto // See also CreatePartition().
76899f0937fSHermès Bélusca-Maïto static
769626c654aSHermès Bélusca-Maïto BOOLEAN
InitializePartitionEntry(_Inout_ PPARTENTRY PartEntry,_In_opt_ ULONGLONG SizeBytes,_In_opt_ ULONG_PTR PartitionInfo)7707df92966SHermès Bélusca-Maïto InitializePartitionEntry(
771b7ad4a22SHermès Bélusca-Maïto _Inout_ PPARTENTRY PartEntry,
77299f0937fSHermès Bélusca-Maïto _In_opt_ ULONGLONG SizeBytes,
77399f0937fSHermès Bélusca-Maïto _In_opt_ ULONG_PTR PartitionInfo)
7747df92966SHermès Bélusca-Maïto {
775626c654aSHermès Bélusca-Maïto PDISKENTRY DiskEntry = PartEntry->DiskEntry;
776b7ad4a22SHermès Bélusca-Maïto ULONGLONG SectorCount;
77799f0937fSHermès Bélusca-Maïto BOOLEAN isContainer = IsContainerPartition((UCHAR)PartitionInfo);
7787df92966SHermès Bélusca-Maïto
779b7ad4a22SHermès Bélusca-Maïto DPRINT1("Current entry sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
7807df92966SHermès Bélusca-Maïto
781b7ad4a22SHermès Bélusca-Maïto /* The entry must not be already partitioned and not be void */
782b7ad4a22SHermès Bélusca-Maïto ASSERT(!PartEntry->IsPartitioned);
783b7ad4a22SHermès Bélusca-Maïto ASSERT(PartEntry->SectorCount.QuadPart);
7846f15802aSHermès Bélusca-Maïto ASSERT(!PartEntry->Volume);
785b7ad4a22SHermès Bélusca-Maïto
78699f0937fSHermès Bélusca-Maïto /* Either we create a primary/logical partition, or we create an
78799f0937fSHermès Bélusca-Maïto * extended partition but the entry must not be logical space */
78899f0937fSHermès Bélusca-Maïto ASSERT(!isContainer || !PartEntry->LogicalPartition);
78999f0937fSHermès Bélusca-Maïto
790b7ad4a22SHermès Bélusca-Maïto /* Convert the size in bytes to sector count. SizeBytes being
791b7ad4a22SHermès Bélusca-Maïto * zero means the caller wants to use all the empty space. */
792b7ad4a22SHermès Bélusca-Maïto if ((SizeBytes == 0) || (SizeBytes == GetPartEntrySizeInBytes(PartEntry)))
793b7ad4a22SHermès Bélusca-Maïto {
794b7ad4a22SHermès Bélusca-Maïto /* Use all of the unpartitioned disk space */
795b7ad4a22SHermès Bélusca-Maïto SectorCount = PartEntry->SectorCount.QuadPart;
796b7ad4a22SHermès Bélusca-Maïto }
797b7ad4a22SHermès Bélusca-Maïto else
798b7ad4a22SHermès Bélusca-Maïto {
799b7ad4a22SHermès Bélusca-Maïto SectorCount = SizeBytes / DiskEntry->BytesPerSector;
800b7ad4a22SHermès Bélusca-Maïto if (SectorCount == 0)
801b7ad4a22SHermès Bélusca-Maïto {
802b7ad4a22SHermès Bélusca-Maïto /* SizeBytes was certainly less than the minimal size, so fail */
803b7ad4a22SHermès Bélusca-Maïto DPRINT1("Partition size %I64u too small\n", SizeBytes);
804b7ad4a22SHermès Bélusca-Maïto return FALSE;
805b7ad4a22SHermès Bélusca-Maïto }
806b7ad4a22SHermès Bélusca-Maïto }
807b7ad4a22SHermès Bélusca-Maïto DPRINT1(" New sector count: %I64u\n", SectorCount);
808b7ad4a22SHermès Bélusca-Maïto
809b7ad4a22SHermès Bélusca-Maïto /* Fail if we request more sectors than what the entry actually contains */
810626c654aSHermès Bélusca-Maïto if (SectorCount > PartEntry->SectorCount.QuadPart)
811626c654aSHermès Bélusca-Maïto return FALSE;
812626c654aSHermès Bélusca-Maïto
813b7ad4a22SHermès Bélusca-Maïto if ((SectorCount == 0) ||
8147df92966SHermès Bélusca-Maïto (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
8157df92966SHermès Bélusca-Maïto PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart))
8167df92966SHermès Bélusca-Maïto {
817b7ad4a22SHermès Bélusca-Maïto /* Reuse the whole current entry */
8187df92966SHermès Bélusca-Maïto }
8197df92966SHermès Bélusca-Maïto else
8207df92966SHermès Bélusca-Maïto {
821626c654aSHermès Bélusca-Maïto ULONGLONG StartSector;
822626c654aSHermès Bélusca-Maïto ULONGLONG SectorCount2;
823626c654aSHermès Bélusca-Maïto PPARTENTRY NewPartEntry;
8247df92966SHermès Bélusca-Maïto
825b7ad4a22SHermès Bélusca-Maïto /* Create a partition entry that represents the remaining space
826b7ad4a22SHermès Bélusca-Maïto * after the partition to be initialized */
827626c654aSHermès Bélusca-Maïto
828626c654aSHermès Bélusca-Maïto StartSector = AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment);
829626c654aSHermès Bélusca-Maïto SectorCount2 = PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - StartSector;
830626c654aSHermès Bélusca-Maïto
831626c654aSHermès Bélusca-Maïto NewPartEntry = CreateInsertBlankRegion(DiskEntry,
832626c654aSHermès Bélusca-Maïto PartEntry->ListEntry.Flink,
833626c654aSHermès Bélusca-Maïto StartSector,
834626c654aSHermès Bélusca-Maïto SectorCount2,
835626c654aSHermès Bélusca-Maïto PartEntry->LogicalPartition);
83699f0937fSHermès Bélusca-Maïto if (!NewPartEntry)
837626c654aSHermès Bélusca-Maïto {
838626c654aSHermès Bélusca-Maïto DPRINT1("Failed to create a new empty region for disk space!\n");
839626c654aSHermès Bélusca-Maïto return FALSE;
8407df92966SHermès Bélusca-Maïto }
8417df92966SHermès Bélusca-Maïto
842626c654aSHermès Bélusca-Maïto /* Resize down the partition entry; its StartSector remains the same */
843626c654aSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart = StartSector - PartEntry->StartSector.QuadPart;
844626c654aSHermès Bélusca-Maïto }
845c1fbc2d6SHermès Bélusca-Maïto
8466f15802aSHermès Bélusca-Maïto /* Convert to a new partition entry */
847626c654aSHermès Bélusca-Maïto PartEntry->New = TRUE;
848626c654aSHermès Bélusca-Maïto PartEntry->IsPartitioned = TRUE;
849c1fbc2d6SHermès Bélusca-Maïto
85099f0937fSHermès Bélusca-Maïto PartEntry->BootIndicator = FALSE;
85199f0937fSHermès Bélusca-Maïto if (PartitionInfo)
85299f0937fSHermès Bélusca-Maïto {
85399f0937fSHermès Bélusca-Maïto if (!isContainer)
85499f0937fSHermès Bélusca-Maïto {
85599f0937fSHermès Bélusca-Maïto PartEntry->PartitionType = (UCHAR)PartitionInfo;
85699f0937fSHermès Bélusca-Maïto }
85799f0937fSHermès Bélusca-Maïto else
85899f0937fSHermès Bélusca-Maïto {
85999f0937fSHermès Bélusca-Maïto /* Set the correct extended container partition type,
86099f0937fSHermès Bélusca-Maïto * depending on whether it is contained below or above
86199f0937fSHermès Bélusca-Maïto * the 1024-cylinder (usually 8.4GB/7.8GiB) boundary:
86299f0937fSHermès Bélusca-Maïto * - below: INT13h CHS partition;
86399f0937fSHermès Bélusca-Maïto * - above: Extended INT13h LBA partition. */
86499f0937fSHermès Bélusca-Maïto if ((PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1)
86599f0937fSHermès Bélusca-Maïto / (DiskEntry->TracksPerCylinder * DiskEntry->SectorsPerTrack) < 1024)
86699f0937fSHermès Bélusca-Maïto {
86799f0937fSHermès Bélusca-Maïto PartEntry->PartitionType = PARTITION_EXTENDED;
86899f0937fSHermès Bélusca-Maïto }
86999f0937fSHermès Bélusca-Maïto else
87099f0937fSHermès Bélusca-Maïto {
87199f0937fSHermès Bélusca-Maïto PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
87299f0937fSHermès Bélusca-Maïto }
87399f0937fSHermès Bélusca-Maïto }
87499f0937fSHermès Bélusca-Maïto }
87599f0937fSHermès Bélusca-Maïto else
87699f0937fSHermès Bélusca-Maïto {
8779735a837SHermès Bélusca-Maïto // FIXME: Use FileSystemToMBRPartitionType() only for MBR, otherwise use PARTITION_BASIC_DATA_GUID.
87899f0937fSHermès Bélusca-Maïto ASSERT(!isContainer);
8799735a837SHermès Bélusca-Maïto PartEntry->PartitionType = FileSystemToMBRPartitionType(L"RAW",
8809735a837SHermès Bélusca-Maïto PartEntry->StartSector.QuadPart,
8819735a837SHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart);
88299f0937fSHermès Bélusca-Maïto }
883626c654aSHermès Bélusca-Maïto ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
884c1fbc2d6SHermès Bélusca-Maïto
88599f0937fSHermès Bélusca-Maïto if (isContainer)
88699f0937fSHermès Bélusca-Maïto {
88799f0937fSHermès Bélusca-Maïto DiskEntry->ExtendedPartition = PartEntry;
88899f0937fSHermès Bélusca-Maïto AddLogicalDiskSpace(DiskEntry);
88999f0937fSHermès Bélusca-Maïto }
8907df92966SHermès Bélusca-Maïto
891626c654aSHermès Bélusca-Maïto DPRINT1("First Sector : %I64u\n", PartEntry->StartSector.QuadPart);
892626c654aSHermès Bélusca-Maïto DPRINT1("Last Sector : %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
893626c654aSHermès Bélusca-Maïto DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
894626c654aSHermès Bélusca-Maïto
895626c654aSHermès Bélusca-Maïto return TRUE;
8967df92966SHermès Bélusca-Maïto }
8977df92966SHermès Bélusca-Maïto
8986f15802aSHermès Bélusca-Maïto static
8996f15802aSHermès Bélusca-Maïto VOID
InitPartitionDeviceName(_Inout_ PPARTENTRY PartEntry)9006f15802aSHermès Bélusca-Maïto InitPartitionDeviceName(
9016f15802aSHermès Bélusca-Maïto _Inout_ PPARTENTRY PartEntry)
9026f15802aSHermès Bélusca-Maïto {
9036f15802aSHermès Bélusca-Maïto NTSTATUS Status;
9046f15802aSHermès Bélusca-Maïto
9056f15802aSHermès Bélusca-Maïto /* Ignore if this is a container partition */
9066f15802aSHermès Bélusca-Maïto if (IsContainerPartition(PartEntry->PartitionType))
9076f15802aSHermès Bélusca-Maïto return;
9086f15802aSHermès Bélusca-Maïto ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
9096f15802aSHermès Bélusca-Maïto
9106f15802aSHermès Bélusca-Maïto /* Make a device name for the partition */
9116f15802aSHermès Bélusca-Maïto Status = RtlStringCchPrintfW(PartEntry->DeviceName,
9126f15802aSHermès Bélusca-Maïto _countof(PartEntry->DeviceName),
9136f15802aSHermès Bélusca-Maïto L"\\Device\\Harddisk%lu\\Partition%lu",
9146f15802aSHermès Bélusca-Maïto PartEntry->DiskEntry->DiskNumber,
9156f15802aSHermès Bélusca-Maïto PartEntry->PartitionNumber);
9166f15802aSHermès Bélusca-Maïto ASSERT(NT_SUCCESS(Status));
9176f15802aSHermès Bélusca-Maïto }
9186f15802aSHermès Bélusca-Maïto
9196f15802aSHermès Bélusca-Maïto static
9206f15802aSHermès Bélusca-Maïto VOID
InitVolumeDeviceName(_Inout_ PVOLENTRY Volume)9216f15802aSHermès Bélusca-Maïto InitVolumeDeviceName(
9226f15802aSHermès Bélusca-Maïto _Inout_ PVOLENTRY Volume)
9236f15802aSHermès Bélusca-Maïto {
9246f15802aSHermès Bélusca-Maïto NTSTATUS Status;
9256f15802aSHermès Bélusca-Maïto PPARTENTRY PartEntry;
9266f15802aSHermès Bélusca-Maïto
9276f15802aSHermès Bélusca-Maïto /* If we already have a volume device name, do nothing more */
9286f15802aSHermès Bélusca-Maïto if (*Volume->Info.DeviceName)
9296f15802aSHermès Bélusca-Maïto return;
9306f15802aSHermès Bélusca-Maïto
9316f15802aSHermès Bélusca-Maïto /* Use the partition device name as a temporary volume device name */
9326f15802aSHermès Bélusca-Maïto // TODO: Ask instead the MOUNTMGR for the name.
9336f15802aSHermès Bélusca-Maïto PartEntry = Volume->PartEntry;
9346f15802aSHermès Bélusca-Maïto ASSERT(PartEntry);
9356f15802aSHermès Bélusca-Maïto ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
9366f15802aSHermès Bélusca-Maïto
9376f15802aSHermès Bélusca-Maïto /* Copy the volume device name */
9386f15802aSHermès Bélusca-Maïto Status = RtlStringCchCopyW(Volume->Info.DeviceName,
9396f15802aSHermès Bélusca-Maïto _countof(Volume->Info.DeviceName),
9406f15802aSHermès Bélusca-Maïto PartEntry->DeviceName);
9416f15802aSHermès Bélusca-Maïto ASSERT(NT_SUCCESS(Status));
9426f15802aSHermès Bélusca-Maïto }
9436f15802aSHermès Bélusca-Maïto
9446f15802aSHermès Bélusca-Maïto static
9456f15802aSHermès Bélusca-Maïto PVOLENTRY
InitVolume(_In_ PPARTLIST List,_In_opt_ PPARTENTRY PartEntry)9466f15802aSHermès Bélusca-Maïto InitVolume(
9476f15802aSHermès Bélusca-Maïto _In_ PPARTLIST List,
9486f15802aSHermès Bélusca-Maïto _In_opt_ PPARTENTRY PartEntry)
9496f15802aSHermès Bélusca-Maïto {
9506f15802aSHermès Bélusca-Maïto PVOLENTRY Volume;
9516f15802aSHermès Bélusca-Maïto
9526f15802aSHermès Bélusca-Maïto Volume = RtlAllocateHeap(ProcessHeap,
9536f15802aSHermès Bélusca-Maïto HEAP_ZERO_MEMORY,
9546f15802aSHermès Bélusca-Maïto sizeof(VOLENTRY));
9556f15802aSHermès Bélusca-Maïto if (!Volume)
9566f15802aSHermès Bélusca-Maïto return NULL;
9576f15802aSHermès Bélusca-Maïto
9586f15802aSHermès Bélusca-Maïto /* Reset some volume information */
9596f15802aSHermès Bélusca-Maïto
9606f15802aSHermès Bélusca-Maïto /* No device name for now */
9616f15802aSHermès Bélusca-Maïto Volume->Info.DeviceName[0] = UNICODE_NULL;
9626f15802aSHermès Bélusca-Maïto // Volume->Info.VolumeName[0] = UNICODE_NULL;
9636f15802aSHermès Bélusca-Maïto
9646f15802aSHermès Bélusca-Maïto /* Initialize the volume letter and label */
9656f15802aSHermès Bélusca-Maïto Volume->Info.DriveLetter = UNICODE_NULL;
9666f15802aSHermès Bélusca-Maïto Volume->Info.VolumeLabel[0] = UNICODE_NULL;
9676f15802aSHermès Bélusca-Maïto
9686f15802aSHermès Bélusca-Maïto /* Specify the volume as initially unformatted */
9696f15802aSHermès Bélusca-Maïto Volume->Info.FileSystem[0] = UNICODE_NULL;
9706f15802aSHermès Bélusca-Maïto Volume->FormatState = Unformatted;
9716f15802aSHermès Bélusca-Maïto Volume->NeedsCheck = FALSE;
9726f15802aSHermès Bélusca-Maïto Volume->New = TRUE;
9736f15802aSHermès Bélusca-Maïto
9746f15802aSHermès Bélusca-Maïto if (PartEntry)
9756f15802aSHermès Bélusca-Maïto {
9766f15802aSHermès Bélusca-Maïto ASSERT(PartEntry->DiskEntry->PartList == List);
9776f15802aSHermès Bélusca-Maïto Volume->PartEntry = PartEntry;
9786f15802aSHermès Bélusca-Maïto }
9796f15802aSHermès Bélusca-Maïto InsertTailList(&List->VolumesList, &Volume->ListEntry);
9806f15802aSHermès Bélusca-Maïto return Volume;
9816f15802aSHermès Bélusca-Maïto }
9827df92966SHermès Bélusca-Maïto
9836f19c83bSHermès Bélusca-Maïto static
9846f19c83bSHermès Bélusca-Maïto VOID
AddPartitionToDisk(IN ULONG DiskNumber,IN PDISKENTRY DiskEntry,IN ULONG PartitionIndex,IN BOOLEAN LogicalPartition)9856f19c83bSHermès Bélusca-Maïto AddPartitionToDisk(
9866f19c83bSHermès Bélusca-Maïto IN ULONG DiskNumber,
9876f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry,
9886f19c83bSHermès Bélusca-Maïto IN ULONG PartitionIndex,
9896f19c83bSHermès Bélusca-Maïto IN BOOLEAN LogicalPartition)
9906f19c83bSHermès Bélusca-Maïto {
9916f19c83bSHermès Bélusca-Maïto PPARTITION_INFORMATION PartitionInfo;
9926f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry;
9936f19c83bSHermès Bélusca-Maïto
9946f19c83bSHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
9956f19c83bSHermès Bélusca-Maïto
9966f15802aSHermès Bélusca-Maïto /* Ignore empty partitions */
9976f15802aSHermès Bélusca-Maïto if (PartitionInfo->PartitionType == PARTITION_ENTRY_UNUSED)
9986f19c83bSHermès Bélusca-Maïto return;
9996f15802aSHermès Bélusca-Maïto /* Request must be consistent, though! */
10006f15802aSHermès Bélusca-Maïto ASSERT(!(LogicalPartition && IsContainerPartition(PartitionInfo->PartitionType)));
10016f19c83bSHermès Bélusca-Maïto
10026f19c83bSHermès Bélusca-Maïto PartEntry = RtlAllocateHeap(ProcessHeap,
10036f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY,
10046f19c83bSHermès Bélusca-Maïto sizeof(PARTENTRY));
10056f15802aSHermès Bélusca-Maïto if (!PartEntry)
10066f19c83bSHermès Bélusca-Maïto return;
10076f19c83bSHermès Bélusca-Maïto
10086f19c83bSHermès Bélusca-Maïto PartEntry->DiskEntry = DiskEntry;
10096f19c83bSHermès Bélusca-Maïto
10106f19c83bSHermès Bélusca-Maïto PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
10116f19c83bSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
10126f19c83bSHermès Bélusca-Maïto
10136f19c83bSHermès Bélusca-Maïto PartEntry->BootIndicator = PartitionInfo->BootIndicator;
10146f19c83bSHermès Bélusca-Maïto PartEntry->PartitionType = PartitionInfo->PartitionType;
10156f19c83bSHermès Bélusca-Maïto
10166f19c83bSHermès Bélusca-Maïto PartEntry->LogicalPartition = LogicalPartition;
10176f19c83bSHermès Bélusca-Maïto PartEntry->IsPartitioned = TRUE;
10187df92966SHermès Bélusca-Maïto PartEntry->OnDiskPartitionNumber = PartitionInfo->PartitionNumber;
10196f19c83bSHermès Bélusca-Maïto PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
10206f19c83bSHermès Bélusca-Maïto PartEntry->PartitionIndex = PartitionIndex;
10216f15802aSHermès Bélusca-Maïto InitPartitionDeviceName(PartEntry);
10226f19c83bSHermès Bélusca-Maïto
10236f15802aSHermès Bélusca-Maïto /* No volume initially */
10246f15802aSHermès Bélusca-Maïto PartEntry->Volume = NULL;
1025c1fbc2d6SHermès Bélusca-Maïto
10266f19c83bSHermès Bélusca-Maïto if (IsContainerPartition(PartEntry->PartitionType))
10276f19c83bSHermès Bélusca-Maïto {
10286f15802aSHermès Bélusca-Maïto if (!LogicalPartition && DiskEntry->ExtendedPartition == NULL)
10296f19c83bSHermès Bélusca-Maïto DiskEntry->ExtendedPartition = PartEntry;
10306f19c83bSHermès Bélusca-Maïto }
10316f15802aSHermès Bélusca-Maïto else if (IsRecognizedPartition(PartEntry->PartitionType) || // PartitionInfo->RecognizedPartition
10326f15802aSHermès Bélusca-Maïto IsOEMPartition(PartEntry->PartitionType))
10336f19c83bSHermès Bélusca-Maïto {
10346f15802aSHermès Bélusca-Maïto PVOLENTRY Volume;
10356f15802aSHermès Bélusca-Maïto NTSTATUS Status;
10367df92966SHermès Bélusca-Maïto
10376f15802aSHermès Bélusca-Maïto ASSERT(PartEntry->PartitionNumber != 0);
1038f41750abSHermès Bélusca-Maïto
10396f15802aSHermès Bélusca-Maïto /* The PARTMGR should have notified the MOUNTMGR that a volume
10406f15802aSHermès Bélusca-Maïto * associated with this partition had to be created */
10416f15802aSHermès Bélusca-Maïto Volume = InitVolume(DiskEntry->PartList, PartEntry);
10426f15802aSHermès Bélusca-Maïto if (!Volume)
10436f15802aSHermès Bélusca-Maïto {
10446f15802aSHermès Bélusca-Maïto DPRINT1("Couldn't allocate a volume for device '%S'\n",
10456f15802aSHermès Bélusca-Maïto PartEntry->DeviceName);
10466f15802aSHermès Bélusca-Maïto goto SkipVolume;
10476f15802aSHermès Bélusca-Maïto }
10486f15802aSHermès Bélusca-Maïto PartEntry->Volume = Volume;
10496f15802aSHermès Bélusca-Maïto InitVolumeDeviceName(Volume);
10506f15802aSHermès Bélusca-Maïto Volume->New = FALSE;
1051f41750abSHermès Bélusca-Maïto
10526f15802aSHermès Bélusca-Maïto /* Attach and mount the volume */
10536f15802aSHermès Bélusca-Maïto Status = MountVolume(&Volume->Info, PartEntry->PartitionType);
1054c1fbc2d6SHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
1055f41750abSHermès Bélusca-Maïto {
10566f15802aSHermès Bélusca-Maïto DPRINT1("Failed to mount volume '%S', Status 0x%08lx\n",
10576f15802aSHermès Bélusca-Maïto Volume->Info.DeviceName, Status);
1058c1fbc2d6SHermès Bélusca-Maïto }
1059c1fbc2d6SHermès Bélusca-Maïto
10606f15802aSHermès Bélusca-Maïto //
10616f15802aSHermès Bélusca-Maïto // FIXME: TEMP Backward-compatibility: Set the FormatState
10626f15802aSHermès Bélusca-Maïto // flag in accordance with the FileSystem volume value.
10636f15802aSHermès Bélusca-Maïto //
1064626c654aSHermès Bélusca-Maïto /*
10656f15802aSHermès Bélusca-Maïto * MountVolume() determines whether the given volume is actually
10666f15802aSHermès Bélusca-Maïto * unformatted, if it was mounted with RawFS and the partition
10676f15802aSHermès Bélusca-Maïto * type has specific values for FAT volumes. If so, the volume
10686f15802aSHermès Bélusca-Maïto * stays mounted with RawFS (the FileSystem is "RAW"). However,
10696f15802aSHermès Bélusca-Maïto * if the partition type has different values, the volume is
10706f15802aSHermès Bélusca-Maïto * considered as having an unknown format (it may or may not be
10716f15802aSHermès Bélusca-Maïto * formatted) and the FileSystem value has been emptied.
1072626c654aSHermès Bélusca-Maïto */
10736f15802aSHermès Bélusca-Maïto if (IsUnknown(&Volume->Info))
10746f15802aSHermès Bélusca-Maïto Volume->FormatState = UnknownFormat;
10756f15802aSHermès Bélusca-Maïto else if (IsUnformatted(&Volume->Info)) // FileSystem is "RAW"
10766f15802aSHermès Bélusca-Maïto Volume->FormatState = Unformatted;
10776f15802aSHermès Bélusca-Maïto else // !IsUnknown && !IsUnformatted == IsFormatted
10786f15802aSHermès Bélusca-Maïto Volume->FormatState = Formatted;
10796f15802aSHermès Bélusca-Maïto SkipVolume:;
1080626c654aSHermès Bélusca-Maïto }
1081c1fbc2d6SHermès Bélusca-Maïto else
1082626c654aSHermès Bélusca-Maïto {
10836f15802aSHermès Bélusca-Maïto /* Unknown partition (may or may not be actually formatted):
10846f15802aSHermès Bélusca-Maïto * the partition is hidden, hence no volume */
10856f15802aSHermès Bélusca-Maïto DPRINT1("Disk %lu Partition %lu is not recognized (Type 0x%02x)\n",
10866f15802aSHermès Bélusca-Maïto DiskEntry->DiskNumber, PartEntry->PartitionNumber,
10876f15802aSHermès Bélusca-Maïto PartEntry->PartitionType);
1088f41750abSHermès Bélusca-Maïto }
1089f41750abSHermès Bélusca-Maïto
10907df92966SHermès Bélusca-Maïto InsertDiskRegion(DiskEntry, PartEntry, LogicalPartition);
10916f19c83bSHermès Bélusca-Maïto }
10926f19c83bSHermès Bélusca-Maïto
10936f19c83bSHermès Bélusca-Maïto static
10946f19c83bSHermès Bélusca-Maïto VOID
ScanForUnpartitionedDiskSpace(IN PDISKENTRY DiskEntry)10956f19c83bSHermès Bélusca-Maïto ScanForUnpartitionedDiskSpace(
10966f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry)
10976f19c83bSHermès Bélusca-Maïto {
10987df92966SHermès Bélusca-Maïto ULONGLONG StartSector;
10997df92966SHermès Bélusca-Maïto ULONGLONG SectorCount;
11006f19c83bSHermès Bélusca-Maïto ULONGLONG LastStartSector;
11016f19c83bSHermès Bélusca-Maïto ULONGLONG LastSectorCount;
11026f19c83bSHermès Bélusca-Maïto ULONGLONG LastUnusedSectorCount;
11036f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry;
11046f19c83bSHermès Bélusca-Maïto PPARTENTRY NewPartEntry;
11056f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry;
11066f19c83bSHermès Bélusca-Maïto
11076f19c83bSHermès Bélusca-Maïto DPRINT("ScanForUnpartitionedDiskSpace()\n");
11086f19c83bSHermès Bélusca-Maïto
11096f19c83bSHermès Bélusca-Maïto if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
11106f19c83bSHermès Bélusca-Maïto {
11116f19c83bSHermès Bélusca-Maïto DPRINT1("No primary partition!\n");
11126f19c83bSHermès Bélusca-Maïto
11136f19c83bSHermès Bélusca-Maïto /* Create a partition entry that represents the empty disk */
11146f19c83bSHermès Bélusca-Maïto
111526408b02SPierre Schweitzer if (DiskEntry->SectorAlignment < 2048)
11167df92966SHermès Bélusca-Maïto StartSector = 2048ULL;
111726408b02SPierre Schweitzer else
11187df92966SHermès Bélusca-Maïto StartSector = (ULONGLONG)DiskEntry->SectorAlignment;
11197df92966SHermès Bélusca-Maïto SectorCount = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) - StartSector;
11206f19c83bSHermès Bélusca-Maïto
11217df92966SHermès Bélusca-Maïto NewPartEntry = CreateInsertBlankRegion(DiskEntry,
11227df92966SHermès Bélusca-Maïto &DiskEntry->PrimaryPartListHead,
11237df92966SHermès Bélusca-Maïto StartSector,
11247df92966SHermès Bélusca-Maïto SectorCount,
11257df92966SHermès Bélusca-Maïto FALSE);
112699f0937fSHermès Bélusca-Maïto if (!NewPartEntry)
11277df92966SHermès Bélusca-Maïto DPRINT1("Failed to create a new empty region for full disk space!\n");
11286f19c83bSHermès Bélusca-Maïto
11296f19c83bSHermès Bélusca-Maïto return;
11306f19c83bSHermès Bélusca-Maïto }
11316f19c83bSHermès Bélusca-Maïto
11326f19c83bSHermès Bélusca-Maïto /* Start partition at head 1, cylinder 0 */
113326408b02SPierre Schweitzer if (DiskEntry->SectorAlignment < 2048)
113426408b02SPierre Schweitzer LastStartSector = 2048ULL;
113526408b02SPierre Schweitzer else
11367df92966SHermès Bélusca-Maïto LastStartSector = (ULONGLONG)DiskEntry->SectorAlignment;
11376f19c83bSHermès Bélusca-Maïto LastSectorCount = 0ULL;
11386f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount = 0ULL;
11396f19c83bSHermès Bélusca-Maïto
11408bed4adfSHermès Bélusca-Maïto for (Entry = DiskEntry->PrimaryPartListHead.Flink;
11418bed4adfSHermès Bélusca-Maïto Entry != &DiskEntry->PrimaryPartListHead;
11428bed4adfSHermès Bélusca-Maïto Entry = Entry->Flink)
11436f19c83bSHermès Bélusca-Maïto {
11446f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
11456f19c83bSHermès Bélusca-Maïto
11466f19c83bSHermès Bélusca-Maïto if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
11476f19c83bSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart != 0ULL)
11486f19c83bSHermès Bélusca-Maïto {
11496f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount =
11506f19c83bSHermès Bélusca-Maïto PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
11516f19c83bSHermès Bélusca-Maïto
11526f19c83bSHermès Bélusca-Maïto if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
11536f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
11546f19c83bSHermès Bélusca-Maïto {
11556f19c83bSHermès Bélusca-Maïto DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
11566f19c83bSHermès Bélusca-Maïto
11577df92966SHermès Bélusca-Maïto StartSector = LastStartSector + LastSectorCount;
11587df92966SHermès Bélusca-Maïto SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
11596f19c83bSHermès Bélusca-Maïto
11606f19c83bSHermès Bélusca-Maïto /* Insert the table into the list */
11617df92966SHermès Bélusca-Maïto NewPartEntry = CreateInsertBlankRegion(DiskEntry,
11627df92966SHermès Bélusca-Maïto &PartEntry->ListEntry,
11637df92966SHermès Bélusca-Maïto StartSector,
11647df92966SHermès Bélusca-Maïto SectorCount,
11657df92966SHermès Bélusca-Maïto FALSE);
116699f0937fSHermès Bélusca-Maïto if (!NewPartEntry)
11677df92966SHermès Bélusca-Maïto {
11687df92966SHermès Bélusca-Maïto DPRINT1("Failed to create a new empty region for disk space!\n");
11697df92966SHermès Bélusca-Maïto return;
11707df92966SHermès Bélusca-Maïto }
11716f19c83bSHermès Bélusca-Maïto }
11726f19c83bSHermès Bélusca-Maïto
11736f19c83bSHermès Bélusca-Maïto LastStartSector = PartEntry->StartSector.QuadPart;
11746f19c83bSHermès Bélusca-Maïto LastSectorCount = PartEntry->SectorCount.QuadPart;
11756f19c83bSHermès Bélusca-Maïto }
11766f19c83bSHermès Bélusca-Maïto }
11776f19c83bSHermès Bélusca-Maïto
11786f19c83bSHermès Bélusca-Maïto /* Check for trailing unpartitioned disk space */
11796f19c83bSHermès Bélusca-Maïto if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
11806f19c83bSHermès Bélusca-Maïto {
11816f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
11826f19c83bSHermès Bélusca-Maïto
11836f19c83bSHermès Bélusca-Maïto if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
11846f19c83bSHermès Bélusca-Maïto {
11856f19c83bSHermès Bélusca-Maïto DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
11866f19c83bSHermès Bélusca-Maïto
11877df92966SHermès Bélusca-Maïto StartSector = LastStartSector + LastSectorCount;
11887df92966SHermès Bélusca-Maïto SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
11896f19c83bSHermès Bélusca-Maïto
11906f19c83bSHermès Bélusca-Maïto /* Append the table to the list */
11917df92966SHermès Bélusca-Maïto NewPartEntry = CreateInsertBlankRegion(DiskEntry,
11927df92966SHermès Bélusca-Maïto &DiskEntry->PrimaryPartListHead,
11937df92966SHermès Bélusca-Maïto StartSector,
11947df92966SHermès Bélusca-Maïto SectorCount,
11957df92966SHermès Bélusca-Maïto FALSE);
119699f0937fSHermès Bélusca-Maïto if (!NewPartEntry)
11977df92966SHermès Bélusca-Maïto {
11987df92966SHermès Bélusca-Maïto DPRINT1("Failed to create a new empty region for trailing disk space!\n");
11997df92966SHermès Bélusca-Maïto return;
12007df92966SHermès Bélusca-Maïto }
12016f19c83bSHermès Bélusca-Maïto }
12026f19c83bSHermès Bélusca-Maïto }
12036f19c83bSHermès Bélusca-Maïto
12046f19c83bSHermès Bélusca-Maïto if (DiskEntry->ExtendedPartition != NULL)
12056f19c83bSHermès Bélusca-Maïto {
12066f19c83bSHermès Bélusca-Maïto if (IsListEmpty(&DiskEntry->LogicalPartListHead))
12076f19c83bSHermès Bélusca-Maïto {
12086f19c83bSHermès Bélusca-Maïto DPRINT1("No logical partition!\n");
12096f19c83bSHermès Bélusca-Maïto
12106f19c83bSHermès Bélusca-Maïto /* Create a partition entry that represents the empty extended partition */
121199f0937fSHermès Bélusca-Maïto AddLogicalDiskSpace(DiskEntry);
12126f19c83bSHermès Bélusca-Maïto return;
12136f19c83bSHermès Bélusca-Maïto }
12146f19c83bSHermès Bélusca-Maïto
12156f19c83bSHermès Bélusca-Maïto /* Start partition at head 1, cylinder 0 */
12166f19c83bSHermès Bélusca-Maïto LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
12176f19c83bSHermès Bélusca-Maïto LastSectorCount = 0ULL;
12186f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount = 0ULL;
12196f19c83bSHermès Bélusca-Maïto
12208bed4adfSHermès Bélusca-Maïto for (Entry = DiskEntry->LogicalPartListHead.Flink;
12218bed4adfSHermès Bélusca-Maïto Entry != &DiskEntry->LogicalPartListHead;
12228bed4adfSHermès Bélusca-Maïto Entry = Entry->Flink)
12236f19c83bSHermès Bélusca-Maïto {
12246f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
12256f19c83bSHermès Bélusca-Maïto
12266f19c83bSHermès Bélusca-Maïto if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
12276f19c83bSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart != 0ULL)
12286f19c83bSHermès Bélusca-Maïto {
12296f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount =
12306f19c83bSHermès Bélusca-Maïto PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);
12316f19c83bSHermès Bélusca-Maïto
12326f19c83bSHermès Bélusca-Maïto if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) &&
12336f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
12346f19c83bSHermès Bélusca-Maïto {
12356f19c83bSHermès Bélusca-Maïto DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
12366f19c83bSHermès Bélusca-Maïto
12377df92966SHermès Bélusca-Maïto StartSector = LastStartSector + LastSectorCount;
12387df92966SHermès Bélusca-Maïto SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
12396f19c83bSHermès Bélusca-Maïto
12406f19c83bSHermès Bélusca-Maïto /* Insert the table into the list */
12417df92966SHermès Bélusca-Maïto NewPartEntry = CreateInsertBlankRegion(DiskEntry,
12427df92966SHermès Bélusca-Maïto &PartEntry->ListEntry,
12437df92966SHermès Bélusca-Maïto StartSector,
12447df92966SHermès Bélusca-Maïto SectorCount,
12457df92966SHermès Bélusca-Maïto TRUE);
124699f0937fSHermès Bélusca-Maïto if (!NewPartEntry)
12477df92966SHermès Bélusca-Maïto {
12487df92966SHermès Bélusca-Maïto DPRINT1("Failed to create a new empty region for extended partition space!\n");
12497df92966SHermès Bélusca-Maïto return;
12507df92966SHermès Bélusca-Maïto }
12516f19c83bSHermès Bélusca-Maïto }
12526f19c83bSHermès Bélusca-Maïto
12536f19c83bSHermès Bélusca-Maïto LastStartSector = PartEntry->StartSector.QuadPart;
12546f19c83bSHermès Bélusca-Maïto LastSectorCount = PartEntry->SectorCount.QuadPart;
12556f19c83bSHermès Bélusca-Maïto }
12566f19c83bSHermès Bélusca-Maïto }
12576f19c83bSHermès Bélusca-Maïto
12586f19c83bSHermès Bélusca-Maïto /* Check for trailing unpartitioned disk space */
12596f19c83bSHermès Bélusca-Maïto if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
12606f19c83bSHermès Bélusca-Maïto {
12617df92966SHermès Bélusca-Maïto LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart +
12627df92966SHermès Bélusca-Maïto DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount),
12637df92966SHermès Bélusca-Maïto DiskEntry->SectorAlignment);
12646f19c83bSHermès Bélusca-Maïto
12656f19c83bSHermès Bélusca-Maïto if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
12666f19c83bSHermès Bélusca-Maïto {
12676f19c83bSHermès Bélusca-Maïto DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
12686f19c83bSHermès Bélusca-Maïto
12697df92966SHermès Bélusca-Maïto StartSector = LastStartSector + LastSectorCount;
12707df92966SHermès Bélusca-Maïto SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
12716f19c83bSHermès Bélusca-Maïto
12726f19c83bSHermès Bélusca-Maïto /* Append the table to the list */
12737df92966SHermès Bélusca-Maïto NewPartEntry = CreateInsertBlankRegion(DiskEntry,
12747df92966SHermès Bélusca-Maïto &DiskEntry->LogicalPartListHead,
12757df92966SHermès Bélusca-Maïto StartSector,
12767df92966SHermès Bélusca-Maïto SectorCount,
12777df92966SHermès Bélusca-Maïto TRUE);
127899f0937fSHermès Bélusca-Maïto if (!NewPartEntry)
12797df92966SHermès Bélusca-Maïto {
12807df92966SHermès Bélusca-Maïto DPRINT1("Failed to create a new empty region for extended partition space!\n");
12817df92966SHermès Bélusca-Maïto return;
12827df92966SHermès Bélusca-Maïto }
12836f19c83bSHermès Bélusca-Maïto }
12846f19c83bSHermès Bélusca-Maïto }
12856f19c83bSHermès Bélusca-Maïto }
12866f19c83bSHermès Bélusca-Maïto
12876f19c83bSHermès Bélusca-Maïto DPRINT("ScanForUnpartitionedDiskSpace() done\n");
12886f19c83bSHermès Bélusca-Maïto }
12896f19c83bSHermès Bélusca-Maïto
12906f19c83bSHermès Bélusca-Maïto static
12916f19c83bSHermès Bélusca-Maïto VOID
SetDiskSignature(IN PPARTLIST List,IN PDISKENTRY DiskEntry)12926f19c83bSHermès Bélusca-Maïto SetDiskSignature(
12936f19c83bSHermès Bélusca-Maïto IN PPARTLIST List,
12946f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry)
12956f19c83bSHermès Bélusca-Maïto {
12966f19c83bSHermès Bélusca-Maïto LARGE_INTEGER SystemTime;
12976f19c83bSHermès Bélusca-Maïto TIME_FIELDS TimeFields;
12986f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry2;
12996f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry2;
13006f19c83bSHermès Bélusca-Maïto PUCHAR Buffer;
13016f19c83bSHermès Bélusca-Maïto
1302a3168373SHermès Bélusca-Maïto if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1303a3168373SHermès Bélusca-Maïto {
1304a3168373SHermès Bélusca-Maïto DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1305a3168373SHermès Bélusca-Maïto return;
1306a3168373SHermès Bélusca-Maïto }
1307a3168373SHermès Bélusca-Maïto
13086f19c83bSHermès Bélusca-Maïto Buffer = (PUCHAR)&DiskEntry->LayoutBuffer->Signature;
13096f19c83bSHermès Bélusca-Maïto
13106f19c83bSHermès Bélusca-Maïto while (TRUE)
13116f19c83bSHermès Bélusca-Maïto {
13126f19c83bSHermès Bélusca-Maïto NtQuerySystemTime(&SystemTime);
13136f19c83bSHermès Bélusca-Maïto RtlTimeToTimeFields(&SystemTime, &TimeFields);
13146f19c83bSHermès Bélusca-Maïto
13156f19c83bSHermès Bélusca-Maïto Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
13166f19c83bSHermès Bélusca-Maïto Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
13176f19c83bSHermès Bélusca-Maïto Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
13186f19c83bSHermès Bélusca-Maïto Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);
13196f19c83bSHermès Bélusca-Maïto
13206f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer->Signature == 0)
13216f19c83bSHermès Bélusca-Maïto {
13226f19c83bSHermès Bélusca-Maïto continue;
13236f19c83bSHermès Bélusca-Maïto }
13246f19c83bSHermès Bélusca-Maïto
13256f19c83bSHermès Bélusca-Maïto /* Check if the signature already exist */
13266f19c83bSHermès Bélusca-Maïto /* FIXME:
13276f19c83bSHermès Bélusca-Maïto * Check also signatures from disks, which are
13286f15802aSHermès Bélusca-Maïto * not visible (bootable) by the BIOS.
13296f19c83bSHermès Bélusca-Maïto */
13308bed4adfSHermès Bélusca-Maïto for (Entry2 = List->DiskListHead.Flink;
13318bed4adfSHermès Bélusca-Maïto Entry2 != &List->DiskListHead;
13328bed4adfSHermès Bélusca-Maïto Entry2 = Entry2->Flink)
13336f19c83bSHermès Bélusca-Maïto {
13346f19c83bSHermès Bélusca-Maïto DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry);
13356f19c83bSHermès Bélusca-Maïto
1336a3168373SHermès Bélusca-Maïto if (DiskEntry2->DiskStyle == PARTITION_STYLE_GPT)
1337a3168373SHermès Bélusca-Maïto {
1338a3168373SHermès Bélusca-Maïto DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1339a3168373SHermès Bélusca-Maïto continue;
1340a3168373SHermès Bélusca-Maïto }
1341a3168373SHermès Bélusca-Maïto
13426f19c83bSHermès Bélusca-Maïto if (DiskEntry != DiskEntry2 &&
13436f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->Signature == DiskEntry2->LayoutBuffer->Signature)
13446f19c83bSHermès Bélusca-Maïto break;
13456f19c83bSHermès Bélusca-Maïto }
13466f19c83bSHermès Bélusca-Maïto
13476f19c83bSHermès Bélusca-Maïto if (Entry2 == &List->DiskListHead)
13486f19c83bSHermès Bélusca-Maïto break;
13496f19c83bSHermès Bélusca-Maïto }
13506f19c83bSHermès Bélusca-Maïto }
13516f19c83bSHermès Bélusca-Maïto
13526f19c83bSHermès Bélusca-Maïto static
13536f19c83bSHermès Bélusca-Maïto VOID
UpdateDiskSignatures(IN PPARTLIST List)13546f19c83bSHermès Bélusca-Maïto UpdateDiskSignatures(
13556f19c83bSHermès Bélusca-Maïto IN PPARTLIST List)
13566f19c83bSHermès Bélusca-Maïto {
13576f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry;
13586f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
13596f19c83bSHermès Bélusca-Maïto
1360a3168373SHermès Bélusca-Maïto /* Update each disk */
13618bed4adfSHermès Bélusca-Maïto for (Entry = List->DiskListHead.Flink;
13628bed4adfSHermès Bélusca-Maïto Entry != &List->DiskListHead;
13638bed4adfSHermès Bélusca-Maïto Entry = Entry->Flink)
13646f19c83bSHermès Bélusca-Maïto {
13656f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
13666f19c83bSHermès Bélusca-Maïto
1367a3168373SHermès Bélusca-Maïto if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1368a3168373SHermès Bélusca-Maïto {
1369a3168373SHermès Bélusca-Maïto DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1370a3168373SHermès Bélusca-Maïto continue;
1371a3168373SHermès Bélusca-Maïto }
1372a3168373SHermès Bélusca-Maïto
13736f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer &&
13746f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->Signature == 0)
13756f19c83bSHermès Bélusca-Maïto {
13766f19c83bSHermès Bélusca-Maïto SetDiskSignature(List, DiskEntry);
13776f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionEntry[0].RewritePartition = TRUE;
13786f19c83bSHermès Bélusca-Maïto }
13796f19c83bSHermès Bélusca-Maïto }
13806f19c83bSHermès Bélusca-Maïto }
13816f19c83bSHermès Bélusca-Maïto
13826f19c83bSHermès Bélusca-Maïto static
13836f19c83bSHermès Bélusca-Maïto VOID
UpdateHwDiskNumbers(IN PPARTLIST List)138447a1acedSHermès Bélusca-Maïto UpdateHwDiskNumbers(
138547a1acedSHermès Bélusca-Maïto IN PPARTLIST List)
138647a1acedSHermès Bélusca-Maïto {
138747a1acedSHermès Bélusca-Maïto PLIST_ENTRY ListEntry;
138847a1acedSHermès Bélusca-Maïto PBIOSDISKENTRY BiosDiskEntry;
138947a1acedSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
139047a1acedSHermès Bélusca-Maïto ULONG HwAdapterNumber = 0;
139147a1acedSHermès Bélusca-Maïto ULONG HwControllerNumber = 0;
139247a1acedSHermès Bélusca-Maïto ULONG RemovableDiskCount = 0;
139347a1acedSHermès Bélusca-Maïto
139447a1acedSHermès Bélusca-Maïto /*
139547a1acedSHermès Bélusca-Maïto * Enumerate the disks recognized by the BIOS and recompute the disk
139647a1acedSHermès Bélusca-Maïto * numbers on the system when *ALL* removable disks are not connected.
139747a1acedSHermès Bélusca-Maïto * The entries are inserted in increasing order of AdapterNumber,
139847a1acedSHermès Bélusca-Maïto * ControllerNumber and DiskNumber.
139947a1acedSHermès Bélusca-Maïto */
140047a1acedSHermès Bélusca-Maïto for (ListEntry = List->BiosDiskListHead.Flink;
140147a1acedSHermès Bélusca-Maïto ListEntry != &List->BiosDiskListHead;
140247a1acedSHermès Bélusca-Maïto ListEntry = ListEntry->Flink)
140347a1acedSHermès Bélusca-Maïto {
140447a1acedSHermès Bélusca-Maïto BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
140547a1acedSHermès Bélusca-Maïto DiskEntry = BiosDiskEntry->DiskEntry;
140647a1acedSHermès Bélusca-Maïto
140747a1acedSHermès Bélusca-Maïto /*
140847a1acedSHermès Bélusca-Maïto * If the adapter or controller numbers change, update them and reset
140947a1acedSHermès Bélusca-Maïto * the number of removable disks on this adapter/controller.
141047a1acedSHermès Bélusca-Maïto */
141147a1acedSHermès Bélusca-Maïto if (HwAdapterNumber != BiosDiskEntry->AdapterNumber ||
141247a1acedSHermès Bélusca-Maïto HwControllerNumber != BiosDiskEntry->ControllerNumber)
141347a1acedSHermès Bélusca-Maïto {
141447a1acedSHermès Bélusca-Maïto HwAdapterNumber = BiosDiskEntry->AdapterNumber;
141547a1acedSHermès Bélusca-Maïto HwControllerNumber = BiosDiskEntry->ControllerNumber;
141647a1acedSHermès Bélusca-Maïto RemovableDiskCount = 0;
141747a1acedSHermès Bélusca-Maïto }
141847a1acedSHermès Bélusca-Maïto
141947a1acedSHermès Bélusca-Maïto /* Adjust the actual hardware disk number */
142047a1acedSHermès Bélusca-Maïto if (DiskEntry)
142147a1acedSHermès Bélusca-Maïto {
142247a1acedSHermès Bélusca-Maïto ASSERT(DiskEntry->HwDiskNumber == BiosDiskEntry->DiskNumber);
142347a1acedSHermès Bélusca-Maïto
142447a1acedSHermès Bélusca-Maïto if (DiskEntry->MediaType == RemovableMedia)
142547a1acedSHermès Bélusca-Maïto {
142647a1acedSHermès Bélusca-Maïto /* Increase the number of removable disks and set the disk number to zero */
142747a1acedSHermès Bélusca-Maïto ++RemovableDiskCount;
142847a1acedSHermès Bélusca-Maïto DiskEntry->HwFixedDiskNumber = 0;
142947a1acedSHermès Bélusca-Maïto }
143047a1acedSHermès Bélusca-Maïto else // if (DiskEntry->MediaType == FixedMedia)
143147a1acedSHermès Bélusca-Maïto {
143247a1acedSHermès Bélusca-Maïto /* Adjust the fixed disk number, offset by the number of removable disks found before this one */
143347a1acedSHermès Bélusca-Maïto DiskEntry->HwFixedDiskNumber = BiosDiskEntry->DiskNumber - RemovableDiskCount;
143447a1acedSHermès Bélusca-Maïto }
143547a1acedSHermès Bélusca-Maïto }
143647a1acedSHermès Bélusca-Maïto else
143747a1acedSHermès Bélusca-Maïto {
143847a1acedSHermès Bélusca-Maïto DPRINT1("BIOS disk %lu is not recognized by NTOS!\n", BiosDiskEntry->DiskNumber);
143947a1acedSHermès Bélusca-Maïto }
144047a1acedSHermès Bélusca-Maïto }
144147a1acedSHermès Bélusca-Maïto }
144247a1acedSHermès Bélusca-Maïto
144347a1acedSHermès Bélusca-Maïto static
144447a1acedSHermès Bélusca-Maïto VOID
AddDiskToList(IN HANDLE FileHandle,IN ULONG DiskNumber,IN PPARTLIST List)14456f19c83bSHermès Bélusca-Maïto AddDiskToList(
14466f19c83bSHermès Bélusca-Maïto IN HANDLE FileHandle,
14476f19c83bSHermès Bélusca-Maïto IN ULONG DiskNumber,
14486f19c83bSHermès Bélusca-Maïto IN PPARTLIST List)
14496f19c83bSHermès Bélusca-Maïto {
14506f19c83bSHermès Bélusca-Maïto DISK_GEOMETRY DiskGeometry;
14516f19c83bSHermès Bélusca-Maïto SCSI_ADDRESS ScsiAddress;
14526f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
14536f19c83bSHermès Bélusca-Maïto IO_STATUS_BLOCK Iosb;
14546f19c83bSHermès Bélusca-Maïto NTSTATUS Status;
14556f19c83bSHermès Bélusca-Maïto PPARTITION_SECTOR Mbr;
14566f19c83bSHermès Bélusca-Maïto PULONG Buffer;
14576f19c83bSHermès Bélusca-Maïto LARGE_INTEGER FileOffset;
14586f19c83bSHermès Bélusca-Maïto WCHAR Identifier[20];
14596f19c83bSHermès Bélusca-Maïto ULONG Checksum;
14606f19c83bSHermès Bélusca-Maïto ULONG Signature;
14616f19c83bSHermès Bélusca-Maïto ULONG i;
14626f19c83bSHermès Bélusca-Maïto PLIST_ENTRY ListEntry;
14636f19c83bSHermès Bélusca-Maïto PBIOSDISKENTRY BiosDiskEntry;
14646f19c83bSHermès Bélusca-Maïto ULONG LayoutBufferSize;
14656f19c83bSHermès Bélusca-Maïto PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
14666f19c83bSHermès Bélusca-Maïto
1467f41750abSHermès Bélusca-Maïto /* Retrieve the drive geometry */
14686f19c83bSHermès Bélusca-Maïto Status = NtDeviceIoControlFile(FileHandle,
14696f19c83bSHermès Bélusca-Maïto NULL,
14706f19c83bSHermès Bélusca-Maïto NULL,
14716f19c83bSHermès Bélusca-Maïto NULL,
14726f19c83bSHermès Bélusca-Maïto &Iosb,
14736f19c83bSHermès Bélusca-Maïto IOCTL_DISK_GET_DRIVE_GEOMETRY,
14746f19c83bSHermès Bélusca-Maïto NULL,
14756f19c83bSHermès Bélusca-Maïto 0,
14766f19c83bSHermès Bélusca-Maïto &DiskGeometry,
1477f41750abSHermès Bélusca-Maïto sizeof(DiskGeometry));
14786f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
14796f19c83bSHermès Bélusca-Maïto return;
14806f19c83bSHermès Bélusca-Maïto
14816f19c83bSHermès Bélusca-Maïto if (DiskGeometry.MediaType != FixedMedia &&
14826f19c83bSHermès Bélusca-Maïto DiskGeometry.MediaType != RemovableMedia)
14836f19c83bSHermès Bélusca-Maïto {
14846f19c83bSHermès Bélusca-Maïto return;
14856f19c83bSHermès Bélusca-Maïto }
14866f19c83bSHermès Bélusca-Maïto
1487f41750abSHermès Bélusca-Maïto /*
1488f41750abSHermès Bélusca-Maïto * FIXME: Here we suppose the disk is always SCSI. What if it is
1489f41750abSHermès Bélusca-Maïto * of another type? To check this we need to retrieve the name of
1490f41750abSHermès Bélusca-Maïto * the driver the disk device belongs to.
1491f41750abSHermès Bélusca-Maïto */
14926f19c83bSHermès Bélusca-Maïto Status = NtDeviceIoControlFile(FileHandle,
14936f19c83bSHermès Bélusca-Maïto NULL,
14946f19c83bSHermès Bélusca-Maïto NULL,
14956f19c83bSHermès Bélusca-Maïto NULL,
14966f19c83bSHermès Bélusca-Maïto &Iosb,
14976f19c83bSHermès Bélusca-Maïto IOCTL_SCSI_GET_ADDRESS,
14986f19c83bSHermès Bélusca-Maïto NULL,
14996f19c83bSHermès Bélusca-Maïto 0,
15006f19c83bSHermès Bélusca-Maïto &ScsiAddress,
1501f41750abSHermès Bélusca-Maïto sizeof(ScsiAddress));
15026f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
15036f19c83bSHermès Bélusca-Maïto return;
15046f19c83bSHermès Bélusca-Maïto
15056f19c83bSHermès Bélusca-Maïto /*
15066f19c83bSHermès Bélusca-Maïto * Check whether the disk is initialized, by looking at its MBR.
15076f19c83bSHermès Bélusca-Maïto * NOTE that this must be generalized to GPT disks as well!
15086f19c83bSHermès Bélusca-Maïto */
15096f19c83bSHermès Bélusca-Maïto
15106f19c83bSHermès Bélusca-Maïto Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(ProcessHeap,
15116f19c83bSHermès Bélusca-Maïto 0,
15126f19c83bSHermès Bélusca-Maïto DiskGeometry.BytesPerSector);
15136f19c83bSHermès Bélusca-Maïto if (Mbr == NULL)
15146f19c83bSHermès Bélusca-Maïto return;
15156f19c83bSHermès Bélusca-Maïto
15166f19c83bSHermès Bélusca-Maïto FileOffset.QuadPart = 0;
15176f19c83bSHermès Bélusca-Maïto Status = NtReadFile(FileHandle,
15186f19c83bSHermès Bélusca-Maïto NULL,
15196f19c83bSHermès Bélusca-Maïto NULL,
15206f19c83bSHermès Bélusca-Maïto NULL,
15216f19c83bSHermès Bélusca-Maïto &Iosb,
15226f19c83bSHermès Bélusca-Maïto (PVOID)Mbr,
15236f19c83bSHermès Bélusca-Maïto DiskGeometry.BytesPerSector,
15246f19c83bSHermès Bélusca-Maïto &FileOffset,
15256f19c83bSHermès Bélusca-Maïto NULL);
15266f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
15276f19c83bSHermès Bélusca-Maïto {
15286f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Mbr);
15296f19c83bSHermès Bélusca-Maïto DPRINT1("NtReadFile failed, status=%x\n", Status);
15306f19c83bSHermès Bélusca-Maïto return;
15316f19c83bSHermès Bélusca-Maïto }
15326f19c83bSHermès Bélusca-Maïto Signature = Mbr->Signature;
15336f19c83bSHermès Bélusca-Maïto
15346f19c83bSHermès Bélusca-Maïto /* Calculate the MBR checksum */
15356f19c83bSHermès Bélusca-Maïto Checksum = 0;
15366f19c83bSHermès Bélusca-Maïto Buffer = (PULONG)Mbr;
15376f19c83bSHermès Bélusca-Maïto for (i = 0; i < 128; i++)
15386f19c83bSHermès Bélusca-Maïto {
15396f19c83bSHermès Bélusca-Maïto Checksum += Buffer[i];
15406f19c83bSHermès Bélusca-Maïto }
15416f19c83bSHermès Bélusca-Maïto Checksum = ~Checksum + 1;
15426f19c83bSHermès Bélusca-Maïto
15436f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Identifier, ARRAYSIZE(Identifier),
154447a1acedSHermès Bélusca-Maïto L"%08x-%08x-%c",
154547a1acedSHermès Bélusca-Maïto Checksum, Signature,
154647a1acedSHermès Bélusca-Maïto (Mbr->Magic == PARTITION_MAGIC) ? L'A' : L'X');
15476f19c83bSHermès Bélusca-Maïto DPRINT("Identifier: %S\n", Identifier);
15486f19c83bSHermès Bélusca-Maïto
15496f19c83bSHermès Bélusca-Maïto DiskEntry = RtlAllocateHeap(ProcessHeap,
15506f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY,
15516f19c83bSHermès Bélusca-Maïto sizeof(DISKENTRY));
15526f19c83bSHermès Bélusca-Maïto if (DiskEntry == NULL)
15536f19c83bSHermès Bélusca-Maïto {
1554f41750abSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Mbr);
1555f41750abSHermès Bélusca-Maïto DPRINT1("Failed to allocate a new disk entry.\n");
15566f19c83bSHermès Bélusca-Maïto return;
15576f19c83bSHermès Bélusca-Maïto }
15586f19c83bSHermès Bélusca-Maïto
155984f3e2dfSHermès Bélusca-Maïto DiskEntry->PartList = List;
156084f3e2dfSHermès Bélusca-Maïto
156147a1acedSHermès Bélusca-Maïto #if 0
156247a1acedSHermès Bélusca-Maïto {
156347a1acedSHermès Bélusca-Maïto FILE_FS_DEVICE_INFORMATION FileFsDevice;
156447a1acedSHermès Bélusca-Maïto
156547a1acedSHermès Bélusca-Maïto /* Query the device for its type */
156647a1acedSHermès Bélusca-Maïto Status = NtQueryVolumeInformationFile(FileHandle,
156747a1acedSHermès Bélusca-Maïto &Iosb,
156847a1acedSHermès Bélusca-Maïto &FileFsDevice,
156947a1acedSHermès Bélusca-Maïto sizeof(FileFsDevice),
157047a1acedSHermès Bélusca-Maïto FileFsDeviceInformation);
157147a1acedSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
157247a1acedSHermès Bélusca-Maïto {
157347a1acedSHermès Bélusca-Maïto DPRINT1("Couldn't detect device type for disk %lu of identifier '%S'...\n", DiskNumber, Identifier);
157447a1acedSHermès Bélusca-Maïto }
157547a1acedSHermès Bélusca-Maïto else
157647a1acedSHermès Bélusca-Maïto {
157747a1acedSHermès Bélusca-Maïto DPRINT1("Disk %lu : DeviceType: 0x%08x ; Characteristics: 0x%08x\n", DiskNumber, FileFsDevice.DeviceType, FileFsDevice.Characteristics);
157847a1acedSHermès Bélusca-Maïto }
157947a1acedSHermès Bélusca-Maïto }
158047a1acedSHermès Bélusca-Maïto // NOTE: We may also use NtQueryVolumeInformationFile(FileFsDeviceInformation).
158147a1acedSHermès Bélusca-Maïto #endif
158247a1acedSHermès Bélusca-Maïto DiskEntry->MediaType = DiskGeometry.MediaType;
158347a1acedSHermès Bélusca-Maïto if (DiskEntry->MediaType == RemovableMedia)
158447a1acedSHermès Bélusca-Maïto {
158547a1acedSHermès Bélusca-Maïto DPRINT1("Disk %lu of identifier '%S' is removable\n", DiskNumber, Identifier);
158647a1acedSHermès Bélusca-Maïto }
158747a1acedSHermès Bélusca-Maïto else // if (DiskEntry->MediaType == FixedMedia)
158847a1acedSHermès Bélusca-Maïto {
158947a1acedSHermès Bélusca-Maïto DPRINT1("Disk %lu of identifier '%S' is fixed\n", DiskNumber, Identifier);
159047a1acedSHermès Bélusca-Maïto }
159147a1acedSHermès Bélusca-Maïto
15926f19c83bSHermès Bélusca-Maïto // DiskEntry->Checksum = Checksum;
15936f19c83bSHermès Bélusca-Maïto // DiskEntry->Signature = Signature;
15946f19c83bSHermès Bélusca-Maïto DiskEntry->BiosFound = FALSE;
15956f19c83bSHermès Bélusca-Maïto
15966f19c83bSHermès Bélusca-Maïto /*
15976f19c83bSHermès Bélusca-Maïto * Check if this disk has a valid MBR: verify its signature,
15986f19c83bSHermès Bélusca-Maïto * and whether its two first bytes are a valid instruction
15996f19c83bSHermès Bélusca-Maïto * (related to this, see IsThereAValidBootSector() in partlist.c).
1600a3168373SHermès Bélusca-Maïto *
1601a3168373SHermès Bélusca-Maïto * See also ntoskrnl/fstub/fstubex.c!FstubDetectPartitionStyle().
16026f19c83bSHermès Bélusca-Maïto */
1603a3168373SHermès Bélusca-Maïto
1604a3168373SHermès Bélusca-Maïto // DiskEntry->NoMbr = (Mbr->Magic != PARTITION_MAGIC || (*(PUSHORT)Mbr->BootCode) == 0x0000);
1605a3168373SHermès Bélusca-Maïto
1606a3168373SHermès Bélusca-Maïto /* If we have not the 0xAA55 then it's raw partition */
1607a3168373SHermès Bélusca-Maïto if (Mbr->Magic != PARTITION_MAGIC)
1608a3168373SHermès Bélusca-Maïto {
1609a3168373SHermès Bélusca-Maïto DiskEntry->DiskStyle = PARTITION_STYLE_RAW;
1610a3168373SHermès Bélusca-Maïto }
1611a3168373SHermès Bélusca-Maïto /* Check partitions types: if first is 0xEE and all the others 0, we have GPT */
1612a3168373SHermès Bélusca-Maïto else if (Mbr->Partition[0].PartitionType == EFI_PMBR_OSTYPE_EFI &&
1613a3168373SHermès Bélusca-Maïto Mbr->Partition[1].PartitionType == 0 &&
1614a3168373SHermès Bélusca-Maïto Mbr->Partition[2].PartitionType == 0 &&
1615a3168373SHermès Bélusca-Maïto Mbr->Partition[3].PartitionType == 0)
1616a3168373SHermès Bélusca-Maïto {
1617a3168373SHermès Bélusca-Maïto DiskEntry->DiskStyle = PARTITION_STYLE_GPT;
1618a3168373SHermès Bélusca-Maïto }
1619a3168373SHermès Bélusca-Maïto /* Otherwise, partition table is in MBR */
16206f19c83bSHermès Bélusca-Maïto else
1621a3168373SHermès Bélusca-Maïto {
1622a3168373SHermès Bélusca-Maïto DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
1623a3168373SHermès Bélusca-Maïto }
16246f19c83bSHermès Bélusca-Maïto
16256f19c83bSHermès Bélusca-Maïto /* Free the MBR sector buffer */
16266f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Mbr);
16276f19c83bSHermès Bélusca-Maïto
16286f19c83bSHermès Bélusca-Maïto
16298bed4adfSHermès Bélusca-Maïto for (ListEntry = List->BiosDiskListHead.Flink;
16308bed4adfSHermès Bélusca-Maïto ListEntry != &List->BiosDiskListHead;
16318bed4adfSHermès Bélusca-Maïto ListEntry = ListEntry->Flink)
16326f19c83bSHermès Bélusca-Maïto {
16336f19c83bSHermès Bélusca-Maïto BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
16346f19c83bSHermès Bélusca-Maïto /* FIXME:
16356f15802aSHermès Bélusca-Maïto * Compare the size from BIOS and the reported size from driver.
16366f19c83bSHermès Bélusca-Maïto * If we have more than one disk with a zero or with the same signature
16376f19c83bSHermès Bélusca-Maïto * we must create new signatures and reboot. After the reboot,
16386f19c83bSHermès Bélusca-Maïto * it is possible to identify the disks.
16396f19c83bSHermès Bélusca-Maïto */
16406f19c83bSHermès Bélusca-Maïto if (BiosDiskEntry->Signature == Signature &&
16416f19c83bSHermès Bélusca-Maïto BiosDiskEntry->Checksum == Checksum &&
164247a1acedSHermès Bélusca-Maïto BiosDiskEntry->DiskEntry == NULL)
16436f19c83bSHermès Bélusca-Maïto {
16446f19c83bSHermès Bélusca-Maïto if (!DiskEntry->BiosFound)
16456f19c83bSHermès Bélusca-Maïto {
164647a1acedSHermès Bélusca-Maïto DiskEntry->HwAdapterNumber = BiosDiskEntry->AdapterNumber;
164747a1acedSHermès Bélusca-Maïto DiskEntry->HwControllerNumber = BiosDiskEntry->ControllerNumber;
164847a1acedSHermès Bélusca-Maïto DiskEntry->HwDiskNumber = BiosDiskEntry->DiskNumber;
164947a1acedSHermès Bélusca-Maïto
165047a1acedSHermès Bélusca-Maïto if (DiskEntry->MediaType == RemovableMedia)
165147a1acedSHermès Bélusca-Maïto {
165247a1acedSHermès Bélusca-Maïto /* Set the removable disk number to zero */
165347a1acedSHermès Bélusca-Maïto DiskEntry->HwFixedDiskNumber = 0;
165447a1acedSHermès Bélusca-Maïto }
165547a1acedSHermès Bélusca-Maïto else // if (DiskEntry->MediaType == FixedMedia)
165647a1acedSHermès Bélusca-Maïto {
165747a1acedSHermès Bélusca-Maïto /* The fixed disk number will later be adjusted using the number of removable disks */
165847a1acedSHermès Bélusca-Maïto DiskEntry->HwFixedDiskNumber = BiosDiskEntry->DiskNumber;
165947a1acedSHermès Bélusca-Maïto }
166047a1acedSHermès Bélusca-Maïto
16616f19c83bSHermès Bélusca-Maïto DiskEntry->BiosFound = TRUE;
166247a1acedSHermès Bélusca-Maïto BiosDiskEntry->DiskEntry = DiskEntry;
166347a1acedSHermès Bélusca-Maïto break;
16646f19c83bSHermès Bélusca-Maïto }
16656f19c83bSHermès Bélusca-Maïto else
16666f19c83bSHermès Bélusca-Maïto {
1667f41750abSHermès Bélusca-Maïto // FIXME: What to do?
166847a1acedSHermès Bélusca-Maïto DPRINT1("Disk %lu of identifier '%S' has already been found?!\n", DiskNumber, Identifier);
16696f19c83bSHermès Bélusca-Maïto }
16706f19c83bSHermès Bélusca-Maïto }
16716f19c83bSHermès Bélusca-Maïto }
16726f19c83bSHermès Bélusca-Maïto
16736f19c83bSHermès Bélusca-Maïto if (!DiskEntry->BiosFound)
16746f19c83bSHermès Bélusca-Maïto {
167547a1acedSHermès Bélusca-Maïto DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %lu may not be bootable by the BIOS!\n", DiskNumber);
16766f19c83bSHermès Bélusca-Maïto }
16776f19c83bSHermès Bélusca-Maïto
16786f19c83bSHermès Bélusca-Maïto DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
16796f19c83bSHermès Bélusca-Maïto DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
16806f19c83bSHermès Bélusca-Maïto DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
16816f19c83bSHermès Bélusca-Maïto DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
16826f19c83bSHermès Bélusca-Maïto
16836f19c83bSHermès Bélusca-Maïto DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
16846f19c83bSHermès Bélusca-Maïto DPRINT("TracksPerCylinder %lu\n", DiskEntry->TracksPerCylinder);
16856f19c83bSHermès Bélusca-Maïto DPRINT("SectorsPerTrack %lu\n", DiskEntry->SectorsPerTrack);
16866f19c83bSHermès Bélusca-Maïto DPRINT("BytesPerSector %lu\n", DiskEntry->BytesPerSector);
16876f19c83bSHermès Bélusca-Maïto
16886f19c83bSHermès Bélusca-Maïto DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
16896f19c83bSHermès Bélusca-Maïto (ULONGLONG)DiskGeometry.TracksPerCylinder *
16906f19c83bSHermès Bélusca-Maïto (ULONGLONG)DiskGeometry.SectorsPerTrack;
16916f19c83bSHermès Bélusca-Maïto
16926f19c83bSHermès Bélusca-Maïto DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
16936f19c83bSHermès Bélusca-Maïto DiskEntry->CylinderAlignment = DiskGeometry.TracksPerCylinder *
16946f19c83bSHermès Bélusca-Maïto DiskGeometry.SectorsPerTrack;
16956f19c83bSHermès Bélusca-Maïto
16966f19c83bSHermès Bélusca-Maïto DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount.QuadPart);
16976f19c83bSHermès Bélusca-Maïto DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment);
16986f19c83bSHermès Bélusca-Maïto
16996f19c83bSHermès Bélusca-Maïto DiskEntry->DiskNumber = DiskNumber;
17006f19c83bSHermès Bélusca-Maïto DiskEntry->Port = ScsiAddress.PortNumber;
17016f19c83bSHermès Bélusca-Maïto DiskEntry->Bus = ScsiAddress.PathId;
17026f19c83bSHermès Bélusca-Maïto DiskEntry->Id = ScsiAddress.TargetId;
17036f19c83bSHermès Bélusca-Maïto
17046f19c83bSHermès Bélusca-Maïto GetDriverName(DiskEntry);
17056f19c83bSHermès Bélusca-Maïto /*
17066f19c83bSHermès Bélusca-Maïto * Actually it would be more correct somehow to use:
17076f19c83bSHermès Bélusca-Maïto *
17086f19c83bSHermès Bélusca-Maïto * OBJECT_NAME_INFORMATION NameInfo; // ObjectNameInfo;
17096f19c83bSHermès Bélusca-Maïto * ULONG ReturnedLength;
17106f19c83bSHermès Bélusca-Maïto *
17116f19c83bSHermès Bélusca-Maïto * Status = NtQueryObject(SomeHandleToTheDisk,
17126f19c83bSHermès Bélusca-Maïto * ObjectNameInformation,
17136f19c83bSHermès Bélusca-Maïto * &NameInfo,
17146f19c83bSHermès Bélusca-Maïto * sizeof(NameInfo),
17156f19c83bSHermès Bélusca-Maïto * &ReturnedLength);
17166f19c83bSHermès Bélusca-Maïto * etc...
17176f19c83bSHermès Bélusca-Maïto *
17186f19c83bSHermès Bélusca-Maïto * See examples in https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/ntoskrnl/io/iomgr/error.c;hb=2f3a93ee9cec8322a86bf74b356f1ad83fc912dc#l267
17196f19c83bSHermès Bélusca-Maïto */
17206f19c83bSHermès Bélusca-Maïto
172147a1acedSHermès Bélusca-Maïto InitializeListHead(&DiskEntry->PrimaryPartListHead);
172247a1acedSHermès Bélusca-Maïto InitializeListHead(&DiskEntry->LogicalPartListHead);
172347a1acedSHermès Bélusca-Maïto
17246f19c83bSHermès Bélusca-Maïto InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
17256f19c83bSHermès Bélusca-Maïto
1726f41750abSHermès Bélusca-Maïto
1727f41750abSHermès Bélusca-Maïto /*
1728f41750abSHermès Bélusca-Maïto * We now retrieve the disk partition layout
1729f41750abSHermès Bélusca-Maïto */
1730f41750abSHermès Bélusca-Maïto
1731a3168373SHermès Bélusca-Maïto /*
1732a3168373SHermès Bélusca-Maïto * Stop there now if the disk is GPT-partitioned,
1733a3168373SHermès Bélusca-Maïto * since we currently do not support such disks.
1734a3168373SHermès Bélusca-Maïto */
1735a3168373SHermès Bélusca-Maïto if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1736a3168373SHermès Bélusca-Maïto {
1737a3168373SHermès Bélusca-Maïto DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1738a3168373SHermès Bélusca-Maïto return;
1739a3168373SHermès Bélusca-Maïto }
1740a3168373SHermès Bélusca-Maïto
17416f19c83bSHermès Bélusca-Maïto /* Allocate a layout buffer with 4 partition entries first */
17426f19c83bSHermès Bélusca-Maïto LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
17436f19c83bSHermès Bélusca-Maïto ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
17446f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer = RtlAllocateHeap(ProcessHeap,
17456f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY,
17466f19c83bSHermès Bélusca-Maïto LayoutBufferSize);
17476f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer == NULL)
17486f19c83bSHermès Bélusca-Maïto {
17496f19c83bSHermès Bélusca-Maïto DPRINT1("Failed to allocate the disk layout buffer!\n");
17506f19c83bSHermès Bélusca-Maïto return;
17516f19c83bSHermès Bélusca-Maïto }
17526f19c83bSHermès Bélusca-Maïto
1753f41750abSHermès Bélusca-Maïto /* Keep looping while the drive layout buffer is too small */
17546f19c83bSHermès Bélusca-Maïto for (;;)
17556f19c83bSHermès Bélusca-Maïto {
17566f19c83bSHermès Bélusca-Maïto DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
17576f19c83bSHermès Bélusca-Maïto Status = NtDeviceIoControlFile(FileHandle,
17586f19c83bSHermès Bélusca-Maïto NULL,
17596f19c83bSHermès Bélusca-Maïto NULL,
17606f19c83bSHermès Bélusca-Maïto NULL,
17616f19c83bSHermès Bélusca-Maïto &Iosb,
17626f19c83bSHermès Bélusca-Maïto IOCTL_DISK_GET_DRIVE_LAYOUT,
17636f19c83bSHermès Bélusca-Maïto NULL,
17646f19c83bSHermès Bélusca-Maïto 0,
17656f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer,
17666f19c83bSHermès Bélusca-Maïto LayoutBufferSize);
17676f19c83bSHermès Bélusca-Maïto if (NT_SUCCESS(Status))
17686f19c83bSHermès Bélusca-Maïto break;
17696f19c83bSHermès Bélusca-Maïto
17706f19c83bSHermès Bélusca-Maïto if (Status != STATUS_BUFFER_TOO_SMALL)
17716f19c83bSHermès Bélusca-Maïto {
17726f19c83bSHermès Bélusca-Maïto DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
17736f19c83bSHermès Bélusca-Maïto return;
17746f19c83bSHermès Bélusca-Maïto }
17756f19c83bSHermès Bélusca-Maïto
17766f19c83bSHermès Bélusca-Maïto LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
17776f19c83bSHermès Bélusca-Maïto NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
17786f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY,
17796f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer,
17806f19c83bSHermès Bélusca-Maïto LayoutBufferSize);
17816f19c83bSHermès Bélusca-Maïto if (NewLayoutBuffer == NULL)
17826f19c83bSHermès Bélusca-Maïto {
17836f19c83bSHermès Bélusca-Maïto DPRINT1("Failed to reallocate the disk layout buffer!\n");
17846f19c83bSHermès Bélusca-Maïto return;
17856f19c83bSHermès Bélusca-Maïto }
17866f19c83bSHermès Bélusca-Maïto
17876f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer = NewLayoutBuffer;
17886f19c83bSHermès Bélusca-Maïto }
17896f19c83bSHermès Bélusca-Maïto
17906f19c83bSHermès Bélusca-Maïto DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
17916f19c83bSHermès Bélusca-Maïto
17926f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
17936f19c83bSHermès Bélusca-Maïto DumpPartitionTable(DiskEntry);
17946f19c83bSHermès Bélusca-Maïto #endif
17956f19c83bSHermès Bélusca-Maïto
179647a1acedSHermès Bélusca-Maïto if (IsSuperFloppy(DiskEntry))
179747a1acedSHermès Bélusca-Maïto DPRINT1("Disk %lu is a super-floppy\n", DiskNumber);
179847a1acedSHermès Bélusca-Maïto
17996f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
18006f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
18016f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != PARTITION_ENTRY_UNUSED)
18026f19c83bSHermès Bélusca-Maïto {
18036f19c83bSHermès Bélusca-Maïto if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
18046f19c83bSHermès Bélusca-Maïto {
18056f19c83bSHermès Bélusca-Maïto DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
18066f19c83bSHermès Bélusca-Maïto }
18076f19c83bSHermès Bélusca-Maïto else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
18086f19c83bSHermès Bélusca-Maïto {
18096f19c83bSHermès Bélusca-Maïto DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
18106f19c83bSHermès Bélusca-Maïto }
18116f19c83bSHermès Bélusca-Maïto else
18126f19c83bSHermès Bélusca-Maïto {
18136f19c83bSHermès Bélusca-Maïto DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
18146f19c83bSHermès Bélusca-Maïto }
18156f19c83bSHermès Bélusca-Maïto }
18166f19c83bSHermès Bélusca-Maïto else
18176f19c83bSHermès Bélusca-Maïto {
18186f19c83bSHermès Bélusca-Maïto DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
18196f19c83bSHermès Bélusca-Maïto }
18206f19c83bSHermès Bélusca-Maïto
18216f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer->PartitionCount == 0)
18226f19c83bSHermès Bélusca-Maïto {
18236f19c83bSHermès Bélusca-Maïto DiskEntry->NewDisk = TRUE;
18246f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionCount = 4;
18256f19c83bSHermès Bélusca-Maïto
18266f19c83bSHermès Bélusca-Maïto for (i = 0; i < 4; i++)
18277df92966SHermès Bélusca-Maïto {
18286f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
18296f19c83bSHermès Bélusca-Maïto }
18307df92966SHermès Bélusca-Maïto }
18316f19c83bSHermès Bélusca-Maïto else
18326f19c83bSHermès Bélusca-Maïto {
18337df92966SHermès Bélusca-Maïto /* Enumerate and add the first four primary partitions */
18346f19c83bSHermès Bélusca-Maïto for (i = 0; i < 4; i++)
18356f19c83bSHermès Bélusca-Maïto {
18366f19c83bSHermès Bélusca-Maïto AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
18376f19c83bSHermès Bélusca-Maïto }
18386f19c83bSHermès Bélusca-Maïto
18397df92966SHermès Bélusca-Maïto /* Enumerate and add the remaining partitions as logical ones */
18406f19c83bSHermès Bélusca-Maïto for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
18416f19c83bSHermès Bélusca-Maïto {
18426f19c83bSHermès Bélusca-Maïto AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
18436f19c83bSHermès Bélusca-Maïto }
18446f19c83bSHermès Bélusca-Maïto }
18456f19c83bSHermès Bélusca-Maïto
18466f19c83bSHermès Bélusca-Maïto ScanForUnpartitionedDiskSpace(DiskEntry);
18476f19c83bSHermès Bélusca-Maïto }
18486f19c83bSHermès Bélusca-Maïto
184959acff79SHermès Bélusca-Maïto /*
185059acff79SHermès Bélusca-Maïto * Retrieve the system disk, i.e. the fixed disk that is accessible by the
185159acff79SHermès Bélusca-Maïto * firmware during boot time and where the system partition resides.
185259acff79SHermès Bélusca-Maïto * If no system partition has been determined, we retrieve the first disk
185359acff79SHermès Bélusca-Maïto * that verifies the mentioned criteria above.
185459acff79SHermès Bélusca-Maïto */
185559acff79SHermès Bélusca-Maïto static
185659acff79SHermès Bélusca-Maïto PDISKENTRY
GetSystemDisk(IN PPARTLIST List)185759acff79SHermès Bélusca-Maïto GetSystemDisk(
185859acff79SHermès Bélusca-Maïto IN PPARTLIST List)
185959acff79SHermès Bélusca-Maïto {
186059acff79SHermès Bélusca-Maïto PLIST_ENTRY Entry;
186159acff79SHermès Bélusca-Maïto PDISKENTRY DiskEntry;
186259acff79SHermès Bélusca-Maïto
186359acff79SHermès Bélusca-Maïto /* Check for empty disk list */
186459acff79SHermès Bélusca-Maïto if (IsListEmpty(&List->DiskListHead))
186559acff79SHermès Bélusca-Maïto return NULL;
186659acff79SHermès Bélusca-Maïto
186759acff79SHermès Bélusca-Maïto /*
186859acff79SHermès Bélusca-Maïto * If we already have a system partition, the system disk
186959acff79SHermès Bélusca-Maïto * is the one on which the system partition resides.
187059acff79SHermès Bélusca-Maïto */
187159acff79SHermès Bélusca-Maïto if (List->SystemPartition)
187259acff79SHermès Bélusca-Maïto return List->SystemPartition->DiskEntry;
187359acff79SHermès Bélusca-Maïto
187459acff79SHermès Bélusca-Maïto /* Loop over the disks and find the correct one */
187559acff79SHermès Bélusca-Maïto for (Entry = List->DiskListHead.Flink;
187659acff79SHermès Bélusca-Maïto Entry != &List->DiskListHead;
187759acff79SHermès Bélusca-Maïto Entry = Entry->Flink)
187859acff79SHermès Bélusca-Maïto {
187959acff79SHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
188059acff79SHermès Bélusca-Maïto
188159acff79SHermès Bélusca-Maïto /* The disk must be a fixed disk and be found by the firmware */
188259acff79SHermès Bélusca-Maïto if (DiskEntry->MediaType == FixedMedia && DiskEntry->BiosFound)
188359acff79SHermès Bélusca-Maïto {
188459acff79SHermès Bélusca-Maïto break;
188559acff79SHermès Bélusca-Maïto }
188659acff79SHermès Bélusca-Maïto }
188759acff79SHermès Bélusca-Maïto if (Entry == &List->DiskListHead)
188859acff79SHermès Bélusca-Maïto {
188959acff79SHermès Bélusca-Maïto /* We haven't encountered any suitable disk */
189059acff79SHermès Bélusca-Maïto return NULL;
189159acff79SHermès Bélusca-Maïto }
189259acff79SHermès Bélusca-Maïto
189359acff79SHermès Bélusca-Maïto if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
189459acff79SHermès Bélusca-Maïto {
189559acff79SHermès Bélusca-Maïto DPRINT1("System disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
189659acff79SHermès Bélusca-Maïto }
189759acff79SHermès Bélusca-Maïto
189859acff79SHermès Bélusca-Maïto return DiskEntry;
189959acff79SHermès Bélusca-Maïto }
190059acff79SHermès Bélusca-Maïto
190159acff79SHermès Bélusca-Maïto /*
190259acff79SHermès Bélusca-Maïto * Retrieve the actual "active" partition of the given disk.
190359acff79SHermès Bélusca-Maïto * On MBR disks, partition with the Active/Boot flag set;
190459acff79SHermès Bélusca-Maïto * on GPT disks, partition with the correct GUID.
190559acff79SHermès Bélusca-Maïto */
190659acff79SHermès Bélusca-Maïto BOOLEAN
IsPartitionActive(IN PPARTENTRY PartEntry)190759acff79SHermès Bélusca-Maïto IsPartitionActive(
190859acff79SHermès Bélusca-Maïto IN PPARTENTRY PartEntry)
190959acff79SHermès Bélusca-Maïto {
191059acff79SHermès Bélusca-Maïto // TODO: Support for GPT disks!
191159acff79SHermès Bélusca-Maïto
191259acff79SHermès Bélusca-Maïto if (IsContainerPartition(PartEntry->PartitionType))
191359acff79SHermès Bélusca-Maïto return FALSE;
191459acff79SHermès Bélusca-Maïto
191559acff79SHermès Bélusca-Maïto /* Check if the partition is partitioned, used and active */
191659acff79SHermès Bélusca-Maïto if (PartEntry->IsPartitioned &&
191759acff79SHermès Bélusca-Maïto // !IsContainerPartition(PartEntry->PartitionType) &&
191859acff79SHermès Bélusca-Maïto PartEntry->BootIndicator)
191959acff79SHermès Bélusca-Maïto {
192059acff79SHermès Bélusca-Maïto /* Yes it is */
192159acff79SHermès Bélusca-Maïto ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
192259acff79SHermès Bélusca-Maïto return TRUE;
192359acff79SHermès Bélusca-Maïto }
192459acff79SHermès Bélusca-Maïto
192559acff79SHermès Bélusca-Maïto return FALSE;
192659acff79SHermès Bélusca-Maïto }
192759acff79SHermès Bélusca-Maïto
192859acff79SHermès Bélusca-Maïto static
192959acff79SHermès Bélusca-Maïto PPARTENTRY
GetActiveDiskPartition(IN PDISKENTRY DiskEntry)193059acff79SHermès Bélusca-Maïto GetActiveDiskPartition(
193159acff79SHermès Bélusca-Maïto IN PDISKENTRY DiskEntry)
193259acff79SHermès Bélusca-Maïto {
193359acff79SHermès Bélusca-Maïto PLIST_ENTRY ListEntry;
193459acff79SHermès Bélusca-Maïto PPARTENTRY PartEntry;
193559acff79SHermès Bélusca-Maïto PPARTENTRY ActivePartition = NULL;
193659acff79SHermès Bélusca-Maïto
193759acff79SHermès Bélusca-Maïto /* Check for empty disk list */
193859acff79SHermès Bélusca-Maïto // ASSERT(DiskEntry);
193959acff79SHermès Bélusca-Maïto if (!DiskEntry)
194059acff79SHermès Bélusca-Maïto return NULL;
194159acff79SHermès Bélusca-Maïto
194259acff79SHermès Bélusca-Maïto /* Check for empty partition list */
194359acff79SHermès Bélusca-Maïto if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
194459acff79SHermès Bélusca-Maïto return NULL;
194559acff79SHermès Bélusca-Maïto
194659acff79SHermès Bélusca-Maïto if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
194759acff79SHermès Bélusca-Maïto {
194859acff79SHermès Bélusca-Maïto DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
194959acff79SHermès Bélusca-Maïto return NULL;
195059acff79SHermès Bélusca-Maïto }
195159acff79SHermès Bélusca-Maïto
195259acff79SHermès Bélusca-Maïto /* Scan all (primary) partitions to find the active disk partition */
195359acff79SHermès Bélusca-Maïto for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
195459acff79SHermès Bélusca-Maïto ListEntry != &DiskEntry->PrimaryPartListHead;
195559acff79SHermès Bélusca-Maïto ListEntry = ListEntry->Flink)
195659acff79SHermès Bélusca-Maïto {
195759acff79SHermès Bélusca-Maïto /* Retrieve the partition */
195859acff79SHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
195959acff79SHermès Bélusca-Maïto if (IsPartitionActive(PartEntry))
196059acff79SHermès Bélusca-Maïto {
196159acff79SHermès Bélusca-Maïto /* Yes, we've found it */
196259acff79SHermès Bélusca-Maïto ASSERT(DiskEntry == PartEntry->DiskEntry);
196359acff79SHermès Bélusca-Maïto ASSERT(PartEntry->IsPartitioned);
19646f15802aSHermès Bélusca-Maïto ASSERT(PartEntry->Volume);
196559acff79SHermès Bélusca-Maïto
196659acff79SHermès Bélusca-Maïto ActivePartition = PartEntry;
196759acff79SHermès Bélusca-Maïto
196859acff79SHermès Bélusca-Maïto DPRINT1("Found active system partition %lu in disk %lu, drive letter %C\n",
196959acff79SHermès Bélusca-Maïto PartEntry->PartitionNumber, DiskEntry->DiskNumber,
19706f15802aSHermès Bélusca-Maïto !PartEntry->Volume->Info.DriveLetter ? L'-' : PartEntry->Volume->Info.DriveLetter);
197159acff79SHermès Bélusca-Maïto break;
197259acff79SHermès Bélusca-Maïto }
197359acff79SHermès Bélusca-Maïto }
197459acff79SHermès Bélusca-Maïto
197559acff79SHermès Bélusca-Maïto /* Check if the disk is new and if so, use its first partition as the active system partition */
197659acff79SHermès Bélusca-Maïto if (DiskEntry->NewDisk && ActivePartition != NULL)
197759acff79SHermès Bélusca-Maïto {
197859acff79SHermès Bélusca-Maïto // FIXME: What to do??
197959acff79SHermès Bélusca-Maïto DPRINT1("NewDisk TRUE but already existing active partition?\n");
198059acff79SHermès Bélusca-Maïto }
198159acff79SHermès Bélusca-Maïto
198259acff79SHermès Bélusca-Maïto /* Return the active partition found (or none) */
198359acff79SHermès Bélusca-Maïto return ActivePartition;
198459acff79SHermès Bélusca-Maïto }
198559acff79SHermès Bélusca-Maïto
19866f19c83bSHermès Bélusca-Maïto PPARTLIST
CreatePartitionList(VOID)19876f19c83bSHermès Bélusca-Maïto CreatePartitionList(VOID)
19886f19c83bSHermès Bélusca-Maïto {
19896f19c83bSHermès Bélusca-Maïto PPARTLIST List;
199059acff79SHermès Bélusca-Maïto PDISKENTRY SystemDisk;
19916f19c83bSHermès Bélusca-Maïto OBJECT_ATTRIBUTES ObjectAttributes;
19926f19c83bSHermès Bélusca-Maïto SYSTEM_DEVICE_INFORMATION Sdi;
19936f19c83bSHermès Bélusca-Maïto IO_STATUS_BLOCK Iosb;
19946f19c83bSHermès Bélusca-Maïto ULONG ReturnSize;
19956f19c83bSHermès Bélusca-Maïto NTSTATUS Status;
19966f19c83bSHermès Bélusca-Maïto ULONG DiskNumber;
19976f19c83bSHermès Bélusca-Maïto HANDLE FileHandle;
1998626c654aSHermès Bélusca-Maïto UNICODE_STRING Name;
1999626c654aSHermès Bélusca-Maïto WCHAR Buffer[MAX_PATH];
20006f19c83bSHermès Bélusca-Maïto
20016f19c83bSHermès Bélusca-Maïto List = (PPARTLIST)RtlAllocateHeap(ProcessHeap,
20026f19c83bSHermès Bélusca-Maïto 0,
20036f19c83bSHermès Bélusca-Maïto sizeof(PARTLIST));
20046f15802aSHermès Bélusca-Maïto if (!List)
20056f19c83bSHermès Bélusca-Maïto return NULL;
20066f19c83bSHermès Bélusca-Maïto
20076f19c83bSHermès Bélusca-Maïto List->SystemPartition = NULL;
20086f19c83bSHermès Bélusca-Maïto
20096f19c83bSHermès Bélusca-Maïto InitializeListHead(&List->DiskListHead);
20106f19c83bSHermès Bélusca-Maïto InitializeListHead(&List->BiosDiskListHead);
20116f15802aSHermès Bélusca-Maïto InitializeListHead(&List->VolumesList);
20126f19c83bSHermès Bélusca-Maïto
2013f41750abSHermès Bélusca-Maïto /*
2014f41750abSHermès Bélusca-Maïto * Enumerate the disks seen by the BIOS; this will be used later
2015f41750abSHermès Bélusca-Maïto * to map drives seen by NTOS with their corresponding BIOS names.
2016f41750abSHermès Bélusca-Maïto */
20176f19c83bSHermès Bélusca-Maïto EnumerateBiosDiskEntries(List);
20186f19c83bSHermès Bélusca-Maïto
2019f41750abSHermès Bélusca-Maïto /* Enumerate disks seen by NTOS */
20206f19c83bSHermès Bélusca-Maïto Status = NtQuerySystemInformation(SystemDeviceInformation,
20216f19c83bSHermès Bélusca-Maïto &Sdi,
20226f19c83bSHermès Bélusca-Maïto sizeof(Sdi),
20236f19c83bSHermès Bélusca-Maïto &ReturnSize);
20246f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
20256f19c83bSHermès Bélusca-Maïto {
2026780c2a03SSerge Gautherie DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx\n", Status);
20276f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, List);
20286f19c83bSHermès Bélusca-Maïto return NULL;
20296f19c83bSHermès Bélusca-Maïto }
20306f19c83bSHermès Bélusca-Maïto
20316f19c83bSHermès Bélusca-Maïto for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
20326f19c83bSHermès Bélusca-Maïto {
20336f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
20346f19c83bSHermès Bélusca-Maïto L"\\Device\\Harddisk%lu\\Partition0",
20356f19c83bSHermès Bélusca-Maïto DiskNumber);
20366f19c83bSHermès Bélusca-Maïto RtlInitUnicodeString(&Name, Buffer);
20376f19c83bSHermès Bélusca-Maïto
20386f19c83bSHermès Bélusca-Maïto InitializeObjectAttributes(&ObjectAttributes,
20396f19c83bSHermès Bélusca-Maïto &Name,
2040765994c9SHermès Bélusca-Maïto OBJ_CASE_INSENSITIVE,
20416f19c83bSHermès Bélusca-Maïto NULL,
20426f19c83bSHermès Bélusca-Maïto NULL);
20436f19c83bSHermès Bélusca-Maïto
20446f19c83bSHermès Bélusca-Maïto Status = NtOpenFile(&FileHandle,
20456f19c83bSHermès Bélusca-Maïto FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
20466f19c83bSHermès Bélusca-Maïto &ObjectAttributes,
20476f19c83bSHermès Bélusca-Maïto &Iosb,
2048f41750abSHermès Bélusca-Maïto FILE_SHARE_READ | FILE_SHARE_WRITE,
20496f19c83bSHermès Bélusca-Maïto FILE_SYNCHRONOUS_IO_NONALERT);
20506f19c83bSHermès Bélusca-Maïto if (NT_SUCCESS(Status))
20516f19c83bSHermès Bélusca-Maïto {
20526f19c83bSHermès Bélusca-Maïto AddDiskToList(FileHandle, DiskNumber, List);
20536f19c83bSHermès Bélusca-Maïto NtClose(FileHandle);
20546f19c83bSHermès Bélusca-Maïto }
20556f19c83bSHermès Bélusca-Maïto }
20566f19c83bSHermès Bélusca-Maïto
20576f19c83bSHermès Bélusca-Maïto UpdateDiskSignatures(List);
205847a1acedSHermès Bélusca-Maïto UpdateHwDiskNumbers(List);
20596f19c83bSHermès Bélusca-Maïto AssignDriveLetters(List);
20606f19c83bSHermès Bélusca-Maïto
206159acff79SHermès Bélusca-Maïto /*
206259acff79SHermès Bélusca-Maïto * Retrieve the system partition: the active partition on the system
206359acff79SHermès Bélusca-Maïto * disk (the one that will be booted by default by the hardware).
206459acff79SHermès Bélusca-Maïto */
206559acff79SHermès Bélusca-Maïto SystemDisk = GetSystemDisk(List);
206659acff79SHermès Bélusca-Maïto List->SystemPartition = (SystemDisk ? GetActiveDiskPartition(SystemDisk) : NULL);
206759acff79SHermès Bélusca-Maïto
20686f19c83bSHermès Bélusca-Maïto return List;
20696f19c83bSHermès Bélusca-Maïto }
20706f19c83bSHermès Bélusca-Maïto
20716f19c83bSHermès Bélusca-Maïto VOID
DestroyPartitionList(IN PPARTLIST List)20726f19c83bSHermès Bélusca-Maïto DestroyPartitionList(
20736f19c83bSHermès Bélusca-Maïto IN PPARTLIST List)
20746f19c83bSHermès Bélusca-Maïto {
20756f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
20766f19c83bSHermès Bélusca-Maïto PBIOSDISKENTRY BiosDiskEntry;
20776f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry;
20786f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry;
20796f19c83bSHermès Bélusca-Maïto
20806f19c83bSHermès Bélusca-Maïto /* Release disk and partition info */
20816f19c83bSHermès Bélusca-Maïto while (!IsListEmpty(&List->DiskListHead))
20826f19c83bSHermès Bélusca-Maïto {
20836f19c83bSHermès Bélusca-Maïto Entry = RemoveHeadList(&List->DiskListHead);
20846f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
20856f19c83bSHermès Bélusca-Maïto
20866f19c83bSHermès Bélusca-Maïto /* Release driver name */
20876f19c83bSHermès Bélusca-Maïto RtlFreeUnicodeString(&DiskEntry->DriverName);
20886f19c83bSHermès Bélusca-Maïto
20896f19c83bSHermès Bélusca-Maïto /* Release primary partition list */
20906f19c83bSHermès Bélusca-Maïto while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
20916f19c83bSHermès Bélusca-Maïto {
20926f19c83bSHermès Bélusca-Maïto Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead);
20936f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
20946f15802aSHermès Bélusca-Maïto DestroyRegion(PartEntry);
20956f19c83bSHermès Bélusca-Maïto }
20966f19c83bSHermès Bélusca-Maïto
20976f19c83bSHermès Bélusca-Maïto /* Release logical partition list */
20986f19c83bSHermès Bélusca-Maïto while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
20996f19c83bSHermès Bélusca-Maïto {
21006f19c83bSHermès Bélusca-Maïto Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
21016f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
21026f15802aSHermès Bélusca-Maïto DestroyRegion(PartEntry);
21036f19c83bSHermès Bélusca-Maïto }
21046f19c83bSHermès Bélusca-Maïto
21056f19c83bSHermès Bélusca-Maïto /* Release layout buffer */
21066f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer != NULL)
21076f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
21086f19c83bSHermès Bélusca-Maïto
21096f19c83bSHermès Bélusca-Maïto /* Release disk entry */
21106f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, DiskEntry);
21116f19c83bSHermès Bélusca-Maïto }
21126f19c83bSHermès Bélusca-Maïto
21136f15802aSHermès Bélusca-Maïto /* Release the BIOS disk info */
21146f19c83bSHermès Bélusca-Maïto while (!IsListEmpty(&List->BiosDiskListHead))
21156f19c83bSHermès Bélusca-Maïto {
21166f19c83bSHermès Bélusca-Maïto Entry = RemoveHeadList(&List->BiosDiskListHead);
21176f19c83bSHermès Bélusca-Maïto BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
21186f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
21196f19c83bSHermès Bélusca-Maïto }
21206f19c83bSHermès Bélusca-Maïto
21216f19c83bSHermès Bélusca-Maïto /* Release list head */
21226f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, List);
21236f19c83bSHermès Bélusca-Maïto }
21246f19c83bSHermès Bélusca-Maïto
21256f19c83bSHermès Bélusca-Maïto PDISKENTRY
GetDiskByBiosNumber(_In_ PPARTLIST List,_In_ ULONG HwDiskNumber)21266f19c83bSHermès Bélusca-Maïto GetDiskByBiosNumber(
2127a2777cd8SHermès Bélusca-Maïto _In_ PPARTLIST List,
2128a2777cd8SHermès Bélusca-Maïto _In_ ULONG HwDiskNumber)
21296f19c83bSHermès Bélusca-Maïto {
21306f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
21316f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry;
21326f19c83bSHermès Bélusca-Maïto
21336f19c83bSHermès Bélusca-Maïto /* Loop over the disks and find the correct one */
21348bed4adfSHermès Bélusca-Maïto for (Entry = List->DiskListHead.Flink;
21358bed4adfSHermès Bélusca-Maïto Entry != &List->DiskListHead;
21368bed4adfSHermès Bélusca-Maïto Entry = Entry->Flink)
21376f19c83bSHermès Bélusca-Maïto {
21386f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
21396f19c83bSHermès Bélusca-Maïto
214047a1acedSHermès Bélusca-Maïto if (DiskEntry->HwDiskNumber == HwDiskNumber)
2141a2777cd8SHermès Bélusca-Maïto return DiskEntry; /* Disk found, return it */
21426f19c83bSHermès Bélusca-Maïto }
21436f19c83bSHermès Bélusca-Maïto
21446f19c83bSHermès Bélusca-Maïto /* Disk not found, stop there */
21456f19c83bSHermès Bélusca-Maïto return NULL;
21466f19c83bSHermès Bélusca-Maïto }
21476f19c83bSHermès Bélusca-Maïto
21486f19c83bSHermès Bélusca-Maïto PDISKENTRY
GetDiskByNumber(_In_ PPARTLIST List,_In_ ULONG DiskNumber)21496f19c83bSHermès Bélusca-Maïto GetDiskByNumber(
2150a2777cd8SHermès Bélusca-Maïto _In_ PPARTLIST List,
2151a2777cd8SHermès Bélusca-Maïto _In_ ULONG DiskNumber)
21526f19c83bSHermès Bélusca-Maïto {
21536f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
21546f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry;
21556f19c83bSHermès Bélusca-Maïto
21566f19c83bSHermès Bélusca-Maïto /* Loop over the disks and find the correct one */
21578bed4adfSHermès Bélusca-Maïto for (Entry = List->DiskListHead.Flink;
21588bed4adfSHermès Bélusca-Maïto Entry != &List->DiskListHead;
21598bed4adfSHermès Bélusca-Maïto Entry = Entry->Flink)
21606f19c83bSHermès Bélusca-Maïto {
21616f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
21626f19c83bSHermès Bélusca-Maïto
21636f19c83bSHermès Bélusca-Maïto if (DiskEntry->DiskNumber == DiskNumber)
2164a2777cd8SHermès Bélusca-Maïto return DiskEntry; /* Disk found, return it */
21656f19c83bSHermès Bélusca-Maïto }
21666f19c83bSHermès Bélusca-Maïto
21676f19c83bSHermès Bélusca-Maïto /* Disk not found, stop there */
21686f19c83bSHermès Bélusca-Maïto return NULL;
21696f19c83bSHermès Bélusca-Maïto }
21706f19c83bSHermès Bélusca-Maïto
21716f19c83bSHermès Bélusca-Maïto PDISKENTRY
GetDiskBySCSI(_In_ PPARTLIST List,_In_ USHORT Port,_In_ USHORT Bus,_In_ USHORT Id)21726f19c83bSHermès Bélusca-Maïto GetDiskBySCSI(
2173a2777cd8SHermès Bélusca-Maïto _In_ PPARTLIST List,
2174a2777cd8SHermès Bélusca-Maïto _In_ USHORT Port,
2175a2777cd8SHermès Bélusca-Maïto _In_ USHORT Bus,
2176a2777cd8SHermès Bélusca-Maïto _In_ USHORT Id)
21776f19c83bSHermès Bélusca-Maïto {
21786f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
21796f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry;
21806f19c83bSHermès Bélusca-Maïto
21816f19c83bSHermès Bélusca-Maïto /* Loop over the disks and find the correct one */
21828bed4adfSHermès Bélusca-Maïto for (Entry = List->DiskListHead.Flink;
21838bed4adfSHermès Bélusca-Maïto Entry != &List->DiskListHead;
21848bed4adfSHermès Bélusca-Maïto Entry = Entry->Flink)
21856f19c83bSHermès Bélusca-Maïto {
21866f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
21876f19c83bSHermès Bélusca-Maïto
21886f19c83bSHermès Bélusca-Maïto if (DiskEntry->Port == Port &&
21896f19c83bSHermès Bélusca-Maïto DiskEntry->Bus == Bus &&
21906f19c83bSHermès Bélusca-Maïto DiskEntry->Id == Id)
21916f19c83bSHermès Bélusca-Maïto {
2192a2777cd8SHermès Bélusca-Maïto /* Disk found, return it */
21936f19c83bSHermès Bélusca-Maïto return DiskEntry;
21946f19c83bSHermès Bélusca-Maïto }
21956f19c83bSHermès Bélusca-Maïto }
21966f19c83bSHermès Bélusca-Maïto
21976f19c83bSHermès Bélusca-Maïto /* Disk not found, stop there */
21986f19c83bSHermès Bélusca-Maïto return NULL;
21996f19c83bSHermès Bélusca-Maïto }
22006f19c83bSHermès Bélusca-Maïto
22016f19c83bSHermès Bélusca-Maïto PDISKENTRY
GetDiskBySignature(_In_ PPARTLIST List,_In_ ULONG Signature)22026f19c83bSHermès Bélusca-Maïto GetDiskBySignature(
2203a2777cd8SHermès Bélusca-Maïto _In_ PPARTLIST List,
2204a2777cd8SHermès Bélusca-Maïto _In_ ULONG Signature)
22056f19c83bSHermès Bélusca-Maïto {
22066f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
22076f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry;
22086f19c83bSHermès Bélusca-Maïto
22096f19c83bSHermès Bélusca-Maïto /* Loop over the disks and find the correct one */
22108bed4adfSHermès Bélusca-Maïto for (Entry = List->DiskListHead.Flink;
22118bed4adfSHermès Bélusca-Maïto Entry != &List->DiskListHead;
22128bed4adfSHermès Bélusca-Maïto Entry = Entry->Flink)
22136f19c83bSHermès Bélusca-Maïto {
22146f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
22156f19c83bSHermès Bélusca-Maïto
22166f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer->Signature == Signature)
2217a2777cd8SHermès Bélusca-Maïto return DiskEntry; /* Disk found, return it */
22186f19c83bSHermès Bélusca-Maïto }
22196f19c83bSHermès Bélusca-Maïto
22206f19c83bSHermès Bélusca-Maïto /* Disk not found, stop there */
22216f19c83bSHermès Bélusca-Maïto return NULL;
22226f19c83bSHermès Bélusca-Maïto }
22236f19c83bSHermès Bélusca-Maïto
22246f19c83bSHermès Bélusca-Maïto PPARTENTRY
GetPartition(_In_ PDISKENTRY DiskEntry,_In_ ULONG PartitionNumber)22256f19c83bSHermès Bélusca-Maïto GetPartition(
2226a2777cd8SHermès Bélusca-Maïto _In_ PDISKENTRY DiskEntry,
2227a2777cd8SHermès Bélusca-Maïto _In_ ULONG PartitionNumber)
22286f19c83bSHermès Bélusca-Maïto {
22296f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry;
22306f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry;
22316f19c83bSHermès Bélusca-Maïto
223297821f00SHermès Bélusca-Maïto /* Forbid whole-disk or extended container partition access */
223397821f00SHermès Bélusca-Maïto if (PartitionNumber == 0)
223497821f00SHermès Bélusca-Maïto return NULL;
223597821f00SHermès Bélusca-Maïto
2236a2777cd8SHermès Bélusca-Maïto /* Loop over the primary partitions first... */
22378bed4adfSHermès Bélusca-Maïto for (Entry = DiskEntry->PrimaryPartListHead.Flink;
22388bed4adfSHermès Bélusca-Maïto Entry != &DiskEntry->PrimaryPartListHead;
22398bed4adfSHermès Bélusca-Maïto Entry = Entry->Flink)
22406f19c83bSHermès Bélusca-Maïto {
22416f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
22426f19c83bSHermès Bélusca-Maïto
22436f19c83bSHermès Bélusca-Maïto if (PartEntry->PartitionNumber == PartitionNumber)
2244a2777cd8SHermès Bélusca-Maïto return PartEntry; /* Partition found, return it */
22456f19c83bSHermès Bélusca-Maïto }
2246a2777cd8SHermès Bélusca-Maïto
2247a2777cd8SHermès Bélusca-Maïto if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2248a2777cd8SHermès Bélusca-Maïto return NULL;
22496f19c83bSHermès Bélusca-Maïto
22506f19c83bSHermès Bélusca-Maïto /* ... then over the logical partitions if needed */
22518bed4adfSHermès Bélusca-Maïto for (Entry = DiskEntry->LogicalPartListHead.Flink;
22528bed4adfSHermès Bélusca-Maïto Entry != &DiskEntry->LogicalPartListHead;
22538bed4adfSHermès Bélusca-Maïto Entry = Entry->Flink)
22546f19c83bSHermès Bélusca-Maïto {
22556f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
22566f19c83bSHermès Bélusca-Maïto
22576f19c83bSHermès Bélusca-Maïto if (PartEntry->PartitionNumber == PartitionNumber)
2258a2777cd8SHermès Bélusca-Maïto return PartEntry; /* Partition found, return it */
22596f19c83bSHermès Bélusca-Maïto }
22606f19c83bSHermès Bélusca-Maïto
22616f19c83bSHermès Bélusca-Maïto /* The partition was not found on the disk, stop there */
22626f19c83bSHermès Bélusca-Maïto return NULL;
22636f19c83bSHermès Bélusca-Maïto }
22646f19c83bSHermès Bélusca-Maïto
226584f3e2dfSHermès Bélusca-Maïto PPARTENTRY
SelectPartition(_In_ PPARTLIST List,_In_ ULONG DiskNumber,_In_ ULONG PartitionNumber)22666f19c83bSHermès Bélusca-Maïto SelectPartition(
2267a2777cd8SHermès Bélusca-Maïto _In_ PPARTLIST List,
2268a2777cd8SHermès Bélusca-Maïto _In_ ULONG DiskNumber,
2269a2777cd8SHermès Bélusca-Maïto _In_ ULONG PartitionNumber)
22706f19c83bSHermès Bélusca-Maïto {
22716f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
22726f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry;
22736f19c83bSHermès Bélusca-Maïto
2274a2777cd8SHermès Bélusca-Maïto /* Find the disk */
22756f19c83bSHermès Bélusca-Maïto DiskEntry = GetDiskByNumber(List, DiskNumber);
22766f19c83bSHermès Bélusca-Maïto if (!DiskEntry)
227784f3e2dfSHermès Bélusca-Maïto return NULL;
2278a2777cd8SHermès Bélusca-Maïto ASSERT(DiskEntry->DiskNumber == DiskNumber);
22796f19c83bSHermès Bélusca-Maïto
2280a2777cd8SHermès Bélusca-Maïto /* Find the partition */
2281a2777cd8SHermès Bélusca-Maïto PartEntry = GetPartition(DiskEntry, PartitionNumber);
22826f19c83bSHermès Bélusca-Maïto if (!PartEntry)
228384f3e2dfSHermès Bélusca-Maïto return NULL;
22846f19c83bSHermès Bélusca-Maïto ASSERT(PartEntry->DiskEntry == DiskEntry);
22856f19c83bSHermès Bélusca-Maïto ASSERT(PartEntry->PartitionNumber == PartitionNumber);
22866f19c83bSHermès Bélusca-Maïto
228784f3e2dfSHermès Bélusca-Maïto return PartEntry;
22886f19c83bSHermès Bélusca-Maïto }
22896f19c83bSHermès Bélusca-Maïto
22906f19c83bSHermès Bélusca-Maïto PPARTENTRY
GetNextPartition(IN PPARTLIST List,IN PPARTENTRY CurrentPart OPTIONAL)22916f19c83bSHermès Bélusca-Maïto GetNextPartition(
229284f3e2dfSHermès Bélusca-Maïto IN PPARTLIST List,
229384f3e2dfSHermès Bélusca-Maïto IN PPARTENTRY CurrentPart OPTIONAL)
22946f19c83bSHermès Bélusca-Maïto {
22956f19c83bSHermès Bélusca-Maïto PLIST_ENTRY DiskListEntry;
22966f19c83bSHermès Bélusca-Maïto PLIST_ENTRY PartListEntry;
229784f3e2dfSHermès Bélusca-Maïto PDISKENTRY CurrentDisk;
22986f19c83bSHermès Bélusca-Maïto
22996f19c83bSHermès Bélusca-Maïto /* Fail if no disks are available */
23006f19c83bSHermès Bélusca-Maïto if (IsListEmpty(&List->DiskListHead))
23016f19c83bSHermès Bélusca-Maïto return NULL;
23026f19c83bSHermès Bélusca-Maïto
230384f3e2dfSHermès Bélusca-Maïto /* Check for the next usable entry on the current partition's disk */
230484f3e2dfSHermès Bélusca-Maïto if (CurrentPart != NULL)
23056f19c83bSHermès Bélusca-Maïto {
230684f3e2dfSHermès Bélusca-Maïto CurrentDisk = CurrentPart->DiskEntry;
230784f3e2dfSHermès Bélusca-Maïto
230884f3e2dfSHermès Bélusca-Maïto if (CurrentPart->LogicalPartition)
23096f19c83bSHermès Bélusca-Maïto {
23106f19c83bSHermès Bélusca-Maïto /* Logical partition */
23116f19c83bSHermès Bélusca-Maïto
231284f3e2dfSHermès Bélusca-Maïto PartListEntry = CurrentPart->ListEntry.Flink;
231384f3e2dfSHermès Bélusca-Maïto if (PartListEntry != &CurrentDisk->LogicalPartListHead)
23146f19c83bSHermès Bélusca-Maïto {
23156f19c83bSHermès Bélusca-Maïto /* Next logical partition */
231684f3e2dfSHermès Bélusca-Maïto CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
231784f3e2dfSHermès Bélusca-Maïto return CurrentPart;
23186f19c83bSHermès Bélusca-Maïto }
23196f19c83bSHermès Bélusca-Maïto else
23206f19c83bSHermès Bélusca-Maïto {
232184f3e2dfSHermès Bélusca-Maïto PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink;
232284f3e2dfSHermès Bélusca-Maïto if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
23236f19c83bSHermès Bélusca-Maïto {
232484f3e2dfSHermès Bélusca-Maïto CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
232584f3e2dfSHermès Bélusca-Maïto return CurrentPart;
23266f19c83bSHermès Bélusca-Maïto }
23276f19c83bSHermès Bélusca-Maïto }
23286f19c83bSHermès Bélusca-Maïto }
23296f19c83bSHermès Bélusca-Maïto else
23306f19c83bSHermès Bélusca-Maïto {
23316f19c83bSHermès Bélusca-Maïto /* Primary or extended partition */
23326f19c83bSHermès Bélusca-Maïto
233384f3e2dfSHermès Bélusca-Maïto if (CurrentPart->IsPartitioned &&
233484f3e2dfSHermès Bélusca-Maïto IsContainerPartition(CurrentPart->PartitionType))
23356f19c83bSHermès Bélusca-Maïto {
23366f19c83bSHermès Bélusca-Maïto /* First logical partition */
233784f3e2dfSHermès Bélusca-Maïto PartListEntry = CurrentDisk->LogicalPartListHead.Flink;
233884f3e2dfSHermès Bélusca-Maïto if (PartListEntry != &CurrentDisk->LogicalPartListHead)
23396f19c83bSHermès Bélusca-Maïto {
234084f3e2dfSHermès Bélusca-Maïto CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
234184f3e2dfSHermès Bélusca-Maïto return CurrentPart;
23426f19c83bSHermès Bélusca-Maïto }
23436f19c83bSHermès Bélusca-Maïto }
23446f19c83bSHermès Bélusca-Maïto else
23456f19c83bSHermès Bélusca-Maïto {
23466f19c83bSHermès Bélusca-Maïto /* Next primary partition */
234784f3e2dfSHermès Bélusca-Maïto PartListEntry = CurrentPart->ListEntry.Flink;
234884f3e2dfSHermès Bélusca-Maïto if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
23496f19c83bSHermès Bélusca-Maïto {
235084f3e2dfSHermès Bélusca-Maïto CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
235184f3e2dfSHermès Bélusca-Maïto return CurrentPart;
23526f19c83bSHermès Bélusca-Maïto }
23536f19c83bSHermès Bélusca-Maïto }
23546f19c83bSHermès Bélusca-Maïto }
23556f19c83bSHermès Bélusca-Maïto }
23566f19c83bSHermès Bélusca-Maïto
23576f19c83bSHermès Bélusca-Maïto /* Search for the first partition entry on the next disk */
235884f3e2dfSHermès Bélusca-Maïto for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink
235984f3e2dfSHermès Bélusca-Maïto : List->DiskListHead.Flink);
23608bed4adfSHermès Bélusca-Maïto DiskListEntry != &List->DiskListHead;
23618bed4adfSHermès Bélusca-Maïto DiskListEntry = DiskListEntry->Flink)
23626f19c83bSHermès Bélusca-Maïto {
236384f3e2dfSHermès Bélusca-Maïto CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
23646f19c83bSHermès Bélusca-Maïto
236584f3e2dfSHermès Bélusca-Maïto if (CurrentDisk->DiskStyle == PARTITION_STYLE_GPT)
2366a3168373SHermès Bélusca-Maïto {
2367a3168373SHermès Bélusca-Maïto DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2368a3168373SHermès Bélusca-Maïto continue;
2369a3168373SHermès Bélusca-Maïto }
2370a3168373SHermès Bélusca-Maïto
237184f3e2dfSHermès Bélusca-Maïto PartListEntry = CurrentDisk->PrimaryPartListHead.Flink;
237284f3e2dfSHermès Bélusca-Maïto if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
23736f19c83bSHermès Bélusca-Maïto {
237484f3e2dfSHermès Bélusca-Maïto CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
237584f3e2dfSHermès Bélusca-Maïto return CurrentPart;
23766f19c83bSHermès Bélusca-Maïto }
23776f19c83bSHermès Bélusca-Maïto }
23786f19c83bSHermès Bélusca-Maïto
23796f19c83bSHermès Bélusca-Maïto return NULL;
23806f19c83bSHermès Bélusca-Maïto }
23816f19c83bSHermès Bélusca-Maïto
23826f19c83bSHermès Bélusca-Maïto PPARTENTRY
GetPrevPartition(IN PPARTLIST List,IN PPARTENTRY CurrentPart OPTIONAL)23836f19c83bSHermès Bélusca-Maïto GetPrevPartition(
238484f3e2dfSHermès Bélusca-Maïto IN PPARTLIST List,
238584f3e2dfSHermès Bélusca-Maïto IN PPARTENTRY CurrentPart OPTIONAL)
23866f19c83bSHermès Bélusca-Maïto {
23876f19c83bSHermès Bélusca-Maïto PLIST_ENTRY DiskListEntry;
23886f19c83bSHermès Bélusca-Maïto PLIST_ENTRY PartListEntry;
238984f3e2dfSHermès Bélusca-Maïto PDISKENTRY CurrentDisk;
23906f19c83bSHermès Bélusca-Maïto
23916f19c83bSHermès Bélusca-Maïto /* Fail if no disks are available */
23926f19c83bSHermès Bélusca-Maïto if (IsListEmpty(&List->DiskListHead))
23936f19c83bSHermès Bélusca-Maïto return NULL;
23946f19c83bSHermès Bélusca-Maïto
239584f3e2dfSHermès Bélusca-Maïto /* Check for the previous usable entry on the current partition's disk */
239684f3e2dfSHermès Bélusca-Maïto if (CurrentPart != NULL)
23976f19c83bSHermès Bélusca-Maïto {
239884f3e2dfSHermès Bélusca-Maïto CurrentDisk = CurrentPart->DiskEntry;
239984f3e2dfSHermès Bélusca-Maïto
240084f3e2dfSHermès Bélusca-Maïto if (CurrentPart->LogicalPartition)
24016f19c83bSHermès Bélusca-Maïto {
24026f19c83bSHermès Bélusca-Maïto /* Logical partition */
240384f3e2dfSHermès Bélusca-Maïto
240484f3e2dfSHermès Bélusca-Maïto PartListEntry = CurrentPart->ListEntry.Blink;
240584f3e2dfSHermès Bélusca-Maïto if (PartListEntry != &CurrentDisk->LogicalPartListHead)
24066f19c83bSHermès Bélusca-Maïto {
24076f19c83bSHermès Bélusca-Maïto /* Previous logical partition */
240884f3e2dfSHermès Bélusca-Maïto CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
24096f19c83bSHermès Bélusca-Maïto }
24106f19c83bSHermès Bélusca-Maïto else
24116f19c83bSHermès Bélusca-Maïto {
24126f19c83bSHermès Bélusca-Maïto /* Extended partition */
241384f3e2dfSHermès Bélusca-Maïto CurrentPart = CurrentDisk->ExtendedPartition;
24146f19c83bSHermès Bélusca-Maïto }
241584f3e2dfSHermès Bélusca-Maïto return CurrentPart;
24166f19c83bSHermès Bélusca-Maïto }
24176f19c83bSHermès Bélusca-Maïto else
24186f19c83bSHermès Bélusca-Maïto {
24196f19c83bSHermès Bélusca-Maïto /* Primary or extended partition */
24206f19c83bSHermès Bélusca-Maïto
242184f3e2dfSHermès Bélusca-Maïto PartListEntry = CurrentPart->ListEntry.Blink;
242284f3e2dfSHermès Bélusca-Maïto if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
24236f19c83bSHermès Bélusca-Maïto {
242484f3e2dfSHermès Bélusca-Maïto CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
24256f19c83bSHermès Bélusca-Maïto
242684f3e2dfSHermès Bélusca-Maïto if (CurrentPart->IsPartitioned &&
242784f3e2dfSHermès Bélusca-Maïto IsContainerPartition(CurrentPart->PartitionType))
24286f19c83bSHermès Bélusca-Maïto {
242984f3e2dfSHermès Bélusca-Maïto PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
243084f3e2dfSHermès Bélusca-Maïto CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
24316f19c83bSHermès Bélusca-Maïto }
24326f19c83bSHermès Bélusca-Maïto
243384f3e2dfSHermès Bélusca-Maïto return CurrentPart;
24346f19c83bSHermès Bélusca-Maïto }
24356f19c83bSHermès Bélusca-Maïto }
24366f19c83bSHermès Bélusca-Maïto }
24376f19c83bSHermès Bélusca-Maïto
24386f19c83bSHermès Bélusca-Maïto /* Search for the last partition entry on the previous disk */
243984f3e2dfSHermès Bélusca-Maïto for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
244084f3e2dfSHermès Bélusca-Maïto : List->DiskListHead.Blink);
24418bed4adfSHermès Bélusca-Maïto DiskListEntry != &List->DiskListHead;
24428bed4adfSHermès Bélusca-Maïto DiskListEntry = DiskListEntry->Blink)
24436f19c83bSHermès Bélusca-Maïto {
244484f3e2dfSHermès Bélusca-Maïto CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
24456f19c83bSHermès Bélusca-Maïto
244684f3e2dfSHermès Bélusca-Maïto if (CurrentDisk->DiskStyle == PARTITION_STYLE_GPT)
2447a3168373SHermès Bélusca-Maïto {
2448a3168373SHermès Bélusca-Maïto DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2449a3168373SHermès Bélusca-Maïto continue;
2450a3168373SHermès Bélusca-Maïto }
2451a3168373SHermès Bélusca-Maïto
245284f3e2dfSHermès Bélusca-Maïto PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
245384f3e2dfSHermès Bélusca-Maïto if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
24546f19c83bSHermès Bélusca-Maïto {
245584f3e2dfSHermès Bélusca-Maïto CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
24566f19c83bSHermès Bélusca-Maïto
245784f3e2dfSHermès Bélusca-Maïto if (CurrentPart->IsPartitioned &&
245884f3e2dfSHermès Bélusca-Maïto IsContainerPartition(CurrentPart->PartitionType))
24596f19c83bSHermès Bélusca-Maïto {
246084f3e2dfSHermès Bélusca-Maïto PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
246184f3e2dfSHermès Bélusca-Maïto if (PartListEntry != &CurrentDisk->LogicalPartListHead)
24626f19c83bSHermès Bélusca-Maïto {
246384f3e2dfSHermès Bélusca-Maïto CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
246484f3e2dfSHermès Bélusca-Maïto return CurrentPart;
24656f19c83bSHermès Bélusca-Maïto }
24666f19c83bSHermès Bélusca-Maïto }
24676f19c83bSHermès Bélusca-Maïto else
24686f19c83bSHermès Bélusca-Maïto {
246984f3e2dfSHermès Bélusca-Maïto return CurrentPart;
24706f19c83bSHermès Bélusca-Maïto }
24716f19c83bSHermès Bélusca-Maïto }
24726f19c83bSHermès Bélusca-Maïto }
24736f19c83bSHermès Bélusca-Maïto
24746f19c83bSHermès Bélusca-Maïto return NULL;
24756f19c83bSHermès Bélusca-Maïto }
24766f19c83bSHermès Bélusca-Maïto
2477b7ad4a22SHermès Bélusca-Maïto static inline
24786f19c83bSHermès Bélusca-Maïto BOOLEAN
IsEmptyLayoutEntry(_In_ PPARTITION_INFORMATION PartitionInfo)24796f19c83bSHermès Bélusca-Maïto IsEmptyLayoutEntry(
2480b7ad4a22SHermès Bélusca-Maïto _In_ PPARTITION_INFORMATION PartitionInfo)
24816f19c83bSHermès Bélusca-Maïto {
2482b7ad4a22SHermès Bélusca-Maïto return (PartitionInfo->StartingOffset.QuadPart == 0 &&
2483b7ad4a22SHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart == 0);
24846f19c83bSHermès Bélusca-Maïto }
24856f19c83bSHermès Bélusca-Maïto
2486b7ad4a22SHermès Bélusca-Maïto static inline
24876f19c83bSHermès Bélusca-Maïto BOOLEAN
IsSamePrimaryLayoutEntry(_In_ PPARTITION_INFORMATION PartitionInfo,_In_ PPARTENTRY PartEntry)24886f19c83bSHermès Bélusca-Maïto IsSamePrimaryLayoutEntry(
2489b7ad4a22SHermès Bélusca-Maïto _In_ PPARTITION_INFORMATION PartitionInfo,
2490b7ad4a22SHermès Bélusca-Maïto _In_ PPARTENTRY PartEntry)
24916f19c83bSHermès Bélusca-Maïto {
2492b7ad4a22SHermès Bélusca-Maïto return ((PartitionInfo->StartingOffset.QuadPart == GetPartEntryOffsetInBytes(PartEntry)) &&
2493b7ad4a22SHermès Bélusca-Maïto (PartitionInfo->PartitionLength.QuadPart == GetPartEntrySizeInBytes(PartEntry)));
24946f19c83bSHermès Bélusca-Maïto // PartitionInfo->PartitionType == PartEntry->PartitionType
24956f19c83bSHermès Bélusca-Maïto }
24966f19c83bSHermès Bélusca-Maïto
24977639cb75SHermès Bélusca-Maïto
24987639cb75SHermès Bélusca-Maïto /**
24997639cb75SHermès Bélusca-Maïto * @brief
25007639cb75SHermès Bélusca-Maïto * Counts the number of partitioned disk regions in a given partition list.
25017639cb75SHermès Bélusca-Maïto **/
25026f19c83bSHermès Bélusca-Maïto static
25036f19c83bSHermès Bélusca-Maïto ULONG
GetPartitionCount(_In_ PLIST_ENTRY PartListHead)25047639cb75SHermès Bélusca-Maïto GetPartitionCount(
25057639cb75SHermès Bélusca-Maïto _In_ PLIST_ENTRY PartListHead)
25066f19c83bSHermès Bélusca-Maïto {
25076f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry;
25086f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry;
25096f19c83bSHermès Bélusca-Maïto ULONG Count = 0;
25106f19c83bSHermès Bélusca-Maïto
25117639cb75SHermès Bélusca-Maïto for (Entry = PartListHead->Flink;
25127639cb75SHermès Bélusca-Maïto Entry != PartListHead;
25138bed4adfSHermès Bélusca-Maïto Entry = Entry->Flink)
25146f19c83bSHermès Bélusca-Maïto {
25156f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
25166f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned)
25177639cb75SHermès Bélusca-Maïto ++Count;
25186f19c83bSHermès Bélusca-Maïto }
25196f19c83bSHermès Bélusca-Maïto
25206f19c83bSHermès Bélusca-Maïto return Count;
25216f19c83bSHermès Bélusca-Maïto }
25226f19c83bSHermès Bélusca-Maïto
25237639cb75SHermès Bélusca-Maïto #define GetPrimaryPartitionCount(DiskEntry) \
25247639cb75SHermès Bélusca-Maïto GetPartitionCount(&(DiskEntry)->PrimaryPartListHead)
25256f19c83bSHermès Bélusca-Maïto
25267639cb75SHermès Bélusca-Maïto #define GetLogicalPartitionCount(DiskEntry) \
25277639cb75SHermès Bélusca-Maïto (((DiskEntry)->DiskStyle == PARTITION_STYLE_MBR) \
25287639cb75SHermès Bélusca-Maïto ? GetPartitionCount(&(DiskEntry)->LogicalPartListHead) : 0)
2529a3168373SHermès Bélusca-Maïto
25306f19c83bSHermès Bélusca-Maïto
25316f19c83bSHermès Bélusca-Maïto static
25326f19c83bSHermès Bélusca-Maïto BOOLEAN
ReAllocateLayoutBuffer(IN PDISKENTRY DiskEntry)25336f19c83bSHermès Bélusca-Maïto ReAllocateLayoutBuffer(
25346f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry)
25356f19c83bSHermès Bélusca-Maïto {
25366f19c83bSHermès Bélusca-Maïto PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
25376f19c83bSHermès Bélusca-Maïto ULONG NewPartitionCount;
25386f19c83bSHermès Bélusca-Maïto ULONG CurrentPartitionCount = 0;
25396f19c83bSHermès Bélusca-Maïto ULONG LayoutBufferSize;
25406f19c83bSHermès Bélusca-Maïto ULONG i;
25416f19c83bSHermès Bélusca-Maïto
25426f19c83bSHermès Bélusca-Maïto DPRINT1("ReAllocateLayoutBuffer()\n");
25436f19c83bSHermès Bélusca-Maïto
25446f19c83bSHermès Bélusca-Maïto NewPartitionCount = 4 + GetLogicalPartitionCount(DiskEntry) * 4;
25456f19c83bSHermès Bélusca-Maïto
25466f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer)
25476f19c83bSHermès Bélusca-Maïto CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
25486f19c83bSHermès Bélusca-Maïto
25497df92966SHermès Bélusca-Maïto DPRINT1("CurrentPartitionCount: %lu ; NewPartitionCount: %lu\n",
25506f19c83bSHermès Bélusca-Maïto CurrentPartitionCount, NewPartitionCount);
25516f19c83bSHermès Bélusca-Maïto
25526f19c83bSHermès Bélusca-Maïto if (CurrentPartitionCount == NewPartitionCount)
25536f19c83bSHermès Bélusca-Maïto return TRUE;
25546f19c83bSHermès Bélusca-Maïto
25556f19c83bSHermès Bélusca-Maïto LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
25566f19c83bSHermès Bélusca-Maïto ((NewPartitionCount - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
25576f19c83bSHermès Bélusca-Maïto NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
25586f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY,
25596f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer,
25606f19c83bSHermès Bélusca-Maïto LayoutBufferSize);
25616f19c83bSHermès Bélusca-Maïto if (NewLayoutBuffer == NULL)
25626f19c83bSHermès Bélusca-Maïto {
25636f19c83bSHermès Bélusca-Maïto DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize);
25646f19c83bSHermès Bélusca-Maïto return FALSE;
25656f19c83bSHermès Bélusca-Maïto }
25666f19c83bSHermès Bélusca-Maïto
25677df92966SHermès Bélusca-Maïto NewLayoutBuffer->PartitionCount = NewPartitionCount;
25687df92966SHermès Bélusca-Maïto
25696f19c83bSHermès Bélusca-Maïto /* If the layout buffer grows, make sure the new (empty) entries are written to the disk */
25706f19c83bSHermès Bélusca-Maïto if (NewPartitionCount > CurrentPartitionCount)
25716f19c83bSHermès Bélusca-Maïto {
25726f19c83bSHermès Bélusca-Maïto for (i = CurrentPartitionCount; i < NewPartitionCount; i++)
25737df92966SHermès Bélusca-Maïto {
25746f19c83bSHermès Bélusca-Maïto NewLayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
25756f19c83bSHermès Bélusca-Maïto }
25767df92966SHermès Bélusca-Maïto }
25776f19c83bSHermès Bélusca-Maïto
25786f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer = NewLayoutBuffer;
25796f19c83bSHermès Bélusca-Maïto
25806f19c83bSHermès Bélusca-Maïto return TRUE;
25816f19c83bSHermès Bélusca-Maïto }
25826f19c83bSHermès Bélusca-Maïto
25836f19c83bSHermès Bélusca-Maïto static
25846f19c83bSHermès Bélusca-Maïto VOID
UpdateDiskLayout(IN PDISKENTRY DiskEntry)25856f19c83bSHermès Bélusca-Maïto UpdateDiskLayout(
25866f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry)
25876f19c83bSHermès Bélusca-Maïto {
25886f19c83bSHermès Bélusca-Maïto PPARTITION_INFORMATION PartitionInfo;
258999f0937fSHermès Bélusca-Maïto PPARTITION_INFORMATION LinkInfo;
25906f19c83bSHermès Bélusca-Maïto PLIST_ENTRY ListEntry;
25916f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry;
25926f19c83bSHermès Bélusca-Maïto LARGE_INTEGER HiddenSectors64;
25936f19c83bSHermès Bélusca-Maïto ULONG Index;
25946f19c83bSHermès Bélusca-Maïto ULONG PartitionNumber = 1;
25956f19c83bSHermès Bélusca-Maïto
25966f19c83bSHermès Bélusca-Maïto DPRINT1("UpdateDiskLayout()\n");
25976f19c83bSHermès Bélusca-Maïto
2598a3168373SHermès Bélusca-Maïto if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2599a3168373SHermès Bélusca-Maïto {
260029cc1843SHermès Bélusca-Maïto DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2601a3168373SHermès Bélusca-Maïto return;
2602a3168373SHermès Bélusca-Maïto }
2603a3168373SHermès Bélusca-Maïto
26046f19c83bSHermès Bélusca-Maïto /* Resize the layout buffer if necessary */
26056f15802aSHermès Bélusca-Maïto if (!ReAllocateLayoutBuffer(DiskEntry))
26066f19c83bSHermès Bélusca-Maïto {
26076f19c83bSHermès Bélusca-Maïto DPRINT("ReAllocateLayoutBuffer() failed.\n");
26086f19c83bSHermès Bélusca-Maïto return;
26096f19c83bSHermès Bélusca-Maïto }
26106f19c83bSHermès Bélusca-Maïto
26116f19c83bSHermès Bélusca-Maïto /* Update the primary partition table */
26126f19c83bSHermès Bélusca-Maïto Index = 0;
26138bed4adfSHermès Bélusca-Maïto for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
26148bed4adfSHermès Bélusca-Maïto ListEntry != &DiskEntry->PrimaryPartListHead;
26158bed4adfSHermès Bélusca-Maïto ListEntry = ListEntry->Flink)
26166f19c83bSHermès Bélusca-Maïto {
26176f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
26186f19c83bSHermès Bélusca-Maïto
26197df92966SHermès Bélusca-Maïto if (PartEntry->IsPartitioned)
26206f19c83bSHermès Bélusca-Maïto {
262129cc1843SHermès Bélusca-Maïto ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
262229cc1843SHermès Bélusca-Maïto
26236f19c83bSHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
26247df92966SHermès Bélusca-Maïto PartEntry->PartitionIndex = Index;
26257df92966SHermès Bélusca-Maïto
26266f15802aSHermès Bélusca-Maïto /* Reset the current partition number only for not-yet written partitions */
26277df92966SHermès Bélusca-Maïto if (PartEntry->New)
26287df92966SHermès Bélusca-Maïto PartEntry->PartitionNumber = 0;
26297df92966SHermès Bélusca-Maïto
263029cc1843SHermès Bélusca-Maïto PartEntry->OnDiskPartitionNumber = (!IsContainerPartition(PartEntry->PartitionType) ? PartitionNumber : 0);
26316f19c83bSHermès Bélusca-Maïto
2632b7ad4a22SHermès Bélusca-Maïto if (!IsSamePrimaryLayoutEntry(PartitionInfo, PartEntry))
26336f19c83bSHermès Bélusca-Maïto {
26346f19c83bSHermès Bélusca-Maïto DPRINT1("Updating primary partition entry %lu\n", Index);
26356f19c83bSHermès Bélusca-Maïto
2636b7ad4a22SHermès Bélusca-Maïto PartitionInfo->StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry);
2637b7ad4a22SHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart = GetPartEntrySizeInBytes(PartEntry);
26386f19c83bSHermès Bélusca-Maïto PartitionInfo->HiddenSectors = PartEntry->StartSector.LowPart;
26397df92966SHermès Bélusca-Maïto PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
26406f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionType = PartEntry->PartitionType;
26416f19c83bSHermès Bélusca-Maïto PartitionInfo->BootIndicator = PartEntry->BootIndicator;
26427df92966SHermès Bélusca-Maïto PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
26436f19c83bSHermès Bélusca-Maïto PartitionInfo->RewritePartition = TRUE;
26446f19c83bSHermès Bélusca-Maïto }
26456f19c83bSHermès Bélusca-Maïto
26466f19c83bSHermès Bélusca-Maïto if (!IsContainerPartition(PartEntry->PartitionType))
26476f19c83bSHermès Bélusca-Maïto PartitionNumber++;
26486f19c83bSHermès Bélusca-Maïto
26496f19c83bSHermès Bélusca-Maïto Index++;
26506f19c83bSHermès Bélusca-Maïto }
26516f19c83bSHermès Bélusca-Maïto }
26526f19c83bSHermès Bélusca-Maïto
265370fa2e2eSHermès Bélusca-Maïto ASSERT(Index <= 4);
265470fa2e2eSHermès Bélusca-Maïto
26556f19c83bSHermès Bélusca-Maïto /* Update the logical partition table */
265699f0937fSHermès Bélusca-Maïto LinkInfo = NULL;
26576f19c83bSHermès Bélusca-Maïto Index = 4;
26588bed4adfSHermès Bélusca-Maïto for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
26598bed4adfSHermès Bélusca-Maïto ListEntry != &DiskEntry->LogicalPartListHead;
26608bed4adfSHermès Bélusca-Maïto ListEntry = ListEntry->Flink)
26616f19c83bSHermès Bélusca-Maïto {
26626f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
26636f19c83bSHermès Bélusca-Maïto
26646f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned)
26656f19c83bSHermès Bélusca-Maïto {
266629cc1843SHermès Bélusca-Maïto ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
266729cc1843SHermès Bélusca-Maïto
26686f19c83bSHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
26697df92966SHermès Bélusca-Maïto PartEntry->PartitionIndex = Index;
26706f19c83bSHermès Bélusca-Maïto
26716f15802aSHermès Bélusca-Maïto /* Reset the current partition number only for not-yet written partitions */
26727df92966SHermès Bélusca-Maïto if (PartEntry->New)
26737df92966SHermès Bélusca-Maïto PartEntry->PartitionNumber = 0;
26747df92966SHermès Bélusca-Maïto
26757df92966SHermès Bélusca-Maïto PartEntry->OnDiskPartitionNumber = PartitionNumber;
26767df92966SHermès Bélusca-Maïto
267729cc1843SHermès Bélusca-Maïto DPRINT1("Updating logical partition entry %lu\n", Index);
267829cc1843SHermès Bélusca-Maïto
2679b7ad4a22SHermès Bélusca-Maïto PartitionInfo->StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry);
2680b7ad4a22SHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart = GetPartEntrySizeInBytes(PartEntry);
26816f19c83bSHermès Bélusca-Maïto PartitionInfo->HiddenSectors = DiskEntry->SectorAlignment;
26827df92966SHermès Bélusca-Maïto PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
26836f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionType = PartEntry->PartitionType;
26846f19c83bSHermès Bélusca-Maïto PartitionInfo->BootIndicator = FALSE;
26857df92966SHermès Bélusca-Maïto PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
26866f19c83bSHermès Bélusca-Maïto PartitionInfo->RewritePartition = TRUE;
26876f19c83bSHermès Bélusca-Maïto
26886f19c83bSHermès Bélusca-Maïto /* Fill the link entry of the previous partition entry */
268999f0937fSHermès Bélusca-Maïto if (LinkInfo)
26906f19c83bSHermès Bélusca-Maïto {
26916f19c83bSHermès Bélusca-Maïto LinkInfo->StartingOffset.QuadPart = (PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
26926f19c83bSHermès Bélusca-Maïto LinkInfo->PartitionLength.QuadPart = (PartEntry->StartSector.QuadPart + DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
26936f19c83bSHermès Bélusca-Maïto HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart;
26946f19c83bSHermès Bélusca-Maïto LinkInfo->HiddenSectors = HiddenSectors64.LowPart;
26956f19c83bSHermès Bélusca-Maïto LinkInfo->PartitionNumber = 0;
269699f0937fSHermès Bélusca-Maïto
269799f0937fSHermès Bélusca-Maïto /* Extended partition links only use type 0x05, as observed
269899f0937fSHermès Bélusca-Maïto * on Windows NT. Alternatively they could inherit the type
269999f0937fSHermès Bélusca-Maïto * of the main extended container. */
270099f0937fSHermès Bélusca-Maïto LinkInfo->PartitionType = PARTITION_EXTENDED; // DiskEntry->ExtendedPartition->PartitionType;
270199f0937fSHermès Bélusca-Maïto
27026f19c83bSHermès Bélusca-Maïto LinkInfo->BootIndicator = FALSE;
27036f19c83bSHermès Bélusca-Maïto LinkInfo->RecognizedPartition = FALSE;
27046f19c83bSHermès Bélusca-Maïto LinkInfo->RewritePartition = TRUE;
27056f19c83bSHermès Bélusca-Maïto }
27066f19c83bSHermès Bélusca-Maïto
27076f19c83bSHermès Bélusca-Maïto /* Save a pointer to the link entry of the current partition entry */
27086f19c83bSHermès Bélusca-Maïto LinkInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index + 1];
27096f19c83bSHermès Bélusca-Maïto
27106f19c83bSHermès Bélusca-Maïto PartitionNumber++;
27116f19c83bSHermès Bélusca-Maïto Index += 4;
27126f19c83bSHermès Bélusca-Maïto }
27136f19c83bSHermès Bélusca-Maïto }
27146f19c83bSHermès Bélusca-Maïto
27156f19c83bSHermès Bélusca-Maïto /* Wipe unused primary partition entries */
27166f19c83bSHermès Bélusca-Maïto for (Index = GetPrimaryPartitionCount(DiskEntry); Index < 4; Index++)
27176f19c83bSHermès Bélusca-Maïto {
27186f19c83bSHermès Bélusca-Maïto DPRINT1("Primary partition entry %lu\n", Index);
27196f19c83bSHermès Bélusca-Maïto
27206f19c83bSHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
27216f19c83bSHermès Bélusca-Maïto
27226f19c83bSHermès Bélusca-Maïto if (!IsEmptyLayoutEntry(PartitionInfo))
27236f19c83bSHermès Bélusca-Maïto {
27246f19c83bSHermès Bélusca-Maïto DPRINT1("Wiping primary partition entry %lu\n", Index);
27256f19c83bSHermès Bélusca-Maïto
27266f19c83bSHermès Bélusca-Maïto PartitionInfo->StartingOffset.QuadPart = 0;
27276f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart = 0;
27286f19c83bSHermès Bélusca-Maïto PartitionInfo->HiddenSectors = 0;
27296f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionNumber = 0;
27306f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
27316f19c83bSHermès Bélusca-Maïto PartitionInfo->BootIndicator = FALSE;
27326f19c83bSHermès Bélusca-Maïto PartitionInfo->RecognizedPartition = FALSE;
27336f19c83bSHermès Bélusca-Maïto PartitionInfo->RewritePartition = TRUE;
27346f19c83bSHermès Bélusca-Maïto }
27356f19c83bSHermès Bélusca-Maïto }
27366f19c83bSHermès Bélusca-Maïto
27376f19c83bSHermès Bélusca-Maïto /* Wipe unused logical partition entries */
27386f19c83bSHermès Bélusca-Maïto for (Index = 4; Index < DiskEntry->LayoutBuffer->PartitionCount; Index++)
27396f19c83bSHermès Bélusca-Maïto {
27406f19c83bSHermès Bélusca-Maïto if (Index % 4 >= 2)
27416f19c83bSHermès Bélusca-Maïto {
27426f19c83bSHermès Bélusca-Maïto DPRINT1("Logical partition entry %lu\n", Index);
27436f19c83bSHermès Bélusca-Maïto
27446f19c83bSHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
27456f19c83bSHermès Bélusca-Maïto
27466f19c83bSHermès Bélusca-Maïto if (!IsEmptyLayoutEntry(PartitionInfo))
27476f19c83bSHermès Bélusca-Maïto {
27486f19c83bSHermès Bélusca-Maïto DPRINT1("Wiping partition entry %lu\n", Index);
27496f19c83bSHermès Bélusca-Maïto
27506f19c83bSHermès Bélusca-Maïto PartitionInfo->StartingOffset.QuadPart = 0;
27516f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart = 0;
27526f19c83bSHermès Bélusca-Maïto PartitionInfo->HiddenSectors = 0;
27536f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionNumber = 0;
27546f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
27556f19c83bSHermès Bélusca-Maïto PartitionInfo->BootIndicator = FALSE;
27566f19c83bSHermès Bélusca-Maïto PartitionInfo->RecognizedPartition = FALSE;
27576f19c83bSHermès Bélusca-Maïto PartitionInfo->RewritePartition = TRUE;
27586f19c83bSHermès Bélusca-Maïto }
27596f19c83bSHermès Bélusca-Maïto }
27606f19c83bSHermès Bélusca-Maïto }
27616f19c83bSHermès Bélusca-Maïto
2762a59cecd8SHermès Bélusca-Maïto // HACK: See the FIXMEs in WritePartitions(): (Re)set the PartitionStyle to MBR.
2763a59cecd8SHermès Bélusca-Maïto DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
2764a59cecd8SHermès Bélusca-Maïto
27657df92966SHermès Bélusca-Maïto DiskEntry->Dirty = TRUE;
27667df92966SHermès Bélusca-Maïto
27676f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
27686f19c83bSHermès Bélusca-Maïto DumpPartitionTable(DiskEntry);
27696f19c83bSHermès Bélusca-Maïto #endif
27706f19c83bSHermès Bélusca-Maïto }
27716f19c83bSHermès Bélusca-Maïto
27727639cb75SHermès Bélusca-Maïto /**
27737639cb75SHermès Bélusca-Maïto * @brief
27747639cb75SHermès Bélusca-Maïto * Retrieves, if any, the unpartitioned disk region that is adjacent
27757639cb75SHermès Bélusca-Maïto * (next or previous) to the specified partition.
27767639cb75SHermès Bélusca-Maïto *
27777639cb75SHermès Bélusca-Maïto * @param[in] PartEntry
27787639cb75SHermès Bélusca-Maïto * Partition from where to find the adjacent unpartitioned region.
27797639cb75SHermès Bélusca-Maïto *
27807639cb75SHermès Bélusca-Maïto * @param[in] Direction
27817639cb75SHermès Bélusca-Maïto * TRUE or FALSE to search the next or previous region, respectively.
27827639cb75SHermès Bélusca-Maïto *
27837639cb75SHermès Bélusca-Maïto * @return The adjacent unpartitioned region, if it exists, or NULL.
27847639cb75SHermès Bélusca-Maïto **/
27856f19c83bSHermès Bélusca-Maïto PPARTENTRY
GetAdjUnpartitionedEntry(_In_ PPARTENTRY PartEntry,_In_ BOOLEAN Direction)27867639cb75SHermès Bélusca-Maïto GetAdjUnpartitionedEntry(
27877639cb75SHermès Bélusca-Maïto _In_ PPARTENTRY PartEntry,
27887639cb75SHermès Bélusca-Maïto _In_ BOOLEAN Direction)
27896f19c83bSHermès Bélusca-Maïto {
279084f3e2dfSHermès Bélusca-Maïto PDISKENTRY DiskEntry = PartEntry->DiskEntry;
27917639cb75SHermès Bélusca-Maïto PLIST_ENTRY ListHead, AdjEntry;
27926f19c83bSHermès Bélusca-Maïto
27937639cb75SHermès Bélusca-Maïto /* In case of MBR disks only, check the logical partitions if necessary */
27947639cb75SHermès Bélusca-Maïto if ((DiskEntry->DiskStyle == PARTITION_STYLE_MBR) &&
27957639cb75SHermès Bélusca-Maïto PartEntry->LogicalPartition)
2796a3168373SHermès Bélusca-Maïto {
27976f19c83bSHermès Bélusca-Maïto ListHead = &DiskEntry->LogicalPartListHead;
27987639cb75SHermès Bélusca-Maïto }
27996f19c83bSHermès Bélusca-Maïto else
28007639cb75SHermès Bélusca-Maïto {
28016f19c83bSHermès Bélusca-Maïto ListHead = &DiskEntry->PrimaryPartListHead;
280229cc1843SHermès Bélusca-Maïto }
28036f19c83bSHermès Bélusca-Maïto
28047639cb75SHermès Bélusca-Maïto if (Direction)
28057639cb75SHermès Bélusca-Maïto AdjEntry = PartEntry->ListEntry.Flink; // Next region.
28066f19c83bSHermès Bélusca-Maïto else
28077639cb75SHermès Bélusca-Maïto AdjEntry = PartEntry->ListEntry.Blink; // Previous region.
28086f19c83bSHermès Bélusca-Maïto
28097639cb75SHermès Bélusca-Maïto if (AdjEntry != ListHead)
28106f19c83bSHermès Bélusca-Maïto {
28117639cb75SHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(AdjEntry, PARTENTRY, ListEntry);
28127639cb75SHermès Bélusca-Maïto if (!PartEntry->IsPartitioned)
281329cc1843SHermès Bélusca-Maïto {
28147639cb75SHermès Bélusca-Maïto ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
28157639cb75SHermès Bélusca-Maïto return PartEntry;
28166f19c83bSHermès Bélusca-Maïto }
281729cc1843SHermès Bélusca-Maïto }
28186f19c83bSHermès Bélusca-Maïto return NULL;
28196f19c83bSHermès Bélusca-Maïto }
28206f19c83bSHermès Bélusca-Maïto
2821ebcf3cf3SHermès Bélusca-Maïto ERROR_NUMBER
PartitionCreationChecks(_In_ PPARTENTRY PartEntry)2822ebcf3cf3SHermès Bélusca-Maïto PartitionCreationChecks(
2823ebcf3cf3SHermès Bélusca-Maïto _In_ PPARTENTRY PartEntry)
2824ebcf3cf3SHermès Bélusca-Maïto {
2825ebcf3cf3SHermès Bélusca-Maïto PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2826ebcf3cf3SHermès Bélusca-Maïto
2827ebcf3cf3SHermès Bélusca-Maïto if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2828ebcf3cf3SHermès Bélusca-Maïto {
2829ebcf3cf3SHermès Bélusca-Maïto DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2830ebcf3cf3SHermès Bélusca-Maïto return ERROR_WARN_PARTITION;
2831ebcf3cf3SHermès Bélusca-Maïto }
2832ebcf3cf3SHermès Bélusca-Maïto
2833ebcf3cf3SHermès Bélusca-Maïto /* Fail if the partition is already in use */
2834ebcf3cf3SHermès Bélusca-Maïto if (PartEntry->IsPartitioned)
2835ebcf3cf3SHermès Bélusca-Maïto return ERROR_NEW_PARTITION;
2836ebcf3cf3SHermès Bélusca-Maïto
2837ebcf3cf3SHermès Bélusca-Maïto /*
2838ebcf3cf3SHermès Bélusca-Maïto * For primary partitions
2839ebcf3cf3SHermès Bélusca-Maïto */
2840ebcf3cf3SHermès Bélusca-Maïto if (!PartEntry->LogicalPartition)
2841ebcf3cf3SHermès Bélusca-Maïto {
2842ebcf3cf3SHermès Bélusca-Maïto /* Only one primary partition is allowed on super-floppy */
2843ebcf3cf3SHermès Bélusca-Maïto if (IsSuperFloppy(DiskEntry))
2844ebcf3cf3SHermès Bélusca-Maïto return ERROR_PARTITION_TABLE_FULL;
2845ebcf3cf3SHermès Bélusca-Maïto
2846ebcf3cf3SHermès Bélusca-Maïto /* Fail if there are already 4 primary partitions in the list */
2847ebcf3cf3SHermès Bélusca-Maïto if (GetPrimaryPartitionCount(DiskEntry) >= 4)
2848ebcf3cf3SHermès Bélusca-Maïto return ERROR_PARTITION_TABLE_FULL;
2849ebcf3cf3SHermès Bélusca-Maïto }
2850ebcf3cf3SHermès Bélusca-Maïto /*
2851ebcf3cf3SHermès Bélusca-Maïto * For logical partitions
2852ebcf3cf3SHermès Bélusca-Maïto */
2853ebcf3cf3SHermès Bélusca-Maïto else
2854ebcf3cf3SHermès Bélusca-Maïto {
2855ebcf3cf3SHermès Bélusca-Maïto // TODO: Check that we are inside an extended partition!!
2856ebcf3cf3SHermès Bélusca-Maïto // Then the following check will be useless.
2857ebcf3cf3SHermès Bélusca-Maïto
2858ebcf3cf3SHermès Bélusca-Maïto /* Only one (primary) partition is allowed on super-floppy */
2859ebcf3cf3SHermès Bélusca-Maïto if (IsSuperFloppy(DiskEntry))
2860ebcf3cf3SHermès Bélusca-Maïto return ERROR_PARTITION_TABLE_FULL;
2861ebcf3cf3SHermès Bélusca-Maïto }
2862ebcf3cf3SHermès Bélusca-Maïto
2863ebcf3cf3SHermès Bélusca-Maïto return ERROR_SUCCESS;
2864ebcf3cf3SHermès Bélusca-Maïto }
2865ebcf3cf3SHermès Bélusca-Maïto
2866ebcf3cf3SHermès Bélusca-Maïto ERROR_NUMBER
ExtendedPartitionCreationChecks(_In_ PPARTENTRY PartEntry)2867ebcf3cf3SHermès Bélusca-Maïto ExtendedPartitionCreationChecks(
2868ebcf3cf3SHermès Bélusca-Maïto _In_ PPARTENTRY PartEntry)
2869ebcf3cf3SHermès Bélusca-Maïto {
2870ebcf3cf3SHermès Bélusca-Maïto PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2871ebcf3cf3SHermès Bélusca-Maïto
2872ebcf3cf3SHermès Bélusca-Maïto if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2873ebcf3cf3SHermès Bélusca-Maïto {
2874ebcf3cf3SHermès Bélusca-Maïto DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2875ebcf3cf3SHermès Bélusca-Maïto return ERROR_WARN_PARTITION;
2876ebcf3cf3SHermès Bélusca-Maïto }
2877ebcf3cf3SHermès Bélusca-Maïto
2878ebcf3cf3SHermès Bélusca-Maïto /* Fail if the partition is already in use */
2879ebcf3cf3SHermès Bélusca-Maïto if (PartEntry->IsPartitioned)
2880ebcf3cf3SHermès Bélusca-Maïto return ERROR_NEW_PARTITION;
2881ebcf3cf3SHermès Bélusca-Maïto
288299f0937fSHermès Bélusca-Maïto /* Cannot create an extended partition within logical partition space */
288399f0937fSHermès Bélusca-Maïto if (PartEntry->LogicalPartition)
288499f0937fSHermès Bélusca-Maïto return ERROR_ONLY_ONE_EXTENDED;
288599f0937fSHermès Bélusca-Maïto
2886ebcf3cf3SHermès Bélusca-Maïto /* Only one primary partition is allowed on super-floppy */
2887ebcf3cf3SHermès Bélusca-Maïto if (IsSuperFloppy(DiskEntry))
2888ebcf3cf3SHermès Bélusca-Maïto return ERROR_PARTITION_TABLE_FULL;
2889ebcf3cf3SHermès Bélusca-Maïto
2890ebcf3cf3SHermès Bélusca-Maïto /* Fail if there are already 4 primary partitions in the list */
2891ebcf3cf3SHermès Bélusca-Maïto if (GetPrimaryPartitionCount(DiskEntry) >= 4)
2892ebcf3cf3SHermès Bélusca-Maïto return ERROR_PARTITION_TABLE_FULL;
2893ebcf3cf3SHermès Bélusca-Maïto
2894ebcf3cf3SHermès Bélusca-Maïto /* Fail if there is another extended partition in the list */
289599f0937fSHermès Bélusca-Maïto if (DiskEntry->ExtendedPartition)
2896ebcf3cf3SHermès Bélusca-Maïto return ERROR_ONLY_ONE_EXTENDED;
2897ebcf3cf3SHermès Bélusca-Maïto
2898ebcf3cf3SHermès Bélusca-Maïto return ERROR_SUCCESS;
2899ebcf3cf3SHermès Bélusca-Maïto }
2900ebcf3cf3SHermès Bélusca-Maïto
290199f0937fSHermès Bélusca-Maïto // TODO: Improve upon the PartitionInfo parameter later
290299f0937fSHermès Bélusca-Maïto // (see VDS::CREATE_PARTITION_PARAMETERS and PPARTITION_INFORMATION_MBR/GPT for example)
290399f0937fSHermès Bélusca-Maïto // So far we only use it as the optional type of the partition to create.
290470fa2e2eSHermès Bélusca-Maïto BOOLEAN
CreatePartition(_In_ PPARTLIST List,_Inout_ PPARTENTRY PartEntry,_In_opt_ ULONGLONG SizeBytes,_In_opt_ ULONG_PTR PartitionInfo)2905ebcf3cf3SHermès Bélusca-Maïto CreatePartition(
2906ebcf3cf3SHermès Bélusca-Maïto _In_ PPARTLIST List,
2907ebcf3cf3SHermès Bélusca-Maïto _Inout_ PPARTENTRY PartEntry,
290899f0937fSHermès Bélusca-Maïto _In_opt_ ULONGLONG SizeBytes,
290999f0937fSHermès Bélusca-Maïto _In_opt_ ULONG_PTR PartitionInfo)
29106f19c83bSHermès Bélusca-Maïto {
291170fa2e2eSHermès Bélusca-Maïto ERROR_NUMBER Error;
291299f0937fSHermès Bélusca-Maïto BOOLEAN isContainer = IsContainerPartition((UCHAR)PartitionInfo);
29136f15802aSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
291499f0937fSHermès Bélusca-Maïto PCSTR mainType = "Primary";
29156f19c83bSHermès Bélusca-Maïto
291699f0937fSHermès Bélusca-Maïto if (isContainer)
291799f0937fSHermès Bélusca-Maïto mainType = "Extended";
291899f0937fSHermès Bélusca-Maïto else if (PartEntry && PartEntry->LogicalPartition)
291999f0937fSHermès Bélusca-Maïto mainType = "Logical";
29206f19c83bSHermès Bélusca-Maïto
292199f0937fSHermès Bélusca-Maïto DPRINT1("CreatePartition(%s, %I64u bytes)\n", mainType, SizeBytes);
292299f0937fSHermès Bélusca-Maïto
292399f0937fSHermès Bélusca-Maïto if (!List || !PartEntry ||
292499f0937fSHermès Bélusca-Maïto !PartEntry->DiskEntry || PartEntry->IsPartitioned)
29256f19c83bSHermès Bélusca-Maïto {
292670fa2e2eSHermès Bélusca-Maïto return FALSE;
292770fa2e2eSHermès Bélusca-Maïto }
292870fa2e2eSHermès Bélusca-Maïto
292999f0937fSHermès Bélusca-Maïto if (isContainer)
293099f0937fSHermès Bélusca-Maïto Error = ExtendedPartitionCreationChecks(PartEntry);
293199f0937fSHermès Bélusca-Maïto else
2932ebcf3cf3SHermès Bélusca-Maïto Error = PartitionCreationChecks(PartEntry);
293370fa2e2eSHermès Bélusca-Maïto if (Error != NOT_AN_ERROR)
293470fa2e2eSHermès Bélusca-Maïto {
293599f0937fSHermès Bélusca-Maïto DPRINT1("PartitionCreationChecks(%s) failed with error %lu\n", mainType, Error);
293670fa2e2eSHermès Bélusca-Maïto return FALSE;
29376f19c83bSHermès Bélusca-Maïto }
29386f19c83bSHermès Bélusca-Maïto
2939626c654aSHermès Bélusca-Maïto /* Initialize the partition entry, inserting a new blank region if needed */
294099f0937fSHermès Bélusca-Maïto if (!InitializePartitionEntry(PartEntry, SizeBytes, PartitionInfo))
294170fa2e2eSHermès Bélusca-Maïto return FALSE;
29426f19c83bSHermès Bélusca-Maïto
29436f15802aSHermès Bélusca-Maïto DiskEntry = PartEntry->DiskEntry;
29446f15802aSHermès Bélusca-Maïto UpdateDiskLayout(DiskEntry);
29456f15802aSHermès Bélusca-Maïto
29466f15802aSHermès Bélusca-Maïto ASSERT(!PartEntry->Volume);
29476f15802aSHermès Bélusca-Maïto if (!isContainer)
29486f19c83bSHermès Bélusca-Maïto {
29496f15802aSHermès Bélusca-Maïto /* We create a primary/logical partition: initialize a new basic
29506f15802aSHermès Bélusca-Maïto * volume entry. When the partition will actually be written onto
29516f15802aSHermès Bélusca-Maïto * the disk, the PARTMGR will notify the MOUNTMGR that a volume
29526f15802aSHermès Bélusca-Maïto * associated with this partition has to be created. */
29536f15802aSHermès Bélusca-Maïto PartEntry->Volume = InitVolume(DiskEntry->PartList, PartEntry);
29546f15802aSHermès Bélusca-Maïto ASSERT(PartEntry->Volume);
295599f0937fSHermès Bélusca-Maïto }
29566f19c83bSHermès Bélusca-Maïto
29576f19c83bSHermès Bélusca-Maïto AssignDriveLetters(List);
295870fa2e2eSHermès Bélusca-Maïto
295970fa2e2eSHermès Bélusca-Maïto return TRUE;
29606f19c83bSHermès Bélusca-Maïto }
29616f19c83bSHermès Bélusca-Maïto
29626f15802aSHermès Bélusca-Maïto static NTSTATUS
DismountPartition(_In_ PPARTLIST List,_In_ PPARTENTRY PartEntry)29636f15802aSHermès Bélusca-Maïto DismountPartition(
29646f15802aSHermès Bélusca-Maïto _In_ PPARTLIST List,
29656f15802aSHermès Bélusca-Maïto _In_ PPARTENTRY PartEntry)
29669504a38fSHermès Bélusca-Maïto {
29679504a38fSHermès Bélusca-Maïto NTSTATUS Status;
29686f15802aSHermès Bélusca-Maïto PVOLENTRY Volume = PartEntry->Volume;
29696f15802aSHermès Bélusca-Maïto
29706f15802aSHermès Bélusca-Maïto ASSERT(PartEntry->DiskEntry->PartList == List);
29719504a38fSHermès Bélusca-Maïto
297229cc1843SHermès Bélusca-Maïto /* Check whether the partition is valid and was mounted by the system */
29739504a38fSHermès Bélusca-Maïto if (!PartEntry->IsPartitioned ||
29749504a38fSHermès Bélusca-Maïto IsContainerPartition(PartEntry->PartitionType) ||
29759504a38fSHermès Bélusca-Maïto !IsRecognizedPartition(PartEntry->PartitionType) ||
29766f15802aSHermès Bélusca-Maïto !Volume || Volume->FormatState == UnknownFormat ||
2977626c654aSHermès Bélusca-Maïto // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
2978626c654aSHermès Bélusca-Maïto // it has been usually mounted with RawFS and thus needs to be dismounted.
29799504a38fSHermès Bélusca-Maïto PartEntry->PartitionNumber == 0)
29809504a38fSHermès Bélusca-Maïto {
29819504a38fSHermès Bélusca-Maïto /* The partition is not mounted, so just return success */
29829504a38fSHermès Bélusca-Maïto return STATUS_SUCCESS;
29839504a38fSHermès Bélusca-Maïto }
29849504a38fSHermès Bélusca-Maïto
298529cc1843SHermès Bélusca-Maïto ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
29866f15802aSHermès Bélusca-Maïto ASSERT(Volume->PartEntry == PartEntry);
298729cc1843SHermès Bélusca-Maïto
29886f15802aSHermès Bélusca-Maïto /* Unlink the basic volume from the volumes list and dismount it */
29896f15802aSHermès Bélusca-Maïto PartEntry->Volume = NULL;
29906f15802aSHermès Bélusca-Maïto Volume->PartEntry = NULL;
29916f15802aSHermès Bélusca-Maïto RemoveEntryList(&Volume->ListEntry);
29926f15802aSHermès Bélusca-Maïto Status = DismountVolume(&Volume->Info, TRUE);
29936f15802aSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Volume);
29949504a38fSHermès Bélusca-Maïto return Status;
29959504a38fSHermès Bélusca-Maïto }
29969504a38fSHermès Bélusca-Maïto
299784f3e2dfSHermès Bélusca-Maïto BOOLEAN
DeletePartition(_In_ PPARTLIST List,_In_ PPARTENTRY PartEntry,_Out_opt_ PPARTENTRY * FreeRegion)299829cc1843SHermès Bélusca-Maïto DeletePartition(
299999f0937fSHermès Bélusca-Maïto _In_ PPARTLIST List,
300099f0937fSHermès Bélusca-Maïto _In_ PPARTENTRY PartEntry,
300199f0937fSHermès Bélusca-Maïto _Out_opt_ PPARTENTRY* FreeRegion)
30026f19c83bSHermès Bélusca-Maïto {
30036f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
30046f19c83bSHermès Bélusca-Maïto PPARTENTRY PrevPartEntry;
30056f19c83bSHermès Bélusca-Maïto PPARTENTRY NextPartEntry;
30066f19c83bSHermès Bélusca-Maïto PPARTENTRY LogicalPartEntry;
30076f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry;
30086f19c83bSHermès Bélusca-Maïto
300999f0937fSHermès Bélusca-Maïto if (!List || !PartEntry ||
301099f0937fSHermès Bélusca-Maïto !PartEntry->DiskEntry || !PartEntry->IsPartitioned)
30116f19c83bSHermès Bélusca-Maïto {
301284f3e2dfSHermès Bélusca-Maïto return FALSE;
30136f19c83bSHermès Bélusca-Maïto }
30146f19c83bSHermès Bélusca-Maïto
30156f15802aSHermès Bélusca-Maïto ASSERT(PartEntry->DiskEntry->PartList == List);
301629cc1843SHermès Bélusca-Maïto ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
301729cc1843SHermès Bélusca-Maïto
301859acff79SHermès Bélusca-Maïto /* Clear the system partition if it is being deleted */
301929cc1843SHermès Bélusca-Maïto if (List->SystemPartition == PartEntry)
30206f19c83bSHermès Bélusca-Maïto {
302129cc1843SHermès Bélusca-Maïto ASSERT(List->SystemPartition);
30226f19c83bSHermès Bélusca-Maïto List->SystemPartition = NULL;
30236f19c83bSHermès Bélusca-Maïto }
30246f19c83bSHermès Bélusca-Maïto
302529cc1843SHermès Bélusca-Maïto DiskEntry = PartEntry->DiskEntry;
30266f19c83bSHermès Bélusca-Maïto
30279504a38fSHermès Bélusca-Maïto /* Check which type of partition (primary/logical or extended) is being deleted */
30286f19c83bSHermès Bélusca-Maïto if (DiskEntry->ExtendedPartition == PartEntry)
30296f19c83bSHermès Bélusca-Maïto {
30309504a38fSHermès Bélusca-Maïto /* An extended partition is being deleted: delete all logical partition entries */
30316f19c83bSHermès Bélusca-Maïto while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
30326f19c83bSHermès Bélusca-Maïto {
30336f19c83bSHermès Bélusca-Maïto Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
30346f19c83bSHermès Bélusca-Maïto LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
30356f19c83bSHermès Bélusca-Maïto
30366f15802aSHermès Bélusca-Maïto /* Dismount the logical partition and delete it */
30376f15802aSHermès Bélusca-Maïto DismountPartition(List, LogicalPartEntry);
30386f15802aSHermès Bélusca-Maïto DestroyRegion(LogicalPartEntry);
30396f19c83bSHermès Bélusca-Maïto }
30406f19c83bSHermès Bélusca-Maïto
30416f19c83bSHermès Bélusca-Maïto DiskEntry->ExtendedPartition = NULL;
30426f19c83bSHermès Bélusca-Maïto }
30439504a38fSHermès Bélusca-Maïto else
30449504a38fSHermès Bélusca-Maïto {
30456f15802aSHermès Bélusca-Maïto /* A primary/logical partition is being deleted: dismount it */
30466f15802aSHermès Bélusca-Maïto DismountPartition(List, PartEntry);
30479504a38fSHermès Bélusca-Maïto }
30486f19c83bSHermès Bélusca-Maïto
304984f3e2dfSHermès Bélusca-Maïto /* Adjust the unpartitioned disk space entries */
30506f19c83bSHermès Bélusca-Maïto
30516f19c83bSHermès Bélusca-Maïto /* Get pointer to previous and next unpartitioned entries */
30527639cb75SHermès Bélusca-Maïto PrevPartEntry = GetAdjUnpartitionedEntry(PartEntry, FALSE);
30537639cb75SHermès Bélusca-Maïto NextPartEntry = GetAdjUnpartitionedEntry(PartEntry, TRUE);
30546f19c83bSHermès Bélusca-Maïto
30556f19c83bSHermès Bélusca-Maïto if (PrevPartEntry != NULL && NextPartEntry != NULL)
30566f19c83bSHermès Bélusca-Maïto {
305784f3e2dfSHermès Bélusca-Maïto /* Merge the previous, current and next unpartitioned entries */
30586f19c83bSHermès Bélusca-Maïto
305984f3e2dfSHermès Bélusca-Maïto /* Adjust the previous entry length */
30606f19c83bSHermès Bélusca-Maïto PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
30616f19c83bSHermès Bélusca-Maïto
306284f3e2dfSHermès Bélusca-Maïto /* Remove the current and next entries */
30636f19c83bSHermès Bélusca-Maïto RemoveEntryList(&PartEntry->ListEntry);
30646f15802aSHermès Bélusca-Maïto DestroyRegion(PartEntry);
30656f19c83bSHermès Bélusca-Maïto RemoveEntryList(&NextPartEntry->ListEntry);
30666f15802aSHermès Bélusca-Maïto DestroyRegion(NextPartEntry);
30676f19c83bSHermès Bélusca-Maïto
306884f3e2dfSHermès Bélusca-Maïto /* Optionally return the freed region */
306984f3e2dfSHermès Bélusca-Maïto if (FreeRegion)
307084f3e2dfSHermès Bélusca-Maïto *FreeRegion = PrevPartEntry;
307129cc1843SHermès Bélusca-Maïto }
30726f19c83bSHermès Bélusca-Maïto else if (PrevPartEntry != NULL && NextPartEntry == NULL)
30736f19c83bSHermès Bélusca-Maïto {
307484f3e2dfSHermès Bélusca-Maïto /* Merge the current and the previous unpartitioned entries */
30756f19c83bSHermès Bélusca-Maïto
307684f3e2dfSHermès Bélusca-Maïto /* Adjust the previous entry length */
30776f19c83bSHermès Bélusca-Maïto PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
30786f19c83bSHermès Bélusca-Maïto
30796f19c83bSHermès Bélusca-Maïto /* Remove the current entry */
30806f19c83bSHermès Bélusca-Maïto RemoveEntryList(&PartEntry->ListEntry);
30816f15802aSHermès Bélusca-Maïto DestroyRegion(PartEntry);
30826f19c83bSHermès Bélusca-Maïto
308384f3e2dfSHermès Bélusca-Maïto /* Optionally return the freed region */
308484f3e2dfSHermès Bélusca-Maïto if (FreeRegion)
308584f3e2dfSHermès Bélusca-Maïto *FreeRegion = PrevPartEntry;
308629cc1843SHermès Bélusca-Maïto }
30876f19c83bSHermès Bélusca-Maïto else if (PrevPartEntry == NULL && NextPartEntry != NULL)
30886f19c83bSHermès Bélusca-Maïto {
308984f3e2dfSHermès Bélusca-Maïto /* Merge the current and the next unpartitioned entries */
30906f19c83bSHermès Bélusca-Maïto
309184f3e2dfSHermès Bélusca-Maïto /* Adjust the next entry offset and length */
30926f19c83bSHermès Bélusca-Maïto NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
30936f19c83bSHermès Bélusca-Maïto NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
30946f19c83bSHermès Bélusca-Maïto
30956f19c83bSHermès Bélusca-Maïto /* Remove the current entry */
30966f19c83bSHermès Bélusca-Maïto RemoveEntryList(&PartEntry->ListEntry);
30976f15802aSHermès Bélusca-Maïto DestroyRegion(PartEntry);
30986f19c83bSHermès Bélusca-Maïto
309984f3e2dfSHermès Bélusca-Maïto /* Optionally return the freed region */
310084f3e2dfSHermès Bélusca-Maïto if (FreeRegion)
310184f3e2dfSHermès Bélusca-Maïto *FreeRegion = NextPartEntry;
310229cc1843SHermès Bélusca-Maïto }
31036f19c83bSHermès Bélusca-Maïto else
31046f19c83bSHermès Bélusca-Maïto {
310584f3e2dfSHermès Bélusca-Maïto /* Nothing to merge but change the current entry */
31066f15802aSHermès Bélusca-Maïto PartEntry->New = FALSE;
31076f19c83bSHermès Bélusca-Maïto PartEntry->IsPartitioned = FALSE;
31086f15802aSHermès Bélusca-Maïto PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
3109626c654aSHermès Bélusca-Maïto PartEntry->OnDiskPartitionNumber = 0;
3110626c654aSHermès Bélusca-Maïto PartEntry->PartitionNumber = 0;
3111626c654aSHermès Bélusca-Maïto // PartEntry->PartitionIndex = 0;
3112626c654aSHermès Bélusca-Maïto PartEntry->BootIndicator = FALSE;
31136f15802aSHermès Bélusca-Maïto PartEntry->DeviceName[0] = UNICODE_NULL;
31146f15802aSHermès Bélusca-Maïto
31156f15802aSHermès Bélusca-Maïto if (PartEntry->Volume)
31166f15802aSHermès Bélusca-Maïto {
31176f15802aSHermès Bélusca-Maïto RemoveEntryList(&PartEntry->Volume->ListEntry);
31186f15802aSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, PartEntry->Volume);
31196f15802aSHermès Bélusca-Maïto }
31206f15802aSHermès Bélusca-Maïto PartEntry->Volume = NULL;
312184f3e2dfSHermès Bélusca-Maïto
312284f3e2dfSHermès Bélusca-Maïto /* Optionally return the freed region */
312384f3e2dfSHermès Bélusca-Maïto if (FreeRegion)
312484f3e2dfSHermès Bélusca-Maïto *FreeRegion = PartEntry;
31256f19c83bSHermès Bélusca-Maïto }
31266f19c83bSHermès Bélusca-Maïto
31276f19c83bSHermès Bélusca-Maïto UpdateDiskLayout(DiskEntry);
31286f19c83bSHermès Bélusca-Maïto AssignDriveLetters(List);
31296f19c83bSHermès Bélusca-Maïto
313084f3e2dfSHermès Bélusca-Maïto return TRUE;
313129cc1843SHermès Bélusca-Maïto }
313229cc1843SHermès Bélusca-Maïto
3133c1fbc2d6SHermès Bélusca-Maïto static
3134c1fbc2d6SHermès Bélusca-Maïto BOOLEAN
IsSupportedActivePartition(IN PPARTENTRY PartEntry)3135c1fbc2d6SHermès Bélusca-Maïto IsSupportedActivePartition(
3136c1fbc2d6SHermès Bélusca-Maïto IN PPARTENTRY PartEntry)
3137c1fbc2d6SHermès Bélusca-Maïto {
31386f15802aSHermès Bélusca-Maïto PVOLENTRY Volume;
31396f15802aSHermès Bélusca-Maïto
3140c1fbc2d6SHermès Bélusca-Maïto /* Check the type and the file system of this partition */
3141c1fbc2d6SHermès Bélusca-Maïto
3142c1fbc2d6SHermès Bélusca-Maïto /*
3143c1fbc2d6SHermès Bélusca-Maïto * We do not support extended partition containers (on MBR disks) marked
3144c1fbc2d6SHermès Bélusca-Maïto * as active, and containing code inside their extended boot records.
3145c1fbc2d6SHermès Bélusca-Maïto */
3146c1fbc2d6SHermès Bélusca-Maïto if (IsContainerPartition(PartEntry->PartitionType))
3147c1fbc2d6SHermès Bélusca-Maïto {
3148c1fbc2d6SHermès Bélusca-Maïto DPRINT1("System partition %lu in disk %lu is an extended partition container?!\n",
3149c1fbc2d6SHermès Bélusca-Maïto PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
3150c1fbc2d6SHermès Bélusca-Maïto return FALSE;
3151c1fbc2d6SHermès Bélusca-Maïto }
3152c1fbc2d6SHermès Bélusca-Maïto
31536f15802aSHermès Bélusca-Maïto Volume = PartEntry->Volume;
31546f15802aSHermès Bélusca-Maïto if (!Volume)
31556f15802aSHermès Bélusca-Maïto {
31566f15802aSHermès Bélusca-Maïto /* Still no recognizable volume mounted: partition not supported */
31576f15802aSHermès Bélusca-Maïto return FALSE;
31586f15802aSHermès Bélusca-Maïto }
31596f15802aSHermès Bélusca-Maïto
3160c1fbc2d6SHermès Bélusca-Maïto /*
3161c1fbc2d6SHermès Bélusca-Maïto * ADDITIONAL CHECKS / BIG HACK:
3162c1fbc2d6SHermès Bélusca-Maïto *
3163c1fbc2d6SHermès Bélusca-Maïto * Retrieve its file system and check whether we have
3164c1fbc2d6SHermès Bélusca-Maïto * write support for it. If that is the case we are fine
3165c1fbc2d6SHermès Bélusca-Maïto * and we can use it directly. However if we don't have
3166c1fbc2d6SHermès Bélusca-Maïto * write support we will need to change the active system
3167c1fbc2d6SHermès Bélusca-Maïto * partition.
3168c1fbc2d6SHermès Bélusca-Maïto *
3169c1fbc2d6SHermès Bélusca-Maïto * NOTE that this is completely useless on architectures
3170c1fbc2d6SHermès Bélusca-Maïto * where a real system partition is required, as on these
3171c1fbc2d6SHermès Bélusca-Maïto * architectures the partition uses the FAT FS, for which
3172c1fbc2d6SHermès Bélusca-Maïto * we do have write support.
3173c1fbc2d6SHermès Bélusca-Maïto * NOTE also that for those architectures looking for a
3174c1fbc2d6SHermès Bélusca-Maïto * partition boot indicator is insufficient.
3175c1fbc2d6SHermès Bélusca-Maïto */
31766f15802aSHermès Bélusca-Maïto if (Volume->FormatState == Unformatted)
3177626c654aSHermès Bélusca-Maïto {
3178626c654aSHermès Bélusca-Maïto /* If this partition is mounted, it would use RawFS ("RAW") */
3179626c654aSHermès Bélusca-Maïto return TRUE;
3180626c654aSHermès Bélusca-Maïto }
31816f15802aSHermès Bélusca-Maïto else if (Volume->FormatState == Formatted)
3182c1fbc2d6SHermès Bélusca-Maïto {
31836f15802aSHermès Bélusca-Maïto ASSERT(*Volume->Info.FileSystem);
3184c1fbc2d6SHermès Bélusca-Maïto
3185c1fbc2d6SHermès Bélusca-Maïto /* NOTE: Please keep in sync with the RegisteredFileSystems list! */
3186e4930be4STimo Kreuzer if (_wcsicmp(Volume->Info.FileSystem, L"FAT") == 0 ||
3187e4930be4STimo Kreuzer _wcsicmp(Volume->Info.FileSystem, L"FAT32") == 0 ||
3188e4930be4STimo Kreuzer // _wcsicmp(Volume->Info.FileSystem, L"NTFS") == 0 ||
3189e4930be4STimo Kreuzer _wcsicmp(Volume->Info.FileSystem, L"BTRFS") == 0)
3190c1fbc2d6SHermès Bélusca-Maïto {
3191c1fbc2d6SHermès Bélusca-Maïto return TRUE;
3192c1fbc2d6SHermès Bélusca-Maïto }
3193c1fbc2d6SHermès Bélusca-Maïto else
3194c1fbc2d6SHermès Bélusca-Maïto {
3195c1fbc2d6SHermès Bélusca-Maïto // WARNING: We cannot write on this FS yet!
3196c1fbc2d6SHermès Bélusca-Maïto DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
31976f15802aSHermès Bélusca-Maïto Volume->Info.FileSystem);
3198c1fbc2d6SHermès Bélusca-Maïto return FALSE;
3199c1fbc2d6SHermès Bélusca-Maïto }
3200c1fbc2d6SHermès Bélusca-Maïto }
32016f15802aSHermès Bélusca-Maïto else // if (Volume->FormatState == UnknownFormat)
3202c1fbc2d6SHermès Bélusca-Maïto {
32036f15802aSHermès Bélusca-Maïto ASSERT(!*Volume->Info.FileSystem);
3204c1fbc2d6SHermès Bélusca-Maïto
3205c1fbc2d6SHermès Bélusca-Maïto DPRINT1("System partition %lu in disk %lu with no or unknown FS?!\n",
3206c1fbc2d6SHermès Bélusca-Maïto PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
3207c1fbc2d6SHermès Bélusca-Maïto return FALSE;
3208c1fbc2d6SHermès Bélusca-Maïto }
3209c1fbc2d6SHermès Bélusca-Maïto
3210c1fbc2d6SHermès Bélusca-Maïto // HACK: WARNING: We cannot write on this FS yet!
3211c1fbc2d6SHermès Bélusca-Maïto // See fsutil.c:InferFileSystem()
3212c1fbc2d6SHermès Bélusca-Maïto if (PartEntry->PartitionType == PARTITION_IFS)
3213c1fbc2d6SHermès Bélusca-Maïto {
3214c1fbc2d6SHermès Bélusca-Maïto DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
32156f15802aSHermès Bélusca-Maïto Volume->Info.FileSystem);
3216c1fbc2d6SHermès Bélusca-Maïto return FALSE;
3217c1fbc2d6SHermès Bélusca-Maïto }
3218c1fbc2d6SHermès Bélusca-Maïto
3219c1fbc2d6SHermès Bélusca-Maïto return TRUE;
3220c1fbc2d6SHermès Bélusca-Maïto }
3221c1fbc2d6SHermès Bélusca-Maïto
322259acff79SHermès Bélusca-Maïto PPARTENTRY
FindSupportedSystemPartition(IN PPARTLIST List,IN BOOLEAN ForceSelect,IN PDISKENTRY AlternativeDisk OPTIONAL,IN PPARTENTRY AlternativePart OPTIONAL)322359acff79SHermès Bélusca-Maïto FindSupportedSystemPartition(
322484f3e2dfSHermès Bélusca-Maïto IN PPARTLIST List,
322584f3e2dfSHermès Bélusca-Maïto IN BOOLEAN ForceSelect,
322659acff79SHermès Bélusca-Maïto IN PDISKENTRY AlternativeDisk OPTIONAL,
322759acff79SHermès Bélusca-Maïto IN PPARTENTRY AlternativePart OPTIONAL)
32286f19c83bSHermès Bélusca-Maïto {
32290d9ebb67SHermès Bélusca-Maïto PLIST_ENTRY ListEntry;
32306f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
32316f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry;
32320d9ebb67SHermès Bélusca-Maïto PPARTENTRY ActivePartition;
32330d9ebb67SHermès Bélusca-Maïto PPARTENTRY CandidatePartition = NULL;
32346f19c83bSHermès Bélusca-Maïto
32356f19c83bSHermès Bélusca-Maïto /* Check for empty disk list */
32366f19c83bSHermès Bélusca-Maïto if (IsListEmpty(&List->DiskListHead))
32376f19c83bSHermès Bélusca-Maïto {
32380d9ebb67SHermès Bélusca-Maïto /* No system partition! */
323959acff79SHermès Bélusca-Maïto ASSERT(List->SystemPartition == NULL);
324084f3e2dfSHermès Bélusca-Maïto goto NoSystemPartition;
32416f19c83bSHermès Bélusca-Maïto }
32426f19c83bSHermès Bélusca-Maïto
324359acff79SHermès Bélusca-Maïto /* Adjust the optional alternative disk if needed */
324459acff79SHermès Bélusca-Maïto if (!AlternativeDisk && AlternativePart)
324559acff79SHermès Bélusca-Maïto AlternativeDisk = AlternativePart->DiskEntry;
324659acff79SHermès Bélusca-Maïto
324759acff79SHermès Bélusca-Maïto /* Ensure that the alternative partition is on the alternative disk */
324859acff79SHermès Bélusca-Maïto if (AlternativePart)
324959acff79SHermès Bélusca-Maïto ASSERT(AlternativeDisk && (AlternativePart->DiskEntry == AlternativeDisk));
325059acff79SHermès Bélusca-Maïto
325159acff79SHermès Bélusca-Maïto /* Ensure that the alternative disk is in the list */
325259acff79SHermès Bélusca-Maïto if (AlternativeDisk)
325359acff79SHermès Bélusca-Maïto ASSERT(AlternativeDisk->PartList == List);
32546f19c83bSHermès Bélusca-Maïto
32550d9ebb67SHermès Bélusca-Maïto /* Start fresh */
325659acff79SHermès Bélusca-Maïto CandidatePartition = NULL;
32570d9ebb67SHermès Bélusca-Maïto
32580d9ebb67SHermès Bélusca-Maïto //
325959acff79SHermès Bélusca-Maïto // Step 1 : Check the system disk.
32600d9ebb67SHermès Bélusca-Maïto //
32610d9ebb67SHermès Bélusca-Maïto
32620d9ebb67SHermès Bélusca-Maïto /*
326359acff79SHermès Bélusca-Maïto * First, check whether the system disk, i.e. the one that will be booted
326459acff79SHermès Bélusca-Maïto * by default by the hardware, contains an active partition. If so this
326559acff79SHermès Bélusca-Maïto * should be our system partition.
32660d9ebb67SHermès Bélusca-Maïto */
326759acff79SHermès Bélusca-Maïto DiskEntry = GetSystemDisk(List);
3268c752e8c0SHermès Bélusca-Maïto if (!DiskEntry)
3269c752e8c0SHermès Bélusca-Maïto {
3270c752e8c0SHermès Bélusca-Maïto /* No system disk found, directly go check the alternative disk */
3271c752e8c0SHermès Bélusca-Maïto goto UseAlternativeDisk;
3272c752e8c0SHermès Bélusca-Maïto }
32730d9ebb67SHermès Bélusca-Maïto
327484f3e2dfSHermès Bélusca-Maïto if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
327584f3e2dfSHermès Bélusca-Maïto {
327659acff79SHermès Bélusca-Maïto DPRINT1("System disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
327759acff79SHermès Bélusca-Maïto goto UseAlternativeDisk;
327884f3e2dfSHermès Bélusca-Maïto }
32790d9ebb67SHermès Bélusca-Maïto
328059acff79SHermès Bélusca-Maïto /* If we have a system partition (in the system disk), validate it */
328159acff79SHermès Bélusca-Maïto ActivePartition = List->SystemPartition;
328259acff79SHermès Bélusca-Maïto if (ActivePartition && IsSupportedActivePartition(ActivePartition))
32830d9ebb67SHermès Bélusca-Maïto {
32840d9ebb67SHermès Bélusca-Maïto CandidatePartition = ActivePartition;
328559acff79SHermès Bélusca-Maïto
328659acff79SHermès Bélusca-Maïto DPRINT1("Use the current system partition %lu in disk %lu, drive letter %C\n",
328759acff79SHermès Bélusca-Maïto CandidatePartition->PartitionNumber,
328859acff79SHermès Bélusca-Maïto CandidatePartition->DiskEntry->DiskNumber,
32896f15802aSHermès Bélusca-Maïto !CandidatePartition->Volume->Info.DriveLetter ? L'-' : CandidatePartition->Volume->Info.DriveLetter);
329059acff79SHermès Bélusca-Maïto
329159acff79SHermès Bélusca-Maïto /* Return the candidate system partition */
329259acff79SHermès Bélusca-Maïto return CandidatePartition;
32930d9ebb67SHermès Bélusca-Maïto }
32940d9ebb67SHermès Bélusca-Maïto
329559acff79SHermès Bélusca-Maïto /* If the system disk is not the optional alternative disk, perform the minimal checks */
329659acff79SHermès Bélusca-Maïto if (DiskEntry != AlternativeDisk)
32970d9ebb67SHermès Bélusca-Maïto {
32980d9ebb67SHermès Bélusca-Maïto /*
329984f3e2dfSHermès Bélusca-Maïto * No active partition has been recognized. Enumerate all the (primary)
330059acff79SHermès Bélusca-Maïto * partitions in the system disk, excluding the possible current active
330184f3e2dfSHermès Bélusca-Maïto * partition, to find a new candidate.
33020d9ebb67SHermès Bélusca-Maïto */
33030d9ebb67SHermès Bélusca-Maïto for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
33040d9ebb67SHermès Bélusca-Maïto ListEntry != &DiskEntry->PrimaryPartListHead;
33050d9ebb67SHermès Bélusca-Maïto ListEntry = ListEntry->Flink)
33060d9ebb67SHermès Bélusca-Maïto {
33070d9ebb67SHermès Bélusca-Maïto /* Retrieve the partition */
33080d9ebb67SHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
33090d9ebb67SHermès Bélusca-Maïto
33100d9ebb67SHermès Bélusca-Maïto /* Skip the current active partition */
331159acff79SHermès Bélusca-Maïto if (PartEntry == ActivePartition)
33120d9ebb67SHermès Bélusca-Maïto continue;
33130d9ebb67SHermès Bélusca-Maïto
33140d9ebb67SHermès Bélusca-Maïto /* Check if the partition is partitioned and used */
33150d9ebb67SHermès Bélusca-Maïto if (PartEntry->IsPartitioned &&
33160d9ebb67SHermès Bélusca-Maïto !IsContainerPartition(PartEntry->PartitionType))
33170d9ebb67SHermès Bélusca-Maïto {
33180d9ebb67SHermès Bélusca-Maïto ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
33190d9ebb67SHermès Bélusca-Maïto
332059acff79SHermès Bélusca-Maïto /* If we get a candidate active partition in the disk, validate it */
33210d9ebb67SHermès Bélusca-Maïto if (IsSupportedActivePartition(PartEntry))
33220d9ebb67SHermès Bélusca-Maïto {
33230d9ebb67SHermès Bélusca-Maïto CandidatePartition = PartEntry;
332459acff79SHermès Bélusca-Maïto goto UseAlternativePartition;
33250d9ebb67SHermès Bélusca-Maïto }
33260d9ebb67SHermès Bélusca-Maïto }
33270d9ebb67SHermès Bélusca-Maïto
33280d9ebb67SHermès Bélusca-Maïto #if 0
33290d9ebb67SHermès Bélusca-Maïto /* Check if the partition is partitioned and used */
33300d9ebb67SHermès Bélusca-Maïto if (!PartEntry->IsPartitioned)
33310d9ebb67SHermès Bélusca-Maïto {
33320d9ebb67SHermès Bélusca-Maïto ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
33330d9ebb67SHermès Bélusca-Maïto
33340d9ebb67SHermès Bélusca-Maïto // TODO: Check for minimal size!!
33350d9ebb67SHermès Bélusca-Maïto CandidatePartition = PartEntry;
333659acff79SHermès Bélusca-Maïto goto UseAlternativePartition;
33370d9ebb67SHermès Bélusca-Maïto }
33380d9ebb67SHermès Bélusca-Maïto #endif
33390d9ebb67SHermès Bélusca-Maïto }
33400d9ebb67SHermès Bélusca-Maïto
33410d9ebb67SHermès Bélusca-Maïto /*
33420d9ebb67SHermès Bélusca-Maïto * Still nothing, look whether there is some free space that we can use
33430d9ebb67SHermès Bélusca-Maïto * for the new system partition. We must be sure that the total number
33440d9ebb67SHermès Bélusca-Maïto * of partition is less than the maximum allowed, and that the minimal
33450d9ebb67SHermès Bélusca-Maïto * size is fine.
33460d9ebb67SHermès Bélusca-Maïto */
33470d9ebb67SHermès Bélusca-Maïto //
33480d9ebb67SHermès Bélusca-Maïto // TODO: Fix the handling of system partition being created in unpartitioned space!!
33490d9ebb67SHermès Bélusca-Maïto // --> When to partition it? etc...
33500d9ebb67SHermès Bélusca-Maïto //
33510d9ebb67SHermès Bélusca-Maïto if (GetPrimaryPartitionCount(DiskEntry) < 4)
33520d9ebb67SHermès Bélusca-Maïto {
33530d9ebb67SHermès Bélusca-Maïto for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
33540d9ebb67SHermès Bélusca-Maïto ListEntry != &DiskEntry->PrimaryPartListHead;
33550d9ebb67SHermès Bélusca-Maïto ListEntry = ListEntry->Flink)
33560d9ebb67SHermès Bélusca-Maïto {
33570d9ebb67SHermès Bélusca-Maïto /* Retrieve the partition */
33580d9ebb67SHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
33590d9ebb67SHermès Bélusca-Maïto
33600d9ebb67SHermès Bélusca-Maïto /* Skip the current active partition */
336159acff79SHermès Bélusca-Maïto if (PartEntry == ActivePartition)
33620d9ebb67SHermès Bélusca-Maïto continue;
33630d9ebb67SHermès Bélusca-Maïto
33640d9ebb67SHermès Bélusca-Maïto /* Check for unpartitioned space */
33650d9ebb67SHermès Bélusca-Maïto if (!PartEntry->IsPartitioned)
33660d9ebb67SHermès Bélusca-Maïto {
33670d9ebb67SHermès Bélusca-Maïto ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
33680d9ebb67SHermès Bélusca-Maïto
33690d9ebb67SHermès Bélusca-Maïto // TODO: Check for minimal size!!
33700d9ebb67SHermès Bélusca-Maïto CandidatePartition = PartEntry;
337159acff79SHermès Bélusca-Maïto goto UseAlternativePartition;
33720d9ebb67SHermès Bélusca-Maïto }
33730d9ebb67SHermès Bélusca-Maïto }
33740d9ebb67SHermès Bélusca-Maïto }
33750d9ebb67SHermès Bélusca-Maïto }
33760d9ebb67SHermès Bélusca-Maïto
33770d9ebb67SHermès Bélusca-Maïto
33780d9ebb67SHermès Bélusca-Maïto //
337959acff79SHermès Bélusca-Maïto // Step 2 : No active partition found: Check the alternative disk if specified.
33800d9ebb67SHermès Bélusca-Maïto //
33810d9ebb67SHermès Bélusca-Maïto
338259acff79SHermès Bélusca-Maïto UseAlternativeDisk:
338359acff79SHermès Bélusca-Maïto if (!AlternativeDisk || (!ForceSelect && (DiskEntry != AlternativeDisk)))
338484f3e2dfSHermès Bélusca-Maïto goto NoSystemPartition;
33850d9ebb67SHermès Bélusca-Maïto
338659acff79SHermès Bélusca-Maïto if (AlternativeDisk->DiskStyle == PARTITION_STYLE_GPT)
33870d9ebb67SHermès Bélusca-Maïto {
338859acff79SHermès Bélusca-Maïto DPRINT1("Alternative disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
338984f3e2dfSHermès Bélusca-Maïto goto NoSystemPartition;
33900d9ebb67SHermès Bélusca-Maïto }
33910d9ebb67SHermès Bélusca-Maïto
339259acff79SHermès Bélusca-Maïto if (DiskEntry != AlternativeDisk)
339384f3e2dfSHermès Bélusca-Maïto {
339459acff79SHermès Bélusca-Maïto /* Choose the alternative disk */
339559acff79SHermès Bélusca-Maïto DiskEntry = AlternativeDisk;
33960d9ebb67SHermès Bélusca-Maïto
33970d9ebb67SHermès Bélusca-Maïto /* If we get a candidate active partition, validate it */
339859acff79SHermès Bélusca-Maïto ActivePartition = GetActiveDiskPartition(DiskEntry);
339959acff79SHermès Bélusca-Maïto if (ActivePartition && IsSupportedActivePartition(ActivePartition))
34000d9ebb67SHermès Bélusca-Maïto {
34010d9ebb67SHermès Bélusca-Maïto CandidatePartition = ActivePartition;
340259acff79SHermès Bélusca-Maïto goto UseAlternativePartition;
34030d9ebb67SHermès Bélusca-Maïto }
34040d9ebb67SHermès Bélusca-Maïto }
34050d9ebb67SHermès Bélusca-Maïto
340684f3e2dfSHermès Bélusca-Maïto /* We now may have an unsupported active partition, or none */
34070d9ebb67SHermès Bélusca-Maïto
34080d9ebb67SHermès Bélusca-Maïto /***
34090d9ebb67SHermès Bélusca-Maïto *** TODO: Improve the selection:
34100d9ebb67SHermès Bélusca-Maïto *** - If we want a really separate system partition from the partition where
34110d9ebb67SHermès Bélusca-Maïto *** we install, do something similar to what's done below in the code.
34120d9ebb67SHermès Bélusca-Maïto *** - Otherwise if we allow for the system partition to be also the partition
341359acff79SHermès Bélusca-Maïto *** where we install, just directly fall down to using AlternativePart.
34140d9ebb67SHermès Bélusca-Maïto ***/
34150d9ebb67SHermès Bélusca-Maïto
34166f19c83bSHermès Bélusca-Maïto /* Retrieve the first partition of the disk */
34176f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink,
34180d9ebb67SHermès Bélusca-Maïto PARTENTRY, ListEntry);
34196f19c83bSHermès Bélusca-Maïto ASSERT(DiskEntry == PartEntry->DiskEntry);
34200d9ebb67SHermès Bélusca-Maïto
34210d9ebb67SHermès Bélusca-Maïto CandidatePartition = PartEntry;
34226f19c83bSHermès Bélusca-Maïto
34236f19c83bSHermès Bélusca-Maïto //
34246f19c83bSHermès Bélusca-Maïto // See: https://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/partlist.c?r1=63355&r2=63354&pathrev=63355#l2318
34256f19c83bSHermès Bélusca-Maïto //
34266f19c83bSHermès Bélusca-Maïto
34276f19c83bSHermès Bélusca-Maïto /* Check if the disk is new and if so, use its first partition as the active system partition */
34286f19c83bSHermès Bélusca-Maïto if (DiskEntry->NewDisk)
34296f19c83bSHermès Bélusca-Maïto {
34300d9ebb67SHermès Bélusca-Maïto // !IsContainerPartition(PartEntry->PartitionType);
34310d9ebb67SHermès Bélusca-Maïto if (!CandidatePartition->IsPartitioned || !CandidatePartition->BootIndicator) /* CandidatePartition != ActivePartition */
34326f19c83bSHermès Bélusca-Maïto {
34330d9ebb67SHermès Bélusca-Maïto ASSERT(DiskEntry == CandidatePartition->DiskEntry);
34346f19c83bSHermès Bélusca-Maïto
3435f41750abSHermès Bélusca-Maïto DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %C\n",
343659acff79SHermès Bélusca-Maïto CandidatePartition->PartitionNumber,
343759acff79SHermès Bélusca-Maïto CandidatePartition->DiskEntry->DiskNumber,
34386f15802aSHermès Bélusca-Maïto !CandidatePartition->Volume->Info.DriveLetter ? L'-' : CandidatePartition->Volume->Info.DriveLetter);
34396f19c83bSHermès Bélusca-Maïto
344059acff79SHermès Bélusca-Maïto /* Return the candidate system partition */
344159acff79SHermès Bélusca-Maïto return CandidatePartition;
34426f19c83bSHermès Bélusca-Maïto }
34436f19c83bSHermès Bélusca-Maïto
34446f19c83bSHermès Bélusca-Maïto // FIXME: What to do??
34456f19c83bSHermès Bélusca-Maïto DPRINT1("NewDisk TRUE but first partition is used?\n");
34466f19c83bSHermès Bélusca-Maïto }
34476f19c83bSHermès Bélusca-Maïto
34486f19c83bSHermès Bélusca-Maïto /*
34496f19c83bSHermès Bélusca-Maïto * The disk is not new, check if any partition is initialized;
34506f19c83bSHermès Bélusca-Maïto * if not, the first one becomes the system partition.
34516f19c83bSHermès Bélusca-Maïto */
34528bed4adfSHermès Bélusca-Maïto for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
34538bed4adfSHermès Bélusca-Maïto ListEntry != &DiskEntry->PrimaryPartListHead;
34548bed4adfSHermès Bélusca-Maïto ListEntry = ListEntry->Flink)
34556f19c83bSHermès Bélusca-Maïto {
34568bed4adfSHermès Bélusca-Maïto /* Retrieve the partition */
34570d9ebb67SHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
34586f19c83bSHermès Bélusca-Maïto
34596f19c83bSHermès Bélusca-Maïto /* Check if the partition is partitioned and is used */
34600d9ebb67SHermès Bélusca-Maïto // !IsContainerPartition(PartEntry->PartitionType);
34610d9ebb67SHermès Bélusca-Maïto if (/* PartEntry->IsPartitioned && */
34620d9ebb67SHermès Bélusca-Maïto PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator)
34636f19c83bSHermès Bélusca-Maïto {
34646f19c83bSHermès Bélusca-Maïto break;
34656f19c83bSHermès Bélusca-Maïto }
34666f19c83bSHermès Bélusca-Maïto }
34676f19c83bSHermès Bélusca-Maïto if (ListEntry == &DiskEntry->PrimaryPartListHead)
34686f19c83bSHermès Bélusca-Maïto {
34696f19c83bSHermès Bélusca-Maïto /*
34706f19c83bSHermès Bélusca-Maïto * OK we haven't encountered any used and active partition,
34716f19c83bSHermès Bélusca-Maïto * so use the first one as the system partition.
34726f19c83bSHermès Bélusca-Maïto */
34730d9ebb67SHermès Bélusca-Maïto ASSERT(DiskEntry == CandidatePartition->DiskEntry);
34746f19c83bSHermès Bélusca-Maïto
3475f41750abSHermès Bélusca-Maïto DPRINT1("Use first active system partition %lu in disk %lu, drive letter %C\n",
347659acff79SHermès Bélusca-Maïto CandidatePartition->PartitionNumber,
347759acff79SHermès Bélusca-Maïto CandidatePartition->DiskEntry->DiskNumber,
34786f15802aSHermès Bélusca-Maïto !CandidatePartition->Volume->Info.DriveLetter ? L'-' : CandidatePartition->Volume->Info.DriveLetter);
34796f19c83bSHermès Bélusca-Maïto
348059acff79SHermès Bélusca-Maïto /* Return the candidate system partition */
348159acff79SHermès Bélusca-Maïto return CandidatePartition;
34826f19c83bSHermès Bélusca-Maïto }
34836f19c83bSHermès Bélusca-Maïto
34840d9ebb67SHermès Bélusca-Maïto /*
34850d9ebb67SHermès Bélusca-Maïto * The disk is not new, we did not find any actual active partition,
348659acff79SHermès Bélusca-Maïto * or the one we found was not supported, or any possible other candidate
348759acff79SHermès Bélusca-Maïto * is not supported. We then use the alternative partition if specified.
34880d9ebb67SHermès Bélusca-Maïto */
348959acff79SHermès Bélusca-Maïto if (AlternativePart)
349084f3e2dfSHermès Bélusca-Maïto {
349159acff79SHermès Bélusca-Maïto DPRINT1("No valid or supported system partition has been found, use the alternative partition!\n");
349259acff79SHermès Bélusca-Maïto CandidatePartition = AlternativePart;
349359acff79SHermès Bélusca-Maïto goto UseAlternativePartition;
349484f3e2dfSHermès Bélusca-Maïto }
349584f3e2dfSHermès Bélusca-Maïto else
349684f3e2dfSHermès Bélusca-Maïto {
349784f3e2dfSHermès Bélusca-Maïto NoSystemPartition:
349884f3e2dfSHermès Bélusca-Maïto DPRINT1("No valid or supported system partition has been found on this system!\n");
349959acff79SHermès Bélusca-Maïto return NULL;
350084f3e2dfSHermès Bélusca-Maïto }
35016f19c83bSHermès Bélusca-Maïto
350259acff79SHermès Bélusca-Maïto UseAlternativePartition:
35036f19c83bSHermès Bélusca-Maïto /*
350459acff79SHermès Bélusca-Maïto * We are here because we did not find any (active) candidate system
350559acff79SHermès Bélusca-Maïto * partition that we know how to support. What we are going to do is
350659acff79SHermès Bélusca-Maïto * to change the existing system partition and use the alternative partition
350759acff79SHermès Bélusca-Maïto * (e.g. on which we install ReactOS) as the new system partition.
350859acff79SHermès Bélusca-Maïto * Then we will need to add in FreeLdr's boot menu an entry for booting
35096f19c83bSHermès Bélusca-Maïto * from the original system partition.
35106f19c83bSHermès Bélusca-Maïto */
351184f3e2dfSHermès Bélusca-Maïto ASSERT(CandidatePartition);
35126f19c83bSHermès Bélusca-Maïto
3513f41750abSHermès Bélusca-Maïto DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %C\n",
351459acff79SHermès Bélusca-Maïto CandidatePartition->PartitionNumber,
351559acff79SHermès Bélusca-Maïto CandidatePartition->DiskEntry->DiskNumber,
35166f15802aSHermès Bélusca-Maïto !CandidatePartition->Volume->Info.DriveLetter ? L'-' : CandidatePartition->Volume->Info.DriveLetter);
35176f19c83bSHermès Bélusca-Maïto
351859acff79SHermès Bélusca-Maïto /* Return the candidate system partition */
351959acff79SHermès Bélusca-Maïto return CandidatePartition;
352059acff79SHermès Bélusca-Maïto }
352159acff79SHermès Bélusca-Maïto
352259acff79SHermès Bélusca-Maïto BOOLEAN
SetActivePartition(IN PPARTLIST List,IN PPARTENTRY PartEntry,IN PPARTENTRY OldActivePart OPTIONAL)352359acff79SHermès Bélusca-Maïto SetActivePartition(
352459acff79SHermès Bélusca-Maïto IN PPARTLIST List,
352559acff79SHermès Bélusca-Maïto IN PPARTENTRY PartEntry,
352659acff79SHermès Bélusca-Maïto IN PPARTENTRY OldActivePart OPTIONAL)
352759acff79SHermès Bélusca-Maïto {
352859acff79SHermès Bélusca-Maïto /* Check for empty disk list */
352959acff79SHermès Bélusca-Maïto if (IsListEmpty(&List->DiskListHead))
353059acff79SHermès Bélusca-Maïto return FALSE;
353159acff79SHermès Bélusca-Maïto
353259acff79SHermès Bélusca-Maïto /* Validate the partition entry */
353359acff79SHermès Bélusca-Maïto if (!PartEntry)
353459acff79SHermès Bélusca-Maïto return FALSE;
353559acff79SHermès Bélusca-Maïto
353659acff79SHermès Bélusca-Maïto /*
353759acff79SHermès Bélusca-Maïto * If the partition entry is already the system partition, or if it is
353859acff79SHermès Bélusca-Maïto * the same as the old active partition hint the user provided (and if
353959acff79SHermès Bélusca-Maïto * it is already active), just return success.
354059acff79SHermès Bélusca-Maïto */
354159acff79SHermès Bélusca-Maïto if ((PartEntry == List->SystemPartition) ||
354259acff79SHermès Bélusca-Maïto ((PartEntry == OldActivePart) && IsPartitionActive(OldActivePart)))
354359acff79SHermès Bélusca-Maïto {
354459acff79SHermès Bélusca-Maïto return TRUE;
354559acff79SHermès Bélusca-Maïto }
354659acff79SHermès Bélusca-Maïto
354759acff79SHermès Bélusca-Maïto ASSERT(PartEntry->DiskEntry);
354859acff79SHermès Bélusca-Maïto
354959acff79SHermès Bélusca-Maïto /* Ensure that the partition's disk is in the list */
355059acff79SHermès Bélusca-Maïto ASSERT(PartEntry->DiskEntry->PartList == List);
355159acff79SHermès Bélusca-Maïto
355259acff79SHermès Bélusca-Maïto /*
355359acff79SHermès Bélusca-Maïto * If the user provided an old active partition hint, verify that it is
35546f15802aSHermès Bélusca-Maïto * indeed active and belongs to the same disk where the new partition
355559acff79SHermès Bélusca-Maïto * belongs. Otherwise determine the current active partition on the disk
355659acff79SHermès Bélusca-Maïto * where the new partition belongs.
355759acff79SHermès Bélusca-Maïto */
355859acff79SHermès Bélusca-Maïto if (!(OldActivePart && IsPartitionActive(OldActivePart) && (OldActivePart->DiskEntry == PartEntry->DiskEntry)))
355959acff79SHermès Bélusca-Maïto {
356059acff79SHermès Bélusca-Maïto /* It's not, determine the current active partition for the disk */
356159acff79SHermès Bélusca-Maïto OldActivePart = GetActiveDiskPartition(PartEntry->DiskEntry);
356259acff79SHermès Bélusca-Maïto }
356359acff79SHermès Bélusca-Maïto
356459acff79SHermès Bélusca-Maïto /* Unset the old active partition if it exists */
356559acff79SHermès Bélusca-Maïto if (OldActivePart)
356659acff79SHermès Bélusca-Maïto {
356759acff79SHermès Bélusca-Maïto OldActivePart->BootIndicator = FALSE;
356859acff79SHermès Bélusca-Maïto OldActivePart->DiskEntry->LayoutBuffer->PartitionEntry[OldActivePart->PartitionIndex].BootIndicator = FALSE;
356959acff79SHermès Bélusca-Maïto OldActivePart->DiskEntry->LayoutBuffer->PartitionEntry[OldActivePart->PartitionIndex].RewritePartition = TRUE;
357059acff79SHermès Bélusca-Maïto OldActivePart->DiskEntry->Dirty = TRUE;
357159acff79SHermès Bélusca-Maïto }
357259acff79SHermès Bélusca-Maïto
357359acff79SHermès Bélusca-Maïto /* Modify the system partition if the new partition is on the system disk */
357459acff79SHermès Bélusca-Maïto if (PartEntry->DiskEntry == GetSystemDisk(List))
357559acff79SHermès Bélusca-Maïto List->SystemPartition = PartEntry;
357659acff79SHermès Bélusca-Maïto
357759acff79SHermès Bélusca-Maïto /* Set the new active partition */
357859acff79SHermès Bélusca-Maïto PartEntry->BootIndicator = TRUE;
357959acff79SHermès Bélusca-Maïto PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].BootIndicator = TRUE;
358059acff79SHermès Bélusca-Maïto PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
358159acff79SHermès Bélusca-Maïto PartEntry->DiskEntry->Dirty = TRUE;
358259acff79SHermès Bélusca-Maïto
358359acff79SHermès Bélusca-Maïto return TRUE;
35846f19c83bSHermès Bélusca-Maïto }
35856f19c83bSHermès Bélusca-Maïto
35866f19c83bSHermès Bélusca-Maïto NTSTATUS
WritePartitions(IN PDISKENTRY DiskEntry)35876f19c83bSHermès Bélusca-Maïto WritePartitions(
35886f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry)
35896f19c83bSHermès Bélusca-Maïto {
35906f19c83bSHermès Bélusca-Maïto NTSTATUS Status;
35917df92966SHermès Bélusca-Maïto OBJECT_ATTRIBUTES ObjectAttributes;
35927df92966SHermès Bélusca-Maïto UNICODE_STRING Name;
35937df92966SHermès Bélusca-Maïto HANDLE FileHandle;
35947df92966SHermès Bélusca-Maïto IO_STATUS_BLOCK Iosb;
35957df92966SHermès Bélusca-Maïto ULONG BufferSize;
35967df92966SHermès Bélusca-Maïto PPARTITION_INFORMATION PartitionInfo;
35977df92966SHermès Bélusca-Maïto ULONG PartitionCount;
35987df92966SHermès Bélusca-Maïto PLIST_ENTRY ListEntry;
35997df92966SHermès Bélusca-Maïto PPARTENTRY PartEntry;
36007df92966SHermès Bélusca-Maïto WCHAR DstPath[MAX_PATH];
36016f19c83bSHermès Bélusca-Maïto
36026f19c83bSHermès Bélusca-Maïto DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
36036f19c83bSHermès Bélusca-Maïto
360429cc1843SHermès Bélusca-Maïto /* If the disk is not dirty, there is nothing to do */
360529cc1843SHermès Bélusca-Maïto if (!DiskEntry->Dirty)
360629cc1843SHermès Bélusca-Maïto return STATUS_SUCCESS;
360729cc1843SHermès Bélusca-Maïto
36086f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(DstPath, ARRAYSIZE(DstPath),
36096f19c83bSHermès Bélusca-Maïto L"\\Device\\Harddisk%lu\\Partition0",
36106f19c83bSHermès Bélusca-Maïto DiskEntry->DiskNumber);
36116f19c83bSHermès Bélusca-Maïto RtlInitUnicodeString(&Name, DstPath);
3612765994c9SHermès Bélusca-Maïto
36136f19c83bSHermès Bélusca-Maïto InitializeObjectAttributes(&ObjectAttributes,
36146f19c83bSHermès Bélusca-Maïto &Name,
3615765994c9SHermès Bélusca-Maïto OBJ_CASE_INSENSITIVE,
36166f19c83bSHermès Bélusca-Maïto NULL,
36176f19c83bSHermès Bélusca-Maïto NULL);
36186f19c83bSHermès Bélusca-Maïto
36196f19c83bSHermès Bélusca-Maïto Status = NtOpenFile(&FileHandle,
36206f19c83bSHermès Bélusca-Maïto GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
36216f19c83bSHermès Bélusca-Maïto &ObjectAttributes,
36226f19c83bSHermès Bélusca-Maïto &Iosb,
36236f19c83bSHermès Bélusca-Maïto 0,
36246f19c83bSHermès Bélusca-Maïto FILE_SYNCHRONOUS_IO_NONALERT);
36256f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
36266f19c83bSHermès Bélusca-Maïto {
36276f19c83bSHermès Bélusca-Maïto DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
36286f19c83bSHermès Bélusca-Maïto return Status;
36296f19c83bSHermès Bélusca-Maïto }
36306f19c83bSHermès Bélusca-Maïto
36316f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
36326f19c83bSHermès Bélusca-Maïto DumpPartitionTable(DiskEntry);
36336f19c83bSHermès Bélusca-Maïto #endif
36346f19c83bSHermès Bélusca-Maïto
3635f41750abSHermès Bélusca-Maïto //
3636f41750abSHermès Bélusca-Maïto // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
3637f41750abSHermès Bélusca-Maïto // the disk in MBR or GPT format in case the disk was not initialized!!
3638f41750abSHermès Bélusca-Maïto // For this we must ask the user which format to use.
3639f41750abSHermès Bélusca-Maïto //
3640f41750abSHermès Bélusca-Maïto
36417df92966SHermès Bélusca-Maïto /* Save the original partition count to be restored later (see comment below) */
36427df92966SHermès Bélusca-Maïto PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
36437df92966SHermès Bélusca-Maïto
36446f15802aSHermès Bélusca-Maïto /* Set the new disk layout and retrieve its updated version with
36456f15802aSHermès Bélusca-Maïto * new partition numbers for the new partitions. The PARTMGR will
36466f15802aSHermès Bélusca-Maïto * automatically notify the MOUNTMGR of new or deleted volumes. */
36476f19c83bSHermès Bélusca-Maïto BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
36487df92966SHermès Bélusca-Maïto ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
36496f19c83bSHermès Bélusca-Maïto Status = NtDeviceIoControlFile(FileHandle,
36506f19c83bSHermès Bélusca-Maïto NULL,
36516f19c83bSHermès Bélusca-Maïto NULL,
36526f19c83bSHermès Bélusca-Maïto NULL,
36536f19c83bSHermès Bélusca-Maïto &Iosb,
36546f19c83bSHermès Bélusca-Maïto IOCTL_DISK_SET_DRIVE_LAYOUT,
36556f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer,
36566f19c83bSHermès Bélusca-Maïto BufferSize,
36577df92966SHermès Bélusca-Maïto DiskEntry->LayoutBuffer,
36587df92966SHermès Bélusca-Maïto BufferSize);
36597df92966SHermès Bélusca-Maïto NtClose(FileHandle);
36607df92966SHermès Bélusca-Maïto
36617df92966SHermès Bélusca-Maïto /*
36627df92966SHermès Bélusca-Maïto * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
36637df92966SHermès Bélusca-Maïto * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
36647df92966SHermès Bélusca-Maïto * where such a table is expected to enumerate up to 4 partitions:
36657df92966SHermès Bélusca-Maïto * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
36667df92966SHermès Bélusca-Maïto * Due to this we need to restore the original PartitionCount number.
36677df92966SHermès Bélusca-Maïto */
36687df92966SHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
36697df92966SHermès Bélusca-Maïto
36707df92966SHermès Bélusca-Maïto /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
36716f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
36726f19c83bSHermès Bélusca-Maïto {
36736f19c83bSHermès Bélusca-Maïto DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
36747df92966SHermès Bélusca-Maïto return Status;
36756f19c83bSHermès Bélusca-Maïto }
36766f19c83bSHermès Bélusca-Maïto
36777df92966SHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
36787df92966SHermès Bélusca-Maïto DumpPartitionTable(DiskEntry);
36797df92966SHermès Bélusca-Maïto #endif
36807df92966SHermès Bélusca-Maïto
36816f15802aSHermès Bélusca-Maïto /* Update the partition numbers and device names */
36827df92966SHermès Bélusca-Maïto
36837df92966SHermès Bélusca-Maïto /* Update the primary partition table */
36848bed4adfSHermès Bélusca-Maïto for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
36858bed4adfSHermès Bélusca-Maïto ListEntry != &DiskEntry->PrimaryPartListHead;
36868bed4adfSHermès Bélusca-Maïto ListEntry = ListEntry->Flink)
36877df92966SHermès Bélusca-Maïto {
36887df92966SHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
36896f15802aSHermès Bélusca-Maïto if (!PartEntry->IsPartitioned)
36906f15802aSHermès Bélusca-Maïto continue;
369129cc1843SHermès Bélusca-Maïto ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
36926f15802aSHermès Bélusca-Maïto
36936f15802aSHermès Bélusca-Maïto /*
36946f15802aSHermès Bélusca-Maïto * Initialize the partition's number and its device name only
36956f15802aSHermès Bélusca-Maïto * if the partition was new. Note that the partition number
36966f15802aSHermès Bélusca-Maïto * should not change if this partition has not been deleted
36976f15802aSHermès Bélusca-Maïto * during repartitioning.
36986f15802aSHermès Bélusca-Maïto */
36996f15802aSHermès Bélusca-Maïto // FIXME: Our PartMgr currently returns modified numbers
37006f15802aSHermès Bélusca-Maïto // in the layout, this needs to be investigated and fixed.
37016f15802aSHermès Bélusca-Maïto if (PartEntry->New)
37026f15802aSHermès Bélusca-Maïto {
37037df92966SHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
37047df92966SHermès Bélusca-Maïto PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
37056f15802aSHermès Bélusca-Maïto InitPartitionDeviceName(PartEntry);
37067df92966SHermès Bélusca-Maïto }
37076f15802aSHermès Bélusca-Maïto PartEntry->New = FALSE;
37087df92966SHermès Bélusca-Maïto }
37097df92966SHermès Bélusca-Maïto
37107df92966SHermès Bélusca-Maïto /* Update the logical partition table */
37118bed4adfSHermès Bélusca-Maïto for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
37128bed4adfSHermès Bélusca-Maïto ListEntry != &DiskEntry->LogicalPartListHead;
37138bed4adfSHermès Bélusca-Maïto ListEntry = ListEntry->Flink)
37147df92966SHermès Bélusca-Maïto {
37157df92966SHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
37166f15802aSHermès Bélusca-Maïto if (!PartEntry->IsPartitioned)
37176f15802aSHermès Bélusca-Maïto continue;
371829cc1843SHermès Bélusca-Maïto ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
37196f15802aSHermès Bélusca-Maïto
37206f15802aSHermès Bélusca-Maïto /* See comment above */
37216f15802aSHermès Bélusca-Maïto if (PartEntry->New)
37226f15802aSHermès Bélusca-Maïto {
37237df92966SHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
37247df92966SHermès Bélusca-Maïto PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
37256f15802aSHermès Bélusca-Maïto InitPartitionDeviceName(PartEntry);
37267df92966SHermès Bélusca-Maïto }
37276f15802aSHermès Bélusca-Maïto PartEntry->New = FALSE;
37287df92966SHermès Bélusca-Maïto }
37296f19c83bSHermès Bélusca-Maïto
37306f19c83bSHermès Bélusca-Maïto //
37316f19c83bSHermès Bélusca-Maïto // NOTE: Originally (see r40437), we used to install here also a new MBR
37326f19c83bSHermès Bélusca-Maïto // for this disk (by calling InstallMbrBootCodeToDisk), only if:
373347a1acedSHermès Bélusca-Maïto // DiskEntry->NewDisk == TRUE and DiskEntry->HwDiskNumber == 0.
37346f19c83bSHermès Bélusca-Maïto // Then after that, both DiskEntry->NewDisk and DiskEntry->NoMbr were set
37356f19c83bSHermès Bélusca-Maïto // to FALSE. In the other place (in usetup.c) where InstallMbrBootCodeToDisk
37366f19c83bSHermès Bélusca-Maïto // was called too, the installation test was modified by checking whether
37376f19c83bSHermès Bélusca-Maïto // DiskEntry->NoMbr was TRUE (instead of NewDisk).
37386f19c83bSHermès Bélusca-Maïto //
37396f19c83bSHermès Bélusca-Maïto
3740a59cecd8SHermès Bélusca-Maïto // HACK: Parts of FIXMEs described above: (Re)set the PartitionStyle to MBR.
3741a59cecd8SHermès Bélusca-Maïto DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
3742a59cecd8SHermès Bélusca-Maïto
374329cc1843SHermès Bélusca-Maïto /* The layout has been successfully updated, the disk is not dirty anymore */
374429cc1843SHermès Bélusca-Maïto DiskEntry->Dirty = FALSE;
37457df92966SHermès Bélusca-Maïto
37466f19c83bSHermès Bélusca-Maïto return Status;
37476f19c83bSHermès Bélusca-Maïto }
37486f19c83bSHermès Bélusca-Maïto
37496f19c83bSHermès Bélusca-Maïto BOOLEAN
WritePartitionsToDisk(IN PPARTLIST List)37506f19c83bSHermès Bélusca-Maïto WritePartitionsToDisk(
37516f19c83bSHermès Bélusca-Maïto IN PPARTLIST List)
37526f19c83bSHermès Bélusca-Maïto {
375329cc1843SHermès Bélusca-Maïto NTSTATUS Status;
37546f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry;
37556f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry;
37566f15802aSHermès Bélusca-Maïto PVOLENTRY Volume;
37576f19c83bSHermès Bélusca-Maïto
37586f15802aSHermès Bélusca-Maïto if (!List)
37596f19c83bSHermès Bélusca-Maïto return TRUE;
37606f19c83bSHermès Bélusca-Maïto
37616f15802aSHermès Bélusca-Maïto /* Write all the partitions to all the disks */
37628bed4adfSHermès Bélusca-Maïto for (Entry = List->DiskListHead.Flink;
37638bed4adfSHermès Bélusca-Maïto Entry != &List->DiskListHead;
37648bed4adfSHermès Bélusca-Maïto Entry = Entry->Flink)
37656f19c83bSHermès Bélusca-Maïto {
37666f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
37676f19c83bSHermès Bélusca-Maïto
3768a3168373SHermès Bélusca-Maïto if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3769a3168373SHermès Bélusca-Maïto {
3770a3168373SHermès Bélusca-Maïto DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3771a3168373SHermès Bélusca-Maïto continue;
3772a3168373SHermès Bélusca-Maïto }
3773a3168373SHermès Bélusca-Maïto
37746f19c83bSHermès Bélusca-Maïto if (DiskEntry->Dirty != FALSE)
37756f19c83bSHermès Bélusca-Maïto {
377629cc1843SHermès Bélusca-Maïto Status = WritePartitions(DiskEntry);
377729cc1843SHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
377829cc1843SHermès Bélusca-Maïto {
377929cc1843SHermès Bélusca-Maïto DPRINT1("WritePartitionsToDisk() failed to update disk %lu, Status 0x%08lx\n",
378029cc1843SHermès Bélusca-Maïto DiskEntry->DiskNumber, Status);
378129cc1843SHermès Bélusca-Maïto }
37826f19c83bSHermès Bélusca-Maïto }
37836f19c83bSHermès Bélusca-Maïto }
37846f19c83bSHermès Bélusca-Maïto
37856f15802aSHermès Bélusca-Maïto /* The PARTMGR should have notified the MOUNTMGR that new volumes
37866f15802aSHermès Bélusca-Maïto * associated with the new partitions had to be created */
37876f15802aSHermès Bélusca-Maïto
37886f15802aSHermès Bélusca-Maïto /* Assign valid device names to new volumes */
37896f15802aSHermès Bélusca-Maïto for (Entry = List->VolumesList.Flink;
37906f15802aSHermès Bélusca-Maïto Entry != &List->VolumesList;
37916f15802aSHermès Bélusca-Maïto Entry = Entry->Flink)
37926f15802aSHermès Bélusca-Maïto {
37936f15802aSHermès Bélusca-Maïto Volume = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
37946f15802aSHermès Bélusca-Maïto InitVolumeDeviceName(Volume);
37956f15802aSHermès Bélusca-Maïto }
37966f15802aSHermès Bélusca-Maïto
37976f19c83bSHermès Bélusca-Maïto return TRUE;
37986f19c83bSHermès Bélusca-Maïto }
37996f19c83bSHermès Bélusca-Maïto
38006f15802aSHermès Bélusca-Maïto
38016f15802aSHermès Bélusca-Maïto /**
38026f15802aSHermès Bélusca-Maïto * @brief
38036f15802aSHermès Bélusca-Maïto * Assign a "\DosDevices\#:" mount point drive letter to a disk partition or
38046f15802aSHermès Bélusca-Maïto * volume, specified by a given disk signature and starting partition offset.
38056f15802aSHermès Bélusca-Maïto **/
38066f15802aSHermès Bélusca-Maïto static BOOLEAN
SetMountedDeviceValue(_In_ PVOLENTRY Volume)38076f19c83bSHermès Bélusca-Maïto SetMountedDeviceValue(
38086f15802aSHermès Bélusca-Maïto _In_ PVOLENTRY Volume)
38096f19c83bSHermès Bélusca-Maïto {
38106f15802aSHermès Bélusca-Maïto PPARTENTRY PartEntry = Volume->PartEntry;
38116f15802aSHermès Bélusca-Maïto WCHAR Letter = Volume->Info.DriveLetter;
38126f19c83bSHermès Bélusca-Maïto NTSTATUS Status;
381351cb3cc6SHermès Bélusca-Maïto OBJECT_ATTRIBUTES ObjectAttributes;
381451cb3cc6SHermès Bélusca-Maïto UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"SYSTEM\\MountedDevices");
381551cb3cc6SHermès Bélusca-Maïto UNICODE_STRING ValueName;
38166f15802aSHermès Bélusca-Maïto WCHAR Buffer[16];
38176f19c83bSHermès Bélusca-Maïto HANDLE KeyHandle;
381851cb3cc6SHermès Bélusca-Maïto REG_DISK_MOUNT_INFO MountInfo;
38196f19c83bSHermès Bélusca-Maïto
38206f15802aSHermès Bélusca-Maïto /* Ignore no letter */
38216f15802aSHermès Bélusca-Maïto if (!Letter)
38226f15802aSHermès Bélusca-Maïto return TRUE;
38236f15802aSHermès Bélusca-Maïto
38246f15802aSHermès Bélusca-Maïto RtlStringCchPrintfW(Buffer, _countof(Buffer),
3825f41750abSHermès Bélusca-Maïto L"\\DosDevices\\%c:", Letter);
38266f15802aSHermès Bélusca-Maïto RtlInitUnicodeString(&ValueName, Buffer);
38276f19c83bSHermès Bélusca-Maïto
38286f19c83bSHermès Bélusca-Maïto InitializeObjectAttributes(&ObjectAttributes,
38296f19c83bSHermès Bélusca-Maïto &KeyName,
38306f19c83bSHermès Bélusca-Maïto OBJ_CASE_INSENSITIVE,
383151cb3cc6SHermès Bélusca-Maïto GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE, NULL),
38326f19c83bSHermès Bélusca-Maïto NULL);
3833765994c9SHermès Bélusca-Maïto
38346f19c83bSHermès Bélusca-Maïto Status = NtOpenKey(&KeyHandle,
38356f19c83bSHermès Bélusca-Maïto KEY_ALL_ACCESS,
38366f19c83bSHermès Bélusca-Maïto &ObjectAttributes);
38376f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
38386f19c83bSHermès Bélusca-Maïto {
38396f19c83bSHermès Bélusca-Maïto Status = NtCreateKey(&KeyHandle,
38406f19c83bSHermès Bélusca-Maïto KEY_ALL_ACCESS,
38416f19c83bSHermès Bélusca-Maïto &ObjectAttributes,
38426f19c83bSHermès Bélusca-Maïto 0,
38436f19c83bSHermès Bélusca-Maïto NULL,
38446f19c83bSHermès Bélusca-Maïto REG_OPTION_NON_VOLATILE,
38456f19c83bSHermès Bélusca-Maïto NULL);
38466f19c83bSHermès Bélusca-Maïto }
38476f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
38486f19c83bSHermès Bélusca-Maïto {
38496f19c83bSHermès Bélusca-Maïto DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
38506f19c83bSHermès Bélusca-Maïto return FALSE;
38516f19c83bSHermès Bélusca-Maïto }
38526f19c83bSHermès Bélusca-Maïto
38536f15802aSHermès Bélusca-Maïto MountInfo.Signature = PartEntry->DiskEntry->LayoutBuffer->Signature;
38546f15802aSHermès Bélusca-Maïto MountInfo.StartingOffset = GetPartEntryOffsetInBytes(PartEntry);
38556f19c83bSHermès Bélusca-Maïto Status = NtSetValueKey(KeyHandle,
38566f19c83bSHermès Bélusca-Maïto &ValueName,
38576f19c83bSHermès Bélusca-Maïto 0,
38586f19c83bSHermès Bélusca-Maïto REG_BINARY,
38596f19c83bSHermès Bélusca-Maïto (PVOID)&MountInfo,
38606f19c83bSHermès Bélusca-Maïto sizeof(MountInfo));
38616f19c83bSHermès Bélusca-Maïto NtClose(KeyHandle);
38626f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
38636f19c83bSHermès Bélusca-Maïto {
38646f19c83bSHermès Bélusca-Maïto DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
38656f19c83bSHermès Bélusca-Maïto return FALSE;
38666f19c83bSHermès Bélusca-Maïto }
38676f19c83bSHermès Bélusca-Maïto
38686f19c83bSHermès Bélusca-Maïto return TRUE;
38696f19c83bSHermès Bélusca-Maïto }
38706f19c83bSHermès Bélusca-Maïto
38716f19c83bSHermès Bélusca-Maïto BOOLEAN
SetMountedDeviceValues(_In_ PPARTLIST List)38726f19c83bSHermès Bélusca-Maïto SetMountedDeviceValues(
38736f15802aSHermès Bélusca-Maïto _In_ PPARTLIST List)
38746f19c83bSHermès Bélusca-Maïto {
38756f15802aSHermès Bélusca-Maïto PLIST_ENTRY Entry;
38766f15802aSHermès Bélusca-Maïto PVOLENTRY Volume;
38776f19c83bSHermès Bélusca-Maïto
38786f15802aSHermès Bélusca-Maïto if (!List)
38796f19c83bSHermès Bélusca-Maïto return FALSE;
38806f19c83bSHermès Bélusca-Maïto
38816f15802aSHermès Bélusca-Maïto for (Entry = List->VolumesList.Flink;
38826f15802aSHermès Bélusca-Maïto Entry != &List->VolumesList;
38836f15802aSHermès Bélusca-Maïto Entry = Entry->Flink)
38846f19c83bSHermès Bélusca-Maïto {
38856f15802aSHermès Bélusca-Maïto Volume = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
38866f19c83bSHermès Bélusca-Maïto
38876f15802aSHermès Bélusca-Maïto /* Assign a "\DosDevices\#:" mount point to this volume */
38886f15802aSHermès Bélusca-Maïto if (!SetMountedDeviceValue(Volume))
38896f19c83bSHermès Bélusca-Maïto return FALSE;
38906f19c83bSHermès Bélusca-Maïto }
38916f19c83bSHermès Bélusca-Maïto
38926f19c83bSHermès Bélusca-Maïto return TRUE;
38936f19c83bSHermès Bélusca-Maïto }
38946f19c83bSHermès Bélusca-Maïto
38956f19c83bSHermès Bélusca-Maïto VOID
SetMBRPartitionType(IN PPARTENTRY PartEntry,IN UCHAR PartitionType)38969735a837SHermès Bélusca-Maïto SetMBRPartitionType(
38976f19c83bSHermès Bélusca-Maïto IN PPARTENTRY PartEntry,
38986f19c83bSHermès Bélusca-Maïto IN UCHAR PartitionType)
38996f19c83bSHermès Bélusca-Maïto {
39006f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry = PartEntry->DiskEntry;
39016f19c83bSHermès Bélusca-Maïto
39029735a837SHermès Bélusca-Maïto ASSERT(DiskEntry->DiskStyle == PARTITION_STYLE_MBR);
39039735a837SHermès Bélusca-Maïto
39046f15802aSHermès Bélusca-Maïto /* Nothing to do if we assign the same type */
39056f15802aSHermès Bélusca-Maïto if (PartitionType == PartEntry->PartitionType)
39066f15802aSHermès Bélusca-Maïto return;
39076f15802aSHermès Bélusca-Maïto
39086f15802aSHermès Bélusca-Maïto // TODO: We might need to remount the associated basic volume...
39096f15802aSHermès Bélusca-Maïto
39106f19c83bSHermès Bélusca-Maïto PartEntry->PartitionType = PartitionType;
39116f19c83bSHermès Bélusca-Maïto
39126f19c83bSHermès Bélusca-Maïto DiskEntry->Dirty = TRUE;
39136f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartitionType;
39147df92966SHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RecognizedPartition = IsRecognizedPartition(PartitionType);
39156f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
39166f19c83bSHermès Bélusca-Maïto }
39176f19c83bSHermès Bélusca-Maïto
39186f19c83bSHermès Bélusca-Maïto /* EOF */
3919