3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/xhaldrv.c
6 * PURPOSE: Hal drive routines
7 * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/xhal.h>
18 #include <internal/debug.h>
20 /* LOCAL MACROS and TYPES ***************************************************/
22 #define AUTO_DRIVE ((ULONG)-1)
24 #define PARTITION_MAGIC 0xaa55
26 #define PARTITION_TBL_SIZE 4
29 typedef struct _PARTITION
31 unsigned char BootFlags; /* bootable? 0=no, 128=yes */
32 unsigned char StartingHead; /* beginning head number */
33 unsigned char StartingSector; /* beginning sector number */
34 unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */
35 unsigned char PartitionType; /* Operating System type indicator code */
36 unsigned char EndingHead; /* ending head number */
37 unsigned char EndingSector; /* ending sector number */
38 unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick */
39 unsigned int StartingBlock; /* first sector relative to start of disk */
40 unsigned int SectorCount; /* number of sectors in partition */
41 } PACKED PARTITION, *PPARTITION;
44 typedef struct _PARTITION_SECTOR
46 UCHAR BootCode[440]; /* 0x000 */
47 ULONG Signature; /* 0x1B8 */
48 UCHAR Reserved[2]; /* 0x1BC */
49 PARTITION Partition[PARTITION_TBL_SIZE]; /* 0x1BE */
50 USHORT Magic; /* 0x1FE */
51 } PACKED PARTITION_SECTOR, *PPARTITION_SECTOR;
54 typedef enum _DISK_MANAGER
62 /* FUNCTIONS *****************************************************************/
65 xHalQueryDriveLayout(IN PUNICODE_STRING DeviceName,
66 OUT PDRIVE_LAYOUT_INFORMATION *LayoutInfo)
68 IO_STATUS_BLOCK StatusBlock;
69 DISK_GEOMETRY DiskGeometry;
70 PDEVICE_OBJECT DeviceObject = NULL;
71 PFILE_OBJECT FileObject;
76 DPRINT("xHalpQueryDriveLayout %wZ %p\n",
80 /* Get the drives sector size */
81 Status = IoGetDeviceObjectPointer(DeviceName,
85 if (!NT_SUCCESS(Status))
87 DPRINT("Status %x\n",Status);
91 KeInitializeEvent(&Event,
95 Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY,
100 sizeof(DISK_GEOMETRY),
106 ObDereferenceObject(FileObject);
107 return(STATUS_INSUFFICIENT_RESOURCES);
110 Status = IoCallDriver(DeviceObject,
112 if (Status == STATUS_PENDING)
114 KeWaitForSingleObject(&Event,
119 Status = StatusBlock.Status;
121 if (!NT_SUCCESS(Status))
123 if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
125 DiskGeometry.BytesPerSector = 512;
129 ObDereferenceObject(FileObject);
134 DPRINT("DiskGeometry.BytesPerSector: %d\n",
135 DiskGeometry.BytesPerSector);
137 /* read the partition table */
138 Status = IoReadPartitionTable(DeviceObject,
139 DiskGeometry.BytesPerSector,
143 if ((!NT_SUCCESS(Status) || (*LayoutInfo)->PartitionCount == 0) &&
144 DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
146 PDRIVE_LAYOUT_INFORMATION Buffer;
148 if (NT_SUCCESS(Status))
150 ExFreePool(*LayoutInfo);
153 /* Allocate a partition list for a single entry. */
154 Buffer = ExAllocatePool(NonPagedPool,
155 sizeof(DRIVE_LAYOUT_INFORMATION));
158 RtlZeroMemory(Buffer,
159 sizeof(DRIVE_LAYOUT_INFORMATION));
160 Buffer->PartitionCount = 1;
161 *LayoutInfo = Buffer;
163 Status = STATUS_SUCCESS;
167 ObDereferenceObject(FileObject);
174 xHalpReadSector(IN PDEVICE_OBJECT DeviceObject,
176 IN PLARGE_INTEGER SectorOffset,
180 IO_STATUS_BLOCK StatusBlock;
185 DPRINT("xHalReadMBR()\n");
187 assert(DeviceObject);
192 if (SectorSize < 512)
194 if (SectorSize > 4096)
197 Sector = (PUCHAR)ExAllocatePool(PagedPool,
200 return STATUS_NO_MEMORY;
202 KeInitializeEvent(&Event,
206 /* Read MBR (Master Boot Record) */
207 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
215 Status = IoCallDriver(DeviceObject,
217 if (Status == STATUS_PENDING)
219 KeWaitForSingleObject(&Event,
224 Status = StatusBlock.Status;
227 if (!NT_SUCCESS(Status))
229 DPRINT("Reading MBR failed (Status 0x%08lx)\n",
235 *Buffer = (PVOID)Sector;
241 xHalpWriteSector(IN PDEVICE_OBJECT DeviceObject,
243 IN PLARGE_INTEGER SectorOffset,
247 IO_STATUS_BLOCK StatusBlock;
251 DPRINT("xHalWriteMBR()\n");
253 if (SectorSize < 512)
255 if (SectorSize > 4096)
258 KeInitializeEvent(&Event,
262 /* Write MBR (Master Boot Record) */
263 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
271 Status = IoCallDriver(DeviceObject,
273 if (Status == STATUS_PENDING)
275 KeWaitForSingleObject(&Event,
280 Status = StatusBlock.Status;
283 if (!NT_SUCCESS(Status))
285 DPRINT("Writing MBR failed (Status 0x%08lx)\n",
295 xHalExamineMBR(IN PDEVICE_OBJECT DeviceObject,
297 IN ULONG MBRTypeIdentifier,
300 LARGE_INTEGER SectorOffset;
301 PPARTITION_SECTOR Sector;
305 DPRINT("xHalExamineMBR()\n");
309 SectorOffset.QuadPart = 0ULL;
310 Status = xHalpReadSector(DeviceObject,
314 if (!NT_SUCCESS(Status))
316 DPRINT1("xHalpReadSector() failed (Status %lx)\n", Status);
320 if (Sector->Magic != PARTITION_MAGIC)
322 DPRINT("Invalid MBR magic value\n");
327 if (Sector->Partition[0].PartitionType != MBRTypeIdentifier)
329 DPRINT("Invalid MBRTypeIdentifier\n");
334 if (Sector->Partition[0].PartitionType == 0x54)
336 /* Found 'Ontrack Disk Manager'. Shift all sectors by 63 */
337 DPRINT("Found 'Ontrack Disk Manager'!\n");
338 Shift = (PULONG)Sector;
342 *Buffer = (PVOID)Sector;
347 HalpAssignDrive(IN PUNICODE_STRING PartitionName,
348 IN ULONG DriveNumber,
351 WCHAR DriveNameBuffer[8];
352 UNICODE_STRING DriveName;
355 DPRINT("HalpAssignDrive()\n");
357 if ((DriveNumber != AUTO_DRIVE) && (DriveNumber < 24))
359 /* Force assignment */
360 if ((SharedUserData->DosDeviceMap & (1 << DriveNumber)) != 0)
362 DbgPrint("Drive letter already used!\n");
368 /* Automatic assignment */
369 DriveNumber = AUTO_DRIVE;
371 for (i = 2; i < 24; i++)
373 if ((SharedUserData->DosDeviceMap & (1 << i)) == 0)
380 if (DriveNumber == AUTO_DRIVE)
382 DbgPrint("No drive letter available!\n");
387 DPRINT("DriveNumber %d\n", DriveNumber);
389 /* Update the shared user page */
390 SharedUserData->DosDeviceMap |= (1 << DriveNumber);
391 SharedUserData->DosDeviceDriveType[DriveNumber] = DriveType;
393 /* Build drive name */
394 swprintf(DriveNameBuffer,
397 RtlInitUnicodeString(&DriveName,
400 DPRINT(" %wZ ==> %wZ\n",
404 /* Create symbolic link */
405 IoCreateSymbolicLink(&DriveName,
411 xHalIoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
412 IN PSTRING NtDeviceName,
413 OUT PUCHAR NtSystemPath,
414 OUT PSTRING NtSystemPathString)
416 PDRIVE_LAYOUT_INFORMATION *LayoutArray;
417 PCONFIGURATION_INFORMATION ConfigInfo;
418 OBJECT_ATTRIBUTES ObjectAttributes;
419 IO_STATUS_BLOCK StatusBlock;
420 UNICODE_STRING UnicodeString1;
421 UNICODE_STRING UnicodeString2;
429 DPRINT("xHalIoAssignDriveLetters()\n");
431 ConfigInfo = IoGetConfigurationInformation();
433 Buffer1 = (PWSTR)ExAllocatePool(PagedPool,
435 Buffer2 = (PWSTR)ExAllocatePool(PagedPool,
438 /* Create PhysicalDrive links */
439 DPRINT("Physical disk drives: %d\n", ConfigInfo->DiskCount);
440 for (i = 0; i < ConfigInfo->DiskCount; i++)
443 L"\\Device\\Harddisk%d\\Partition0",
445 RtlInitUnicodeString(&UnicodeString1,
448 InitializeObjectAttributes(&ObjectAttributes,
454 Status = NtOpenFile(&FileHandle,
459 FILE_SYNCHRONOUS_IO_NONALERT);
460 if (NT_SUCCESS(Status))
465 L"\\??\\PhysicalDrive%d",
467 RtlInitUnicodeString(&UnicodeString2,
470 DPRINT("Creating link: %S ==> %S\n",
474 IoCreateSymbolicLink(&UnicodeString2,
479 /* Initialize layout array */
480 LayoutArray = ExAllocatePool(NonPagedPool,
481 ConfigInfo->DiskCount * sizeof(PDRIVE_LAYOUT_INFORMATION));
482 RtlZeroMemory(LayoutArray,
483 ConfigInfo->DiskCount * sizeof(PDRIVE_LAYOUT_INFORMATION));
484 for (i = 0; i < ConfigInfo->DiskCount; i++)
487 L"\\Device\\Harddisk%d\\Partition0",
489 RtlInitUnicodeString(&UnicodeString1,
492 Status = xHalQueryDriveLayout(&UnicodeString1,
494 if (!NT_SUCCESS(Status))
496 DbgPrint("xHalQueryDriveLayout() failed (Status = 0x%lx)\n",
498 LayoutArray[i] = NULL;
504 /* Dump layout array */
505 for (i = 0; i < ConfigInfo->DiskCount; i++)
507 DPRINT("Harddisk %d:\n",
510 if (LayoutArray[i] == NULL)
513 DPRINT("Logical partitions: %d\n",
514 LayoutArray[i]->PartitionCount);
516 for (j = 0; j < LayoutArray[i]->PartitionCount; j++)
518 DPRINT(" %d: nr:%x boot:%x type:%x startblock:%I64u count:%I64u\n",
520 LayoutArray[i]->PartitionEntry[j].PartitionNumber,
521 LayoutArray[i]->PartitionEntry[j].BootIndicator,
522 LayoutArray[i]->PartitionEntry[j].PartitionType,
523 LayoutArray[i]->PartitionEntry[j].StartingOffset.QuadPart,
524 LayoutArray[i]->PartitionEntry[j].PartitionLength.QuadPart);
529 /* Assign pre-assigned (registry) partitions */
532 /* Assign bootable partition on first harddisk */
533 DPRINT("Assigning bootable primary partition on first harddisk:\n");
534 if (ConfigInfo->DiskCount > 0)
536 /* Search for bootable partition */
537 for (j = 0; j < LayoutArray[0]->PartitionCount; j++)
539 if ((LayoutArray[0]->PartitionEntry[j].BootIndicator == TRUE) &&
540 IsRecognizedPartition(LayoutArray[0]->PartitionEntry[j].PartitionType))
543 L"\\Device\\Harddisk0\\Partition%d",
544 LayoutArray[0]->PartitionEntry[j].PartitionNumber);
545 RtlInitUnicodeString(&UnicodeString2,
549 DPRINT(" %wZ\n", &UnicodeString2);
550 HalpAssignDrive(&UnicodeString2,
552 DOSDEVICE_DRIVE_FIXED);
557 /* Assign remaining primary partitions */
558 DPRINT("Assigning remaining primary partitions:\n");
559 for (i = 0; i < ConfigInfo->DiskCount; i++)
561 /* Search for primary partitions */
562 for (j = 0; (j < PARTITION_TBL_SIZE) && (j < LayoutArray[i]->PartitionCount); j++)
564 if ((i == 0) && (LayoutArray[i]->PartitionEntry[j].BootIndicator == TRUE))
567 if (IsRecognizedPartition(LayoutArray[i]->PartitionEntry[j].PartitionType))
570 L"\\Device\\Harddisk%d\\Partition%d",
572 LayoutArray[i]->PartitionEntry[j].PartitionNumber);
573 RtlInitUnicodeString(&UnicodeString2,
579 HalpAssignDrive(&UnicodeString2,
581 DOSDEVICE_DRIVE_FIXED);
586 /* Assign extended (logical) partitions */
587 DPRINT("Assigning extended (logical) partitions:\n");
588 for (i = 0; i < ConfigInfo->DiskCount; i++)
592 /* Search for extended partitions */
593 for (j = PARTITION_TBL_SIZE; j < LayoutArray[i]->PartitionCount; j++)
595 if (IsRecognizedPartition(LayoutArray[i]->PartitionEntry[j].PartitionType) &&
596 (LayoutArray[i]->PartitionEntry[j].PartitionNumber != 0))
599 L"\\Device\\Harddisk%d\\Partition%d",
601 LayoutArray[i]->PartitionEntry[j].PartitionNumber);
602 RtlInitUnicodeString(&UnicodeString2,
608 HalpAssignDrive(&UnicodeString2,
610 DOSDEVICE_DRIVE_FIXED);
616 /* Assign removable disk drives */
617 DPRINT("Assigning removable disk drives:\n");
618 for (i = 0; i < ConfigInfo->DiskCount; i++)
620 /* Search for virtual partitions */
621 if (LayoutArray[i]->PartitionCount == 1 &&
622 LayoutArray[i]->PartitionEntry[0].PartitionType == 0)
625 L"\\Device\\Harddisk%d\\Partition1",
627 RtlInitUnicodeString(&UnicodeString2,
633 HalpAssignDrive(&UnicodeString2,
635 DOSDEVICE_DRIVE_REMOVABLE);
639 /* Free layout array */
640 for (i = 0; i < ConfigInfo->DiskCount; i++)
642 if (LayoutArray[i] != NULL)
643 ExFreePool(LayoutArray[i]);
645 ExFreePool(LayoutArray);
647 /* Assign floppy drives */
648 DPRINT("Floppy drives: %d\n", ConfigInfo->FloppyCount);
649 for (i = 0; i < ConfigInfo->FloppyCount; i++)
652 L"\\Device\\Floppy%d",
654 RtlInitUnicodeString(&UnicodeString1,
657 /* Assign drive letters A: or B: or first free drive letter */
660 HalpAssignDrive(&UnicodeString1,
661 (i < 2) ? i : AUTO_DRIVE,
662 DOSDEVICE_DRIVE_REMOVABLE);
665 /* Assign cdrom drives */
666 DPRINT("CD-Rom drives: %d\n", ConfigInfo->CDRomCount);
667 for (i = 0; i < ConfigInfo->CDRomCount; i++)
670 L"\\Device\\CdRom%d",
672 RtlInitUnicodeString(&UnicodeString1,
675 /* Assign first free drive letter */
676 DPRINT(" %wZ\n", &UnicodeString1);
677 HalpAssignDrive(&UnicodeString1,
679 DOSDEVICE_DRIVE_CDROM);
682 /* Anything else ?? */
690 xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject,
692 BOOLEAN ReturnRecognizedPartitions,
693 PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
696 IO_STATUS_BLOCK StatusBlock;
697 ULARGE_INTEGER PartitionOffset;
698 ULARGE_INTEGER RealPartitionOffset;
699 ULARGE_INTEGER nextPartitionOffset;
700 ULARGE_INTEGER containerOffset;
703 PPARTITION_SECTOR PartitionSector;
704 PDRIVE_LAYOUT_INFORMATION LayoutBuffer;
708 BOOLEAN ExtendedFound = FALSE;
710 DISK_MANAGER DiskManager = NoDiskManager;
712 DPRINT("xHalIoReadPartitionTable(%p %lu %x %p)\n",
715 ReturnRecognizedPartitions,
718 *PartitionBuffer = NULL;
720 /* Check for 'Ontrack Disk Manager' */
721 xHalExamineMBR(DeviceObject,
725 if (MbrBuffer != NULL)
727 DPRINT("Found 'Ontrack Disk Manager'\n");
728 DiskManager = OntrackDiskManager;
729 ExFreePool(MbrBuffer);
732 /* Check for 'EZ-Drive' */
733 xHalExamineMBR(DeviceObject,
737 if (MbrBuffer != NULL)
739 DPRINT("Found 'EZ-Drive'\n");
740 DiskManager = EZ_Drive;
741 ExFreePool(MbrBuffer);
744 PartitionSector = (PPARTITION_SECTOR)ExAllocatePool(PagedPool,
746 if (PartitionSector == NULL)
748 return(STATUS_INSUFFICIENT_RESOURCES);
751 LayoutBuffer = (PDRIVE_LAYOUT_INFORMATION)ExAllocatePool(NonPagedPool,
753 if (LayoutBuffer == NULL)
755 ExFreePool(PartitionSector);
756 return(STATUS_INSUFFICIENT_RESOURCES);
759 RtlZeroMemory(LayoutBuffer,
762 PartitionOffset.QuadPart = (ULONGLONG)0;
763 containerOffset.QuadPart = (ULONGLONG)0;
767 DPRINT("PartitionOffset: %I64u\n", PartitionOffset.QuadPart / SectorSize);
769 if (DiskManager == OntrackDiskManager)
771 RealPartitionOffset.QuadPart = PartitionOffset.QuadPart + (ULONGLONG)(63 * SectorSize);
775 RealPartitionOffset.QuadPart = PartitionOffset.QuadPart;
778 DPRINT("RealPartitionOffset: %I64u\n", RealPartitionOffset.QuadPart / SectorSize);
780 KeInitializeEvent(&Event,
784 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
786 PartitionSector, //SectorBuffer,
788 (PLARGE_INTEGER)&RealPartitionOffset,
791 Status = IoCallDriver(DeviceObject,
793 if (Status == STATUS_PENDING)
795 KeWaitForSingleObject(&Event,
800 Status = StatusBlock.Status;
803 if (!NT_SUCCESS(Status))
805 DPRINT("Failed to read partition table sector (Status = 0x%08lx)\n",
807 ExFreePool(PartitionSector);
808 ExFreePool(LayoutBuffer);
812 /* check the boot sector id */
813 DPRINT("Magic %x\n", PartitionSector->Magic);
814 if (PartitionSector->Magic != PARTITION_MAGIC)
816 DbgPrint("Invalid partition sector magic\n");
817 ExFreePool(PartitionSector);
818 *PartitionBuffer = LayoutBuffer;
819 return(STATUS_SUCCESS);
823 for (i = 0; i < PARTITION_TBL_SIZE; i++)
825 DPRINT1(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",
827 PartitionSector->Partition[i].BootFlags,
828 PartitionSector->Partition[i].PartitionType,
829 PartitionSector->Partition[i].StartingHead,
830 PartitionSector->Partition[i].StartingSector & 0x3f,
831 (((PartitionSector->Partition[i].StartingSector) & 0xc0) << 2) +
832 PartitionSector->Partition[i].StartingCylinder,
833 PartitionSector->Partition[i].EndingHead,
834 PartitionSector->Partition[i].EndingSector,
835 PartitionSector->Partition[i].EndingCylinder,
836 PartitionSector->Partition[i].StartingBlock,
837 PartitionSector->Partition[i].SectorCount);
841 if (PartitionOffset.QuadPart == 0ULL)
843 LayoutBuffer->Signature = PartitionSector->Signature;
844 DPRINT("Disk signature: %lx\n", LayoutBuffer->Signature);
847 ExtendedFound = FALSE;
849 for (i = 0; i < PARTITION_TBL_SIZE; i++)
851 if ((ReturnRecognizedPartitions == FALSE) ||
852 ((ReturnRecognizedPartitions == TRUE) &&
853 IsRecognizedPartition(PartitionSector->Partition[i].PartitionType)))
855 /* handle normal partition */
856 DPRINT("Partition %u: Normal Partition\n", i);
857 Count = LayoutBuffer->PartitionCount;
858 DPRINT("Logical Partition %u\n", Count);
859 if (PartitionSector->Partition[i].StartingBlock == 0)
861 LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart = 0;
863 else if (IsContainerPartition(PartitionSector->Partition[i].PartitionType))
865 LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
866 (ULONGLONG)PartitionOffset.QuadPart;
870 LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
871 (ULONGLONG)PartitionOffset.QuadPart +
872 ((ULONGLONG)PartitionSector->Partition[i].StartingBlock * (ULONGLONG)SectorSize);
874 LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart =
875 (ULONGLONG)PartitionSector->Partition[i].SectorCount * (ULONGLONG)SectorSize;
876 LayoutBuffer->PartitionEntry[Count].HiddenSectors = 0;
878 if (IsRecognizedPartition(PartitionSector->Partition[i].PartitionType))
880 LayoutBuffer->PartitionEntry[Count].PartitionNumber = Number;
885 LayoutBuffer->PartitionEntry[Count].PartitionNumber = 0;
888 LayoutBuffer->PartitionEntry[Count].PartitionType =
889 PartitionSector->Partition[i].PartitionType;
890 LayoutBuffer->PartitionEntry[Count].BootIndicator =
891 (PartitionSector->Partition[i].BootFlags & 0x80)?TRUE:FALSE;
892 LayoutBuffer->PartitionEntry[Count].RecognizedPartition =
893 IsRecognizedPartition (PartitionSector->Partition[i].PartitionType);
894 LayoutBuffer->PartitionEntry[Count].RewritePartition = FALSE;
896 DPRINT(" %ld: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x\n",
898 LayoutBuffer->PartitionEntry[Count].PartitionNumber,
899 LayoutBuffer->PartitionEntry[Count].BootIndicator,
900 LayoutBuffer->PartitionEntry[Count].PartitionType,
901 LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart,
902 LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart);
904 LayoutBuffer->PartitionCount++;
907 if (IsContainerPartition(PartitionSector->Partition[i].PartitionType))
909 ExtendedFound = TRUE;
910 if ((ULONGLONG) containerOffset.QuadPart == (ULONGLONG) 0)
912 containerOffset = PartitionOffset;
914 nextPartitionOffset.QuadPart = (ULONGLONG) containerOffset.QuadPart +
915 (ULONGLONG) PartitionSector->Partition[i].StartingBlock *
916 (ULONGLONG) SectorSize;
919 PartitionOffset = nextPartitionOffset;
921 while (ExtendedFound == TRUE);
923 *PartitionBuffer = LayoutBuffer;
924 ExFreePool(PartitionSector);
926 return(STATUS_SUCCESS);
931 xHalIoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject,
933 IN ULONG PartitionNumber,
934 IN ULONG PartitionType)
936 return(STATUS_NOT_IMPLEMENTED);
941 xHalIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject,
943 IN ULONG SectorsPerTrack,
944 IN ULONG NumberOfHeads,
945 IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
947 PPARTITION_SECTOR PartitionSector;
948 LARGE_INTEGER SectorOffset;
952 DPRINT("xHalIoWritePartitionTable(%p %lu %lu %p)\n",
958 assert(DeviceObject);
959 assert(PartitionBuffer);
961 /* Check for 'Ontrack Disk Manager' */
962 xHalExamineMBR(DeviceObject,
965 (PVOID *) &PartitionSector);
966 if (PartitionSector != NULL)
968 DPRINT1("Ontrack Disk Manager is not supported\n");
969 ExFreePool(PartitionSector);
970 return STATUS_UNSUCCESSFUL;
973 /* Check for 'EZ-Drive' */
974 xHalExamineMBR(DeviceObject,
977 (PVOID *) &PartitionSector);
978 if (PartitionSector != NULL)
980 DPRINT1("EZ-Drive is not supported\n");
981 ExFreePool(PartitionSector);
982 return STATUS_UNSUCCESSFUL;
986 for (i = 0; i < PartitionBuffer->PartitionCount; i++)
988 if (IsContainerPartition(PartitionBuffer->PartitionEntry[i].PartitionType))
990 /* FIXME: Implement */
991 DPRINT1("Writing MBRs with extended partitions is not implemented\n");
992 return STATUS_UNSUCCESSFUL;
997 SectorOffset.QuadPart = 0ULL;
998 Status = xHalpReadSector(DeviceObject,
1001 (PVOID *) &PartitionSector);
1002 if (!NT_SUCCESS(Status))
1004 DPRINT1("xHalpReadSector() failed (Status %lx)\n", Status);
1008 DPRINT1("WARNING: Only 'BootFlags' is implemented\n");
1011 for (i = 0; i < PartitionBuffer->PartitionCount; i++)
1013 //= PartitionBuffer->PartitionEntry[i].StartingOffset;
1014 //= PartitionBuffer->PartitionEntry[i].PartitionLength;
1015 //= PartitionBuffer->PartitionEntry[i].HiddenSectors;
1016 //= PartitionBuffer->PartitionEntry[i].PartitionType;
1017 //= PartitionBuffer->PartitionEntry[i].PartitionType;
1019 if (PartitionBuffer->PartitionEntry[i].BootIndicator)
1021 PartitionSector->Partition[i].BootFlags |= 0x80;
1025 PartitionSector->Partition[i].BootFlags &= ~0x80;
1028 //= PartitionBuffer->PartitionEntry[i].RecognizedPartition;
1029 //= PartitionBuffer->PartitionEntry[i].RewritePartition;
1033 SectorOffset.QuadPart = 0ULL;
1034 Status = xHalpWriteSector(DeviceObject,
1037 (PVOID) PartitionSector);
1038 if (!NT_SUCCESS(Status))
1040 DPRINT1("xHalpWriteSector() failed (Status %lx)\n", Status);
1041 ExFreePool(PartitionSector);
1046 for (i = 0; i < PARTITION_TBL_SIZE; i++)
1048 DPRINT1(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",
1050 PartitionSector->Partition[i].BootFlags,
1051 PartitionSector->Partition[i].PartitionType,
1052 PartitionSector->Partition[i].StartingHead,
1053 PartitionSector->Partition[i].StartingSector & 0x3f,
1054 (((PartitionSector->Partition[i].StartingSector) & 0xc0) << 2) +
1055 PartitionSector->Partition[i].StartingCylinder,
1056 PartitionSector->Partition[i].EndingHead,
1057 PartitionSector->Partition[i].EndingSector,
1058 PartitionSector->Partition[i].EndingCylinder,
1059 PartitionSector->Partition[i].StartingBlock,
1060 PartitionSector->Partition[i].SectorCount);
1064 ExFreePool(PartitionSector);
1066 return(STATUS_SUCCESS);