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
23 #define PARTITION_TBL_SIZE 4
27 typedef struct _PARTITION
29 unsigned char BootFlags
; /* bootable? 0=no, 128=yes */
30 unsigned char StartingHead
; /* beginning head number */
31 unsigned char StartingSector
; /* beginning sector number */
32 unsigned char StartingCylinder
; /* 10 bit nmbr, with high 2 bits put in begsect */
33 unsigned char PartitionType
; /* Operating System type indicator code */
34 unsigned char EndingHead
; /* ending head number */
35 unsigned char EndingSector
; /* ending sector number */
36 unsigned char EndingCylinder
; /* also a 10 bit nmbr, with same high 2 bit trick */
37 unsigned int StartingBlock
; /* first sector relative to start of disk */
38 unsigned int SectorCount
; /* number of sectors in partition */
39 } PARTITION
, *PPARTITION
;
42 typedef struct _PARTITION_SECTOR
44 UCHAR BootCode
[440]; /* 0x000 */
45 ULONG Signature
; /* 0x1B8 */
46 UCHAR Reserved
[2]; /* 0x1BC */
47 PARTITION Partition
[PARTITION_TBL_SIZE
]; /* 0x1BE */
48 USHORT Magic
; /* 0x1FE */
49 } PARTITION_SECTOR
, *PPARTITION_SECTOR
;
51 typedef struct _REG_DISK_MOUNT_INFO
54 LARGE_INTEGER StartingOffset
;
55 } REG_DISK_MOUNT_INFO
, *PREG_DISK_MOUNT_INFO
;
60 typedef enum _DISK_MANAGER
67 HAL_DISPATCH EXPORTED HalDispatchTable
=
70 (pHalQuerySystemInformation
) NULL
, // HalQuerySystemInformation
71 (pHalSetSystemInformation
) NULL
, // HalSetSystemInformation
72 (pHalQueryBusSlots
) NULL
, // HalQueryBusSlots
74 (pHalExamineMBR
) HalExamineMBR
,
75 (pHalIoAssignDriveLetters
) xHalIoAssignDriveLetters
,
76 (pHalIoReadPartitionTable
) xHalIoReadPartitionTable
,
77 (pHalIoSetPartitionInformation
) xHalIoSetPartitionInformation
,
78 (pHalIoWritePartitionTable
) xHalIoWritePartitionTable
,
79 (pHalHandlerForBus
) NULL
, // HalReferenceHandlerForBus
80 (pHalReferenceBusHandler
) NULL
, // HalReferenceBusHandler
81 (pHalReferenceBusHandler
) NULL
, // HalDereferenceBusHandler
82 (pHalInitPnpDriver
) NULL
, //HalInitPnpDriver;
83 (pHalInitPowerManagement
) NULL
, //HalInitPowerManagement;
84 (pHalGetDmaAdapter
) NULL
, //HalGetDmaAdapter;
85 (pHalGetInterruptTranslator
) NULL
, //HalGetInterruptTranslator;
86 (pHalStartMirroring
) NULL
, //HalStartMirroring;
87 (pHalEndMirroring
) NULL
, //HalEndMirroring;
88 (pHalMirrorPhysicalMemory
) NULL
, //HalMirrorPhysicalMemory;
89 (pHalEndOfBoot
) NULL
, //HalEndOfBoot;
90 (pHalMirrorVerify
) NULL
//HalMirrorVerify;
93 HAL_PRIVATE_DISPATCH EXPORTED HalPrivateDispatchTable
=
95 HAL_PRIVATE_DISPATCH_VERSION
98 const WCHAR DiskMountString
[] = L
"\\DosDevices\\%C:";
100 /* FUNCTIONS *****************************************************************/
104 xHalQueryDriveLayout(IN PUNICODE_STRING DeviceName
,
105 OUT PDRIVE_LAYOUT_INFORMATION
*LayoutInfo
)
107 IO_STATUS_BLOCK StatusBlock
;
108 DISK_GEOMETRY DiskGeometry
;
109 PDEVICE_OBJECT DeviceObject
= NULL
;
110 PFILE_OBJECT FileObject
;
115 DPRINT("xHalpQueryDriveLayout %wZ %p\n",
119 /* Get the drives sector size */
120 Status
= IoGetDeviceObjectPointer(DeviceName
,
124 if (!NT_SUCCESS(Status
))
126 DPRINT("Status %x\n", Status
);
130 KeInitializeEvent(&Event
,
134 Irp
= IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY
,
139 sizeof(DISK_GEOMETRY
),
145 ObDereferenceObject(FileObject
);
146 return(STATUS_INSUFFICIENT_RESOURCES
);
149 Status
= IoCallDriver(DeviceObject
,
151 if (Status
== STATUS_PENDING
)
153 KeWaitForSingleObject(&Event
,
158 Status
= StatusBlock
.Status
;
160 if (!NT_SUCCESS(Status
))
162 if (DeviceObject
->Characteristics
& FILE_REMOVABLE_MEDIA
)
164 DiskGeometry
.BytesPerSector
= 512;
168 ObDereferenceObject(FileObject
);
173 DPRINT("DiskGeometry.BytesPerSector: %d\n",
174 DiskGeometry
.BytesPerSector
);
176 if (DeviceObject
->Characteristics
& FILE_REMOVABLE_MEDIA
)
178 PDRIVE_LAYOUT_INFORMATION Buffer
;
180 /* Allocate a partition list for a single entry. */
181 Buffer
= ExAllocatePool(NonPagedPool
,
182 sizeof(DRIVE_LAYOUT_INFORMATION
));
185 RtlZeroMemory(Buffer
,
186 sizeof(DRIVE_LAYOUT_INFORMATION
));
187 Buffer
->PartitionCount
= 1;
188 *LayoutInfo
= Buffer
;
190 Status
= STATUS_SUCCESS
;
194 Status
= STATUS_UNSUCCESSFUL
;
199 /* Read the partition table */
200 Status
= IoReadPartitionTable(DeviceObject
,
201 DiskGeometry
.BytesPerSector
,
206 ObDereferenceObject(FileObject
);
213 xHalpReadSector (IN PDEVICE_OBJECT DeviceObject
,
215 IN PLARGE_INTEGER SectorOffset
,
218 IO_STATUS_BLOCK StatusBlock
;
223 DPRINT("xHalpReadSector() called\n");
225 ASSERT(DeviceObject
);
228 KeInitializeEvent(&Event
,
232 /* Read the sector */
233 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
,
241 Status
= IoCallDriver(DeviceObject
,
243 if (Status
== STATUS_PENDING
)
245 KeWaitForSingleObject(&Event
,
250 Status
= StatusBlock
.Status
;
253 if (!NT_SUCCESS(Status
))
255 DPRINT("Reading sector failed (Status 0x%08lx)\n",
265 xHalpWriteSector (IN PDEVICE_OBJECT DeviceObject
,
267 IN PLARGE_INTEGER SectorOffset
,
270 IO_STATUS_BLOCK StatusBlock
;
275 DPRINT("xHalpWriteSector() called\n");
277 KeInitializeEvent(&Event
,
281 /* Write the sector */
282 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
,
290 Status
= IoCallDriver(DeviceObject
,
292 if (Status
== STATUS_PENDING
)
294 KeWaitForSingleObject(&Event
,
299 Status
= StatusBlock
.Status
;
302 if (!NT_SUCCESS(Status
))
304 DPRINT("Writing sector failed (Status 0x%08lx)\n",
313 HalExamineMBR(IN PDEVICE_OBJECT DeviceObject
,
315 IN ULONG MBRTypeIdentifier
,
318 LARGE_INTEGER SectorOffset
;
319 PPARTITION_SECTOR Sector
;
322 DPRINT("HalExamineMBR()\n");
326 if (SectorSize
< 512)
328 if (SectorSize
> 4096)
331 Sector
= (PPARTITION_SECTOR
) ExAllocatePool (PagedPool
,
335 DPRINT ("Partition sector allocation failed\n");
339 #if defined(__GNUC__)
340 SectorOffset
.QuadPart
= 0LL;
342 SectorOffset
.QuadPart
= 0;
344 Status
= xHalpReadSector (DeviceObject
,
348 if (!NT_SUCCESS(Status
))
350 DPRINT("xHalpReadSector() failed (Status %lx)\n", Status
);
355 if (Sector
->Magic
!= PARTITION_MAGIC
)
357 DPRINT("Invalid MBR magic value\n");
362 if (Sector
->Partition
[0].PartitionType
!= MBRTypeIdentifier
)
364 DPRINT("Invalid MBRTypeIdentifier\n");
369 if (Sector
->Partition
[0].PartitionType
== 0x54)
371 /* Found 'Ontrack Disk Manager'. Shift all sectors by 63 */
372 DPRINT("Found 'Ontrack Disk Manager'!\n");
373 *((PULONG
)Sector
) = 63;
376 *Buffer
= (PVOID
)Sector
;
381 HalpAssignDrive(IN PUNICODE_STRING PartitionName
,
382 IN ULONG DriveNumber
,
385 IN LARGE_INTEGER StartingOffset
,
388 WCHAR DriveNameBuffer
[16];
389 UNICODE_STRING DriveName
;
392 REG_DISK_MOUNT_INFO DiskMountInfo
;
394 DPRINT("HalpAssignDrive()\n");
396 if ((DriveNumber
!= AUTO_DRIVE
) && (DriveNumber
< 26))
398 /* Force assignment */
399 if ((ObSystemDeviceMap
->DriveMap
& (1 << DriveNumber
)) != 0)
401 DbgPrint("Drive letter already used!\n");
407 /* Automatic assignment */
408 DriveNumber
= AUTO_DRIVE
;
410 for (i
= 2; i
< 26; i
++)
412 if ((ObSystemDeviceMap
->DriveMap
& (1 << i
)) == 0)
419 if (DriveNumber
== AUTO_DRIVE
)
421 DbgPrint("No drive letter available!\n");
426 DPRINT("DriveNumber %d\n", DriveNumber
);
428 /* Update the System Device Map */
429 ObSystemDeviceMap
->DriveMap
|= (1 << DriveNumber
);
430 ObSystemDeviceMap
->DriveType
[DriveNumber
] = DriveType
;
432 /* Build drive name */
433 swprintf(DriveNameBuffer
,
436 RtlInitUnicodeString(&DriveName
,
439 DPRINT(" %wZ ==> %wZ\n",
443 /* Create symbolic link */
444 Status
= IoCreateSymbolicLink(&DriveName
,
447 if (DriveType
== DOSDEVICE_DRIVE_FIXED
&& hKey
)
449 DiskMountInfo
.Signature
= Signature
;
450 DiskMountInfo
.StartingOffset
= StartingOffset
;
451 swprintf(DriveNameBuffer
, DiskMountString
, L
'A' + DriveNumber
);
452 RtlInitUnicodeString(&DriveName
, DriveNameBuffer
);
454 Status
= ZwSetValueKey(hKey
,
459 sizeof(DiskMountInfo
));
460 if (!NT_SUCCESS(Status
))
462 DPRINT1("ZwCreateValueKey failed for %wZ, status=%x\n", &DriveName
, Status
);
468 xHalpGetRDiskCount(VOID
)
471 UNICODE_STRING ArcName
;
472 PWCHAR ArcNameBuffer
;
473 OBJECT_ATTRIBUTES ObjectAttributes
;
474 HANDLE DirectoryHandle
;
475 POBJECT_DIRECTORY_INFORMATION DirectoryInfo
;
480 BOOLEAN First
= TRUE
;
483 DirectoryInfo
= ExAllocatePool(PagedPool
, 2 * PAGE_SIZE
);
484 if (DirectoryInfo
== NULL
)
489 RtlInitUnicodeString(&ArcName
, L
"\\ArcName");
490 InitializeObjectAttributes(&ObjectAttributes
,
496 Status
= ZwOpenDirectoryObject (&DirectoryHandle
,
497 SYMBOLIC_LINK_ALL_ACCESS
,
499 if (!NT_SUCCESS(Status
))
501 DPRINT1("ZwOpenDirectoryObject for %wZ failed, status=%lx\n", &ArcName
, Status
);
502 ExFreePool(DirectoryInfo
);
508 while (NT_SUCCESS(Status
))
510 Status
= NtQueryDirectoryObject (DirectoryHandle
,
518 if (NT_SUCCESS(Status
))
521 while (DirectoryInfo
[Count
].ObjectName
.Buffer
)
523 DPRINT("Count %x\n", Count
);
524 DirectoryInfo
[Count
].ObjectName
.Buffer
[DirectoryInfo
[Count
].ObjectName
.Length
/ sizeof(WCHAR
)] = 0;
525 ArcNameBuffer
= DirectoryInfo
[Count
].ObjectName
.Buffer
;
526 if (DirectoryInfo
[Count
].ObjectName
.Length
>= sizeof(L
"multi(0)disk(0)rdisk(0)") - sizeof(WCHAR
) &&
527 !_wcsnicmp(ArcNameBuffer
, L
"multi(0)disk(0)rdisk(", (sizeof(L
"multi(0)disk(0)rdisk(") - sizeof(WCHAR
)) / sizeof(WCHAR
)))
529 DPRINT("%S\n", ArcNameBuffer
);
530 ArcNameBuffer
+= (sizeof(L
"multi(0)disk(0)rdisk(") - sizeof(WCHAR
)) / sizeof(WCHAR
);
532 while (iswdigit(*ArcNameBuffer
))
534 CurrentRDisk
= CurrentRDisk
* 10 + *ArcNameBuffer
- L
'0';
537 if (!_wcsicmp(ArcNameBuffer
, L
")") &&
538 CurrentRDisk
>= RDiskCount
)
540 RDiskCount
= CurrentRDisk
+ 1;
547 ExFreePool(DirectoryInfo
);
552 xHalpGetDiskNumberFromRDisk(ULONG RDisk
, PULONG DiskNumber
)
554 WCHAR NameBuffer
[80];
555 UNICODE_STRING ArcName
;
556 UNICODE_STRING LinkName
;
557 OBJECT_ATTRIBUTES ObjectAttributes
;
562 L
"\\ArcName\\multi(0)disk(0)rdisk(%lu)",
565 RtlInitUnicodeString(&ArcName
, NameBuffer
);
566 InitializeObjectAttributes(&ObjectAttributes
,
571 Status
= ZwOpenSymbolicLinkObject(&LinkHandle
,
572 SYMBOLIC_LINK_ALL_ACCESS
,
574 if (!NT_SUCCESS(Status
))
576 DPRINT1("ZwOpenSymbolicLinkObject failed for %wZ, status=%lx\n", &ArcName
, Status
);
580 LinkName
.Buffer
= NameBuffer
;
582 LinkName
.MaximumLength
= sizeof(NameBuffer
);
583 Status
= ZwQuerySymbolicLinkObject(LinkHandle
,
587 if (!NT_SUCCESS(Status
))
589 DPRINT1("ZwQuerySymbolicLinkObject failed, status=%lx\n", Status
);
592 if (LinkName
.Length
< sizeof(L
"\\Device\\Harddisk0\\Partition0") - sizeof(WCHAR
) ||
593 LinkName
.Length
>= sizeof(NameBuffer
))
595 return STATUS_UNSUCCESSFUL
;
598 NameBuffer
[LinkName
.Length
/ sizeof(WCHAR
)] = 0;
599 if (_wcsnicmp(NameBuffer
, L
"\\Device\\Harddisk", (sizeof(L
"\\Device\\Harddisk") - sizeof(WCHAR
)) / sizeof(WCHAR
)))
601 return STATUS_UNSUCCESSFUL
;
603 LinkName
.Buffer
+= (sizeof(L
"\\Device\\Harddisk") - sizeof(WCHAR
)) / sizeof(WCHAR
);
605 if (!iswdigit(*LinkName
.Buffer
))
607 return STATUS_UNSUCCESSFUL
;
610 while (iswdigit(*LinkName
.Buffer
))
612 *DiskNumber
= *DiskNumber
* 10 + *LinkName
.Buffer
- L
'0';
615 if (_wcsicmp(LinkName
.Buffer
, L
"\\Partition0"))
617 return STATUS_UNSUCCESSFUL
;
619 return STATUS_SUCCESS
;
624 xHalIoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
625 IN PSTRING NtDeviceName
,
626 OUT PUCHAR NtSystemPath
,
627 OUT PSTRING NtSystemPathString
)
629 PDRIVE_LAYOUT_INFORMATION
*LayoutArray
;
630 PCONFIGURATION_INFORMATION ConfigInfo
;
631 OBJECT_ATTRIBUTES ObjectAttributes
;
632 IO_STATUS_BLOCK StatusBlock
;
633 UNICODE_STRING UnicodeString1
;
634 UNICODE_STRING UnicodeString2
;
644 PKEY_VALUE_PARTIAL_INFORMATION PartialInformation
;
645 PREG_DISK_MOUNT_INFO DiskMountInfo
;
648 DPRINT("xHalIoAssignDriveLetters()\n");
650 ConfigInfo
= IoGetConfigurationInformation();
652 RDiskCount
= xHalpGetRDiskCount();
654 DPRINT1("RDiskCount %d\n", RDiskCount
);
656 Buffer1
= (PWSTR
)ExAllocatePool(PagedPool
,
658 Buffer2
= (PWSTR
)ExAllocatePool(PagedPool
,
661 PartialInformation
= (PKEY_VALUE_PARTIAL_INFORMATION
)ExAllocatePool(PagedPool
,
662 sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(REG_DISK_MOUNT_INFO
));
664 DiskMountInfo
= (PREG_DISK_MOUNT_INFO
) PartialInformation
->Data
;
666 /* Open or Create the 'MountedDevices' key */
667 RtlInitUnicodeString(&UnicodeString1
, L
"\\Registry\\Machine\\SYSTEM\\MountedDevices");
668 InitializeObjectAttributes(&ObjectAttributes
,
670 OBJ_CASE_INSENSITIVE
,
673 Status
= ZwOpenKey(&hKey
,
676 if (!NT_SUCCESS(Status
))
678 Status
= ZwCreateKey(&hKey
,
683 REG_OPTION_NON_VOLATILE
,
686 if (!NT_SUCCESS(Status
))
689 DPRINT1("ZwCreateKey failed for %wZ, status=%x\n", &UnicodeString1
, Status
);
692 /* Create PhysicalDrive links */
693 DPRINT("Physical disk drives: %d\n", ConfigInfo
->DiskCount
);
694 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
697 L
"\\Device\\Harddisk%d\\Partition0",
699 RtlInitUnicodeString(&UnicodeString1
,
702 InitializeObjectAttributes(&ObjectAttributes
,
708 Status
= ZwOpenFile(&FileHandle
,
713 FILE_SYNCHRONOUS_IO_NONALERT
);
714 if (NT_SUCCESS(Status
))
719 L
"\\??\\PhysicalDrive%d",
721 RtlInitUnicodeString(&UnicodeString2
,
724 DPRINT("Creating link: %S ==> %S\n",
728 IoCreateSymbolicLink(&UnicodeString2
,
733 /* Initialize layout array */
734 LayoutArray
= ExAllocatePool(NonPagedPool
,
735 ConfigInfo
->DiskCount
* sizeof(PDRIVE_LAYOUT_INFORMATION
));
736 RtlZeroMemory(LayoutArray
,
737 ConfigInfo
->DiskCount
* sizeof(PDRIVE_LAYOUT_INFORMATION
));
738 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
741 L
"\\Device\\Harddisk%d\\Partition0",
743 RtlInitUnicodeString(&UnicodeString1
,
746 Status
= xHalQueryDriveLayout(&UnicodeString1
,
748 if (!NT_SUCCESS(Status
))
750 DbgPrint("xHalQueryDriveLayout() failed (Status = 0x%lx)\n",
752 LayoutArray
[i
] = NULL
;
755 /* We don't use the RewritePartition value while mounting the disks.
756 * We use this value for marking pre-assigned (registry) partitions.
758 for (j
= 0; j
< LayoutArray
[i
]->PartitionCount
; j
++)
760 LayoutArray
[i
]->PartitionEntry
[j
].RewritePartition
= FALSE
;
765 /* Dump layout array */
766 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
768 DPRINT("Harddisk %d:\n",
771 if (LayoutArray
[i
] == NULL
)
774 DPRINT("Logical partitions: %d\n",
775 LayoutArray
[i
]->PartitionCount
);
777 for (j
= 0; j
< LayoutArray
[i
]->PartitionCount
; j
++)
779 DPRINT(" %d: nr:%x boot:%x type:%x startblock:%I64u count:%I64u\n",
781 LayoutArray
[i
]->PartitionEntry
[j
].PartitionNumber
,
782 LayoutArray
[i
]->PartitionEntry
[j
].BootIndicator
,
783 LayoutArray
[i
]->PartitionEntry
[j
].PartitionType
,
784 LayoutArray
[i
]->PartitionEntry
[j
].StartingOffset
.QuadPart
,
785 LayoutArray
[i
]->PartitionEntry
[j
].PartitionLength
.QuadPart
);
790 /* Assign pre-assigned (registry) partitions */
793 for (k
= 2; k
< 26; k
++)
795 swprintf(Buffer1
, DiskMountString
, L
'A' + k
);
796 RtlInitUnicodeString(&UnicodeString1
, Buffer1
);
797 Status
= ZwQueryValueKey(hKey
,
799 KeyValuePartialInformation
,
801 sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(REG_DISK_MOUNT_INFO
),
803 if (NT_SUCCESS(Status
) &&
804 PartialInformation
->Type
== REG_BINARY
&&
805 PartialInformation
->DataLength
== sizeof(REG_DISK_MOUNT_INFO
))
807 DPRINT("%wZ => %08x:%08x%08x\n", &UnicodeString1
, DiskMountInfo
->Signature
,
808 DiskMountInfo
->StartingOffset
.u
.HighPart
, DiskMountInfo
->StartingOffset
.u
.LowPart
);
809 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
811 DPRINT("%x\n", LayoutArray
[i
]->Signature
);
812 if (LayoutArray
[i
] &&
813 LayoutArray
[i
]->Signature
== DiskMountInfo
->Signature
)
815 for (j
= 0; j
< LayoutArray
[i
]->PartitionCount
; j
++)
817 if (LayoutArray
[i
]->PartitionEntry
[j
].StartingOffset
.QuadPart
== DiskMountInfo
->StartingOffset
.QuadPart
)
819 if (IsRecognizedPartition(LayoutArray
[i
]->PartitionEntry
[j
].PartitionType
))
822 L
"\\Device\\Harddisk%d\\Partition%d",
824 LayoutArray
[i
]->PartitionEntry
[j
].PartitionNumber
);
825 RtlInitUnicodeString(&UnicodeString2
,
829 DPRINT(" %wZ\n", &UnicodeString2
);
830 HalpAssignDrive(&UnicodeString2
,
832 DOSDEVICE_DRIVE_FIXED
,
833 DiskMountInfo
->Signature
,
834 DiskMountInfo
->StartingOffset
,
836 /* Mark the partition as assigned */
837 LayoutArray
[i
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
849 /* Assign bootable partition on first harddisk */
850 DPRINT("Assigning bootable primary partition on first harddisk:\n");
853 Status
= xHalpGetDiskNumberFromRDisk(0, &DiskNumber
);
854 if (NT_SUCCESS(Status
) &&
855 DiskNumber
< ConfigInfo
->DiskCount
&&
856 LayoutArray
[DiskNumber
])
858 /* Search for bootable partition */
859 for (j
= 0; j
< PARTITION_TBL_SIZE
&& j
< LayoutArray
[DiskNumber
]->PartitionCount
; j
++)
861 if ((LayoutArray
[DiskNumber
]->PartitionEntry
[j
].BootIndicator
== TRUE
) &&
862 IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
))
864 if (LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
)
867 L
"\\Device\\Harddisk%lu\\Partition%d",
869 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
870 RtlInitUnicodeString(&UnicodeString2
,
874 DPRINT1(" %wZ\n", &UnicodeString2
);
875 HalpAssignDrive(&UnicodeString2
,
877 DOSDEVICE_DRIVE_FIXED
,
878 LayoutArray
[DiskNumber
]->Signature
,
879 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
881 /* Mark the partition as assigned */
882 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
890 /* Assign remaining primary partitions */
891 DPRINT("Assigning remaining primary partitions:\n");
892 for (RDisk
= 0; RDisk
< RDiskCount
; RDisk
++)
894 Status
= xHalpGetDiskNumberFromRDisk(RDisk
, &DiskNumber
);
895 if (NT_SUCCESS(Status
) &&
896 DiskNumber
< ConfigInfo
->DiskCount
&&
897 LayoutArray
[DiskNumber
])
899 /* Search for primary partitions */
900 for (j
= 0; (j
< PARTITION_TBL_SIZE
) && (j
< LayoutArray
[DiskNumber
]->PartitionCount
); j
++)
902 if (LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
&&
903 IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
))
906 L
"\\Device\\Harddisk%d\\Partition%d",
908 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
909 RtlInitUnicodeString(&UnicodeString2
,
915 HalpAssignDrive(&UnicodeString2
,
917 DOSDEVICE_DRIVE_FIXED
,
918 LayoutArray
[DiskNumber
]->Signature
,
919 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
921 /* Mark the partition as assigned */
922 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
928 /* Assign extended (logical) partitions */
929 DPRINT("Assigning extended (logical) partitions:\n");
930 for (RDisk
= 0; RDisk
< RDiskCount
; RDisk
++)
932 Status
= xHalpGetDiskNumberFromRDisk(RDisk
, &DiskNumber
);
933 if (NT_SUCCESS(Status
) &&
934 DiskNumber
< ConfigInfo
->DiskCount
&&
935 LayoutArray
[DiskNumber
])
937 /* Search for extended partitions */
938 for (j
= PARTITION_TBL_SIZE
; j
< LayoutArray
[DiskNumber
]->PartitionCount
; j
++)
940 if (IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
) &&
941 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
&&
942 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
!= 0)
945 L
"\\Device\\Harddisk%d\\Partition%d",
947 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
948 RtlInitUnicodeString(&UnicodeString2
,
954 HalpAssignDrive(&UnicodeString2
,
956 DOSDEVICE_DRIVE_FIXED
,
957 LayoutArray
[DiskNumber
]->Signature
,
958 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
960 /* Mark the partition as assigned */
961 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
967 /* Assign remaining primary partitions without an arc-name */
968 DPRINT("Assigning remaining primary partitions:\n");
969 for (DiskNumber
= 0; DiskNumber
< ConfigInfo
->DiskCount
; DiskNumber
++)
971 if (LayoutArray
[DiskNumber
])
973 /* Search for primary partitions */
974 for (j
= 0; (j
< PARTITION_TBL_SIZE
) && (j
< LayoutArray
[DiskNumber
]->PartitionCount
); j
++)
976 if (LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
&&
977 IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
))
980 L
"\\Device\\Harddisk%d\\Partition%d",
982 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
983 RtlInitUnicodeString(&UnicodeString2
,
989 HalpAssignDrive(&UnicodeString2
,
991 DOSDEVICE_DRIVE_FIXED
,
992 LayoutArray
[DiskNumber
]->Signature
,
993 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
995 /* Mark the partition as assigned */
996 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
1002 /* Assign extended (logical) partitions without an arc-name */
1003 DPRINT("Assigning extended (logical) partitions:\n");
1004 for (DiskNumber
= 0; DiskNumber
< ConfigInfo
->DiskCount
; DiskNumber
++)
1006 if (LayoutArray
[DiskNumber
])
1008 /* Search for extended partitions */
1009 for (j
= PARTITION_TBL_SIZE
; j
< LayoutArray
[DiskNumber
]->PartitionCount
; j
++)
1011 if (IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
) &&
1012 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
&&
1013 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
!= 0)
1016 L
"\\Device\\Harddisk%d\\Partition%d",
1018 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
1019 RtlInitUnicodeString(&UnicodeString2
,
1025 HalpAssignDrive(&UnicodeString2
,
1027 DOSDEVICE_DRIVE_FIXED
,
1028 LayoutArray
[DiskNumber
]->Signature
,
1029 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
1031 /* Mark the partition as assigned */
1032 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
1038 /* Assign removable disk drives */
1039 DPRINT("Assigning removable disk drives:\n");
1040 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
1044 /* Search for virtual partitions */
1045 if (LayoutArray
[i
]->PartitionCount
== 1 &&
1046 LayoutArray
[i
]->PartitionEntry
[0].PartitionType
== 0)
1049 L
"\\Device\\Harddisk%d\\Partition1",
1051 RtlInitUnicodeString(&UnicodeString2
,
1057 HalpAssignDrive(&UnicodeString2
,
1059 DOSDEVICE_DRIVE_REMOVABLE
,
1067 /* Free layout array */
1068 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
1070 if (LayoutArray
[i
] != NULL
)
1071 ExFreePool(LayoutArray
[i
]);
1073 ExFreePool(LayoutArray
);
1075 /* Assign floppy drives */
1076 DPRINT("Floppy drives: %d\n", ConfigInfo
->FloppyCount
);
1077 for (i
= 0; i
< ConfigInfo
->FloppyCount
; i
++)
1080 L
"\\Device\\Floppy%d",
1082 RtlInitUnicodeString(&UnicodeString1
,
1085 /* Assign drive letters A: or B: or first free drive letter */
1088 HalpAssignDrive(&UnicodeString1
,
1089 (i
< 2) ? i
: AUTO_DRIVE
,
1090 DOSDEVICE_DRIVE_REMOVABLE
,
1096 /* Assign cdrom drives */
1097 DPRINT("CD-Rom drives: %d\n", ConfigInfo
->CdRomCount
);
1098 for (i
= 0; i
< ConfigInfo
->CdRomCount
; i
++)
1101 L
"\\Device\\CdRom%d",
1103 RtlInitUnicodeString(&UnicodeString1
,
1106 /* Assign first free drive letter */
1107 DPRINT(" %wZ\n", &UnicodeString1
);
1108 HalpAssignDrive(&UnicodeString1
,
1110 DOSDEVICE_DRIVE_CDROM
,
1116 /* Anything else to do? */
1118 ExFreePool(PartialInformation
);
1119 ExFreePool(Buffer2
);
1120 ExFreePool(Buffer1
);
1129 xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject
,
1131 BOOLEAN ReturnRecognizedPartitions
,
1132 PDRIVE_LAYOUT_INFORMATION
*PartitionBuffer
)
1134 LARGE_INTEGER RealPartitionOffset
;
1135 ULONGLONG PartitionOffset
;
1136 #if defined(__GNUC__)
1137 ULONGLONG nextPartitionOffset
= 0LL;
1139 ULONGLONG nextPartitionOffset
= 0;
1141 ULONGLONG containerOffset
;
1143 PPARTITION_SECTOR PartitionSector
;
1144 PDRIVE_LAYOUT_INFORMATION LayoutBuffer
;
1148 BOOLEAN ExtendedFound
= FALSE
;
1150 DISK_MANAGER DiskManager
= NoDiskManager
;
1152 DPRINT("xHalIoReadPartitionTable(%p %lu %x %p)\n",
1155 ReturnRecognizedPartitions
,
1158 *PartitionBuffer
= NULL
;
1160 /* Check sector size */
1161 if (SectorSize
< 512)
1163 if (SectorSize
> 4096)
1166 /* Check for 'Ontrack Disk Manager' */
1167 HalExamineMBR(DeviceObject
,
1171 if (MbrBuffer
!= NULL
)
1173 DPRINT("Found 'Ontrack Disk Manager'\n");
1174 DiskManager
= OntrackDiskManager
;
1175 ExFreePool(MbrBuffer
);
1178 /* Check for 'EZ-Drive' */
1179 HalExamineMBR(DeviceObject
,
1183 if (MbrBuffer
!= NULL
)
1185 DPRINT("Found 'EZ-Drive'\n");
1186 DiskManager
= EZ_Drive
;
1187 ExFreePool(MbrBuffer
);
1190 PartitionSector
= (PPARTITION_SECTOR
)ExAllocatePool(PagedPool
,
1192 if (PartitionSector
== NULL
)
1194 return(STATUS_INSUFFICIENT_RESOURCES
);
1197 LayoutBuffer
= (PDRIVE_LAYOUT_INFORMATION
)ExAllocatePool(NonPagedPool
,
1199 if (LayoutBuffer
== NULL
)
1201 ExFreePool(PartitionSector
);
1202 return(STATUS_INSUFFICIENT_RESOURCES
);
1205 RtlZeroMemory(LayoutBuffer
,
1208 #if defined(__GNUC__)
1209 PartitionOffset
= 0ULL;
1210 containerOffset
= 0ULL;
1212 PartitionOffset
= 0;
1213 containerOffset
= 0;
1218 DPRINT("PartitionOffset: %I64u\n", PartitionOffset
/ SectorSize
);
1220 /* Handle disk managers */
1221 if (DiskManager
== OntrackDiskManager
)
1223 /* Shift offset by 63 sectors */
1224 RealPartitionOffset
.QuadPart
= PartitionOffset
+ (ULONGLONG
)(63 * SectorSize
);
1226 #if defined(__GNUC__)
1227 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0ULL)
1229 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0)
1232 /* Use sector 1 instead of sector 0 */
1233 RealPartitionOffset
.QuadPart
= (ULONGLONG
)SectorSize
;
1237 RealPartitionOffset
.QuadPart
= PartitionOffset
;
1240 DPRINT ("RealPartitionOffset: %I64u\n",
1241 RealPartitionOffset
.QuadPart
/ SectorSize
);
1243 Status
= xHalpReadSector (DeviceObject
,
1245 &RealPartitionOffset
,
1247 if (!NT_SUCCESS(Status
))
1249 DPRINT ("Failed to read partition table sector (Status = 0x%08lx)\n",
1251 ExFreePool (PartitionSector
);
1252 ExFreePool (LayoutBuffer
);
1256 /* Check the boot sector id */
1257 DPRINT("Magic %x\n", PartitionSector
->Magic
);
1258 if (PartitionSector
->Magic
!= PARTITION_MAGIC
)
1260 DPRINT ("Invalid partition sector magic\n");
1261 ExFreePool (PartitionSector
);
1262 *PartitionBuffer
= LayoutBuffer
;
1263 return STATUS_SUCCESS
;
1267 for (i
= 0; i
< PARTITION_TBL_SIZE
; i
++)
1269 DPRINT1(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",
1271 PartitionSector
->Partition
[i
].BootFlags
,
1272 PartitionSector
->Partition
[i
].PartitionType
,
1273 PartitionSector
->Partition
[i
].StartingHead
,
1274 PartitionSector
->Partition
[i
].StartingSector
& 0x3f,
1275 (((PartitionSector
->Partition
[i
].StartingSector
) & 0xc0) << 2) +
1276 PartitionSector
->Partition
[i
].StartingCylinder
,
1277 PartitionSector
->Partition
[i
].EndingHead
,
1278 PartitionSector
->Partition
[i
].EndingSector
& 0x3f,
1279 (((PartitionSector
->Partition
[i
].EndingSector
) & 0xc0) << 2) +
1280 PartitionSector
->Partition
[i
].EndingCylinder
,
1281 PartitionSector
->Partition
[i
].StartingBlock
,
1282 PartitionSector
->Partition
[i
].SectorCount
);
1286 #if defined(__GNUC__)
1287 if (PartitionOffset
== 0ULL)
1289 if (PartitionOffset
== 0)
1292 LayoutBuffer
->Signature
= PartitionSector
->Signature
;
1293 DPRINT("Disk signature: %lx\n", LayoutBuffer
->Signature
);
1296 ExtendedFound
= FALSE
;
1298 for (i
= 0; i
< PARTITION_TBL_SIZE
; i
++)
1300 if (IsContainerPartition(PartitionSector
->Partition
[i
].PartitionType
))
1302 ExtendedFound
= TRUE
;
1303 if ((ULONGLONG
) containerOffset
== (ULONGLONG
) 0)
1305 containerOffset
= PartitionOffset
;
1307 nextPartitionOffset
= (ULONGLONG
) containerOffset
+
1308 (ULONGLONG
) PartitionSector
->Partition
[i
].StartingBlock
*
1309 (ULONGLONG
) SectorSize
;
1312 if ((ReturnRecognizedPartitions
== FALSE
) ||
1313 ((ReturnRecognizedPartitions
== TRUE
) &&
1314 !IsContainerPartition(PartitionSector
->Partition
[i
].PartitionType
) &&
1315 PartitionSector
->Partition
[i
].PartitionType
!= PARTITION_ENTRY_UNUSED
))
1317 /* handle normal partition */
1318 DPRINT("Partition %u: Normal Partition\n", i
);
1319 Count
= LayoutBuffer
->PartitionCount
;
1320 DPRINT("Logical Partition %u\n", Count
);
1322 if (PartitionSector
->Partition
[i
].StartingBlock
== 0)
1324 LayoutBuffer
->PartitionEntry
[Count
].StartingOffset
.QuadPart
= 0;
1326 else if (IsContainerPartition(PartitionSector
->Partition
[i
].PartitionType
))
1328 LayoutBuffer
->PartitionEntry
[Count
].StartingOffset
.QuadPart
=
1329 (ULONGLONG
) containerOffset
+
1330 (ULONGLONG
) PartitionSector
->Partition
[i
].StartingBlock
*
1331 (ULONGLONG
) SectorSize
;
1335 LayoutBuffer
->PartitionEntry
[Count
].StartingOffset
.QuadPart
=
1336 (ULONGLONG
)PartitionOffset
+
1337 ((ULONGLONG
)PartitionSector
->Partition
[i
].StartingBlock
* (ULONGLONG
)SectorSize
);
1339 LayoutBuffer
->PartitionEntry
[Count
].PartitionLength
.QuadPart
=
1340 (ULONGLONG
)PartitionSector
->Partition
[i
].SectorCount
* (ULONGLONG
)SectorSize
;
1341 LayoutBuffer
->PartitionEntry
[Count
].HiddenSectors
=
1342 PartitionSector
->Partition
[i
].StartingBlock
;
1344 if (!IsContainerPartition(PartitionSector
->Partition
[i
].PartitionType
) &&
1345 PartitionSector
->Partition
[i
].PartitionType
!= PARTITION_ENTRY_UNUSED
)
1347 LayoutBuffer
->PartitionEntry
[Count
].RecognizedPartition
= TRUE
;
1348 /* WinXP returns garbage as PartitionNumber */
1349 LayoutBuffer
->PartitionEntry
[Count
].PartitionNumber
= Number
;
1354 LayoutBuffer
->PartitionEntry
[Count
].RecognizedPartition
= FALSE
;
1355 LayoutBuffer
->PartitionEntry
[Count
].PartitionNumber
= 0;
1358 LayoutBuffer
->PartitionEntry
[Count
].PartitionType
=
1359 PartitionSector
->Partition
[i
].PartitionType
;
1360 LayoutBuffer
->PartitionEntry
[Count
].BootIndicator
=
1361 (PartitionSector
->Partition
[i
].BootFlags
& 0x80)?TRUE
:FALSE
;
1362 LayoutBuffer
->PartitionEntry
[Count
].RewritePartition
= FALSE
;
1364 DPRINT(" %ld: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x rec: %d\n",
1366 LayoutBuffer
->PartitionEntry
[Count
].PartitionNumber
,
1367 LayoutBuffer
->PartitionEntry
[Count
].BootIndicator
,
1368 LayoutBuffer
->PartitionEntry
[Count
].PartitionType
,
1369 LayoutBuffer
->PartitionEntry
[Count
].StartingOffset
.QuadPart
,
1370 LayoutBuffer
->PartitionEntry
[Count
].PartitionLength
.QuadPart
,
1371 LayoutBuffer
->PartitionEntry
[Count
].RecognizedPartition
);
1373 LayoutBuffer
->PartitionCount
++;
1377 PartitionOffset
= nextPartitionOffset
;
1379 while (ExtendedFound
== TRUE
);
1381 *PartitionBuffer
= LayoutBuffer
;
1382 ExFreePool(PartitionSector
);
1384 return(STATUS_SUCCESS
);
1389 xHalIoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject
,
1390 IN ULONG SectorSize
,
1391 IN ULONG PartitionNumber
,
1392 IN ULONG PartitionType
)
1394 PPARTITION_SECTOR PartitionSector
;
1395 LARGE_INTEGER RealPartitionOffset
;
1396 ULONGLONG PartitionOffset
;
1397 #if defined(__GNUC__)
1398 ULONGLONG nextPartitionOffset
= 0LL;
1400 ULONGLONG nextPartitionOffset
= 0;
1402 ULONGLONG containerOffset
;
1406 BOOLEAN ExtendedFound
= FALSE
;
1407 DISK_MANAGER DiskManager
= NoDiskManager
;
1409 DPRINT ("xHalIoSetPartitionInformation(%p %lu %lu %lu)\n",
1415 /* Check sector size */
1416 if (SectorSize
< 512)
1418 if (SectorSize
> 4096)
1421 /* Check for 'Ontrack Disk Manager' */
1422 HalExamineMBR (DeviceObject
,
1425 (PVOID
*)(PVOID
)&PartitionSector
);
1426 if (PartitionSector
!= NULL
)
1428 DPRINT ("Found 'Ontrack Disk Manager'\n");
1429 DiskManager
= OntrackDiskManager
;
1430 ExFreePool (PartitionSector
);
1433 /* Check for 'EZ-Drive' */
1434 HalExamineMBR (DeviceObject
,
1437 (PVOID
*)(PVOID
)&PartitionSector
);
1438 if (PartitionSector
!= NULL
)
1440 DPRINT ("Found 'EZ-Drive'\n");
1441 DiskManager
= EZ_Drive
;
1442 ExFreePool (PartitionSector
);
1445 /* Allocate partition sector */
1446 PartitionSector
= (PPARTITION_SECTOR
) ExAllocatePool (PagedPool
,
1448 if (PartitionSector
== NULL
)
1450 return STATUS_INSUFFICIENT_RESOURCES
;
1453 #if defined(__GNUC__)
1454 PartitionOffset
= 0ULL;
1455 containerOffset
= 0ULL;
1457 PartitionOffset
= 0;
1458 containerOffset
= 0;
1463 DPRINT ("PartitionOffset: %I64u\n", PartitionOffset
/ SectorSize
);
1465 /* Handle disk managers */
1466 if (DiskManager
== OntrackDiskManager
)
1468 /* Shift offset by 63 sectors */
1469 RealPartitionOffset
.QuadPart
= PartitionOffset
+ (ULONGLONG
)(63 * SectorSize
);
1471 #if defined(__GNUC__)
1472 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0ULL)
1474 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0)
1477 /* Use sector 1 instead of sector 0 */
1478 RealPartitionOffset
.QuadPart
= (ULONGLONG
)SectorSize
;
1482 RealPartitionOffset
.QuadPart
= PartitionOffset
;
1485 DPRINT ("RealPartitionOffset: %I64u\n",
1486 RealPartitionOffset
.QuadPart
/ SectorSize
);
1488 Status
= xHalpReadSector (DeviceObject
,
1490 &RealPartitionOffset
,
1492 if (!NT_SUCCESS (Status
))
1494 DPRINT ("Failed to read partition table sector (Status = 0x%08lx)\n",
1496 ExFreePool (PartitionSector
);
1500 /* Check the boot sector id */
1501 DPRINT("Magic %x\n", PartitionSector
->Magic
);
1502 if (PartitionSector
->Magic
!= PARTITION_MAGIC
)
1504 DPRINT ("Invalid partition sector magic\n");
1505 ExFreePool (PartitionSector
);
1506 return STATUS_UNSUCCESSFUL
;
1510 for (i
= 0; i
< PARTITION_TBL_SIZE
; i
++)
1512 DPRINT1(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",
1514 PartitionSector
->Partition
[i
].BootFlags
,
1515 PartitionSector
->Partition
[i
].PartitionType
,
1516 PartitionSector
->Partition
[i
].StartingHead
,
1517 PartitionSector
->Partition
[i
].StartingSector
& 0x3f,
1518 (((PartitionSector
->Partition
[i
].StartingSector
) & 0xc0) << 2) +
1519 PartitionSector
->Partition
[i
].StartingCylinder
,
1520 PartitionSector
->Partition
[i
].EndingHead
,
1521 PartitionSector
->Partition
[i
].EndingSector
& 0x3f,
1522 (((PartitionSector
->Partition
[i
].EndingSector
) & 0xc0) << 2) +
1523 PartitionSector
->Partition
[i
].EndingCylinder
,
1524 PartitionSector
->Partition
[i
].StartingBlock
,
1525 PartitionSector
->Partition
[i
].SectorCount
);
1529 ExtendedFound
= FALSE
;
1530 for (i
= 0; i
< PARTITION_TBL_SIZE
; i
++)
1532 if (IsContainerPartition (PartitionSector
->Partition
[i
].PartitionType
))
1534 ExtendedFound
= TRUE
;
1535 #if defined(__GNUC__)
1536 if (containerOffset
== 0ULL)
1538 if (containerOffset
== 0)
1541 containerOffset
= PartitionOffset
;
1543 nextPartitionOffset
= containerOffset
+
1544 (ULONGLONG
) PartitionSector
->Partition
[i
].StartingBlock
*
1545 (ULONGLONG
) SectorSize
;
1548 /* Handle recognized partition */
1549 if (IsRecognizedPartition (PartitionSector
->Partition
[i
].PartitionType
))
1551 if (Number
== PartitionNumber
)
1553 /* Set partition type */
1554 PartitionSector
->Partition
[i
].PartitionType
= PartitionType
;
1556 /* Write partition sector */
1557 Status
= xHalpWriteSector (DeviceObject
,
1559 &RealPartitionOffset
,
1561 if (!NT_SUCCESS(Status
))
1563 DPRINT1("xHalpWriteSector() failed (Status %lx)\n", Status
);
1566 ExFreePool (PartitionSector
);
1573 PartitionOffset
= nextPartitionOffset
;
1575 while (ExtendedFound
== TRUE
);
1577 ExFreePool(PartitionSector
);
1579 return STATUS_UNSUCCESSFUL
;
1584 xHalIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject
,
1585 IN ULONG SectorSize
,
1586 IN ULONG SectorsPerTrack
,
1587 IN ULONG NumberOfHeads
,
1588 IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer
)
1590 PPARTITION_SECTOR PartitionSector
;
1591 LARGE_INTEGER RealPartitionOffset
;
1592 ULONGLONG PartitionOffset
;
1593 #if defined(__GNUC__)
1594 ULONGLONG NextPartitionOffset
= 0LL;
1596 ULONGLONG NextPartitionOffset
= 0;
1598 ULONGLONG ContainerOffset
;
1599 BOOLEAN ContainerEntry
;
1600 DISK_MANAGER DiskManager
;
1605 ULONG StartCylinder
;
1615 DPRINT ("xHalIoWritePartitionTable(%p %lu %lu %lu %p)\n",
1622 ASSERT(DeviceObject
);
1623 ASSERT(PartitionBuffer
);
1625 DiskManager
= NoDiskManager
;
1627 /* Check sector size */
1628 if (SectorSize
< 512)
1630 if (SectorSize
> 4096)
1633 /* Check for 'Ontrack Disk Manager' */
1634 HalExamineMBR (DeviceObject
,
1637 (PVOID
*)(PVOID
)&PartitionSector
);
1638 if (PartitionSector
!= NULL
)
1640 DPRINT ("Found 'Ontrack Disk Manager'\n");
1641 DiskManager
= OntrackDiskManager
;
1642 ExFreePool (PartitionSector
);
1645 /* Check for 'EZ-Drive' */
1646 HalExamineMBR (DeviceObject
,
1649 (PVOID
*)(PVOID
)&PartitionSector
);
1650 if (PartitionSector
!= NULL
)
1652 DPRINT ("Found 'EZ-Drive'\n");
1653 DiskManager
= EZ_Drive
;
1654 ExFreePool (PartitionSector
);
1657 /* Allocate partition sector */
1658 PartitionSector
= (PPARTITION_SECTOR
)ExAllocatePool(PagedPool
,
1660 if (PartitionSector
== NULL
)
1662 return STATUS_INSUFFICIENT_RESOURCES
;
1665 Status
= STATUS_SUCCESS
;
1666 #if defined(__GNUC__)
1667 PartitionOffset
= 0ULL;
1668 ContainerOffset
= 0ULL;
1670 PartitionOffset
= 0;
1671 ContainerOffset
= 0;
1673 for (i
= 0; i
< PartitionBuffer
->PartitionCount
; i
+= 4)
1675 DPRINT ("PartitionOffset: %I64u\n", PartitionOffset
);
1676 DPRINT ("ContainerOffset: %I64u\n", ContainerOffset
);
1678 /* Handle disk managers */
1679 if (DiskManager
== OntrackDiskManager
)
1681 /* Shift offset by 63 sectors */
1682 RealPartitionOffset
.QuadPart
= PartitionOffset
+ (ULONGLONG
)(63 * SectorSize
);
1684 #if defined(__GNUC__)
1685 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0ULL)
1687 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0)
1690 /* Use sector 1 instead of sector 0 */
1691 RealPartitionOffset
.QuadPart
= (ULONGLONG
)SectorSize
;
1695 RealPartitionOffset
.QuadPart
= PartitionOffset
;
1698 /* Write modified partition tables */
1699 if (PartitionBuffer
->PartitionEntry
[i
].RewritePartition
== TRUE
||
1700 PartitionBuffer
->PartitionEntry
[i
+ 1].RewritePartition
== TRUE
||
1701 PartitionBuffer
->PartitionEntry
[i
+ 2].RewritePartition
== TRUE
||
1702 PartitionBuffer
->PartitionEntry
[i
+ 3].RewritePartition
== TRUE
)
1704 /* Read partition sector */
1705 Status
= xHalpReadSector (DeviceObject
,
1707 &RealPartitionOffset
,
1709 if (!NT_SUCCESS(Status
))
1711 DPRINT1 ("xHalpReadSector() failed (Status %lx)\n", Status
);
1715 /* Initialize a new partition sector */
1716 if (PartitionSector
->Magic
!= PARTITION_MAGIC
)
1718 /* Create empty partition sector */
1719 RtlZeroMemory (PartitionSector
,
1721 PartitionSector
->Magic
= PARTITION_MAGIC
;
1724 PartitionSector
->Signature
= PartitionBuffer
->Signature
;
1725 /* Update partition sector entries */
1726 for (j
= 0; j
< 4; j
++)
1728 if (PartitionBuffer
->PartitionEntry
[i
+ j
].RewritePartition
== TRUE
)
1730 /* Set partition boot flag */
1731 if (PartitionBuffer
->PartitionEntry
[i
+ j
].BootIndicator
)
1733 PartitionSector
->Partition
[j
].BootFlags
|= 0x80;
1737 PartitionSector
->Partition
[j
].BootFlags
&= ~0x80;
1740 /* Set partition type */
1741 PartitionSector
->Partition
[j
].PartitionType
=
1742 PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionType
;
1744 /* Set partition data */
1745 #if defined(__GNUC__)
1746 if (PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
== 0ULL &&
1747 PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionLength
.QuadPart
== 0ULL)
1749 if (PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
== 0 &&
1750 PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionLength
.QuadPart
== 0)
1753 PartitionSector
->Partition
[j
].StartingBlock
= 0;
1754 PartitionSector
->Partition
[j
].SectorCount
= 0;
1755 PartitionSector
->Partition
[j
].StartingCylinder
= 0;
1756 PartitionSector
->Partition
[j
].StartingHead
= 0;
1757 PartitionSector
->Partition
[j
].StartingSector
= 0;
1758 PartitionSector
->Partition
[j
].EndingCylinder
= 0;
1759 PartitionSector
->Partition
[j
].EndingHead
= 0;
1760 PartitionSector
->Partition
[j
].EndingSector
= 0;
1766 * x = LBA DIV SectorsPerTrack
1767 * cylinder = (x DIV NumberOfHeads) % 1024
1768 * head = x MOD NumberOfHeads
1769 * sector = (LBA MOD SectorsPerTrack) + 1
1772 /* Compute starting CHS values */
1773 lba
= (ULONG
)((PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
) / SectorSize
);
1774 x
= lba
/ SectorsPerTrack
;
1775 StartCylinder
= (x
/ NumberOfHeads
) %1024;
1776 StartHead
= x
% NumberOfHeads
;
1777 StartSector
= (lba
% SectorsPerTrack
) + 1;
1778 DPRINT ("StartingOffset (LBA:%d C:%d H:%d S:%d)\n",
1779 lba
, StartCylinder
, StartHead
, StartSector
);
1781 /* Compute ending CHS values */
1782 lba
= (ULONG
)((PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
+
1783 (PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionLength
.QuadPart
- 1)) / SectorSize
);
1784 x
= lba
/ SectorsPerTrack
;
1785 EndCylinder
= (x
/ NumberOfHeads
) % 1024;
1786 EndHead
= x
% NumberOfHeads
;
1787 EndSector
= (lba
% SectorsPerTrack
) + 1;
1788 DPRINT ("EndingOffset (LBA:%d C:%d H:%d S:%d)\n",
1789 lba
, EndCylinder
, EndHead
, EndSector
);
1791 /* Set starting CHS values */
1792 PartitionSector
->Partition
[j
].StartingCylinder
= StartCylinder
& 0xff;
1793 PartitionSector
->Partition
[j
].StartingHead
= StartHead
;
1794 PartitionSector
->Partition
[j
].StartingSector
=
1795 ((StartCylinder
& 0x0300) >> 2) + (StartSector
& 0x3f);
1797 /* Set ending CHS values */
1798 PartitionSector
->Partition
[j
].EndingCylinder
= EndCylinder
& 0xff;
1799 PartitionSector
->Partition
[j
].EndingHead
= EndHead
;
1800 PartitionSector
->Partition
[j
].EndingSector
=
1801 ((EndCylinder
& 0x0300) >> 2) + (EndSector
& 0x3f);
1803 /* Calculate start sector and sector count */
1804 if (IsContainerPartition (PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionType
))
1807 (PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
- ContainerOffset
) / SectorSize
;
1812 (PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
- NextPartitionOffset
) / SectorSize
;
1815 PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionLength
.QuadPart
/ SectorSize
;
1816 DPRINT ("LBA (StartBlock:%lu SectorCount:%lu)\n",
1817 StartBlock
, SectorCount
);
1819 /* Set start sector and sector count */
1820 PartitionSector
->Partition
[j
].StartingBlock
= StartBlock
;
1821 PartitionSector
->Partition
[j
].SectorCount
= SectorCount
;
1826 /* Write partition sector */
1827 Status
= xHalpWriteSector (DeviceObject
,
1829 &RealPartitionOffset
,
1831 if (!NT_SUCCESS(Status
))
1833 DPRINT1("xHalpWriteSector() failed (Status %lx)\n", Status
);
1838 ContainerEntry
= FALSE
;
1839 for (j
= 0; j
< 4; j
++)
1841 if (IsContainerPartition (PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionType
))
1843 ContainerEntry
= TRUE
;
1844 NextPartitionOffset
=
1845 PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
;
1847 #if defined(__GNUC__)
1848 if (ContainerOffset
== 0ULL)
1850 if (ContainerOffset
== 0)
1853 ContainerOffset
= NextPartitionOffset
;
1858 if (ContainerEntry
== FALSE
)
1860 DPRINT ("No container entry in partition sector!\n");
1864 PartitionOffset
= NextPartitionOffset
;
1867 ExFreePool (PartitionSector
);
1877 IoAssignDriveLetters(
1878 IN PLOADER_PARAMETER_BLOCK LoaderBlock,
1879 IN PSTRING NtDeviceName,
1880 OUT PUCHAR NtSystemPath,
1881 OUT PSTRING NtSystemPathString
1893 IN PDEVICE_OBJECT DeviceObject
,
1894 IN
struct _CREATE_DISK
* Disk
1898 return STATUS_NOT_IMPLEMENTED
;
1906 IoGetBootDiskInformation(
1907 IN OUT PBOOTDISK_INFORMATION BootDiskInformation
,
1912 return STATUS_NOT_IMPLEMENTED
;
1921 IoReadDiskSignature(
1922 IN PDEVICE_OBJECT DeviceObject
,
1923 IN ULONG BytesPerSector
,
1924 OUT PDISK_SIGNATURE Signature
1928 return STATUS_NOT_IMPLEMENTED
;
1936 IoReadPartitionTableEx(
1937 IN PDEVICE_OBJECT DeviceObject
,
1938 IN
struct _DRIVE_LAYOUT_INFORMATION_EX
** DriveLayout
1942 return STATUS_NOT_IMPLEMENTED
;
1950 IoSetPartitionInformationEx(
1951 IN PDEVICE_OBJECT DeviceObject
,
1952 IN ULONG PartitionNumber
,
1953 IN
struct _SET_PARTITION_INFORMATION_EX
* PartitionInfo
1957 return STATUS_NOT_IMPLEMENTED
;
1965 IoSetSystemPartition(
1966 PUNICODE_STRING VolumeNameString
1970 return STATUS_NOT_IMPLEMENTED
;
1978 IoVerifyPartitionTable(
1979 IN PDEVICE_OBJECT DeviceObject
,
1980 IN BOOLEAN FixErrors
1984 return STATUS_NOT_IMPLEMENTED
;
1992 IoVolumeDeviceToDosName(
1993 IN PVOID VolumeDeviceObject
,
1994 OUT PUNICODE_STRING DosName
1998 return STATUS_NOT_IMPLEMENTED
;
2006 IoWritePartitionTableEx(
2007 IN PDEVICE_OBJECT DeviceObject
,
2008 IN
struct _DRIVE_LAYOUT_INFORMATION_EX
* DriveLayfout
2012 return STATUS_NOT_IMPLEMENTED
;
2019 IoReadPartitionTable(PDEVICE_OBJECT DeviceObject
,
2021 BOOLEAN ReturnRecognizedPartitions
,
2022 PDRIVE_LAYOUT_INFORMATION
*PartitionBuffer
)
2024 return(HalIoReadPartitionTable(DeviceObject
,
2026 ReturnRecognizedPartitions
,
2032 IoSetPartitionInformation(PDEVICE_OBJECT DeviceObject
,
2034 ULONG PartitionNumber
,
2035 ULONG PartitionType
)
2037 return(HalIoSetPartitionInformation(DeviceObject
,
2045 IoWritePartitionTable(PDEVICE_OBJECT DeviceObject
,
2047 ULONG SectorsPerTrack
,
2048 ULONG NumberOfHeads
,
2049 PDRIVE_LAYOUT_INFORMATION PartitionBuffer
)
2051 return(HalIoWritePartitionTable(DeviceObject
,