+++ /dev/null
-/*
- * PROJECT: ReactOS DiskPart
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: base/system/diskpart/partlist.c
- * PURPOSE: Manages all the partitions of the OS in an interactive way.
- * PROGRAMMERS: Eric Kohl
- */
-
-/* INCLUDES *******************************************************************/
-
-#include "diskpart.h"
-#include <ntddscsi.h>
-
-#define NDEBUG
-#include <debug.h>
-
-#define InsertAscendingList(ListHead, NewEntry, Type, ListEntryField, SortField)\
-{\
- PLIST_ENTRY current;\
-\
- current = (ListHead)->Flink;\
- while (current != (ListHead))\
- {\
- if (CONTAINING_RECORD(current, Type, ListEntryField)->SortField >=\
- (NewEntry)->SortField)\
- {\
- break;\
- }\
- current = current->Flink;\
- }\
-\
- InsertTailList(current, &((NewEntry)->ListEntryField));\
-}
-
-/* We have to define it there, because it is not in the MS DDK */
-#define PARTITION_EXT2 0x83
-
-#define PARTITION_TBL_SIZE 4
-
-#include <pshpack1.h>
-
-typedef struct _PARTITION
-{
- unsigned char BootFlags; /* bootable? 0=no, 128=yes */
- unsigned char StartingHead; /* beginning head number */
- unsigned char StartingSector; /* beginning sector number */
- unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */
- unsigned char PartitionType; /* Operating System type indicator code */
- unsigned char EndingHead; /* ending head number */
- unsigned char EndingSector; /* ending sector number */
- unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick */
- unsigned int StartingBlock; /* first sector relative to start of disk */
- unsigned int SectorCount; /* number of sectors in partition */
-} PARTITION, *PPARTITION;
-
-typedef struct _PARTITION_SECTOR
-{
- UCHAR BootCode[440]; /* 0x000 */
- ULONG Signature; /* 0x1B8 */
- UCHAR Reserved[2]; /* 0x1BC */
- PARTITION Partition[PARTITION_TBL_SIZE]; /* 0x1BE */
- USHORT Magic; /* 0x1FE */
-} PARTITION_SECTOR, *PPARTITION_SECTOR;
-
-#include <poppack.h>
-
-
-/* GLOBALS ********************************************************************/
-
-LIST_ENTRY DiskListHead;
-LIST_ENTRY BiosDiskListHead;
-
-PDISKENTRY CurrentDisk = NULL;
-PPARTENTRY CurrentPartition = NULL;
-
-
-/* FUNCTIONS ******************************************************************/
-
-ULONGLONG
-AlignDown(
- IN ULONGLONG Value,
- IN ULONG Alignment)
-{
- ULONGLONG Temp;
-
- Temp = Value / Alignment;
-
- return Temp * Alignment;
-}
-
-static
-VOID
-GetDriverName(
- PDISKENTRY DiskEntry)
-{
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- WCHAR KeyName[32];
- NTSTATUS Status;
-
- RtlInitUnicodeString(&DiskEntry->DriverName,
- NULL);
-
- swprintf(KeyName,
- L"\\Scsi\\Scsi Port %lu",
- DiskEntry->Port);
-
- RtlZeroMemory(&QueryTable,
- sizeof(QueryTable));
-
- QueryTable[0].Name = L"Driver";
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
- QueryTable[0].EntryContext = &DiskEntry->DriverName;
-
- Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
- KeyName,
- QueryTable,
- NULL,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
- }
-}
-
-static
-NTSTATUS
-NTAPI
-DiskIdentifierQueryRoutine(
- PWSTR ValueName,
- ULONG ValueType,
- PVOID ValueData,
- ULONG ValueLength,
- PVOID Context,
- PVOID EntryContext)
-{
- PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
- UNICODE_STRING NameU;
-
- if (ValueType == REG_SZ &&
- ValueLength == 20 * sizeof(WCHAR))
- {
- NameU.Buffer = (PWCHAR)ValueData;
- NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
- RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
-
- NameU.Buffer = (PWCHAR)ValueData + 9;
- RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
-
- return STATUS_SUCCESS;
- }
-
- return STATUS_UNSUCCESSFUL;
-}
-
-static
-NTSTATUS
-NTAPI
-DiskConfigurationDataQueryRoutine(
- PWSTR ValueName,
- ULONG ValueType,
- PVOID ValueData,
- ULONG ValueLength,
- PVOID Context,
- PVOID EntryContext)
-{
- PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
- PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
- PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
- ULONG i;
-
- if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
- ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
- return STATUS_UNSUCCESSFUL;
-
- FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
-
- /* Hm. Version and Revision are not set on Microsoft Windows XP... */
-#if 0
- if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
- FullResourceDescriptor->PartialResourceList.Revision != 1)
- return STATUS_UNSUCCESSFUL;
-#endif
-
- for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
- {
- if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
- FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA))
- continue;
-
- DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
- BiosDiskEntry->DiskGeometry = *DiskGeometry;
-
- return STATUS_SUCCESS;
- }
-
- return STATUS_UNSUCCESSFUL;
-}
-
-static
-NTSTATUS
-NTAPI
-SystemConfigurationDataQueryRoutine(
- PWSTR ValueName,
- ULONG ValueType,
- PVOID ValueData,
- ULONG ValueLength,
- PVOID Context,
- PVOID EntryContext)
-{
- PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
- PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context;
- ULONG i;
-
- if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
- ValueLength < sizeof (CM_FULL_RESOURCE_DESCRIPTOR))
- return STATUS_UNSUCCESSFUL;
-
- FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
-
- /* Hm. Version and Revision are not set on Microsoft Windows XP... */
-#if 0
- if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
- FullResourceDescriptor->PartialResourceList.Revision != 1)
- return STATUS_UNSUCCESSFUL;
-#endif
-
- for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
- {
- if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
- FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
- continue;
-
- *Int13Drives = (CM_INT13_DRIVE_PARAMETER*)RtlAllocateHeap(RtlGetProcessHeap(), 0,
- FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
- if (*Int13Drives == NULL)
- return STATUS_NO_MEMORY;
-
- memcpy(*Int13Drives,
- &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1],
- FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
- return STATUS_SUCCESS;
- }
-
- return STATUS_UNSUCCESSFUL;
-}
-
-
-#define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
-
-static
-VOID
-EnumerateBiosDiskEntries(VOID)
-{
- RTL_QUERY_REGISTRY_TABLE QueryTable[3];
- WCHAR Name[120];
- ULONG AdapterCount;
- ULONG DiskCount;
- NTSTATUS Status;
- PCM_INT13_DRIVE_PARAMETER Int13Drives;
- PBIOSDISKENTRY BiosDiskEntry;
-
- memset(QueryTable, 0, sizeof(QueryTable));
-
- QueryTable[1].Name = L"Configuration Data";
- QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine;
- Int13Drives = NULL;
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
- &QueryTable[1],
- (PVOID)&Int13Drives,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
- return;
- }
-
- AdapterCount = 0;
- while (1)
- {
- swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount);
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- Name,
- &QueryTable[2],
- NULL,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- break;
- }
-
- swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- Name,
- &QueryTable[2],
- NULL,
- NULL);
- if (NT_SUCCESS(Status))
- {
- while (1)
- {
- swprintf(Name, L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount);
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- Name,
- &QueryTable[2],
- NULL,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
- return;
- }
-
- swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount);
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- Name,
- &QueryTable[2],
- NULL,
- NULL);
- if (NT_SUCCESS(Status))
- {
- QueryTable[0].Name = L"Identifier";
- QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine;
- QueryTable[1].Name = L"Configuration Data";
- QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine;
-
- DiskCount = 0;
- while (1)
- {
- BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
- if (BiosDiskEntry == NULL)
- {
- break;
- }
-
- swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount);
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- Name,
- QueryTable,
- (PVOID)BiosDiskEntry,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
- break;
- }
-
- BiosDiskEntry->DiskNumber = DiskCount;
- BiosDiskEntry->Recognized = FALSE;
-
- if (DiskCount < Int13Drives[0].NumberDrives)
- {
- BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
- }
- else
- {
- DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount);
- }
-
- InsertTailList(&BiosDiskListHead, &BiosDiskEntry->ListEntry);
-
- DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber);
- DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature);
- DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum);
- DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
- DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
- DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
- DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
- DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
- DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
- DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
- DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
-
- DiskCount++;
- }
- }
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
- return;
- }
- }
-
- AdapterCount++;
- }
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
-}
-
-
-static
-VOID
-AddPartitionToDisk(
- ULONG DiskNumber,
- PDISKENTRY DiskEntry,
- ULONG PartitionIndex,
- BOOLEAN LogicalPartition)
-{
- PPARTITION_INFORMATION PartitionInfo;
- PPARTENTRY PartEntry;
-
- PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
- if (PartitionInfo->PartitionType == 0 ||
- (LogicalPartition == TRUE && IsContainerPartition(PartitionInfo->PartitionType)))
- return;
-
- PartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (PartEntry == NULL)
- {
- return;
- }
-
- PartEntry->DiskEntry = DiskEntry;
-
- PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
- PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
-
- PartEntry->BootIndicator = PartitionInfo->BootIndicator;
- PartEntry->PartitionType = PartitionInfo->PartitionType;
- PartEntry->HiddenSectors = PartitionInfo->HiddenSectors;
-
- PartEntry->LogicalPartition = LogicalPartition;
- PartEntry->IsPartitioned = TRUE;
- PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
- PartEntry->PartitionIndex = PartitionIndex;
-
- if (IsContainerPartition(PartEntry->PartitionType))
- {
- PartEntry->FormatState = Unformatted;
-
- if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
- DiskEntry->ExtendedPartition = PartEntry;
- }
- else if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
- (PartEntry->PartitionType == PARTITION_FAT_16) ||
- (PartEntry->PartitionType == PARTITION_HUGE) ||
- (PartEntry->PartitionType == PARTITION_XINT13) ||
- (PartEntry->PartitionType == PARTITION_FAT32) ||
- (PartEntry->PartitionType == PARTITION_FAT32_XINT13))
- {
-#if 0
- if (CheckFatFormat())
- {
- PartEntry->FormatState = Preformatted;
- }
- else
- {
- PartEntry->FormatState = Unformatted;
- }
-#endif
- PartEntry->FormatState = Preformatted;
- }
- else if (PartEntry->PartitionType == PARTITION_EXT2)
- {
-#if 0
- if (CheckExt2Format())
- {
- PartEntry->FormatState = Preformatted;
- }
- else
- {
- PartEntry->FormatState = Unformatted;
- }
-#endif
- PartEntry->FormatState = Preformatted;
- }
- else if (PartEntry->PartitionType == PARTITION_IFS)
- {
-#if 0
- if (CheckNtfsFormat())
- {
- PartEntry->FormatState = Preformatted;
- }
- else if (CheckHpfsFormat())
- {
- PartEntry->FormatState = Preformatted;
- }
- else
- {
- PartEntry->FormatState = Unformatted;
- }
-#endif
- PartEntry->FormatState = Preformatted;
- }
- else
- {
- PartEntry->FormatState = UnknownFormat;
- }
-
- if (LogicalPartition)
- InsertTailList(&DiskEntry->LogicalPartListHead,
- &PartEntry->ListEntry);
- else
- InsertTailList(&DiskEntry->PrimaryPartListHead,
- &PartEntry->ListEntry);
-}
-
-
-static
-VOID
-ScanForUnpartitionedDiskSpace(
- PDISKENTRY DiskEntry)
-{
- ULONGLONG LastStartSector;
- ULONGLONG LastSectorCount;
- ULONGLONG LastUnusedSectorCount;
- PPARTENTRY PartEntry;
- PPARTENTRY NewPartEntry;
- PLIST_ENTRY Entry;
-
- DPRINT("ScanForUnpartitionedDiskSpace()\n");
-
- if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
- {
- DPRINT1("No primary partition!\n");
-
- /* Create a partition table that represents the empty disk */
- NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- NewPartEntry->DiskEntry = DiskEntry;
-
- NewPartEntry->IsPartitioned = FALSE;
- NewPartEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment;
- NewPartEntry->SectorCount.QuadPart = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) -
- NewPartEntry->StartSector.QuadPart;
-
- DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
- DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
- DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
-
- NewPartEntry->FormatState = Unformatted;
-
- InsertTailList(&DiskEntry->PrimaryPartListHead,
- &NewPartEntry->ListEntry);
-
- return;
- }
-
- /* Start partition at head 1, cylinder 0 */
- LastStartSector = DiskEntry->SectorAlignment;
- LastSectorCount = 0ULL;
- LastUnusedSectorCount = 0ULL;
-
- Entry = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry != &DiskEntry->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
-
- if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
- PartEntry->SectorCount.QuadPart != 0ULL)
- {
- LastUnusedSectorCount =
- PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
-
- if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
- LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
- {
- DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
-
- NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- NewPartEntry->DiskEntry = DiskEntry;
-
- NewPartEntry->IsPartitioned = FALSE;
- NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
- NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
- NewPartEntry->StartSector.QuadPart;
-
- DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
- DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
- DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
-
- NewPartEntry->FormatState = Unformatted;
-
- /* Insert the table into the list */
- InsertTailList(&PartEntry->ListEntry,
- &NewPartEntry->ListEntry);
- }
-
- LastStartSector = PartEntry->StartSector.QuadPart;
- LastSectorCount = PartEntry->SectorCount.QuadPart;
- }
-
- Entry = Entry->Flink;
- }
-
- /* Check for trailing unpartitioned disk space */
- if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
- {
- LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
-
- if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
- {
- DPRINT1("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
-
- NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- NewPartEntry->DiskEntry = DiskEntry;
-
- NewPartEntry->IsPartitioned = FALSE;
- NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
- NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
- NewPartEntry->StartSector.QuadPart;
-
- DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
- DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
- DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
-
- NewPartEntry->FormatState = Unformatted;
-
- /* Append the table to the list */
- InsertTailList(&DiskEntry->PrimaryPartListHead,
- &NewPartEntry->ListEntry);
- }
- }
-
- if (DiskEntry->ExtendedPartition != NULL)
- {
- if (IsListEmpty(&DiskEntry->LogicalPartListHead))
- {
- DPRINT1("No logical partition!\n");
-
- /* Create a partition table entry that represents the empty extended partition */
- NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- NewPartEntry->DiskEntry = DiskEntry;
- NewPartEntry->LogicalPartition = TRUE;
-
- NewPartEntry->IsPartitioned = FALSE;
- NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
- NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
-
- DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
- DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
- DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
-
- NewPartEntry->FormatState = Unformatted;
-
- InsertTailList(&DiskEntry->LogicalPartListHead,
- &NewPartEntry->ListEntry);
-
- return;
- }
-
- /* Start partition at head 1, cylinder 0 */
- LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
- LastSectorCount = 0ULL;
- LastUnusedSectorCount = 0ULL;
-
- Entry = DiskEntry->LogicalPartListHead.Flink;
- while (Entry != &DiskEntry->LogicalPartListHead)
- {
- PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
-
- if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
- PartEntry->SectorCount.QuadPart != 0ULL)
- {
- LastUnusedSectorCount =
- PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);
-
- if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) &&
- LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
- {
- DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
-
- NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- NewPartEntry->DiskEntry = DiskEntry;
- NewPartEntry->LogicalPartition = TRUE;
-
- NewPartEntry->IsPartitioned = FALSE;
- NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
- NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
- NewPartEntry->StartSector.QuadPart;
-
- DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
- DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
- DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
-
- NewPartEntry->FormatState = Unformatted;
-
- /* Insert the table into the list */
- InsertTailList(&PartEntry->ListEntry,
- &NewPartEntry->ListEntry);
- }
-
- LastStartSector = PartEntry->StartSector.QuadPart;
- LastSectorCount = PartEntry->SectorCount.QuadPart;
- }
-
- Entry = Entry->Flink;
- }
-
- /* Check for trailing unpartitioned disk space */
- if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
- {
- LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount),
- DiskEntry->SectorAlignment);
-
- if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
- {
- DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
-
- NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- NewPartEntry->DiskEntry = DiskEntry;
- NewPartEntry->LogicalPartition = TRUE;
-
- NewPartEntry->IsPartitioned = FALSE;
- NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
- NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
- NewPartEntry->StartSector.QuadPart;
-
- DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
- DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
- DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
-
- NewPartEntry->FormatState = Unformatted;
-
- /* Append the table to the list */
- InsertTailList(&DiskEntry->LogicalPartListHead,
- &NewPartEntry->ListEntry);
- }
- }
- }
-
- DPRINT("ScanForUnpartitionedDiskSpace() done\n");
-}
-
-
-static
-VOID
-AddDiskToList(
- HANDLE FileHandle,
- ULONG DiskNumber)
-{
- DISK_GEOMETRY DiskGeometry;
- SCSI_ADDRESS ScsiAddress;
- PDISKENTRY DiskEntry;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
- PPARTITION_SECTOR Mbr;
- PULONG Buffer;
- LARGE_INTEGER FileOffset;
- WCHAR Identifier[20];
- ULONG Checksum;
- ULONG Signature;
- ULONG i;
- PLIST_ENTRY ListEntry;
- PBIOSDISKENTRY BiosDiskEntry;
- ULONG LayoutBufferSize;
- PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
-
- Status = NtDeviceIoControlFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_DISK_GET_DRIVE_GEOMETRY,
- NULL,
- 0,
- &DiskGeometry,
- sizeof(DISK_GEOMETRY));
- if (!NT_SUCCESS(Status))
- {
- return;
- }
-
- if (DiskGeometry.MediaType != FixedMedia &&
- DiskGeometry.MediaType != RemovableMedia)
- {
- return;
- }
-
- Status = NtDeviceIoControlFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_SCSI_GET_ADDRESS,
- NULL,
- 0,
- &ScsiAddress,
- sizeof(SCSI_ADDRESS));
- if (!NT_SUCCESS(Status))
- {
- return;
- }
-
- Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- DiskGeometry.BytesPerSector);
- if (Mbr == NULL)
- {
- return;
- }
-
- FileOffset.QuadPart = 0;
- Status = NtReadFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- (PVOID)Mbr,
- DiskGeometry.BytesPerSector,
- &FileOffset,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
- DPRINT1("NtReadFile failed, status=%x\n", Status);
- return;
- }
- Signature = Mbr->Signature;
-
- /* Calculate the MBR checksum */
- Checksum = 0;
- Buffer = (PULONG)Mbr;
- for (i = 0; i < 128; i++)
- {
- Checksum += Buffer[i];
- }
- Checksum = ~Checksum + 1;
-
- swprintf(Identifier, L"%08x-%08x-A", Checksum, Signature);
- DPRINT("Identifier: %S\n", Identifier);
-
- DiskEntry = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(DISKENTRY));
- if (DiskEntry == NULL)
- {
- return;
- }
-
-// DiskEntry->Checksum = Checksum;
-// DiskEntry->Signature = Signature;
- DiskEntry->BiosFound = FALSE;
-
- /* Check if this disk has a valid MBR */
- if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0)
- DiskEntry->NoMbr = TRUE;
- else
- DiskEntry->NoMbr = FALSE;
-
- /* Free Mbr sector buffer */
- RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
-
- ListEntry = BiosDiskListHead.Flink;
- while (ListEntry != &BiosDiskListHead)
- {
- BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
- /* FIXME:
- * Compare the size from bios and the reported size from driver.
- * If we have more than one disk with a zero or with the same signatur
- * we must create new signatures and reboot. After the reboot,
- * it is possible to identify the disks.
- */
- if (BiosDiskEntry->Signature == Signature &&
- BiosDiskEntry->Checksum == Checksum &&
- !BiosDiskEntry->Recognized)
- {
- if (!DiskEntry->BiosFound)
- {
- DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
- DiskEntry->BiosFound = TRUE;
- BiosDiskEntry->Recognized = TRUE;
- }
- else
- {
- }
- }
- ListEntry = ListEntry->Flink;
- }
-
- if (!DiskEntry->BiosFound)
- {
-#if 0
- RtlFreeHeap(ProcessHeap, 0, DiskEntry);
- return;
-#else
- DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber);
-#endif
- }
-
- InitializeListHead(&DiskEntry->PrimaryPartListHead);
- InitializeListHead(&DiskEntry->LogicalPartListHead);
-
- DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
- DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
- DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
- DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
-
- DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
- DPRINT("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder);
- DPRINT("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack);
- DPRINT("BytesPerSector %I64u\n", DiskEntry->BytesPerSector);
-
- DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
- (ULONGLONG)DiskGeometry.TracksPerCylinder *
- (ULONGLONG)DiskGeometry.SectorsPerTrack;
-
- DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
- DiskEntry->CylinderAlignment = DiskGeometry.SectorsPerTrack * DiskGeometry.TracksPerCylinder;
-
- DPRINT1("SectorCount: %I64u\n", DiskEntry->SectorCount);
- DPRINT1("SectorAlignment: %lu\n", DiskEntry->SectorAlignment);
- DPRINT1("CylinderAlignment: %lu\n", DiskEntry->CylinderAlignment);
-
- DiskEntry->DiskNumber = DiskNumber;
- DiskEntry->Port = ScsiAddress.PortNumber;
- DiskEntry->Bus = ScsiAddress.PathId;
- DiskEntry->Id = ScsiAddress.TargetId;
-
- GetDriverName(DiskEntry);
-
- InsertAscendingList(&DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
-
- /* Allocate a layout buffer with 4 partition entries first */
- LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
- ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
- DiskEntry->LayoutBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- LayoutBufferSize);
- if (DiskEntry->LayoutBuffer == NULL)
- {
- DPRINT1("Failed to allocate the disk layout buffer!\n");
- return;
- }
-
- for (;;)
- {
- DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
- Status = NtDeviceIoControlFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_DISK_GET_DRIVE_LAYOUT,
- NULL,
- 0,
- DiskEntry->LayoutBuffer,
- LayoutBufferSize);
- if (NT_SUCCESS(Status))
- break;
-
- if (Status != STATUS_BUFFER_TOO_SMALL)
- {
- DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
- return;
- }
-
- LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
- NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- DiskEntry->LayoutBuffer,
- LayoutBufferSize);
- if (NewLayoutBuffer == NULL)
- {
- DPRINT1("Failed to reallocate the disk layout buffer!\n");
- return;
- }
-
- DiskEntry->LayoutBuffer = NewLayoutBuffer;
- }
-
- DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
-
-#ifdef DUMP_PARTITION_TABLE
- DumpPartitionTable(DiskEntry);
-#endif
-
- if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
- DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
- DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != 0)
- {
- if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
- {
- DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
- }
- else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
- {
- DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
- }
- else
- {
- DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
- }
- }
- else
- {
- DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
- }
-
-
- if (DiskEntry->LayoutBuffer->PartitionCount == 0)
- {
- DiskEntry->NewDisk = TRUE;
- DiskEntry->LayoutBuffer->PartitionCount = 4;
-
- for (i = 0; i < 4; i++)
- DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
- }
- else
- {
- for (i = 0; i < 4; i++)
- {
- AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
- }
-
- for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
- {
- AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
- }
- }
-
- ScanForUnpartitionedDiskSpace(DiskEntry);
-}
-
-
-NTSTATUS
-CreatePartitionList(VOID)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- SYSTEM_DEVICE_INFORMATION Sdi;
- IO_STATUS_BLOCK Iosb;
- ULONG ReturnSize;
- NTSTATUS Status;
- ULONG DiskNumber;
- WCHAR Buffer[MAX_PATH];
- UNICODE_STRING Name;
- HANDLE FileHandle;
-
- CurrentDisk = NULL;
- CurrentPartition = NULL;
-
-// BootDisk = NULL;
-// BootPartition = NULL;
-
-// TempDisk = NULL;
-// TempPartition = NULL;
-// FormatState = Start;
-
- InitializeListHead(&DiskListHead);
- InitializeListHead(&BiosDiskListHead);
-
- EnumerateBiosDiskEntries();
-
- Status = NtQuerySystemInformation(SystemDeviceInformation,
- &Sdi,
- sizeof(SYSTEM_DEVICE_INFORMATION),
- &ReturnSize);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
- {
- swprintf(Buffer,
- L"\\Device\\Harddisk%d\\Partition0",
- DiskNumber);
- RtlInitUnicodeString(&Name,
- Buffer);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- 0,
- NULL,
- NULL);
-
- Status = NtOpenFile(&FileHandle,
- FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
- &ObjectAttributes,
- &Iosb,
- FILE_SHARE_READ,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (NT_SUCCESS(Status))
- {
- AddDiskToList(FileHandle, DiskNumber);
-
- NtClose(FileHandle);
- }
- }
-
-// UpdateDiskSignatures(List);
-
-// AssignDriveLetters(List);
-
- return STATUS_SUCCESS;
-}
-
-
-VOID
-DestroyPartitionList(VOID)
-{
- PDISKENTRY DiskEntry;
- PBIOSDISKENTRY BiosDiskEntry;
- PPARTENTRY PartEntry;
- PLIST_ENTRY Entry;
-
- CurrentDisk = NULL;
- CurrentPartition = NULL;
-
- /* Release disk and partition info */
- while (!IsListEmpty(&DiskListHead))
- {
- Entry = RemoveHeadList(&DiskListHead);
- DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
-
- /* Release driver name */
- RtlFreeUnicodeString(&DiskEntry->DriverName);
-
- /* Release primary partition list */
- while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
- {
- Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead);
- PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
- }
-
- /* Release logical partition list */
- while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
- {
- Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
- PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
- }
-
- /* Release layout buffer */
- if (DiskEntry->LayoutBuffer != NULL)
- RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry->LayoutBuffer);
-
-
- /* Release disk entry */
- RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry);
- }
-
- /* Release the bios disk info */
- while (!IsListEmpty(&BiosDiskListHead))
- {
- Entry = RemoveHeadList(&BiosDiskListHead);
- BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
- }
-}
-
-/* EOF */