* FILE: ntoskrnl/io/xhaldrv.c
* PURPOSE: Hal drive routines
* PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ * Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
* Created 19/06/2000
*/
DPRINT("DiskGeometry.BytesPerSector: %d\n",
DiskGeometry.BytesPerSector);
- /* read the partition table */
+ /* Read the partition table */
Status = IoReadPartitionTable(DeviceObject,
DiskGeometry.BytesPerSector,
FALSE,
static NTSTATUS
-xHalpReadSector(IN PDEVICE_OBJECT DeviceObject,
- IN ULONG SectorSize,
- IN PLARGE_INTEGER SectorOffset,
- OUT PVOID *Buffer)
+xHalpReadSector (IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SectorSize,
+ IN PLARGE_INTEGER SectorOffset,
+ IN PVOID Sector)
{
- KEVENT Event;
IO_STATUS_BLOCK StatusBlock;
- PUCHAR Sector;
+ KEVENT Event;
PIRP Irp;
NTSTATUS Status;
- DPRINT("xHalReadMBR()\n");
+ DPRINT("xHalpReadSector() called\n");
assert(DeviceObject);
- assert(Buffer);
-
- *Buffer = NULL;
-
- if (SectorSize < 512)
- SectorSize = 512;
- if (SectorSize > 4096)
- SectorSize = 4096;
-
- Sector = (PUCHAR)ExAllocatePool(PagedPool,
- SectorSize);
- if (Sector == NULL)
- return STATUS_NO_MEMORY;
+ assert(Sector);
KeInitializeEvent(&Event,
NotificationEvent,
FALSE);
- /* Read MBR (Master Boot Record) */
+ /* Read the sector */
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
DeviceObject,
Sector,
if (!NT_SUCCESS(Status))
{
- DPRINT("Reading MBR failed (Status 0x%08lx)\n",
+ DPRINT("Reading sector failed (Status 0x%08lx)\n",
Status);
- ExFreePool(Sector);
return Status;
}
- *Buffer = (PVOID)Sector;
return Status;
}
static NTSTATUS
-xHalpWriteSector(IN PDEVICE_OBJECT DeviceObject,
- IN ULONG SectorSize,
- IN PLARGE_INTEGER SectorOffset,
- OUT PVOID Sector)
+xHalpWriteSector (IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SectorSize,
+ IN PLARGE_INTEGER SectorOffset,
+ IN PVOID Sector)
{
- KEVENT Event;
IO_STATUS_BLOCK StatusBlock;
+ KEVENT Event;
PIRP Irp;
NTSTATUS Status;
- DPRINT("xHalWriteMBR()\n");
-
- if (SectorSize < 512)
- SectorSize = 512;
- if (SectorSize > 4096)
- SectorSize = 4096;
+ DPRINT("xHalpWriteSector() called\n");
KeInitializeEvent(&Event,
NotificationEvent,
FALSE);
- /* Write MBR (Master Boot Record) */
+ /* Write the sector */
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
DeviceObject,
Sector,
if (!NT_SUCCESS(Status))
{
- DPRINT("Writing MBR failed (Status 0x%08lx)\n",
+ DPRINT("Writing sector failed (Status 0x%08lx)\n",
Status);
- return Status;
}
return Status;
{
LARGE_INTEGER SectorOffset;
PPARTITION_SECTOR Sector;
- PULONG Shift;
NTSTATUS Status;
DPRINT("xHalExamineMBR()\n");
*Buffer = NULL;
- SectorOffset.QuadPart = 0ULL;
- Status = xHalpReadSector(DeviceObject,
- SectorSize,
- &SectorOffset,
- (PVOID *)&Sector);
+ if (SectorSize < 512)
+ SectorSize = 512;
+ if (SectorSize > 4096)
+ SectorSize = 4096;
+
+ Sector = (PPARTITION_SECTOR) ExAllocatePool (PagedPool,
+ SectorSize);
+ if (Sector == NULL)
+ {
+ DPRINT ("Partition sector allocation failed\n");
+ return;
+ }
+
+ SectorOffset.QuadPart = 0LL;
+ Status = xHalpReadSector (DeviceObject,
+ SectorSize,
+ &SectorOffset,
+ (PVOID)Sector);
if (!NT_SUCCESS(Status))
{
- DPRINT1("xHalpReadSector() failed (Status %lx)\n", Status);
+ DPRINT("xHalpReadSector() failed (Status %lx)\n", Status);
+ ExFreePool(Sector);
return;
}
{
/* Found 'Ontrack Disk Manager'. Shift all sectors by 63 */
DPRINT("Found 'Ontrack Disk Manager'!\n");
- Shift = (PULONG)Sector;
- *Shift = 63;
+ *((PULONG)Sector) = 63;
}
*Buffer = (PVOID)Sector;
}
/* Assign cdrom drives */
- DPRINT("CD-Rom drives: %d\n", ConfigInfo->CDRomCount);
- for (i = 0; i < ConfigInfo->CDRomCount; i++)
+ DPRINT("CD-Rom drives: %d\n", ConfigInfo->CdRomCount);
+ for (i = 0; i < ConfigInfo->CdRomCount; i++)
{
swprintf(Buffer1,
L"\\Device\\CdRom%d",
DOSDEVICE_DRIVE_CDROM);
}
- /* Anything else ?? */
+ /* Anything else to do? */
ExFreePool(Buffer2);
ExFreePool(Buffer1);
BOOLEAN ReturnRecognizedPartitions,
PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
{
- KEVENT Event;
- IO_STATUS_BLOCK StatusBlock;
- ULARGE_INTEGER PartitionOffset;
- ULARGE_INTEGER RealPartitionOffset;
- ULARGE_INTEGER nextPartitionOffset;
- ULARGE_INTEGER containerOffset;
- PIRP Irp;
+ LARGE_INTEGER RealPartitionOffset;
+ ULONGLONG PartitionOffset;
+ ULONGLONG nextPartitionOffset;
+ ULONGLONG containerOffset;
NTSTATUS Status;
PPARTITION_SECTOR PartitionSector;
PDRIVE_LAYOUT_INFORMATION LayoutBuffer;
*PartitionBuffer = NULL;
+ /* Check sector size */
+ if (SectorSize < 512)
+ SectorSize = 512;
+ if (SectorSize > 4096)
+ SectorSize = 4096;
+
/* Check for 'Ontrack Disk Manager' */
xHalExamineMBR(DeviceObject,
SectorSize,
RtlZeroMemory(LayoutBuffer,
0x1000);
- PartitionOffset.QuadPart = (ULONGLONG)0;
- containerOffset.QuadPart = (ULONGLONG)0;
+ PartitionOffset = 0ULL;
+ containerOffset = 0ULL;
do
{
- DPRINT("PartitionOffset: %I64u\n", PartitionOffset.QuadPart / SectorSize);
+ DPRINT("PartitionOffset: %I64u\n", PartitionOffset / SectorSize);
+ /* Handle disk managers */
if (DiskManager == OntrackDiskManager)
{
- RealPartitionOffset.QuadPart = PartitionOffset.QuadPart + (ULONGLONG)(63 * SectorSize);
+ /* Shift offset by 63 sectors */
+ RealPartitionOffset.QuadPart = PartitionOffset + (ULONGLONG)(63 * SectorSize);
}
- else
+ else if (DiskManager == EZ_Drive && PartitionOffset == 0ULL)
{
- RealPartitionOffset.QuadPart = PartitionOffset.QuadPart;
+ /* Use sector 1 instead of sector 0 */
+ RealPartitionOffset.QuadPart = (ULONGLONG)SectorSize;
}
-
- DPRINT("RealPartitionOffset: %I64u\n", RealPartitionOffset.QuadPart / SectorSize);
-
- KeInitializeEvent(&Event,
- NotificationEvent,
- FALSE);
-
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
- DeviceObject,
- PartitionSector, //SectorBuffer,
- SectorSize,
- (PLARGE_INTEGER)&RealPartitionOffset,
- &Event,
- &StatusBlock);
- Status = IoCallDriver(DeviceObject,
- Irp);
- if (Status == STATUS_PENDING)
+ else
{
- KeWaitForSingleObject(&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- Status = StatusBlock.Status;
+ RealPartitionOffset.QuadPart = PartitionOffset;
}
+ DPRINT ("RealPartitionOffset: %I64u\n",
+ RealPartitionOffset.QuadPart / SectorSize);
+
+ Status = xHalpReadSector (DeviceObject,
+ SectorSize,
+ &RealPartitionOffset,
+ PartitionSector);
if (!NT_SUCCESS(Status))
{
- DPRINT("Failed to read partition table sector (Status = 0x%08lx)\n",
- Status);
- ExFreePool(PartitionSector);
- ExFreePool(LayoutBuffer);
- return(Status);
+ DPRINT ("Failed to read partition table sector (Status = 0x%08lx)\n",
+ Status);
+ ExFreePool (PartitionSector);
+ ExFreePool (LayoutBuffer);
+ return Status;
}
- /* check the boot sector id */
+ /* Check the boot sector id */
DPRINT("Magic %x\n", PartitionSector->Magic);
if (PartitionSector->Magic != PARTITION_MAGIC)
{
- DbgPrint("Invalid partition sector magic\n");
- ExFreePool(PartitionSector);
+ DPRINT ("Invalid partition sector magic\n");
+ ExFreePool (PartitionSector);
*PartitionBuffer = LayoutBuffer;
- return(STATUS_SUCCESS);
+ return STATUS_SUCCESS;
}
#ifndef NDEBUG
(((PartitionSector->Partition[i].StartingSector) & 0xc0) << 2) +
PartitionSector->Partition[i].StartingCylinder,
PartitionSector->Partition[i].EndingHead,
- PartitionSector->Partition[i].EndingSector,
- PartitionSector->Partition[i].EndingCylinder,
+ PartitionSector->Partition[i].EndingSector & 0x3f,
+ (((PartitionSector->Partition[i].EndingSector) & 0xc0) << 2) +
+ PartitionSector->Partition[i].EndingCylinder,
PartitionSector->Partition[i].StartingBlock,
PartitionSector->Partition[i].SectorCount);
}
#endif
- if (PartitionOffset.QuadPart == 0ULL)
+ if (PartitionOffset == 0ULL)
{
LayoutBuffer->Signature = PartitionSector->Signature;
DPRINT("Disk signature: %lx\n", LayoutBuffer->Signature);
for (i = 0; i < PARTITION_TBL_SIZE; i++)
{
+ if (IsContainerPartition(PartitionSector->Partition[i].PartitionType))
+ {
+ ExtendedFound = TRUE;
+ if ((ULONGLONG) containerOffset == (ULONGLONG) 0)
+ {
+ containerOffset = PartitionOffset;
+ }
+ nextPartitionOffset = (ULONGLONG) containerOffset +
+ (ULONGLONG) PartitionSector->Partition[i].StartingBlock *
+ (ULONGLONG) SectorSize;
+ }
+
if ((ReturnRecognizedPartitions == FALSE) ||
((ReturnRecognizedPartitions == TRUE) &&
IsRecognizedPartition(PartitionSector->Partition[i].PartitionType)))
DPRINT("Partition %u: Normal Partition\n", i);
Count = LayoutBuffer->PartitionCount;
DPRINT("Logical Partition %u\n", Count);
+
if (PartitionSector->Partition[i].StartingBlock == 0)
{
LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart = 0;
else if (IsContainerPartition(PartitionSector->Partition[i].PartitionType))
{
LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
- (ULONGLONG)PartitionOffset.QuadPart;
+ (ULONGLONG) containerOffset +
+ (ULONGLONG) PartitionSector->Partition[i].StartingBlock *
+ (ULONGLONG) SectorSize;
}
else
{
LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
- (ULONGLONG)PartitionOffset.QuadPart +
+ (ULONGLONG)PartitionOffset +
((ULONGLONG)PartitionSector->Partition[i].StartingBlock * (ULONGLONG)SectorSize);
}
LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart =
(ULONGLONG)PartitionSector->Partition[i].SectorCount * (ULONGLONG)SectorSize;
- LayoutBuffer->PartitionEntry[Count].HiddenSectors = 0;
+ LayoutBuffer->PartitionEntry[Count].HiddenSectors =
+ PartitionSector->Partition[i].StartingBlock;
if (IsRecognizedPartition(PartitionSector->Partition[i].PartitionType))
{
LayoutBuffer->PartitionCount++;
}
-
- if (IsContainerPartition(PartitionSector->Partition[i].PartitionType))
- {
- ExtendedFound = TRUE;
- if ((ULONGLONG) containerOffset.QuadPart == (ULONGLONG) 0)
- {
- containerOffset = PartitionOffset;
- }
- nextPartitionOffset.QuadPart = (ULONGLONG) containerOffset.QuadPart +
- (ULONGLONG) PartitionSector->Partition[i].StartingBlock *
- (ULONGLONG) SectorSize;
- }
}
+
PartitionOffset = nextPartitionOffset;
}
while (ExtendedFound == TRUE);
IN ULONG PartitionNumber,
IN ULONG PartitionType)
{
- return(STATUS_NOT_IMPLEMENTED);
-}
-
-
-NTSTATUS FASTCALL
-xHalIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject,
- IN ULONG SectorSize,
- IN ULONG SectorsPerTrack,
- IN ULONG NumberOfHeads,
- IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
-{
PPARTITION_SECTOR PartitionSector;
- LARGE_INTEGER SectorOffset;
+ LARGE_INTEGER RealPartitionOffset;
+ ULONGLONG PartitionOffset;
+ ULONGLONG nextPartitionOffset;
+ ULONGLONG containerOffset;
NTSTATUS Status;
ULONG i;
+ ULONG Number = 1;
+ BOOLEAN ExtendedFound = FALSE;
+ DISK_MANAGER DiskManager = NoDiskManager;
- DPRINT("xHalIoWritePartitionTable(%p %lu %lu %p)\n",
- DeviceObject,
- SectorSize,
- SectorsPerTrack,
- PartitionBuffer);
+ DPRINT ("xHalIoSetPartitionInformation(%p %lu %lu %lu)\n",
+ DeviceObject,
+ SectorSize,
+ PartitionNumber,
+ PartitionType);
- assert(DeviceObject);
- assert(PartitionBuffer);
+ /* Check sector size */
+ if (SectorSize < 512)
+ SectorSize = 512;
+ if (SectorSize > 4096)
+ SectorSize = 4096;
/* Check for 'Ontrack Disk Manager' */
- xHalExamineMBR(DeviceObject,
- SectorSize,
- 0x54,
- (PVOID *) &PartitionSector);
+ xHalExamineMBR (DeviceObject,
+ SectorSize,
+ 0x54,
+ (PVOID*) &PartitionSector);
if (PartitionSector != NULL)
{
- DPRINT1("Ontrack Disk Manager is not supported\n");
- ExFreePool(PartitionSector);
- return STATUS_UNSUCCESSFUL;
+ DPRINT ("Found 'Ontrack Disk Manager'\n");
+ DiskManager = OntrackDiskManager;
+ ExFreePool (PartitionSector);
}
/* Check for 'EZ-Drive' */
- xHalExamineMBR(DeviceObject,
- SectorSize,
- 0x55,
- (PVOID *) &PartitionSector);
+ xHalExamineMBR (DeviceObject,
+ SectorSize,
+ 0x55,
+ (PVOID*) &PartitionSector);
if (PartitionSector != NULL)
{
- DPRINT1("EZ-Drive is not supported\n");
- ExFreePool(PartitionSector);
- return STATUS_UNSUCCESSFUL;
+ DPRINT ("Found 'EZ-Drive'\n");
+ DiskManager = EZ_Drive;
+ ExFreePool (PartitionSector);
}
-
- for (i = 0; i < PartitionBuffer->PartitionCount; i++)
+ /* Allocate partition sector */
+ PartitionSector = (PPARTITION_SECTOR) ExAllocatePool (PagedPool,
+ SectorSize);
+ if (PartitionSector == NULL)
{
- if (IsContainerPartition(PartitionBuffer->PartitionEntry[i].PartitionType))
- {
- /* FIXME: Implement */
- DPRINT1("Writing MBRs with extended partitions is not implemented\n");
- return STATUS_UNSUCCESSFUL;
- }
+ return STATUS_INSUFFICIENT_RESOURCES;
}
+ PartitionOffset = 0ULL;
+ containerOffset = 0ULL;
- SectorOffset.QuadPart = 0ULL;
- Status = xHalpReadSector(DeviceObject,
- SectorSize,
- &SectorOffset,
- (PVOID *) &PartitionSector);
- if (!NT_SUCCESS(Status))
+ do
{
- DPRINT1("xHalpReadSector() failed (Status %lx)\n", Status);
- return Status;
- }
-
- DPRINT1("WARNING: Only 'BootFlags' is implemented\n");
+ DPRINT ("PartitionOffset: %I64u\n", PartitionOffset / SectorSize);
-
- for (i = 0; i < PartitionBuffer->PartitionCount; i++)
- {
- //= PartitionBuffer->PartitionEntry[i].StartingOffset;
- //= PartitionBuffer->PartitionEntry[i].PartitionLength;
- //= PartitionBuffer->PartitionEntry[i].HiddenSectors;
- //= PartitionBuffer->PartitionEntry[i].PartitionType;
- //= PartitionBuffer->PartitionEntry[i].PartitionType;
-
- if (PartitionBuffer->PartitionEntry[i].BootIndicator)
- {
- PartitionSector->Partition[i].BootFlags |= 0x80;
- }
+ /* Handle disk managers */
+ if (DiskManager == OntrackDiskManager)
+ {
+ /* Shift offset by 63 sectors */
+ RealPartitionOffset.QuadPart = PartitionOffset + (ULONGLONG)(63 * SectorSize);
+ }
+ else if (DiskManager == EZ_Drive && PartitionOffset == 0ULL)
+ {
+ /* Use sector 1 instead of sector 0 */
+ RealPartitionOffset.QuadPart = (ULONGLONG)SectorSize;
+ }
else
- {
- PartitionSector->Partition[i].BootFlags &= ~0x80;
- }
+ {
+ RealPartitionOffset.QuadPart = PartitionOffset;
+ }
- //= PartitionBuffer->PartitionEntry[i].RecognizedPartition;
- //= PartitionBuffer->PartitionEntry[i].RewritePartition;
- }
+ DPRINT ("RealPartitionOffset: %I64u\n",
+ RealPartitionOffset.QuadPart / SectorSize);
+ Status = xHalpReadSector (DeviceObject,
+ SectorSize,
+ &RealPartitionOffset,
+ PartitionSector);
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT ("Failed to read partition table sector (Status = 0x%08lx)\n",
+ Status);
+ ExFreePool (PartitionSector);
+ return Status;
+ }
- SectorOffset.QuadPart = 0ULL;
- Status = xHalpWriteSector(DeviceObject,
- SectorSize,
- &SectorOffset,
- (PVOID) PartitionSector);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("xHalpWriteSector() failed (Status %lx)\n", Status);
- ExFreePool(PartitionSector);
- return Status;
- }
+ /* Check the boot sector id */
+ DPRINT("Magic %x\n", PartitionSector->Magic);
+ if (PartitionSector->Magic != PARTITION_MAGIC)
+ {
+ DPRINT ("Invalid partition sector magic\n");
+ ExFreePool (PartitionSector);
+ return STATUS_UNSUCCESSFUL;
+ }
#ifndef NDEBUG
for (i = 0; i < PARTITION_TBL_SIZE; i++)
(((PartitionSector->Partition[i].StartingSector) & 0xc0) << 2) +
PartitionSector->Partition[i].StartingCylinder,
PartitionSector->Partition[i].EndingHead,
- PartitionSector->Partition[i].EndingSector,
- PartitionSector->Partition[i].EndingCylinder,
+ PartitionSector->Partition[i].EndingSector & 0x3f,
+ (((PartitionSector->Partition[i].EndingSector) & 0xc0) << 2) +
+ PartitionSector->Partition[i].EndingCylinder,
PartitionSector->Partition[i].StartingBlock,
PartitionSector->Partition[i].SectorCount);
}
#endif
+ ExtendedFound = FALSE;
+ for (i = 0; i < PARTITION_TBL_SIZE; i++)
+ {
+ if (IsContainerPartition (PartitionSector->Partition[i].PartitionType))
+ {
+ ExtendedFound = TRUE;
+ if (containerOffset == 0ULL)
+ {
+ containerOffset = PartitionOffset;
+ }
+ nextPartitionOffset = containerOffset +
+ (ULONGLONG) PartitionSector->Partition[i].StartingBlock *
+ (ULONGLONG) SectorSize;
+ }
+
+ /* Handle recognized partition */
+ if (IsRecognizedPartition (PartitionSector->Partition[i].PartitionType))
+ {
+ if (Number == PartitionNumber)
+ {
+ /* Set partition type */
+ PartitionSector->Partition[i].PartitionType = PartitionType;
+
+ /* Write partition sector */
+ Status = xHalpWriteSector (DeviceObject,
+ SectorSize,
+ &RealPartitionOffset,
+ PartitionSector);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("xHalpWriteSector() failed (Status %lx)\n", Status);
+ }
+
+ ExFreePool (PartitionSector);
+ return Status;
+ }
+ Number++;
+ }
+ }
+
+ PartitionOffset = nextPartitionOffset;
+ }
+ while (ExtendedFound == TRUE);
+
ExFreePool(PartitionSector);
- return(STATUS_SUCCESS);
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+NTSTATUS FASTCALL
+xHalIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SectorSize,
+ IN ULONG SectorsPerTrack,
+ IN ULONG NumberOfHeads,
+ IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
+{
+ PPARTITION_SECTOR PartitionSector;
+ LARGE_INTEGER RealPartitionOffset;
+ ULONGLONG PartitionOffset;
+ ULONGLONG NextPartitionOffset;
+ ULONGLONG ContainerOffset;
+ BOOLEAN ContainerEntry;
+ DISK_MANAGER DiskManager;
+ ULONG i;
+ ULONG j;
+ ULONG StartBlock;
+ ULONG SectorCount;
+ ULONG StartCylinder;
+ ULONG StartSector;
+ ULONG StartHead;
+ ULONG EndCylinder;
+ ULONG EndSector;
+ ULONG EndHead;
+ ULONG lba;
+ ULONG x;
+ NTSTATUS Status;
+
+ DPRINT ("xHalIoWritePartitionTable(%p %lu %lu %lu %p)\n",
+ DeviceObject,
+ SectorSize,
+ SectorsPerTrack,
+ NumberOfHeads,
+ PartitionBuffer);
+
+ assert(DeviceObject);
+ assert(PartitionBuffer);
+
+ DiskManager = NoDiskManager;
+
+ /* Check sector size */
+ if (SectorSize < 512)
+ SectorSize = 512;
+ if (SectorSize > 4096)
+ SectorSize = 4096;
+
+ /* Check for 'Ontrack Disk Manager' */
+ xHalExamineMBR (DeviceObject,
+ SectorSize,
+ 0x54,
+ (PVOID *) &PartitionSector);
+ if (PartitionSector != NULL)
+ {
+ DPRINT ("Found 'Ontrack Disk Manager'\n");
+ DiskManager = OntrackDiskManager;
+ ExFreePool (PartitionSector);
+ }
+
+ /* Check for 'EZ-Drive' */
+ xHalExamineMBR (DeviceObject,
+ SectorSize,
+ 0x55,
+ (PVOID *) &PartitionSector);
+ if (PartitionSector != NULL)
+ {
+ DPRINT ("Found 'EZ-Drive'\n");
+ DiskManager = EZ_Drive;
+ ExFreePool (PartitionSector);
+ }
+
+ /* Allocate partition sector */
+ PartitionSector = (PPARTITION_SECTOR)ExAllocatePool(PagedPool,
+ SectorSize);
+ if (PartitionSector == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Status = STATUS_SUCCESS;
+ PartitionOffset = 0ULL;
+ ContainerOffset = 0ULL;
+ for (i = 0; i < PartitionBuffer->PartitionCount; i += 4)
+ {
+ DPRINT ("PartitionOffset: %I64u\n", PartitionOffset);
+ DPRINT ("ContainerOffset: %I64u\n", ContainerOffset);
+
+ /* Handle disk managers */
+ if (DiskManager == OntrackDiskManager)
+ {
+ /* Shift offset by 63 sectors */
+ RealPartitionOffset.QuadPart = PartitionOffset + (ULONGLONG)(63 * SectorSize);
+ }
+ else if (DiskManager == EZ_Drive && PartitionOffset == 0ULL)
+ {
+ /* Use sector 1 instead of sector 0 */
+ RealPartitionOffset.QuadPart = (ULONGLONG)SectorSize;
+ }
+ else
+ {
+ RealPartitionOffset.QuadPart = PartitionOffset;
+ }
+
+ /* Write modified partition tables */
+ if (PartitionBuffer->PartitionEntry[i].RewritePartition == TRUE ||
+ PartitionBuffer->PartitionEntry[i + 1].RewritePartition == TRUE ||
+ PartitionBuffer->PartitionEntry[i + 2].RewritePartition == TRUE ||
+ PartitionBuffer->PartitionEntry[i + 3].RewritePartition == TRUE)
+ {
+ /* Read partition sector */
+ Status = xHalpReadSector (DeviceObject,
+ SectorSize,
+ &RealPartitionOffset,
+ PartitionSector);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("xHalpReadSector() failed (Status %lx)\n", Status);
+ break;
+ }
+
+ /* Initialize a new partition sector */
+ if (PartitionSector->Magic != PARTITION_MAGIC)
+ {
+ /* Create empty partition sector */
+ RtlZeroMemory (PartitionSector,
+ SectorSize);
+ PartitionSector->Magic = PARTITION_MAGIC;
+ }
+
+ /* Update partition sector entries */
+ for (j = 0; j < 4; j++)
+ {
+ if (PartitionBuffer->PartitionEntry[i + j].RewritePartition == TRUE)
+ {
+ /* Set partition boot flag */
+ if (PartitionBuffer->PartitionEntry[i + j].BootIndicator)
+ {
+ PartitionSector->Partition[j].BootFlags |= 0x80;
+ }
+ else
+ {
+ PartitionSector->Partition[j].BootFlags &= ~0x80;
+ }
+
+ /* Set partition type */
+ PartitionSector->Partition[j].PartitionType =
+ PartitionBuffer->PartitionEntry[i + j].PartitionType;
+
+ /* Set partition data */
+ if (PartitionBuffer->PartitionEntry[i + j].StartingOffset.QuadPart == 0ULL &&
+ PartitionBuffer->PartitionEntry[i + j].PartitionLength.QuadPart == 0ULL)
+ {
+ PartitionSector->Partition[j].StartingBlock = 0;
+ PartitionSector->Partition[j].SectorCount = 0;
+ PartitionSector->Partition[j].StartingCylinder = 0;
+ PartitionSector->Partition[j].StartingHead = 0;
+ PartitionSector->Partition[j].StartingSector = 0;
+ PartitionSector->Partition[j].EndingCylinder = 0;
+ PartitionSector->Partition[j].EndingHead = 0;
+ PartitionSector->Partition[j].EndingSector = 0;
+ }
+ else
+ {
+ /*
+ * CHS formulas:
+ * x = LBA DIV SectorsPerTrack
+ * cylinder = (x DIV NumberOfHeads) % 1024
+ * head = x MOD NumberOfHeads
+ * sector = (LBA MOD SectorsPerTrack) + 1
+ */
+
+ /* Compute starting CHS values */
+ lba = (PartitionBuffer->PartitionEntry[i + j].StartingOffset.QuadPart) / SectorSize;
+ x = lba / SectorsPerTrack;
+ StartCylinder = (x / NumberOfHeads) %1024;
+ StartHead = x % NumberOfHeads;
+ StartSector = (lba % SectorsPerTrack) + 1;
+ DPRINT ("StartingOffset (LBA:%d C:%d H:%d S:%d)\n",
+ lba, StartCylinder, StartHead, StartSector);
+
+ /* Compute ending CHS values */
+ lba = (PartitionBuffer->PartitionEntry[i + j].StartingOffset.QuadPart +
+ (PartitionBuffer->PartitionEntry[i + j].PartitionLength.QuadPart - 1)) / SectorSize;
+ x = lba / SectorsPerTrack;
+ EndCylinder = (x / NumberOfHeads) % 1024;
+ EndHead = x % NumberOfHeads;
+ EndSector = (lba % SectorsPerTrack) + 1;
+ DPRINT ("EndingOffset (LBA:%d C:%d H:%d S:%d)\n",
+ lba, EndCylinder, EndHead, EndSector);
+
+ /* Set starting CHS values */
+ PartitionSector->Partition[j].StartingCylinder = StartCylinder & 0xff;
+ PartitionSector->Partition[j].StartingHead = StartHead;
+ PartitionSector->Partition[j].StartingSector =
+ ((StartCylinder & 0x0300) >> 2) + (StartSector & 0x3f);
+
+ /* Set ending CHS values */
+ PartitionSector->Partition[j].EndingCylinder = EndCylinder & 0xff;
+ PartitionSector->Partition[j].EndingHead = EndHead;
+ PartitionSector->Partition[j].EndingSector =
+ ((EndCylinder & 0x0300) >> 2) + (EndSector & 0x3f);
+
+ /* Calculate start sector and sector count */
+ StartBlock =
+ (PartitionBuffer->PartitionEntry[i + j].StartingOffset.QuadPart - ContainerOffset) / SectorSize;
+ SectorCount =
+ PartitionBuffer->PartitionEntry[i + j].PartitionLength.QuadPart / SectorSize;
+ DPRINT ("LBA (StartBlock:%lu SectorCount:%lu)\n",
+ StartBlock, SectorCount);
+
+ /* Set start sector and sector count */
+ PartitionSector->Partition[j].StartingBlock = StartBlock;
+ PartitionSector->Partition[j].SectorCount = SectorCount;
+ }
+ }
+ }
+
+ /* Write partition sector */
+ Status = xHalpWriteSector (DeviceObject,
+ SectorSize,
+ &RealPartitionOffset,
+ PartitionSector);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("xHalpWriteSector() failed (Status %lx)\n", Status);
+ break;
+ }
+ }
+
+ ContainerEntry = FALSE;
+ for (j = 0; j < 4; j++)
+ {
+ if (IsContainerPartition (PartitionBuffer->PartitionEntry[i + j].PartitionType))
+ {
+ ContainerEntry = TRUE;
+ NextPartitionOffset =
+ PartitionBuffer->PartitionEntry[i + j].StartingOffset.QuadPart;
+
+ if (ContainerOffset == 0ULL)
+ {
+ ContainerOffset = NextPartitionOffset;
+ }
+ }
+ }
+
+ if (ContainerEntry == FALSE)
+ {
+ DPRINT ("No container entry in partition sector!\n");
+ break;
+ }
+
+ PartitionOffset = NextPartitionOffset;
+ }
+
+ ExFreePool (PartitionSector);
+
+ return Status;
}
/* EOF */