* FILE: ntoskrnl/fstub/disksup.c
* PURPOSE: I/O HAL Routines for Disk Access
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
-* Eric Kohl (ekohl@rz-online.de)
+* Eric Kohl
* Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
#if 1
const WCHAR DiskMountString[] = L"\\DosDevices\\%C:";
-#define AUTO_DRIVE ((ULONG)-1)
+#define AUTO_DRIVE MAXULONG
#define PARTITION_MAGIC 0xaa55
+#define EFI_PMBR_OSTYPE_EFI 0xEE
+
#include <pshpack1.h>
typedef struct _REG_DISK_MOUNT_INFO
IN UCHAR DriveType,
IN ULONG Signature,
IN LARGE_INTEGER StartingOffset,
- IN HANDLE hKey)
+ IN HANDLE hKey,
+ IN PUNICODE_STRING BootDevice,
+ OUT PUCHAR NtSystemPath)
{
WCHAR DriveNameBuffer[16];
UNICODE_STRING DriveName;
DPRINT1("ZwCreateValueKey failed for %wZ, status=%x\n", &DriveName, Status);
}
}
+
+ /* Check if this is a boot partition */
+ if (RtlCompareUnicodeString(PartitionName, BootDevice, FALSE) == 0)
+ {
+ /* Set NtSystemPath to that partition's disk letter */
+ *NtSystemPath = (UCHAR)('A' + DriveNumber);
+ }
+
return TRUE;
}
PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
PREG_DISK_MOUNT_INFO DiskMountInfo;
ULONG RDiskCount;
+ UNICODE_STRING BootDevice;
+
+ Status = RtlAnsiStringToUnicodeString(&BootDevice,
+ NtDeviceName,
+ TRUE);
DPRINT("xHalIoAssignDriveLetters()\n");
PartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(PagedPool,
sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(REG_DISK_MOUNT_INFO));
+ if (!Buffer1 || !Buffer2 || !PartialInformation) return;
+
DiskMountInfo = (PREG_DISK_MOUNT_INFO) PartialInformation->Data;
/* Open or Create the 'MountedDevices' key */
}
/* Initialize layout array */
+ if (ConfigInfo->DiskCount == 0)
+ goto end_assign_disks;
LayoutArray = ExAllocatePool(NonPagedPool,
ConfigInfo->DiskCount * sizeof(PDRIVE_LAYOUT_INFORMATION));
+ if (!LayoutArray)
+ {
+ ExFreePool(PartialInformation);
+ ExFreePool(Buffer2);
+ ExFreePool(Buffer1);
+ if (hKey) ZwClose(hKey);
+ }
+
RtlZeroMemory(LayoutArray,
ConfigInfo->DiskCount * sizeof(PDRIVE_LAYOUT_INFORMATION));
for (i = 0; i < ConfigInfo->DiskCount; i++)
DOSDEVICE_DRIVE_FIXED,
DiskMountInfo->Signature,
DiskMountInfo->StartingOffset,
- NULL);
+ NULL,
+ &BootDevice,
+ NtSystemPath);
/* Mark the partition as assigned */
LayoutArray[i]->PartitionEntry[j].RewritePartition = TRUE;
}
DOSDEVICE_DRIVE_FIXED,
LayoutArray[DiskNumber]->Signature,
LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
- hKey);
+ hKey,
+ &BootDevice,
+ NtSystemPath);
/* Mark the partition as assigned */
LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
}
DOSDEVICE_DRIVE_FIXED,
LayoutArray[DiskNumber]->Signature,
LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
- hKey);
+ hKey,
+ &BootDevice,
+ NtSystemPath);
/* Mark the partition as assigned */
LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
}
DOSDEVICE_DRIVE_FIXED,
LayoutArray[DiskNumber]->Signature,
LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
- hKey);
+ hKey,
+ &BootDevice,
+ NtSystemPath);
/* Mark the partition as assigned */
LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
}
DOSDEVICE_DRIVE_FIXED,
LayoutArray[DiskNumber]->Signature,
LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
- hKey);
+ hKey,
+ &BootDevice,
+ NtSystemPath);
/* Mark the partition as assigned */
LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
}
DOSDEVICE_DRIVE_FIXED,
LayoutArray[DiskNumber]->Signature,
LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
- hKey);
+ hKey,
+ &BootDevice,
+ NtSystemPath);
/* Mark the partition as assigned */
LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
}
DOSDEVICE_DRIVE_REMOVABLE,
0,
RtlConvertLongToLargeInteger(0),
- hKey);
+ hKey,
+ &BootDevice,
+ NtSystemPath);
}
}
}
ExFreePool(LayoutArray[i]);
}
ExFreePool(LayoutArray);
+end_assign_disks:
/* Assign floppy drives */
DPRINT("Floppy drives: %d\n", ConfigInfo->FloppyCount);
DOSDEVICE_DRIVE_REMOVABLE,
0,
RtlConvertLongToLargeInteger(0),
- hKey);
+ hKey,
+ &BootDevice,
+ NtSystemPath);
}
/* Assign cdrom drives */
DOSDEVICE_DRIVE_CDROM,
0,
RtlConvertLongToLargeInteger(0),
- hKey);
+ hKey,
+ &BootDevice,
+ NtSystemPath);
}
/* Anything else to do? */
}
}
+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,
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 */
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);
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,
for (Entry = 1; Entry <= 4; Entry++, PartitionDescriptor++)
{
/* Check if this is a container partition, since we skipped them */
- if (IsContainerPartition(PartitionType))
+ if (IsContainerPartition(PartitionDescriptor->PartitionType))
{
/* Get its offset */
Offset.QuadPart = VolumeOffset.QuadPart +