From c6d8f7de7042a47f267b6df3d76fc94ce164bc39 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Wed, 9 Mar 2011 10:33:13 +0000 Subject: [PATCH] [NTOSKRNL] Implemented FstubFixupEfiPartition(): Purpose is to let ReactOS handle realistic partitions length in case of an EFI/GPT protective MBR. Indeed, when formatting a disk to GPT, you add a protective MBR that contains a fake partition entry, with type 0xEE having the following property: its size is set to maximum allocatable size in MBR. In that case, if disk is small, you may go beyond disk size. This is why a fix to partition length may be needed when re-reading partition entry. This is the way ReactOS creates protective MBR. You may find some more information here: http://msdn.microsoft.com/en-us/windows/hardware/gg463525 Fixed xHalIoReadPartitionTable(): - Allocate a buffer that has the proper size (instead of allocating a buffer which is too big). Especially since this leads to partial init only some lines after. - Remove redundant & useless affectation. - Check/fix 0xEE partition length in case of an EFI/GPT protective MBR (see upper point). svn path=/trunk/; revision=51002 --- reactos/ntoskrnl/fstub/disksup.c | 33 ++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/reactos/ntoskrnl/fstub/disksup.c b/reactos/ntoskrnl/fstub/disksup.c index ce184bcdced..7c4f651f8ff 100644 --- a/reactos/ntoskrnl/fstub/disksup.c +++ b/reactos/ntoskrnl/fstub/disksup.c @@ -24,6 +24,8 @@ const WCHAR DiskMountString[] = L"\\DosDevices\\%C:"; #define PARTITION_MAGIC 0xaa55 +#define EFI_PMBR_OSTYPE_EFI 0xEE + #include typedef struct _REG_DISK_MOUNT_INFO @@ -1358,6 +1360,24 @@ xHalExamineMBR(IN PDEVICE_OBJECT DeviceObject, } } +VOID +NTAPI +FstubFixupEfiPartition(IN PPARTITION_DESCRIPTOR PartitionDescriptor, + IN ULONGLONG MaxOffset) +{ + ULONG PartitionLength; + PAGED_CODE(); + + /* Compute partition length (according to MBR entry) */ + PartitionLength = PartitionDescriptor->StartingSectorLsb0 + PartitionDescriptor->PartitionLengthLsb0; + /* In case the partition length goes beyond disk size... */ + if (PartitionLength > MaxOffset) + { + /* Resize partition to its maximum real length */ + PartitionDescriptor->PartitionLengthLsb0 = MaxOffset - PartitionDescriptor->StartingSectorLsb0; + } +} + NTSTATUS FASTCALL xHalIoReadPartitionTable(IN PDEVICE_OBJECT DeviceObject, @@ -1425,7 +1445,7 @@ xHalIoReadPartitionTable(IN PDEVICE_OBJECT DeviceObject, MaxOffset, MaxSector); /* Allocate our buffer */ - Buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, TAG_FILE_SYSTEM); + Buffer = ExAllocatePoolWithTag(NonPagedPool, InputSize, TAG_FILE_SYSTEM); if (!Buffer) { /* Fail, free the input buffer */ @@ -1503,9 +1523,6 @@ xHalIoReadPartitionTable(IN PDEVICE_OBJECT DeviceObject, PartitionDescriptor = (PPARTITION_DESCRIPTOR) &(((PUSHORT)Buffer)[PARTITION_TABLE_OFFSET]); - /* Get the partition type */ - PartitionType = PartitionDescriptor->PartitionType; - /* Start looping partitions */ j++; DPRINT("FSTUB: Partition Table %d:\n", j); @@ -1524,6 +1541,14 @@ xHalIoReadPartitionTable(IN PDEVICE_OBJECT DeviceObject, GET_STARTING_SECTOR(PartitionDescriptor), GET_PARTITION_LENGTH(PartitionDescriptor)); + /* Check whether we're facing a protective MBR */ + if (PartitionType == EFI_PMBR_OSTYPE_EFI) + { + /* Partition length might be bigger than disk size */ + FstubFixupEfiPartition(PartitionDescriptor, + MaxOffset); + } + /* Make sure that the partition is valid, unless it's the first */ if (!(HalpIsValidPartitionEntry(PartitionDescriptor, MaxOffset, -- 2.17.1