-/* $Id: xhaldrv.c,v 1.35 2003/08/10 16:49:07 ekohl Exp $
+/* $Id: xhaldrv.c,v 1.36 2003/08/15 19:37:32 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
PIRP Irp;
NTSTATUS Status;
- DPRINT("xHalReadMBR()\n");
+ DPRINT("xHalpReadSector()\n");
assert(DeviceObject);
assert(Buffer);
NotificationEvent,
FALSE);
- /* Read MBR (Master Boot Record) */
+ /* Read the sector */
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
DeviceObject,
Sector,
}
+static NTSTATUS
+xHalpReadSector2 (IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SectorSize,
+ IN PLARGE_INTEGER SectorOffset,
+ IN PVOID Sector)
+{
+ IO_STATUS_BLOCK StatusBlock;
+ KEVENT Event;
+ PIRP Irp;
+ NTSTATUS Status;
+
+ DPRINT("xHalpReadSector2() called\n");
+
+ assert(DeviceObject);
+ assert(Buffer);
+
+ KeInitializeEvent(&Event,
+ NotificationEvent,
+ FALSE);
+
+ /* Read the sector */
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
+ DeviceObject,
+ Sector,
+ SectorSize,
+ SectorOffset,
+ &Event,
+ &StatusBlock);
+
+ Status = IoCallDriver(DeviceObject,
+ Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = StatusBlock.Status;
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Reading sector failed (Status 0x%08lx)\n",
+ Status);
+ return Status;
+ }
+
+ return Status;
+}
+
+
static NTSTATUS
xHalpWriteSector(IN PDEVICE_OBJECT DeviceObject,
IN ULONG SectorSize,
PIRP Irp;
NTSTATUS Status;
- DPRINT("xHalWriteMBR()\n");
+ DPRINT("xHalpWriteSector() called\n");
if (SectorSize < 512)
SectorSize = 512;
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;
}
{
KEVENT Event;
IO_STATUS_BLOCK StatusBlock;
- ULARGE_INTEGER PartitionOffset;
- ULARGE_INTEGER RealPartitionOffset;
- ULARGE_INTEGER nextPartitionOffset;
- ULARGE_INTEGER containerOffset;
+ LARGE_INTEGER RealPartitionOffset;
+ ULONGLONG PartitionOffset;
+ ULONGLONG nextPartitionOffset;
+ ULONGLONG containerOffset;
PIRP Irp;
NTSTATUS Status;
PPARTITION_SECTOR PartitionSector;
RtlZeroMemory(LayoutBuffer,
0x1000);
- PartitionOffset.QuadPart = (ULONGLONG)0;
- containerOffset.QuadPart = (ULONGLONG)0;
+ PartitionOffset = 0ULL;
+ containerOffset = 0ULL;
do
{
if (DiskManager == OntrackDiskManager)
{
- RealPartitionOffset.QuadPart = PartitionOffset.QuadPart + (ULONGLONG)(63 * SectorSize);
+ RealPartitionOffset.QuadPart = PartitionOffset + (ULONGLONG)(63 * SectorSize);
}
else
{
- RealPartitionOffset.QuadPart = PartitionOffset.QuadPart;
+ RealPartitionOffset.QuadPart = PartitionOffset;
}
DPRINT("RealPartitionOffset: %I64u\n", RealPartitionOffset.QuadPart / SectorSize);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
DeviceObject,
- PartitionSector, //SectorBuffer,
+ PartitionSector,
SectorSize,
(PLARGE_INTEGER)&RealPartitionOffset,
&Event,
}
#endif
- if (PartitionOffset.QuadPart == 0ULL)
+// if (PartitionOffset.QuadPart == 0ULL)
+ if (PartitionOffset == 0ULL)
{
LayoutBuffer->Signature = PartitionSector->Signature;
DPRINT("Disk signature: %lx\n", LayoutBuffer->Signature);
if (IsContainerPartition(PartitionSector->Partition[i].PartitionType))
{
ExtendedFound = TRUE;
- if ((ULONGLONG) containerOffset.QuadPart == (ULONGLONG) 0)
+ if ((ULONGLONG) containerOffset == (ULONGLONG) 0)
{
containerOffset = PartitionOffset;
}
- nextPartitionOffset.QuadPart = (ULONGLONG) containerOffset.QuadPart +
+ nextPartitionOffset = (ULONGLONG) containerOffset +
(ULONGLONG) PartitionSector->Partition[i].StartingBlock *
(ULONGLONG) SectorSize;
}
else if (IsContainerPartition(PartitionSector->Partition[i].PartitionType))
{
LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
- (ULONGLONG) containerOffset.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 =
IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
{
PPARTITION_SECTOR PartitionSector;
- LARGE_INTEGER SectorOffset;
- NTSTATUS Status;
+ LARGE_INTEGER RealPartitionOffset;
+ ULONGLONG PartitionOffset;
+ ULONGLONG NextPartitionOffset;
+ ULONGLONG ContainerOffset;
+ BOOLEAN ContainerEntry;
ULONG i;
-
+ ULONG j;
ULONG StartBlock;
ULONG SectorCount;
ULONG StartCylinder;
ULONG EndHead;
ULONG lba;
ULONG x;
+ NTSTATUS Status;
- DPRINT("xHalIoWritePartitionTable(%p %lu %lu %lu %p)\n",
- DeviceObject,
- SectorSize,
- SectorsPerTrack,
- NumberOfHeads,
- PartitionBuffer);
+ DPRINT1 ("xHalIoWritePartitionTable(%p %lu %lu %lu %p)\n",
+ DeviceObject,
+ SectorSize,
+ SectorsPerTrack,
+ NumberOfHeads,
+ PartitionBuffer);
assert(DeviceObject);
assert(PartitionBuffer);
return STATUS_UNSUCCESSFUL;
}
-
- 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;
}
-
- SectorOffset.QuadPart = 0ULL;
- Status = xHalpReadSector(DeviceObject,
- SectorSize,
- &SectorOffset,
- (PVOID *) &PartitionSector);
- if (!NT_SUCCESS(Status))
+ Status = STATUS_SUCCESS;
+ PartitionOffset = 0ULL;
+ ContainerOffset = 0ULL;
+ for (i = 0; i < PartitionBuffer->PartitionCount; i += 4)
{
- DPRINT1("xHalpReadSector() failed (Status %lx)\n", Status);
- return Status;
- }
+ DPRINT1 ("PartitionOffset: %I64u\n", PartitionOffset);
+ DPRINT1 ("ContainerOffset: %I64u\n", ContainerOffset);
- for (i = 0; i < PartitionBuffer->PartitionCount; i++)
- {
- if (PartitionBuffer->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED)
+ /* FIXME: Handle partition managers */
+ 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)
{
- /*
- * CHS formulas:
- * x = LBA DIV SectorsPerTrack
- * cylinder = x DIV NumberOfHeads
- * head = x MOD NumberOfHeads
- * sector = (LBA MOD SectorsPerTrack) + 1
- */
-
- if (PartitionBuffer->PartitionEntry[i].BootIndicator)
- {
- PartitionSector->Partition[i].BootFlags |= 0x80;
- }
- else
- {
- PartitionSector->Partition[i].BootFlags &= ~0x80;
- }
-
- PartitionSector->Partition[i].PartitionType = PartitionBuffer->PartitionEntry[i].PartitionType;
-
- /* Compute starting CHS values */
- lba = (PartitionBuffer->PartitionEntry[i].StartingOffset.QuadPart / SectorSize);
- StartBlock = lba; /* Save this for later */
- x = lba / SectorsPerTrack;
- StartCylinder = x / NumberOfHeads;
- 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].StartingOffset.QuadPart
- + (PartitionBuffer->PartitionEntry[i].PartitionLength.QuadPart - 1)) / SectorSize;
- SectorCount = lba - StartBlock; /* Save this for later */
- x = lba / SectorsPerTrack;
- EndCylinder = x / NumberOfHeads;
- EndHead = x % NumberOfHeads;
- EndSector = (lba % SectorsPerTrack) + 1;
- DPRINT("EndingOffset (LBA:%d C:%d H:%d S:%d)\n", lba, EndCylinder, EndHead, EndSector);
-
- /* Set startsector and sectorcount */
- PartitionSector->Partition[i].StartingBlock = StartBlock;
- PartitionSector->Partition[i].SectorCount = SectorCount;
-
- /* Set starting CHS values */
- PartitionSector->Partition[i].StartingCylinder = StartCylinder & 0xff;
- PartitionSector->Partition[i].StartingHead = StartHead;
- PartitionSector->Partition[i].StartingSector = ((StartCylinder & 0x0300) >> 2) + (StartSector & 0x3f);
-
- /* Set ending CHS values */
- PartitionSector->Partition[i].EndingCylinder = EndCylinder & 0xff;
- PartitionSector->Partition[i].EndingHead = EndHead;
- PartitionSector->Partition[i].EndingSector = ((EndCylinder & 0x0300) >> 2) + (EndSector & 0x3f);
+ /* Read partition sector */
+ Status = xHalpReadSector2 (DeviceObject,
+ SectorSize,
+ &RealPartitionOffset,
+ PartitionSector);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("xHalpReadSector2() 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;
+ DPRINT1 ("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;
+ DPRINT1 ("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;
+ DPRINT1 ("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;
+ }
}
- else
+
+ ContainerEntry = FALSE;
+ for (j = 0; j < 4; j++)
{
- PartitionSector->Partition[i].BootFlags = 0;
- PartitionSector->Partition[i].PartitionType = PARTITION_ENTRY_UNUSED;
- PartitionSector->Partition[i].StartingHead = 0;
- PartitionSector->Partition[i].StartingSector = 0;
- PartitionSector->Partition[i].StartingCylinder = 0;
- PartitionSector->Partition[i].EndingHead = 0;
- PartitionSector->Partition[i].EndingSector = 0;
- PartitionSector->Partition[i].EndingCylinder = 0;
- PartitionSector->Partition[i].StartingBlock = 0;
- PartitionSector->Partition[i].SectorCount = 0;
- }
- }
+ if (IsContainerPartition (PartitionBuffer->PartitionEntry[i + j].PartitionType))
+ {
+ ContainerEntry = TRUE;
+ NextPartitionOffset =
+ PartitionBuffer->PartitionEntry[i + j].StartingOffset.QuadPart;
+ if (ContainerOffset == 0ULL)
+ {
+ ContainerOffset = NextPartitionOffset;
+ }
+ }
+ }
- 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;
- }
+ if (ContainerEntry == FALSE)
+ {
+ DPRINT ("No container entry in partition sector!\n");
+ break;
+ }
-#ifndef NDEBUG
- for (i = 0; i < PARTITION_TBL_SIZE; i++)
- {
- DPRINT1(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",
- i,
- PartitionSector->Partition[i].BootFlags,
- PartitionSector->Partition[i].PartitionType,
- PartitionSector->Partition[i].StartingHead,
- PartitionSector->Partition[i].StartingSector & 0x3f,
- (((PartitionSector->Partition[i].StartingSector) & 0xc0) << 2) +
- PartitionSector->Partition[i].StartingCylinder,
- PartitionSector->Partition[i].EndingHead,
- PartitionSector->Partition[i].EndingSector & 0x3f,
- (((PartitionSector->Partition[i].EndingSector) & 0xc0) << 2) +
- PartitionSector->Partition[i].EndingCylinder,
- PartitionSector->Partition[i].StartingBlock,
- PartitionSector->Partition[i].SectorCount);
+ PartitionOffset = NextPartitionOffset;
}
-#endif
- ExFreePool(PartitionSector);
+ ExFreePool (PartitionSector);
- return(STATUS_SUCCESS);
+ return Status;
}
/* EOF */