2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/disk.c
5 * PURPOSE: I/O Support for Hal Disk (Partition Table/MBR) Routines.
7 * PROGRAMMERS: Eric Kohl (ekohl@rz-online.de)
8 * Casper S. Hornstrup (chorns@users.sourceforge.net)
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 /* LOCAL MACROS and TYPES ***************************************************/
19 #define AUTO_DRIVE ((ULONG)-1)
21 #define PARTITION_MAGIC 0xaa55
25 typedef struct _REG_DISK_MOUNT_INFO
28 LARGE_INTEGER StartingOffset
;
29 } REG_DISK_MOUNT_INFO
, *PREG_DISK_MOUNT_INFO
;
33 typedef enum _DISK_MANAGER
40 HAL_DISPATCH HalDispatchTable
=
43 (pHalQuerySystemInformation
) NULL
, // HalQuerySystemInformation
44 (pHalSetSystemInformation
) NULL
, // HalSetSystemInformation
45 (pHalQueryBusSlots
) NULL
, // HalQueryBusSlots
47 (pHalExamineMBR
) HalExamineMBR
,
48 (pHalIoAssignDriveLetters
) xHalIoAssignDriveLetters
,
49 (pHalIoReadPartitionTable
) xHalIoReadPartitionTable
,
50 (pHalIoSetPartitionInformation
) xHalIoSetPartitionInformation
,
51 (pHalIoWritePartitionTable
) xHalIoWritePartitionTable
,
52 (pHalHandlerForBus
) NULL
, // HalReferenceHandlerForBus
53 (pHalReferenceBusHandler
) NULL
, // HalReferenceBusHandler
54 (pHalReferenceBusHandler
) NULL
, // HalDereferenceBusHandler
55 (pHalInitPnpDriver
) NULL
, //HalInitPnpDriver;
56 (pHalInitPowerManagement
) NULL
, //HalInitPowerManagement;
57 (pHalGetDmaAdapter
) NULL
, //HalGetDmaAdapter;
58 (pHalGetInterruptTranslator
) NULL
, //HalGetInterruptTranslator;
59 (pHalStartMirroring
) NULL
, //HalStartMirroring;
60 (pHalEndMirroring
) NULL
, //HalEndMirroring;
61 (pHalMirrorPhysicalMemory
) NULL
, //HalMirrorPhysicalMemory;
62 (pHalEndOfBoot
) NULL
, //HalEndOfBoot;
63 (pHalMirrorVerify
) NULL
//HalMirrorVerify;
66 HAL_PRIVATE_DISPATCH HalPrivateDispatchTable
=
68 HAL_PRIVATE_DISPATCH_VERSION
71 const WCHAR DiskMountString
[] = L
"\\DosDevices\\%C:";
73 /* FUNCTIONS *****************************************************************/
77 xHalQueryDriveLayout(IN PUNICODE_STRING DeviceName
,
78 OUT PDRIVE_LAYOUT_INFORMATION
*LayoutInfo
)
80 IO_STATUS_BLOCK StatusBlock
;
81 DISK_GEOMETRY DiskGeometry
;
82 PDEVICE_OBJECT DeviceObject
= NULL
;
83 PFILE_OBJECT FileObject
;
88 DPRINT("xHalpQueryDriveLayout %wZ %p\n",
92 /* Get the drives sector size */
93 Status
= IoGetDeviceObjectPointer(DeviceName
,
97 if (!NT_SUCCESS(Status
))
99 DPRINT("Status %x\n", Status
);
103 KeInitializeEvent(&Event
,
107 Irp
= IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY
,
112 sizeof(DISK_GEOMETRY
),
118 ObDereferenceObject(FileObject
);
119 return(STATUS_INSUFFICIENT_RESOURCES
);
122 Status
= IoCallDriver(DeviceObject
,
124 if (Status
== STATUS_PENDING
)
126 KeWaitForSingleObject(&Event
,
131 Status
= StatusBlock
.Status
;
133 if (!NT_SUCCESS(Status
))
135 if (DeviceObject
->Characteristics
& FILE_REMOVABLE_MEDIA
)
137 DiskGeometry
.BytesPerSector
= 512;
141 ObDereferenceObject(FileObject
);
146 DPRINT("DiskGeometry.BytesPerSector: %d\n",
147 DiskGeometry
.BytesPerSector
);
149 if (DeviceObject
->Characteristics
& FILE_REMOVABLE_MEDIA
)
151 PDRIVE_LAYOUT_INFORMATION Buffer
;
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 Status
= STATUS_UNSUCCESSFUL
;
172 /* Read the partition table */
173 Status
= IoReadPartitionTable(DeviceObject
,
174 DiskGeometry
.BytesPerSector
,
179 ObDereferenceObject(FileObject
);
186 xHalpReadSector (IN PDEVICE_OBJECT DeviceObject
,
188 IN PLARGE_INTEGER SectorOffset
,
191 IO_STATUS_BLOCK StatusBlock
;
196 DPRINT("xHalpReadSector() called\n");
198 ASSERT(DeviceObject
);
201 KeInitializeEvent(&Event
,
205 /* Read the sector */
206 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
,
214 Status
= IoCallDriver(DeviceObject
,
216 if (Status
== STATUS_PENDING
)
218 KeWaitForSingleObject(&Event
,
223 Status
= StatusBlock
.Status
;
226 if (!NT_SUCCESS(Status
))
228 DPRINT("Reading sector failed (Status 0x%08lx)\n",
238 xHalpWriteSector (IN PDEVICE_OBJECT DeviceObject
,
240 IN PLARGE_INTEGER SectorOffset
,
243 IO_STATUS_BLOCK StatusBlock
;
248 DPRINT("xHalpWriteSector() called\n");
250 KeInitializeEvent(&Event
,
254 /* Write the sector */
255 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
,
263 Status
= IoCallDriver(DeviceObject
,
265 if (Status
== STATUS_PENDING
)
267 KeWaitForSingleObject(&Event
,
272 Status
= StatusBlock
.Status
;
275 if (!NT_SUCCESS(Status
))
277 DPRINT("Writing sector failed (Status 0x%08lx)\n",
286 HalExamineMBR(IN PDEVICE_OBJECT DeviceObject
,
288 IN ULONG MBRTypeIdentifier
,
291 LARGE_INTEGER SectorOffset
;
292 PPARTITION_SECTOR Sector
;
295 DPRINT("HalExamineMBR()\n");
299 if (SectorSize
< 512)
301 if (SectorSize
> 4096)
304 Sector
= (PPARTITION_SECTOR
) ExAllocatePool (PagedPool
,
308 DPRINT ("Partition sector allocation failed\n");
312 #if defined(__GNUC__)
313 SectorOffset
.QuadPart
= 0LL;
315 SectorOffset
.QuadPart
= 0;
317 Status
= xHalpReadSector (DeviceObject
,
321 if (!NT_SUCCESS(Status
))
323 DPRINT("xHalpReadSector() failed (Status %lx)\n", Status
);
328 if (Sector
->Magic
!= PARTITION_MAGIC
)
330 DPRINT("Invalid MBR magic value\n");
335 if (Sector
->Partition
[0].PartitionType
!= MBRTypeIdentifier
)
337 DPRINT("Invalid MBRTypeIdentifier\n");
342 if (Sector
->Partition
[0].PartitionType
== 0x54)
344 /* Found 'Ontrack Disk Manager'. Shift all sectors by 63 */
345 DPRINT("Found 'Ontrack Disk Manager'!\n");
346 *((PULONG
)Sector
) = 63;
349 *Buffer
= (PVOID
)Sector
;
354 HalpAssignDrive(IN PUNICODE_STRING PartitionName
,
355 IN ULONG DriveNumber
,
358 IN LARGE_INTEGER StartingOffset
,
361 WCHAR DriveNameBuffer
[16];
362 UNICODE_STRING DriveName
;
365 REG_DISK_MOUNT_INFO DiskMountInfo
;
367 DPRINT("HalpAssignDrive()\n");
369 if ((DriveNumber
!= AUTO_DRIVE
) && (DriveNumber
< 26))
371 /* Force assignment */
372 if ((ObSystemDeviceMap
->DriveMap
& (1 << DriveNumber
)) != 0)
374 DbgPrint("Drive letter already used!\n");
380 /* Automatic assignment */
381 DriveNumber
= AUTO_DRIVE
;
383 for (i
= 2; i
< 26; i
++)
385 if ((ObSystemDeviceMap
->DriveMap
& (1 << i
)) == 0)
392 if (DriveNumber
== AUTO_DRIVE
)
394 DbgPrint("No drive letter available!\n");
399 DPRINT("DriveNumber %d\n", DriveNumber
);
401 /* Update the System Device Map */
402 ObSystemDeviceMap
->DriveMap
|= (1 << DriveNumber
);
403 ObSystemDeviceMap
->DriveType
[DriveNumber
] = DriveType
;
405 /* Build drive name */
406 swprintf(DriveNameBuffer
,
409 RtlInitUnicodeString(&DriveName
,
412 DPRINT(" %wZ ==> %wZ\n",
416 /* Create symbolic link */
417 Status
= IoCreateSymbolicLink(&DriveName
,
421 DriveType
== DOSDEVICE_DRIVE_FIXED
&&
424 DiskMountInfo
.Signature
= Signature
;
425 DiskMountInfo
.StartingOffset
= StartingOffset
;
426 swprintf(DriveNameBuffer
, DiskMountString
, L
'A' + DriveNumber
);
427 RtlInitUnicodeString(&DriveName
, DriveNameBuffer
);
429 Status
= ZwSetValueKey(hKey
,
434 sizeof(DiskMountInfo
));
435 if (!NT_SUCCESS(Status
))
437 DPRINT1("ZwCreateValueKey failed for %wZ, status=%x\n", &DriveName
, Status
);
444 xHalpGetRDiskCount(VOID
)
447 UNICODE_STRING ArcName
;
448 PWCHAR ArcNameBuffer
;
449 OBJECT_ATTRIBUTES ObjectAttributes
;
450 HANDLE DirectoryHandle
;
451 POBJECT_DIRECTORY_INFORMATION DirectoryInfo
;
456 BOOLEAN First
= TRUE
;
459 DirectoryInfo
= ExAllocatePool(PagedPool
, 2 * PAGE_SIZE
);
460 if (DirectoryInfo
== NULL
)
465 RtlInitUnicodeString(&ArcName
, L
"\\ArcName");
466 InitializeObjectAttributes(&ObjectAttributes
,
472 Status
= ZwOpenDirectoryObject (&DirectoryHandle
,
473 SYMBOLIC_LINK_ALL_ACCESS
,
475 if (!NT_SUCCESS(Status
))
477 DPRINT1("ZwOpenDirectoryObject for %wZ failed, status=%lx\n", &ArcName
, Status
);
478 ExFreePool(DirectoryInfo
);
484 while (NT_SUCCESS(Status
))
486 Status
= NtQueryDirectoryObject (DirectoryHandle
,
494 if (NT_SUCCESS(Status
))
497 while (DirectoryInfo
[Count
].ObjectName
.Buffer
)
499 DPRINT("Count %x\n", Count
);
500 DirectoryInfo
[Count
].ObjectName
.Buffer
[DirectoryInfo
[Count
].ObjectName
.Length
/ sizeof(WCHAR
)] = 0;
501 ArcNameBuffer
= DirectoryInfo
[Count
].ObjectName
.Buffer
;
502 if (DirectoryInfo
[Count
].ObjectName
.Length
>= sizeof(L
"multi(0)disk(0)rdisk(0)") - sizeof(WCHAR
) &&
503 !_wcsnicmp(ArcNameBuffer
, L
"multi(0)disk(0)rdisk(", (sizeof(L
"multi(0)disk(0)rdisk(") - sizeof(WCHAR
)) / sizeof(WCHAR
)))
505 DPRINT("%S\n", ArcNameBuffer
);
506 ArcNameBuffer
+= (sizeof(L
"multi(0)disk(0)rdisk(") - sizeof(WCHAR
)) / sizeof(WCHAR
);
508 while (iswdigit(*ArcNameBuffer
))
510 CurrentRDisk
= CurrentRDisk
* 10 + *ArcNameBuffer
- L
'0';
513 if (!_wcsicmp(ArcNameBuffer
, L
")") &&
514 CurrentRDisk
>= RDiskCount
)
516 RDiskCount
= CurrentRDisk
+ 1;
523 ExFreePool(DirectoryInfo
);
528 xHalpGetDiskNumberFromRDisk(ULONG RDisk
, PULONG DiskNumber
)
530 WCHAR NameBuffer
[80];
531 UNICODE_STRING ArcName
;
532 UNICODE_STRING LinkName
;
533 OBJECT_ATTRIBUTES ObjectAttributes
;
538 L
"\\ArcName\\multi(0)disk(0)rdisk(%lu)",
541 RtlInitUnicodeString(&ArcName
, NameBuffer
);
542 InitializeObjectAttributes(&ObjectAttributes
,
547 Status
= ZwOpenSymbolicLinkObject(&LinkHandle
,
548 SYMBOLIC_LINK_ALL_ACCESS
,
550 if (!NT_SUCCESS(Status
))
552 DPRINT1("ZwOpenSymbolicLinkObject failed for %wZ, status=%lx\n", &ArcName
, Status
);
556 LinkName
.Buffer
= NameBuffer
;
558 LinkName
.MaximumLength
= sizeof(NameBuffer
);
559 Status
= ZwQuerySymbolicLinkObject(LinkHandle
,
563 if (!NT_SUCCESS(Status
))
565 DPRINT1("ZwQuerySymbolicLinkObject failed, status=%lx\n", Status
);
568 if (LinkName
.Length
< sizeof(L
"\\Device\\Harddisk0\\Partition0") - sizeof(WCHAR
) ||
569 LinkName
.Length
>= sizeof(NameBuffer
))
571 return STATUS_UNSUCCESSFUL
;
574 NameBuffer
[LinkName
.Length
/ sizeof(WCHAR
)] = 0;
575 if (_wcsnicmp(NameBuffer
, L
"\\Device\\Harddisk", (sizeof(L
"\\Device\\Harddisk") - sizeof(WCHAR
)) / sizeof(WCHAR
)))
577 return STATUS_UNSUCCESSFUL
;
579 LinkName
.Buffer
+= (sizeof(L
"\\Device\\Harddisk") - sizeof(WCHAR
)) / sizeof(WCHAR
);
581 if (!iswdigit(*LinkName
.Buffer
))
583 return STATUS_UNSUCCESSFUL
;
586 while (iswdigit(*LinkName
.Buffer
))
588 *DiskNumber
= *DiskNumber
* 10 + *LinkName
.Buffer
- L
'0';
591 if (_wcsicmp(LinkName
.Buffer
, L
"\\Partition0"))
593 return STATUS_UNSUCCESSFUL
;
595 return STATUS_SUCCESS
;
600 xHalIoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
601 IN PSTRING NtDeviceName
,
602 OUT PUCHAR NtSystemPath
,
603 OUT PSTRING NtSystemPathString
)
605 PDRIVE_LAYOUT_INFORMATION
*LayoutArray
;
606 PCONFIGURATION_INFORMATION ConfigInfo
;
607 OBJECT_ATTRIBUTES ObjectAttributes
;
608 IO_STATUS_BLOCK StatusBlock
;
609 UNICODE_STRING UnicodeString1
;
610 UNICODE_STRING UnicodeString2
;
620 PKEY_VALUE_PARTIAL_INFORMATION PartialInformation
;
621 PREG_DISK_MOUNT_INFO DiskMountInfo
;
624 DPRINT("xHalIoAssignDriveLetters()\n");
626 ConfigInfo
= IoGetConfigurationInformation();
628 RDiskCount
= xHalpGetRDiskCount();
630 DPRINT1("RDiskCount %d\n", RDiskCount
);
632 Buffer1
= (PWSTR
)ExAllocatePool(PagedPool
,
634 Buffer2
= (PWSTR
)ExAllocatePool(PagedPool
,
637 PartialInformation
= (PKEY_VALUE_PARTIAL_INFORMATION
)ExAllocatePool(PagedPool
,
638 sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(REG_DISK_MOUNT_INFO
));
640 DiskMountInfo
= (PREG_DISK_MOUNT_INFO
) PartialInformation
->Data
;
642 /* Open or Create the 'MountedDevices' key */
643 RtlInitUnicodeString(&UnicodeString1
, L
"\\Registry\\Machine\\SYSTEM\\MountedDevices");
644 InitializeObjectAttributes(&ObjectAttributes
,
646 OBJ_CASE_INSENSITIVE
,
649 Status
= ZwOpenKey(&hKey
,
652 if (!NT_SUCCESS(Status
))
654 Status
= ZwCreateKey(&hKey
,
659 REG_OPTION_NON_VOLATILE
,
662 if (!NT_SUCCESS(Status
))
665 DPRINT1("ZwCreateKey failed for %wZ, status=%x\n", &UnicodeString1
, Status
);
668 /* Create PhysicalDrive links */
669 DPRINT("Physical disk drives: %d\n", ConfigInfo
->DiskCount
);
670 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
673 L
"\\Device\\Harddisk%d\\Partition0",
675 RtlInitUnicodeString(&UnicodeString1
,
678 InitializeObjectAttributes(&ObjectAttributes
,
684 Status
= ZwOpenFile(&FileHandle
,
689 FILE_SYNCHRONOUS_IO_NONALERT
);
690 if (NT_SUCCESS(Status
))
695 L
"\\??\\PhysicalDrive%d",
697 RtlInitUnicodeString(&UnicodeString2
,
700 DPRINT("Creating link: %S ==> %S\n",
704 IoCreateSymbolicLink(&UnicodeString2
,
709 /* Initialize layout array */
710 LayoutArray
= ExAllocatePool(NonPagedPool
,
711 ConfigInfo
->DiskCount
* sizeof(PDRIVE_LAYOUT_INFORMATION
));
712 RtlZeroMemory(LayoutArray
,
713 ConfigInfo
->DiskCount
* sizeof(PDRIVE_LAYOUT_INFORMATION
));
714 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
717 L
"\\Device\\Harddisk%d\\Partition0",
719 RtlInitUnicodeString(&UnicodeString1
,
722 Status
= xHalQueryDriveLayout(&UnicodeString1
,
724 if (!NT_SUCCESS(Status
))
726 DbgPrint("xHalQueryDriveLayout() failed (Status = 0x%lx)\n",
728 LayoutArray
[i
] = NULL
;
731 /* We don't use the RewritePartition value while mounting the disks.
732 * We use this value for marking pre-assigned (registry) partitions.
734 for (j
= 0; j
< LayoutArray
[i
]->PartitionCount
; j
++)
736 LayoutArray
[i
]->PartitionEntry
[j
].RewritePartition
= FALSE
;
741 /* Dump layout array */
742 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
744 DPRINT("Harddisk %d:\n",
747 if (LayoutArray
[i
] == NULL
)
750 DPRINT("Logical partitions: %d\n",
751 LayoutArray
[i
]->PartitionCount
);
753 for (j
= 0; j
< LayoutArray
[i
]->PartitionCount
; j
++)
755 DPRINT(" %d: nr:%x boot:%x type:%x startblock:%I64u count:%I64u\n",
757 LayoutArray
[i
]->PartitionEntry
[j
].PartitionNumber
,
758 LayoutArray
[i
]->PartitionEntry
[j
].BootIndicator
,
759 LayoutArray
[i
]->PartitionEntry
[j
].PartitionType
,
760 LayoutArray
[i
]->PartitionEntry
[j
].StartingOffset
.QuadPart
,
761 LayoutArray
[i
]->PartitionEntry
[j
].PartitionLength
.QuadPart
);
766 /* Assign pre-assigned (registry) partitions */
769 for (k
= 2; k
< 26; k
++)
771 swprintf(Buffer1
, DiskMountString
, L
'A' + k
);
772 RtlInitUnicodeString(&UnicodeString1
, Buffer1
);
773 Status
= ZwQueryValueKey(hKey
,
775 KeyValuePartialInformation
,
777 sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(REG_DISK_MOUNT_INFO
),
779 if (NT_SUCCESS(Status
) &&
780 PartialInformation
->Type
== REG_BINARY
&&
781 PartialInformation
->DataLength
== sizeof(REG_DISK_MOUNT_INFO
))
783 DPRINT("%wZ => %08x:%08x%08x\n", &UnicodeString1
, DiskMountInfo
->Signature
,
784 DiskMountInfo
->StartingOffset
.u
.HighPart
, DiskMountInfo
->StartingOffset
.u
.LowPart
);
786 BOOLEAN Found
= FALSE
;
787 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
789 DPRINT("%x\n", LayoutArray
[i
]->Signature
);
790 if (LayoutArray
[i
] &&
791 LayoutArray
[i
]->Signature
&&
792 LayoutArray
[i
]->Signature
== DiskMountInfo
->Signature
)
794 for (j
= 0; j
< LayoutArray
[i
]->PartitionCount
; j
++)
796 if (LayoutArray
[i
]->PartitionEntry
[j
].StartingOffset
.QuadPart
== DiskMountInfo
->StartingOffset
.QuadPart
)
798 if (IsRecognizedPartition(LayoutArray
[i
]->PartitionEntry
[j
].PartitionType
) &&
799 LayoutArray
[i
]->PartitionEntry
[j
].RewritePartition
== FALSE
)
802 L
"\\Device\\Harddisk%d\\Partition%d",
804 LayoutArray
[i
]->PartitionEntry
[j
].PartitionNumber
);
805 RtlInitUnicodeString(&UnicodeString2
,
809 DPRINT(" %wZ\n", &UnicodeString2
);
810 Found
= HalpAssignDrive(&UnicodeString2
,
812 DOSDEVICE_DRIVE_FIXED
,
813 DiskMountInfo
->Signature
,
814 DiskMountInfo
->StartingOffset
,
816 /* Mark the partition as assigned */
817 LayoutArray
[i
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
826 /* We didn't find a partition for this entry, remove them. */
827 Status
= ZwDeleteValueKey(hKey
, &UnicodeString1
);
834 /* Assign bootable partition on first harddisk */
835 DPRINT("Assigning bootable primary partition on first harddisk:\n");
838 Status
= xHalpGetDiskNumberFromRDisk(0, &DiskNumber
);
839 if (NT_SUCCESS(Status
) &&
840 DiskNumber
< ConfigInfo
->DiskCount
&&
841 LayoutArray
[DiskNumber
])
843 /* Search for bootable partition */
844 for (j
= 0; j
< PARTITION_TBL_SIZE
&& j
< LayoutArray
[DiskNumber
]->PartitionCount
; j
++)
846 if ((LayoutArray
[DiskNumber
]->PartitionEntry
[j
].BootIndicator
== TRUE
) &&
847 IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
))
849 if (LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
)
852 L
"\\Device\\Harddisk%lu\\Partition%d",
854 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
855 RtlInitUnicodeString(&UnicodeString2
,
859 DPRINT(" %wZ\n", &UnicodeString2
);
860 HalpAssignDrive(&UnicodeString2
,
862 DOSDEVICE_DRIVE_FIXED
,
863 LayoutArray
[DiskNumber
]->Signature
,
864 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
866 /* Mark the partition as assigned */
867 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
875 /* Assign remaining primary partitions */
876 DPRINT("Assigning remaining primary partitions:\n");
877 for (RDisk
= 0; RDisk
< RDiskCount
; RDisk
++)
879 Status
= xHalpGetDiskNumberFromRDisk(RDisk
, &DiskNumber
);
880 if (NT_SUCCESS(Status
) &&
881 DiskNumber
< ConfigInfo
->DiskCount
&&
882 LayoutArray
[DiskNumber
])
884 /* Search for primary partitions */
885 for (j
= 0; (j
< PARTITION_TBL_SIZE
) && (j
< LayoutArray
[DiskNumber
]->PartitionCount
); j
++)
887 if (LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
&&
888 IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
))
891 L
"\\Device\\Harddisk%d\\Partition%d",
893 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
894 RtlInitUnicodeString(&UnicodeString2
,
900 HalpAssignDrive(&UnicodeString2
,
902 DOSDEVICE_DRIVE_FIXED
,
903 LayoutArray
[DiskNumber
]->Signature
,
904 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
906 /* Mark the partition as assigned */
907 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
913 /* Assign extended (logical) partitions */
914 DPRINT("Assigning extended (logical) partitions:\n");
915 for (RDisk
= 0; RDisk
< RDiskCount
; RDisk
++)
917 Status
= xHalpGetDiskNumberFromRDisk(RDisk
, &DiskNumber
);
918 if (NT_SUCCESS(Status
) &&
919 DiskNumber
< ConfigInfo
->DiskCount
&&
920 LayoutArray
[DiskNumber
])
922 /* Search for extended partitions */
923 for (j
= PARTITION_TBL_SIZE
; j
< LayoutArray
[DiskNumber
]->PartitionCount
; j
++)
925 if (IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
) &&
926 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
&&
927 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
!= 0)
930 L
"\\Device\\Harddisk%d\\Partition%d",
932 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
933 RtlInitUnicodeString(&UnicodeString2
,
939 HalpAssignDrive(&UnicodeString2
,
941 DOSDEVICE_DRIVE_FIXED
,
942 LayoutArray
[DiskNumber
]->Signature
,
943 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
945 /* Mark the partition as assigned */
946 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
952 /* Assign remaining primary partitions without an arc-name */
953 DPRINT("Assigning remaining primary partitions:\n");
954 for (DiskNumber
= 0; DiskNumber
< ConfigInfo
->DiskCount
; DiskNumber
++)
956 if (LayoutArray
[DiskNumber
])
958 /* Search for primary partitions */
959 for (j
= 0; (j
< PARTITION_TBL_SIZE
) && (j
< LayoutArray
[DiskNumber
]->PartitionCount
); j
++)
961 if (LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
&&
962 IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
))
965 L
"\\Device\\Harddisk%d\\Partition%d",
967 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
968 RtlInitUnicodeString(&UnicodeString2
,
974 HalpAssignDrive(&UnicodeString2
,
976 DOSDEVICE_DRIVE_FIXED
,
977 LayoutArray
[DiskNumber
]->Signature
,
978 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
980 /* Mark the partition as assigned */
981 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
987 /* Assign extended (logical) partitions without an arc-name */
988 DPRINT("Assigning extended (logical) partitions:\n");
989 for (DiskNumber
= 0; DiskNumber
< ConfigInfo
->DiskCount
; DiskNumber
++)
991 if (LayoutArray
[DiskNumber
])
993 /* Search for extended partitions */
994 for (j
= PARTITION_TBL_SIZE
; j
< LayoutArray
[DiskNumber
]->PartitionCount
; j
++)
996 if (IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
) &&
997 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
&&
998 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
!= 0)
1001 L
"\\Device\\Harddisk%d\\Partition%d",
1003 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
1004 RtlInitUnicodeString(&UnicodeString2
,
1010 HalpAssignDrive(&UnicodeString2
,
1012 DOSDEVICE_DRIVE_FIXED
,
1013 LayoutArray
[DiskNumber
]->Signature
,
1014 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
1016 /* Mark the partition as assigned */
1017 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
1023 /* Assign removable disk drives */
1024 DPRINT("Assigning removable disk drives:\n");
1025 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
1029 /* Search for virtual partitions */
1030 if (LayoutArray
[i
]->PartitionCount
== 1 &&
1031 LayoutArray
[i
]->PartitionEntry
[0].PartitionType
== 0)
1034 L
"\\Device\\Harddisk%d\\Partition1",
1036 RtlInitUnicodeString(&UnicodeString2
,
1042 HalpAssignDrive(&UnicodeString2
,
1044 DOSDEVICE_DRIVE_REMOVABLE
,
1046 RtlConvertLongToLargeInteger(0),
1052 /* Free layout array */
1053 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
1055 if (LayoutArray
[i
] != NULL
)
1056 ExFreePool(LayoutArray
[i
]);
1058 ExFreePool(LayoutArray
);
1060 /* Assign floppy drives */
1061 DPRINT("Floppy drives: %d\n", ConfigInfo
->FloppyCount
);
1062 for (i
= 0; i
< ConfigInfo
->FloppyCount
; i
++)
1065 L
"\\Device\\Floppy%d",
1067 RtlInitUnicodeString(&UnicodeString1
,
1070 /* Assign drive letters A: or B: or first free drive letter */
1073 HalpAssignDrive(&UnicodeString1
,
1074 (i
< 2) ? i
: AUTO_DRIVE
,
1075 DOSDEVICE_DRIVE_REMOVABLE
,
1077 RtlConvertLongToLargeInteger(0),
1081 /* Assign cdrom drives */
1082 DPRINT("CD-Rom drives: %d\n", ConfigInfo
->CdRomCount
);
1083 for (i
= 0; i
< ConfigInfo
->CdRomCount
; i
++)
1086 L
"\\Device\\CdRom%d",
1088 RtlInitUnicodeString(&UnicodeString1
,
1091 /* Assign first free drive letter */
1092 DPRINT(" %wZ\n", &UnicodeString1
);
1093 HalpAssignDrive(&UnicodeString1
,
1095 DOSDEVICE_DRIVE_CDROM
,
1097 RtlConvertLongToLargeInteger(0),
1101 /* Anything else to do? */
1103 ExFreePool(PartialInformation
);
1104 ExFreePool(Buffer2
);
1105 ExFreePool(Buffer1
);
1114 xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject
,
1116 BOOLEAN ReturnRecognizedPartitions
,
1117 PDRIVE_LAYOUT_INFORMATION
*PartitionBuffer
)
1119 LARGE_INTEGER RealPartitionOffset
;
1120 ULONGLONG PartitionOffset
;
1121 #if defined(__GNUC__)
1122 ULONGLONG nextPartitionOffset
= 0LL;
1124 ULONGLONG nextPartitionOffset
= 0;
1126 ULONGLONG containerOffset
;
1128 PPARTITION_SECTOR PartitionSector
;
1129 PDRIVE_LAYOUT_INFORMATION LayoutBuffer
;
1133 BOOLEAN ExtendedFound
= FALSE
;
1135 DISK_MANAGER DiskManager
= NoDiskManager
;
1137 DPRINT("xHalIoReadPartitionTable(%p %lu %x %p)\n",
1140 ReturnRecognizedPartitions
,
1143 *PartitionBuffer
= NULL
;
1145 /* Check sector size */
1146 if (SectorSize
< 512)
1148 if (SectorSize
> 4096)
1151 /* Check for 'Ontrack Disk Manager' */
1152 HalExamineMBR(DeviceObject
,
1156 if (MbrBuffer
!= NULL
)
1158 DPRINT("Found 'Ontrack Disk Manager'\n");
1159 DiskManager
= OntrackDiskManager
;
1160 ExFreePool(MbrBuffer
);
1163 /* Check for 'EZ-Drive' */
1164 HalExamineMBR(DeviceObject
,
1168 if (MbrBuffer
!= NULL
)
1170 DPRINT("Found 'EZ-Drive'\n");
1171 DiskManager
= EZ_Drive
;
1172 ExFreePool(MbrBuffer
);
1175 PartitionSector
= (PPARTITION_SECTOR
)ExAllocatePool(PagedPool
,
1177 if (PartitionSector
== NULL
)
1179 return(STATUS_INSUFFICIENT_RESOURCES
);
1182 LayoutBuffer
= (PDRIVE_LAYOUT_INFORMATION
)ExAllocatePool(NonPagedPool
,
1184 if (LayoutBuffer
== NULL
)
1186 ExFreePool(PartitionSector
);
1187 return(STATUS_INSUFFICIENT_RESOURCES
);
1190 RtlZeroMemory(LayoutBuffer
,
1193 #if defined(__GNUC__)
1194 PartitionOffset
= 0ULL;
1195 containerOffset
= 0ULL;
1197 PartitionOffset
= 0;
1198 containerOffset
= 0;
1203 DPRINT("PartitionOffset: %I64u\n", PartitionOffset
/ SectorSize
);
1205 /* Handle disk managers */
1206 if (DiskManager
== OntrackDiskManager
)
1208 /* Shift offset by 63 sectors */
1209 RealPartitionOffset
.QuadPart
= PartitionOffset
+ (ULONGLONG
)(63 * SectorSize
);
1211 #if defined(__GNUC__)
1212 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0ULL)
1214 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0)
1217 /* Use sector 1 instead of sector 0 */
1218 RealPartitionOffset
.QuadPart
= (ULONGLONG
)SectorSize
;
1222 RealPartitionOffset
.QuadPart
= PartitionOffset
;
1225 DPRINT ("RealPartitionOffset: %I64u\n",
1226 RealPartitionOffset
.QuadPart
/ SectorSize
);
1228 Status
= xHalpReadSector (DeviceObject
,
1230 &RealPartitionOffset
,
1232 if (!NT_SUCCESS(Status
))
1234 DPRINT ("Failed to read partition table sector (Status = 0x%08lx)\n",
1236 ExFreePool (PartitionSector
);
1237 ExFreePool (LayoutBuffer
);
1241 /* Check the boot sector id */
1242 DPRINT("Magic %x\n", PartitionSector
->Magic
);
1243 if (PartitionSector
->Magic
!= PARTITION_MAGIC
)
1245 DPRINT ("Invalid partition sector magic\n");
1246 ExFreePool (PartitionSector
);
1247 *PartitionBuffer
= LayoutBuffer
;
1248 return STATUS_SUCCESS
;
1252 for (i
= 0; i
< PARTITION_TBL_SIZE
; i
++)
1254 DPRINT1(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",
1256 PartitionSector
->Partition
[i
].BootFlags
,
1257 PartitionSector
->Partition
[i
].PartitionType
,
1258 PartitionSector
->Partition
[i
].StartingHead
,
1259 PartitionSector
->Partition
[i
].StartingSector
& 0x3f,
1260 (((PartitionSector
->Partition
[i
].StartingSector
) & 0xc0) << 2) +
1261 PartitionSector
->Partition
[i
].StartingCylinder
,
1262 PartitionSector
->Partition
[i
].EndingHead
,
1263 PartitionSector
->Partition
[i
].EndingSector
& 0x3f,
1264 (((PartitionSector
->Partition
[i
].EndingSector
) & 0xc0) << 2) +
1265 PartitionSector
->Partition
[i
].EndingCylinder
,
1266 PartitionSector
->Partition
[i
].StartingBlock
,
1267 PartitionSector
->Partition
[i
].SectorCount
);
1271 #if defined(__GNUC__)
1272 if (PartitionOffset
== 0ULL)
1274 if (PartitionOffset
== 0)
1277 LayoutBuffer
->Signature
= PartitionSector
->Signature
;
1278 DPRINT("Disk signature: %lx\n", LayoutBuffer
->Signature
);
1281 ExtendedFound
= FALSE
;
1283 for (i
= 0; i
< PARTITION_TBL_SIZE
; i
++)
1285 if (IsContainerPartition(PartitionSector
->Partition
[i
].PartitionType
))
1287 ExtendedFound
= TRUE
;
1288 if ((ULONGLONG
) containerOffset
== (ULONGLONG
) 0)
1290 containerOffset
= PartitionOffset
;
1292 nextPartitionOffset
= (ULONGLONG
) containerOffset
+
1293 (ULONGLONG
) PartitionSector
->Partition
[i
].StartingBlock
*
1294 (ULONGLONG
) SectorSize
;
1297 if ((ReturnRecognizedPartitions
== FALSE
) ||
1298 ((ReturnRecognizedPartitions
== TRUE
) &&
1299 !IsContainerPartition(PartitionSector
->Partition
[i
].PartitionType
) &&
1300 PartitionSector
->Partition
[i
].PartitionType
!= PARTITION_ENTRY_UNUSED
))
1302 /* handle normal partition */
1303 DPRINT("Partition %u: Normal Partition\n", i
);
1304 Count
= LayoutBuffer
->PartitionCount
;
1305 DPRINT("Logical Partition %u\n", Count
);
1307 if (PartitionSector
->Partition
[i
].StartingBlock
== 0)
1309 LayoutBuffer
->PartitionEntry
[Count
].StartingOffset
.QuadPart
= 0;
1311 else if (IsContainerPartition(PartitionSector
->Partition
[i
].PartitionType
))
1313 LayoutBuffer
->PartitionEntry
[Count
].StartingOffset
.QuadPart
=
1314 (ULONGLONG
) containerOffset
+
1315 (ULONGLONG
) PartitionSector
->Partition
[i
].StartingBlock
*
1316 (ULONGLONG
) SectorSize
;
1320 LayoutBuffer
->PartitionEntry
[Count
].StartingOffset
.QuadPart
=
1321 (ULONGLONG
)PartitionOffset
+
1322 ((ULONGLONG
)PartitionSector
->Partition
[i
].StartingBlock
* (ULONGLONG
)SectorSize
);
1324 LayoutBuffer
->PartitionEntry
[Count
].PartitionLength
.QuadPart
=
1325 (ULONGLONG
)PartitionSector
->Partition
[i
].SectorCount
* (ULONGLONG
)SectorSize
;
1326 LayoutBuffer
->PartitionEntry
[Count
].HiddenSectors
=
1327 PartitionSector
->Partition
[i
].StartingBlock
;
1329 if (!IsContainerPartition(PartitionSector
->Partition
[i
].PartitionType
) &&
1330 PartitionSector
->Partition
[i
].PartitionType
!= PARTITION_ENTRY_UNUSED
)
1332 LayoutBuffer
->PartitionEntry
[Count
].RecognizedPartition
= TRUE
;
1333 /* WinXP returns garbage as PartitionNumber */
1334 LayoutBuffer
->PartitionEntry
[Count
].PartitionNumber
= Number
;
1339 LayoutBuffer
->PartitionEntry
[Count
].RecognizedPartition
= FALSE
;
1340 LayoutBuffer
->PartitionEntry
[Count
].PartitionNumber
= 0;
1343 LayoutBuffer
->PartitionEntry
[Count
].PartitionType
=
1344 PartitionSector
->Partition
[i
].PartitionType
;
1345 LayoutBuffer
->PartitionEntry
[Count
].BootIndicator
=
1346 (PartitionSector
->Partition
[i
].BootFlags
& 0x80)?TRUE
:FALSE
;
1347 LayoutBuffer
->PartitionEntry
[Count
].RewritePartition
= FALSE
;
1349 DPRINT(" %ld: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x rec: %d\n",
1351 LayoutBuffer
->PartitionEntry
[Count
].PartitionNumber
,
1352 LayoutBuffer
->PartitionEntry
[Count
].BootIndicator
,
1353 LayoutBuffer
->PartitionEntry
[Count
].PartitionType
,
1354 LayoutBuffer
->PartitionEntry
[Count
].StartingOffset
.QuadPart
,
1355 LayoutBuffer
->PartitionEntry
[Count
].PartitionLength
.QuadPart
,
1356 LayoutBuffer
->PartitionEntry
[Count
].RecognizedPartition
);
1358 LayoutBuffer
->PartitionCount
++;
1362 PartitionOffset
= nextPartitionOffset
;
1364 while (ExtendedFound
== TRUE
);
1366 *PartitionBuffer
= LayoutBuffer
;
1367 ExFreePool(PartitionSector
);
1369 return(STATUS_SUCCESS
);
1374 xHalIoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject
,
1375 IN ULONG SectorSize
,
1376 IN ULONG PartitionNumber
,
1377 IN ULONG PartitionType
)
1379 PPARTITION_SECTOR PartitionSector
;
1380 LARGE_INTEGER RealPartitionOffset
;
1381 ULONGLONG PartitionOffset
;
1382 #if defined(__GNUC__)
1383 ULONGLONG nextPartitionOffset
= 0LL;
1385 ULONGLONG nextPartitionOffset
= 0;
1387 ULONGLONG containerOffset
;
1391 BOOLEAN ExtendedFound
= FALSE
;
1392 DISK_MANAGER DiskManager
= NoDiskManager
;
1394 DPRINT ("xHalIoSetPartitionInformation(%p %lu %lu %lu)\n",
1400 /* Check sector size */
1401 if (SectorSize
< 512)
1403 if (SectorSize
> 4096)
1406 /* Check for 'Ontrack Disk Manager' */
1407 HalExamineMBR (DeviceObject
,
1410 (PVOID
*)(PVOID
)&PartitionSector
);
1411 if (PartitionSector
!= NULL
)
1413 DPRINT ("Found 'Ontrack Disk Manager'\n");
1414 DiskManager
= OntrackDiskManager
;
1415 ExFreePool (PartitionSector
);
1418 /* Check for 'EZ-Drive' */
1419 HalExamineMBR (DeviceObject
,
1422 (PVOID
*)(PVOID
)&PartitionSector
);
1423 if (PartitionSector
!= NULL
)
1425 DPRINT ("Found 'EZ-Drive'\n");
1426 DiskManager
= EZ_Drive
;
1427 ExFreePool (PartitionSector
);
1430 /* Allocate partition sector */
1431 PartitionSector
= (PPARTITION_SECTOR
) ExAllocatePool (PagedPool
,
1433 if (PartitionSector
== NULL
)
1435 return STATUS_INSUFFICIENT_RESOURCES
;
1438 #if defined(__GNUC__)
1439 PartitionOffset
= 0ULL;
1440 containerOffset
= 0ULL;
1442 PartitionOffset
= 0;
1443 containerOffset
= 0;
1448 DPRINT ("PartitionOffset: %I64u\n", PartitionOffset
/ SectorSize
);
1450 /* Handle disk managers */
1451 if (DiskManager
== OntrackDiskManager
)
1453 /* Shift offset by 63 sectors */
1454 RealPartitionOffset
.QuadPart
= PartitionOffset
+ (ULONGLONG
)(63 * SectorSize
);
1456 #if defined(__GNUC__)
1457 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0ULL)
1459 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0)
1462 /* Use sector 1 instead of sector 0 */
1463 RealPartitionOffset
.QuadPart
= (ULONGLONG
)SectorSize
;
1467 RealPartitionOffset
.QuadPart
= PartitionOffset
;
1470 DPRINT ("RealPartitionOffset: %I64u\n",
1471 RealPartitionOffset
.QuadPart
/ SectorSize
);
1473 Status
= xHalpReadSector (DeviceObject
,
1475 &RealPartitionOffset
,
1477 if (!NT_SUCCESS (Status
))
1479 DPRINT ("Failed to read partition table sector (Status = 0x%08lx)\n",
1481 ExFreePool (PartitionSector
);
1485 /* Check the boot sector id */
1486 DPRINT("Magic %x\n", PartitionSector
->Magic
);
1487 if (PartitionSector
->Magic
!= PARTITION_MAGIC
)
1489 DPRINT ("Invalid partition sector magic\n");
1490 ExFreePool (PartitionSector
);
1491 return STATUS_UNSUCCESSFUL
;
1495 for (i
= 0; i
< PARTITION_TBL_SIZE
; i
++)
1497 DPRINT1(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",
1499 PartitionSector
->Partition
[i
].BootFlags
,
1500 PartitionSector
->Partition
[i
].PartitionType
,
1501 PartitionSector
->Partition
[i
].StartingHead
,
1502 PartitionSector
->Partition
[i
].StartingSector
& 0x3f,
1503 (((PartitionSector
->Partition
[i
].StartingSector
) & 0xc0) << 2) +
1504 PartitionSector
->Partition
[i
].StartingCylinder
,
1505 PartitionSector
->Partition
[i
].EndingHead
,
1506 PartitionSector
->Partition
[i
].EndingSector
& 0x3f,
1507 (((PartitionSector
->Partition
[i
].EndingSector
) & 0xc0) << 2) +
1508 PartitionSector
->Partition
[i
].EndingCylinder
,
1509 PartitionSector
->Partition
[i
].StartingBlock
,
1510 PartitionSector
->Partition
[i
].SectorCount
);
1514 ExtendedFound
= FALSE
;
1515 for (i
= 0; i
< PARTITION_TBL_SIZE
; i
++)
1517 if (IsContainerPartition (PartitionSector
->Partition
[i
].PartitionType
))
1519 ExtendedFound
= TRUE
;
1520 #if defined(__GNUC__)
1521 if (containerOffset
== 0ULL)
1523 if (containerOffset
== 0)
1526 containerOffset
= PartitionOffset
;
1528 nextPartitionOffset
= containerOffset
+
1529 (ULONGLONG
) PartitionSector
->Partition
[i
].StartingBlock
*
1530 (ULONGLONG
) SectorSize
;
1533 /* Handle recognized partition */
1534 if (IsRecognizedPartition (PartitionSector
->Partition
[i
].PartitionType
))
1536 if (Number
== PartitionNumber
)
1538 /* Set partition type */
1539 PartitionSector
->Partition
[i
].PartitionType
= PartitionType
;
1541 /* Write partition sector */
1542 Status
= xHalpWriteSector (DeviceObject
,
1544 &RealPartitionOffset
,
1546 if (!NT_SUCCESS(Status
))
1548 DPRINT1("xHalpWriteSector() failed (Status %lx)\n", Status
);
1551 ExFreePool (PartitionSector
);
1558 PartitionOffset
= nextPartitionOffset
;
1560 while (ExtendedFound
== TRUE
);
1562 ExFreePool(PartitionSector
);
1564 return STATUS_UNSUCCESSFUL
;
1569 xHalIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject
,
1570 IN ULONG SectorSize
,
1571 IN ULONG SectorsPerTrack
,
1572 IN ULONG NumberOfHeads
,
1573 IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer
)
1575 PPARTITION_SECTOR PartitionSector
;
1576 LARGE_INTEGER RealPartitionOffset
;
1577 ULONGLONG PartitionOffset
;
1578 #if defined(__GNUC__)
1579 ULONGLONG NextPartitionOffset
= 0LL;
1581 ULONGLONG NextPartitionOffset
= 0;
1583 ULONGLONG ContainerOffset
;
1584 BOOLEAN ContainerEntry
;
1585 DISK_MANAGER DiskManager
;
1590 ULONG StartCylinder
;
1600 DPRINT ("xHalIoWritePartitionTable(%p %lu %lu %lu %p)\n",
1607 ASSERT(DeviceObject
);
1608 ASSERT(PartitionBuffer
);
1610 DiskManager
= NoDiskManager
;
1612 /* Check sector size */
1613 if (SectorSize
< 512)
1615 if (SectorSize
> 4096)
1618 /* Check for 'Ontrack Disk Manager' */
1619 HalExamineMBR (DeviceObject
,
1622 (PVOID
*)(PVOID
)&PartitionSector
);
1623 if (PartitionSector
!= NULL
)
1625 DPRINT ("Found 'Ontrack Disk Manager'\n");
1626 DiskManager
= OntrackDiskManager
;
1627 ExFreePool (PartitionSector
);
1630 /* Check for 'EZ-Drive' */
1631 HalExamineMBR (DeviceObject
,
1634 (PVOID
*)(PVOID
)&PartitionSector
);
1635 if (PartitionSector
!= NULL
)
1637 DPRINT ("Found 'EZ-Drive'\n");
1638 DiskManager
= EZ_Drive
;
1639 ExFreePool (PartitionSector
);
1642 /* Allocate partition sector */
1643 PartitionSector
= (PPARTITION_SECTOR
)ExAllocatePool(PagedPool
,
1645 if (PartitionSector
== NULL
)
1647 return STATUS_INSUFFICIENT_RESOURCES
;
1650 Status
= STATUS_SUCCESS
;
1651 #if defined(__GNUC__)
1652 PartitionOffset
= 0ULL;
1653 ContainerOffset
= 0ULL;
1655 PartitionOffset
= 0;
1656 ContainerOffset
= 0;
1658 for (i
= 0; i
< PartitionBuffer
->PartitionCount
; i
+= 4)
1660 DPRINT ("PartitionOffset: %I64u\n", PartitionOffset
);
1661 DPRINT ("ContainerOffset: %I64u\n", ContainerOffset
);
1663 /* Handle disk managers */
1664 if (DiskManager
== OntrackDiskManager
)
1666 /* Shift offset by 63 sectors */
1667 RealPartitionOffset
.QuadPart
= PartitionOffset
+ (ULONGLONG
)(63 * SectorSize
);
1669 #if defined(__GNUC__)
1670 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0ULL)
1672 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0)
1675 /* Use sector 1 instead of sector 0 */
1676 RealPartitionOffset
.QuadPart
= (ULONGLONG
)SectorSize
;
1680 RealPartitionOffset
.QuadPart
= PartitionOffset
;
1683 /* Write modified partition tables */
1684 if (PartitionBuffer
->PartitionEntry
[i
].RewritePartition
== TRUE
||
1685 PartitionBuffer
->PartitionEntry
[i
+ 1].RewritePartition
== TRUE
||
1686 PartitionBuffer
->PartitionEntry
[i
+ 2].RewritePartition
== TRUE
||
1687 PartitionBuffer
->PartitionEntry
[i
+ 3].RewritePartition
== TRUE
)
1689 /* Read partition sector */
1690 Status
= xHalpReadSector (DeviceObject
,
1692 &RealPartitionOffset
,
1694 if (!NT_SUCCESS(Status
))
1696 DPRINT1 ("xHalpReadSector() failed (Status %lx)\n", Status
);
1700 /* Initialize a new partition sector */
1701 if (PartitionSector
->Magic
!= PARTITION_MAGIC
)
1703 /* Create empty partition sector */
1704 RtlZeroMemory (PartitionSector
,
1706 PartitionSector
->Magic
= PARTITION_MAGIC
;
1709 PartitionSector
->Signature
= PartitionBuffer
->Signature
;
1710 /* Update partition sector entries */
1711 for (j
= 0; j
< 4; j
++)
1713 if (PartitionBuffer
->PartitionEntry
[i
+ j
].RewritePartition
== TRUE
)
1715 /* Set partition boot flag */
1716 if (PartitionBuffer
->PartitionEntry
[i
+ j
].BootIndicator
)
1718 PartitionSector
->Partition
[j
].BootFlags
|= 0x80;
1722 PartitionSector
->Partition
[j
].BootFlags
&= ~0x80;
1725 /* Set partition type */
1726 PartitionSector
->Partition
[j
].PartitionType
=
1727 PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionType
;
1729 /* Set partition data */
1730 #if defined(__GNUC__)
1731 if (PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
== 0ULL &&
1732 PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionLength
.QuadPart
== 0ULL)
1734 if (PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
== 0 &&
1735 PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionLength
.QuadPart
== 0)
1738 PartitionSector
->Partition
[j
].StartingBlock
= 0;
1739 PartitionSector
->Partition
[j
].SectorCount
= 0;
1740 PartitionSector
->Partition
[j
].StartingCylinder
= 0;
1741 PartitionSector
->Partition
[j
].StartingHead
= 0;
1742 PartitionSector
->Partition
[j
].StartingSector
= 0;
1743 PartitionSector
->Partition
[j
].EndingCylinder
= 0;
1744 PartitionSector
->Partition
[j
].EndingHead
= 0;
1745 PartitionSector
->Partition
[j
].EndingSector
= 0;
1751 * x = LBA DIV SectorsPerTrack
1752 * cylinder = (x DIV NumberOfHeads) % 1024
1753 * head = x MOD NumberOfHeads
1754 * sector = (LBA MOD SectorsPerTrack) + 1
1757 /* Compute starting CHS values */
1758 lba
= (ULONG
)((PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
) / SectorSize
);
1759 x
= lba
/ SectorsPerTrack
;
1760 StartCylinder
= (x
/ NumberOfHeads
) %1024;
1761 StartHead
= x
% NumberOfHeads
;
1762 StartSector
= (lba
% SectorsPerTrack
) + 1;
1763 DPRINT ("StartingOffset (LBA:%d C:%d H:%d S:%d)\n",
1764 lba
, StartCylinder
, StartHead
, StartSector
);
1766 /* Compute ending CHS values */
1767 lba
= (ULONG
)((PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
+
1768 (PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionLength
.QuadPart
- 1)) / SectorSize
);
1769 x
= lba
/ SectorsPerTrack
;
1770 EndCylinder
= (x
/ NumberOfHeads
) % 1024;
1771 EndHead
= x
% NumberOfHeads
;
1772 EndSector
= (lba
% SectorsPerTrack
) + 1;
1773 DPRINT ("EndingOffset (LBA:%d C:%d H:%d S:%d)\n",
1774 lba
, EndCylinder
, EndHead
, EndSector
);
1776 /* Set starting CHS values */
1777 PartitionSector
->Partition
[j
].StartingCylinder
= StartCylinder
& 0xff;
1778 PartitionSector
->Partition
[j
].StartingHead
= StartHead
;
1779 PartitionSector
->Partition
[j
].StartingSector
=
1780 ((StartCylinder
& 0x0300) >> 2) + (StartSector
& 0x3f);
1782 /* Set ending CHS values */
1783 PartitionSector
->Partition
[j
].EndingCylinder
= EndCylinder
& 0xff;
1784 PartitionSector
->Partition
[j
].EndingHead
= EndHead
;
1785 PartitionSector
->Partition
[j
].EndingSector
=
1786 ((EndCylinder
& 0x0300) >> 2) + (EndSector
& 0x3f);
1788 /* Calculate start sector and sector count */
1789 if (IsContainerPartition (PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionType
))
1792 (PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
- ContainerOffset
) / SectorSize
;
1797 (PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
- NextPartitionOffset
) / SectorSize
;
1800 PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionLength
.QuadPart
/ SectorSize
;
1801 DPRINT ("LBA (StartBlock:%lu SectorCount:%lu)\n",
1802 StartBlock
, SectorCount
);
1804 /* Set start sector and sector count */
1805 PartitionSector
->Partition
[j
].StartingBlock
= StartBlock
;
1806 PartitionSector
->Partition
[j
].SectorCount
= SectorCount
;
1811 /* Write partition sector */
1812 Status
= xHalpWriteSector (DeviceObject
,
1814 &RealPartitionOffset
,
1816 if (!NT_SUCCESS(Status
))
1818 DPRINT1("xHalpWriteSector() failed (Status %lx)\n", Status
);
1823 ContainerEntry
= FALSE
;
1824 for (j
= 0; j
< 4; j
++)
1826 if (IsContainerPartition (PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionType
))
1828 ContainerEntry
= TRUE
;
1829 NextPartitionOffset
=
1830 PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
;
1832 #if defined(__GNUC__)
1833 if (ContainerOffset
== 0ULL)
1835 if (ContainerOffset
== 0)
1838 ContainerOffset
= NextPartitionOffset
;
1843 if (ContainerEntry
== FALSE
)
1845 DPRINT ("No container entry in partition sector!\n");
1849 PartitionOffset
= NextPartitionOffset
;
1852 ExFreePool (PartitionSector
);
1862 IoAssignDriveLetters(
1863 IN PLOADER_PARAMETER_BLOCK LoaderBlock,
1864 IN PSTRING NtDeviceName,
1865 OUT PUCHAR NtSystemPath,
1866 OUT PSTRING NtSystemPathString
1878 IN PDEVICE_OBJECT DeviceObject
,
1879 IN
struct _CREATE_DISK
* Disk
1883 return STATUS_NOT_IMPLEMENTED
;
1891 IoGetBootDiskInformation(
1892 IN OUT PBOOTDISK_INFORMATION BootDiskInformation
,
1897 return STATUS_NOT_IMPLEMENTED
;
1906 IoReadDiskSignature(
1907 IN PDEVICE_OBJECT DeviceObject
,
1908 IN ULONG BytesPerSector
,
1909 OUT PDISK_SIGNATURE Signature
1913 return STATUS_NOT_IMPLEMENTED
;
1921 IoReadPartitionTableEx(
1922 IN PDEVICE_OBJECT DeviceObject
,
1923 IN
struct _DRIVE_LAYOUT_INFORMATION_EX
** DriveLayout
1927 return STATUS_NOT_IMPLEMENTED
;
1935 IoSetPartitionInformationEx(
1936 IN PDEVICE_OBJECT DeviceObject
,
1937 IN ULONG PartitionNumber
,
1938 IN
struct _SET_PARTITION_INFORMATION_EX
* PartitionInfo
1942 return STATUS_NOT_IMPLEMENTED
;
1950 IoSetSystemPartition(
1951 PUNICODE_STRING VolumeNameString
1955 return STATUS_NOT_IMPLEMENTED
;
1963 IoVerifyPartitionTable(
1964 IN PDEVICE_OBJECT DeviceObject
,
1965 IN BOOLEAN FixErrors
1969 return STATUS_NOT_IMPLEMENTED
;
1977 IoVolumeDeviceToDosName(
1978 IN PVOID VolumeDeviceObject
,
1979 OUT PUNICODE_STRING DosName
1983 return STATUS_NOT_IMPLEMENTED
;
1991 IoWritePartitionTableEx(
1992 IN PDEVICE_OBJECT DeviceObject
,
1993 IN
struct _DRIVE_LAYOUT_INFORMATION_EX
* DriveLayfout
1997 return STATUS_NOT_IMPLEMENTED
;
2004 IoReadPartitionTable(PDEVICE_OBJECT DeviceObject
,
2006 BOOLEAN ReturnRecognizedPartitions
,
2007 PDRIVE_LAYOUT_INFORMATION
*PartitionBuffer
)
2009 return(HalIoReadPartitionTable(DeviceObject
,
2011 ReturnRecognizedPartitions
,
2017 IoSetPartitionInformation(PDEVICE_OBJECT DeviceObject
,
2019 ULONG PartitionNumber
,
2020 ULONG PartitionType
)
2022 return(HalIoSetPartitionInformation(DeviceObject
,
2030 IoWritePartitionTable(PDEVICE_OBJECT DeviceObject
,
2032 ULONG SectorsPerTrack
,
2033 ULONG NumberOfHeads
,
2034 PDRIVE_LAYOUT_INFORMATION PartitionBuffer
)
2036 return(HalIoWritePartitionTable(DeviceObject
,