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
,
448 DriveType
== DOSDEVICE_DRIVE_FIXED
&&
451 DiskMountInfo
.Signature
= Signature
;
452 DiskMountInfo
.StartingOffset
= StartingOffset
;
453 swprintf(DriveNameBuffer
, DiskMountString
, L
'A' + DriveNumber
);
454 RtlInitUnicodeString(&DriveName
, DriveNameBuffer
);
456 Status
= ZwSetValueKey(hKey
,
461 sizeof(DiskMountInfo
));
462 if (!NT_SUCCESS(Status
))
464 DPRINT1("ZwCreateValueKey failed for %wZ, status=%x\n", &DriveName
, Status
);
471 xHalpGetRDiskCount(VOID
)
474 UNICODE_STRING ArcName
;
475 PWCHAR ArcNameBuffer
;
476 OBJECT_ATTRIBUTES ObjectAttributes
;
477 HANDLE DirectoryHandle
;
478 POBJECT_DIRECTORY_INFORMATION DirectoryInfo
;
483 BOOLEAN First
= TRUE
;
486 DirectoryInfo
= ExAllocatePool(PagedPool
, 2 * PAGE_SIZE
);
487 if (DirectoryInfo
== NULL
)
492 RtlInitUnicodeString(&ArcName
, L
"\\ArcName");
493 InitializeObjectAttributes(&ObjectAttributes
,
499 Status
= ZwOpenDirectoryObject (&DirectoryHandle
,
500 SYMBOLIC_LINK_ALL_ACCESS
,
502 if (!NT_SUCCESS(Status
))
504 DPRINT1("ZwOpenDirectoryObject for %wZ failed, status=%lx\n", &ArcName
, Status
);
505 ExFreePool(DirectoryInfo
);
511 while (NT_SUCCESS(Status
))
513 Status
= NtQueryDirectoryObject (DirectoryHandle
,
521 if (NT_SUCCESS(Status
))
524 while (DirectoryInfo
[Count
].ObjectName
.Buffer
)
526 DPRINT("Count %x\n", Count
);
527 DirectoryInfo
[Count
].ObjectName
.Buffer
[DirectoryInfo
[Count
].ObjectName
.Length
/ sizeof(WCHAR
)] = 0;
528 ArcNameBuffer
= DirectoryInfo
[Count
].ObjectName
.Buffer
;
529 if (DirectoryInfo
[Count
].ObjectName
.Length
>= sizeof(L
"multi(0)disk(0)rdisk(0)") - sizeof(WCHAR
) &&
530 !_wcsnicmp(ArcNameBuffer
, L
"multi(0)disk(0)rdisk(", (sizeof(L
"multi(0)disk(0)rdisk(") - sizeof(WCHAR
)) / sizeof(WCHAR
)))
532 DPRINT("%S\n", ArcNameBuffer
);
533 ArcNameBuffer
+= (sizeof(L
"multi(0)disk(0)rdisk(") - sizeof(WCHAR
)) / sizeof(WCHAR
);
535 while (iswdigit(*ArcNameBuffer
))
537 CurrentRDisk
= CurrentRDisk
* 10 + *ArcNameBuffer
- L
'0';
540 if (!_wcsicmp(ArcNameBuffer
, L
")") &&
541 CurrentRDisk
>= RDiskCount
)
543 RDiskCount
= CurrentRDisk
+ 1;
550 ExFreePool(DirectoryInfo
);
555 xHalpGetDiskNumberFromRDisk(ULONG RDisk
, PULONG DiskNumber
)
557 WCHAR NameBuffer
[80];
558 UNICODE_STRING ArcName
;
559 UNICODE_STRING LinkName
;
560 OBJECT_ATTRIBUTES ObjectAttributes
;
565 L
"\\ArcName\\multi(0)disk(0)rdisk(%lu)",
568 RtlInitUnicodeString(&ArcName
, NameBuffer
);
569 InitializeObjectAttributes(&ObjectAttributes
,
574 Status
= ZwOpenSymbolicLinkObject(&LinkHandle
,
575 SYMBOLIC_LINK_ALL_ACCESS
,
577 if (!NT_SUCCESS(Status
))
579 DPRINT1("ZwOpenSymbolicLinkObject failed for %wZ, status=%lx\n", &ArcName
, Status
);
583 LinkName
.Buffer
= NameBuffer
;
585 LinkName
.MaximumLength
= sizeof(NameBuffer
);
586 Status
= ZwQuerySymbolicLinkObject(LinkHandle
,
590 if (!NT_SUCCESS(Status
))
592 DPRINT1("ZwQuerySymbolicLinkObject failed, status=%lx\n", Status
);
595 if (LinkName
.Length
< sizeof(L
"\\Device\\Harddisk0\\Partition0") - sizeof(WCHAR
) ||
596 LinkName
.Length
>= sizeof(NameBuffer
))
598 return STATUS_UNSUCCESSFUL
;
601 NameBuffer
[LinkName
.Length
/ sizeof(WCHAR
)] = 0;
602 if (_wcsnicmp(NameBuffer
, L
"\\Device\\Harddisk", (sizeof(L
"\\Device\\Harddisk") - sizeof(WCHAR
)) / sizeof(WCHAR
)))
604 return STATUS_UNSUCCESSFUL
;
606 LinkName
.Buffer
+= (sizeof(L
"\\Device\\Harddisk") - sizeof(WCHAR
)) / sizeof(WCHAR
);
608 if (!iswdigit(*LinkName
.Buffer
))
610 return STATUS_UNSUCCESSFUL
;
613 while (iswdigit(*LinkName
.Buffer
))
615 *DiskNumber
= *DiskNumber
* 10 + *LinkName
.Buffer
- L
'0';
618 if (_wcsicmp(LinkName
.Buffer
, L
"\\Partition0"))
620 return STATUS_UNSUCCESSFUL
;
622 return STATUS_SUCCESS
;
627 xHalIoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
628 IN PSTRING NtDeviceName
,
629 OUT PUCHAR NtSystemPath
,
630 OUT PSTRING NtSystemPathString
)
632 PDRIVE_LAYOUT_INFORMATION
*LayoutArray
;
633 PCONFIGURATION_INFORMATION ConfigInfo
;
634 OBJECT_ATTRIBUTES ObjectAttributes
;
635 IO_STATUS_BLOCK StatusBlock
;
636 UNICODE_STRING UnicodeString1
;
637 UNICODE_STRING UnicodeString2
;
647 PKEY_VALUE_PARTIAL_INFORMATION PartialInformation
;
648 PREG_DISK_MOUNT_INFO DiskMountInfo
;
651 DPRINT("xHalIoAssignDriveLetters()\n");
653 ConfigInfo
= IoGetConfigurationInformation();
655 RDiskCount
= xHalpGetRDiskCount();
657 DPRINT1("RDiskCount %d\n", RDiskCount
);
659 Buffer1
= (PWSTR
)ExAllocatePool(PagedPool
,
661 Buffer2
= (PWSTR
)ExAllocatePool(PagedPool
,
664 PartialInformation
= (PKEY_VALUE_PARTIAL_INFORMATION
)ExAllocatePool(PagedPool
,
665 sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(REG_DISK_MOUNT_INFO
));
667 DiskMountInfo
= (PREG_DISK_MOUNT_INFO
) PartialInformation
->Data
;
669 /* Open or Create the 'MountedDevices' key */
670 RtlInitUnicodeString(&UnicodeString1
, L
"\\Registry\\Machine\\SYSTEM\\MountedDevices");
671 InitializeObjectAttributes(&ObjectAttributes
,
673 OBJ_CASE_INSENSITIVE
,
676 Status
= ZwOpenKey(&hKey
,
679 if (!NT_SUCCESS(Status
))
681 Status
= ZwCreateKey(&hKey
,
686 REG_OPTION_NON_VOLATILE
,
689 if (!NT_SUCCESS(Status
))
692 DPRINT1("ZwCreateKey failed for %wZ, status=%x\n", &UnicodeString1
, Status
);
695 /* Create PhysicalDrive links */
696 DPRINT("Physical disk drives: %d\n", ConfigInfo
->DiskCount
);
697 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
700 L
"\\Device\\Harddisk%d\\Partition0",
702 RtlInitUnicodeString(&UnicodeString1
,
705 InitializeObjectAttributes(&ObjectAttributes
,
711 Status
= ZwOpenFile(&FileHandle
,
716 FILE_SYNCHRONOUS_IO_NONALERT
);
717 if (NT_SUCCESS(Status
))
722 L
"\\??\\PhysicalDrive%d",
724 RtlInitUnicodeString(&UnicodeString2
,
727 DPRINT("Creating link: %S ==> %S\n",
731 IoCreateSymbolicLink(&UnicodeString2
,
736 /* Initialize layout array */
737 LayoutArray
= ExAllocatePool(NonPagedPool
,
738 ConfigInfo
->DiskCount
* sizeof(PDRIVE_LAYOUT_INFORMATION
));
739 RtlZeroMemory(LayoutArray
,
740 ConfigInfo
->DiskCount
* sizeof(PDRIVE_LAYOUT_INFORMATION
));
741 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
744 L
"\\Device\\Harddisk%d\\Partition0",
746 RtlInitUnicodeString(&UnicodeString1
,
749 Status
= xHalQueryDriveLayout(&UnicodeString1
,
751 if (!NT_SUCCESS(Status
))
753 DbgPrint("xHalQueryDriveLayout() failed (Status = 0x%lx)\n",
755 LayoutArray
[i
] = NULL
;
758 /* We don't use the RewritePartition value while mounting the disks.
759 * We use this value for marking pre-assigned (registry) partitions.
761 for (j
= 0; j
< LayoutArray
[i
]->PartitionCount
; j
++)
763 LayoutArray
[i
]->PartitionEntry
[j
].RewritePartition
= FALSE
;
768 /* Dump layout array */
769 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
771 DPRINT("Harddisk %d:\n",
774 if (LayoutArray
[i
] == NULL
)
777 DPRINT("Logical partitions: %d\n",
778 LayoutArray
[i
]->PartitionCount
);
780 for (j
= 0; j
< LayoutArray
[i
]->PartitionCount
; j
++)
782 DPRINT(" %d: nr:%x boot:%x type:%x startblock:%I64u count:%I64u\n",
784 LayoutArray
[i
]->PartitionEntry
[j
].PartitionNumber
,
785 LayoutArray
[i
]->PartitionEntry
[j
].BootIndicator
,
786 LayoutArray
[i
]->PartitionEntry
[j
].PartitionType
,
787 LayoutArray
[i
]->PartitionEntry
[j
].StartingOffset
.QuadPart
,
788 LayoutArray
[i
]->PartitionEntry
[j
].PartitionLength
.QuadPart
);
793 /* Assign pre-assigned (registry) partitions */
796 for (k
= 2; k
< 26; k
++)
798 swprintf(Buffer1
, DiskMountString
, L
'A' + k
);
799 RtlInitUnicodeString(&UnicodeString1
, Buffer1
);
800 Status
= ZwQueryValueKey(hKey
,
802 KeyValuePartialInformation
,
804 sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(REG_DISK_MOUNT_INFO
),
806 if (NT_SUCCESS(Status
) &&
807 PartialInformation
->Type
== REG_BINARY
&&
808 PartialInformation
->DataLength
== sizeof(REG_DISK_MOUNT_INFO
))
810 DPRINT("%wZ => %08x:%08x%08x\n", &UnicodeString1
, DiskMountInfo
->Signature
,
811 DiskMountInfo
->StartingOffset
.u
.HighPart
, DiskMountInfo
->StartingOffset
.u
.LowPart
);
813 BOOLEAN Found
= FALSE
;
814 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
816 DPRINT("%x\n", LayoutArray
[i
]->Signature
);
817 if (LayoutArray
[i
] &&
818 LayoutArray
[i
]->Signature
&&
819 LayoutArray
[i
]->Signature
== DiskMountInfo
->Signature
)
821 for (j
= 0; j
< LayoutArray
[i
]->PartitionCount
; j
++)
823 if (LayoutArray
[i
]->PartitionEntry
[j
].StartingOffset
.QuadPart
== DiskMountInfo
->StartingOffset
.QuadPart
)
825 if (IsRecognizedPartition(LayoutArray
[i
]->PartitionEntry
[j
].PartitionType
) &&
826 LayoutArray
[i
]->PartitionEntry
[j
].RewritePartition
== FALSE
)
829 L
"\\Device\\Harddisk%d\\Partition%d",
831 LayoutArray
[i
]->PartitionEntry
[j
].PartitionNumber
);
832 RtlInitUnicodeString(&UnicodeString2
,
836 DPRINT(" %wZ\n", &UnicodeString2
);
837 Found
= HalpAssignDrive(&UnicodeString2
,
839 DOSDEVICE_DRIVE_FIXED
,
840 DiskMountInfo
->Signature
,
841 DiskMountInfo
->StartingOffset
,
843 /* Mark the partition as assigned */
844 LayoutArray
[i
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
853 /* We didn't find a partition for this entry, remove them. */
854 Status
= ZwDeleteValueKey(hKey
, &UnicodeString1
);
861 /* Assign bootable partition on first harddisk */
862 DPRINT("Assigning bootable primary partition on first harddisk:\n");
865 Status
= xHalpGetDiskNumberFromRDisk(0, &DiskNumber
);
866 if (NT_SUCCESS(Status
) &&
867 DiskNumber
< ConfigInfo
->DiskCount
&&
868 LayoutArray
[DiskNumber
])
870 /* Search for bootable partition */
871 for (j
= 0; j
< PARTITION_TBL_SIZE
&& j
< LayoutArray
[DiskNumber
]->PartitionCount
; j
++)
873 if ((LayoutArray
[DiskNumber
]->PartitionEntry
[j
].BootIndicator
== TRUE
) &&
874 IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
))
876 if (LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
)
879 L
"\\Device\\Harddisk%lu\\Partition%d",
881 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
882 RtlInitUnicodeString(&UnicodeString2
,
886 DPRINT(" %wZ\n", &UnicodeString2
);
887 HalpAssignDrive(&UnicodeString2
,
889 DOSDEVICE_DRIVE_FIXED
,
890 LayoutArray
[DiskNumber
]->Signature
,
891 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
893 /* Mark the partition as assigned */
894 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
902 /* Assign remaining primary partitions */
903 DPRINT("Assigning remaining primary partitions:\n");
904 for (RDisk
= 0; RDisk
< RDiskCount
; RDisk
++)
906 Status
= xHalpGetDiskNumberFromRDisk(RDisk
, &DiskNumber
);
907 if (NT_SUCCESS(Status
) &&
908 DiskNumber
< ConfigInfo
->DiskCount
&&
909 LayoutArray
[DiskNumber
])
911 /* Search for primary partitions */
912 for (j
= 0; (j
< PARTITION_TBL_SIZE
) && (j
< LayoutArray
[DiskNumber
]->PartitionCount
); j
++)
914 if (LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
&&
915 IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
))
918 L
"\\Device\\Harddisk%d\\Partition%d",
920 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
921 RtlInitUnicodeString(&UnicodeString2
,
927 HalpAssignDrive(&UnicodeString2
,
929 DOSDEVICE_DRIVE_FIXED
,
930 LayoutArray
[DiskNumber
]->Signature
,
931 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
933 /* Mark the partition as assigned */
934 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
940 /* Assign extended (logical) partitions */
941 DPRINT("Assigning extended (logical) partitions:\n");
942 for (RDisk
= 0; RDisk
< RDiskCount
; RDisk
++)
944 Status
= xHalpGetDiskNumberFromRDisk(RDisk
, &DiskNumber
);
945 if (NT_SUCCESS(Status
) &&
946 DiskNumber
< ConfigInfo
->DiskCount
&&
947 LayoutArray
[DiskNumber
])
949 /* Search for extended partitions */
950 for (j
= PARTITION_TBL_SIZE
; j
< LayoutArray
[DiskNumber
]->PartitionCount
; j
++)
952 if (IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
) &&
953 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
&&
954 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
!= 0)
957 L
"\\Device\\Harddisk%d\\Partition%d",
959 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
960 RtlInitUnicodeString(&UnicodeString2
,
966 HalpAssignDrive(&UnicodeString2
,
968 DOSDEVICE_DRIVE_FIXED
,
969 LayoutArray
[DiskNumber
]->Signature
,
970 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
972 /* Mark the partition as assigned */
973 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
979 /* Assign remaining primary partitions without an arc-name */
980 DPRINT("Assigning remaining primary partitions:\n");
981 for (DiskNumber
= 0; DiskNumber
< ConfigInfo
->DiskCount
; DiskNumber
++)
983 if (LayoutArray
[DiskNumber
])
985 /* Search for primary partitions */
986 for (j
= 0; (j
< PARTITION_TBL_SIZE
) && (j
< LayoutArray
[DiskNumber
]->PartitionCount
); j
++)
988 if (LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
&&
989 IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
))
992 L
"\\Device\\Harddisk%d\\Partition%d",
994 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
995 RtlInitUnicodeString(&UnicodeString2
,
1001 HalpAssignDrive(&UnicodeString2
,
1003 DOSDEVICE_DRIVE_FIXED
,
1004 LayoutArray
[DiskNumber
]->Signature
,
1005 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
1007 /* Mark the partition as assigned */
1008 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
1014 /* Assign extended (logical) partitions without an arc-name */
1015 DPRINT("Assigning extended (logical) partitions:\n");
1016 for (DiskNumber
= 0; DiskNumber
< ConfigInfo
->DiskCount
; DiskNumber
++)
1018 if (LayoutArray
[DiskNumber
])
1020 /* Search for extended partitions */
1021 for (j
= PARTITION_TBL_SIZE
; j
< LayoutArray
[DiskNumber
]->PartitionCount
; j
++)
1023 if (IsRecognizedPartition(LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionType
) &&
1024 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
== FALSE
&&
1025 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
!= 0)
1028 L
"\\Device\\Harddisk%d\\Partition%d",
1030 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].PartitionNumber
);
1031 RtlInitUnicodeString(&UnicodeString2
,
1037 HalpAssignDrive(&UnicodeString2
,
1039 DOSDEVICE_DRIVE_FIXED
,
1040 LayoutArray
[DiskNumber
]->Signature
,
1041 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].StartingOffset
,
1043 /* Mark the partition as assigned */
1044 LayoutArray
[DiskNumber
]->PartitionEntry
[j
].RewritePartition
= TRUE
;
1050 /* Assign removable disk drives */
1051 DPRINT("Assigning removable disk drives:\n");
1052 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
1056 /* Search for virtual partitions */
1057 if (LayoutArray
[i
]->PartitionCount
== 1 &&
1058 LayoutArray
[i
]->PartitionEntry
[0].PartitionType
== 0)
1061 L
"\\Device\\Harddisk%d\\Partition1",
1063 RtlInitUnicodeString(&UnicodeString2
,
1069 HalpAssignDrive(&UnicodeString2
,
1071 DOSDEVICE_DRIVE_REMOVABLE
,
1079 /* Free layout array */
1080 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
1082 if (LayoutArray
[i
] != NULL
)
1083 ExFreePool(LayoutArray
[i
]);
1085 ExFreePool(LayoutArray
);
1087 /* Assign floppy drives */
1088 DPRINT("Floppy drives: %d\n", ConfigInfo
->FloppyCount
);
1089 for (i
= 0; i
< ConfigInfo
->FloppyCount
; i
++)
1092 L
"\\Device\\Floppy%d",
1094 RtlInitUnicodeString(&UnicodeString1
,
1097 /* Assign drive letters A: or B: or first free drive letter */
1100 HalpAssignDrive(&UnicodeString1
,
1101 (i
< 2) ? i
: AUTO_DRIVE
,
1102 DOSDEVICE_DRIVE_REMOVABLE
,
1108 /* Assign cdrom drives */
1109 DPRINT("CD-Rom drives: %d\n", ConfigInfo
->CdRomCount
);
1110 for (i
= 0; i
< ConfigInfo
->CdRomCount
; i
++)
1113 L
"\\Device\\CdRom%d",
1115 RtlInitUnicodeString(&UnicodeString1
,
1118 /* Assign first free drive letter */
1119 DPRINT(" %wZ\n", &UnicodeString1
);
1120 HalpAssignDrive(&UnicodeString1
,
1122 DOSDEVICE_DRIVE_CDROM
,
1128 /* Anything else to do? */
1130 ExFreePool(PartialInformation
);
1131 ExFreePool(Buffer2
);
1132 ExFreePool(Buffer1
);
1141 xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject
,
1143 BOOLEAN ReturnRecognizedPartitions
,
1144 PDRIVE_LAYOUT_INFORMATION
*PartitionBuffer
)
1146 LARGE_INTEGER RealPartitionOffset
;
1147 ULONGLONG PartitionOffset
;
1148 #if defined(__GNUC__)
1149 ULONGLONG nextPartitionOffset
= 0LL;
1151 ULONGLONG nextPartitionOffset
= 0;
1153 ULONGLONG containerOffset
;
1155 PPARTITION_SECTOR PartitionSector
;
1156 PDRIVE_LAYOUT_INFORMATION LayoutBuffer
;
1160 BOOLEAN ExtendedFound
= FALSE
;
1162 DISK_MANAGER DiskManager
= NoDiskManager
;
1164 DPRINT("xHalIoReadPartitionTable(%p %lu %x %p)\n",
1167 ReturnRecognizedPartitions
,
1170 *PartitionBuffer
= NULL
;
1172 /* Check sector size */
1173 if (SectorSize
< 512)
1175 if (SectorSize
> 4096)
1178 /* Check for 'Ontrack Disk Manager' */
1179 HalExamineMBR(DeviceObject
,
1183 if (MbrBuffer
!= NULL
)
1185 DPRINT("Found 'Ontrack Disk Manager'\n");
1186 DiskManager
= OntrackDiskManager
;
1187 ExFreePool(MbrBuffer
);
1190 /* Check for 'EZ-Drive' */
1191 HalExamineMBR(DeviceObject
,
1195 if (MbrBuffer
!= NULL
)
1197 DPRINT("Found 'EZ-Drive'\n");
1198 DiskManager
= EZ_Drive
;
1199 ExFreePool(MbrBuffer
);
1202 PartitionSector
= (PPARTITION_SECTOR
)ExAllocatePool(PagedPool
,
1204 if (PartitionSector
== NULL
)
1206 return(STATUS_INSUFFICIENT_RESOURCES
);
1209 LayoutBuffer
= (PDRIVE_LAYOUT_INFORMATION
)ExAllocatePool(NonPagedPool
,
1211 if (LayoutBuffer
== NULL
)
1213 ExFreePool(PartitionSector
);
1214 return(STATUS_INSUFFICIENT_RESOURCES
);
1217 RtlZeroMemory(LayoutBuffer
,
1220 #if defined(__GNUC__)
1221 PartitionOffset
= 0ULL;
1222 containerOffset
= 0ULL;
1224 PartitionOffset
= 0;
1225 containerOffset
= 0;
1230 DPRINT("PartitionOffset: %I64u\n", PartitionOffset
/ SectorSize
);
1232 /* Handle disk managers */
1233 if (DiskManager
== OntrackDiskManager
)
1235 /* Shift offset by 63 sectors */
1236 RealPartitionOffset
.QuadPart
= PartitionOffset
+ (ULONGLONG
)(63 * SectorSize
);
1238 #if defined(__GNUC__)
1239 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0ULL)
1241 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0)
1244 /* Use sector 1 instead of sector 0 */
1245 RealPartitionOffset
.QuadPart
= (ULONGLONG
)SectorSize
;
1249 RealPartitionOffset
.QuadPart
= PartitionOffset
;
1252 DPRINT ("RealPartitionOffset: %I64u\n",
1253 RealPartitionOffset
.QuadPart
/ SectorSize
);
1255 Status
= xHalpReadSector (DeviceObject
,
1257 &RealPartitionOffset
,
1259 if (!NT_SUCCESS(Status
))
1261 DPRINT ("Failed to read partition table sector (Status = 0x%08lx)\n",
1263 ExFreePool (PartitionSector
);
1264 ExFreePool (LayoutBuffer
);
1268 /* Check the boot sector id */
1269 DPRINT("Magic %x\n", PartitionSector
->Magic
);
1270 if (PartitionSector
->Magic
!= PARTITION_MAGIC
)
1272 DPRINT ("Invalid partition sector magic\n");
1273 ExFreePool (PartitionSector
);
1274 *PartitionBuffer
= LayoutBuffer
;
1275 return STATUS_SUCCESS
;
1279 for (i
= 0; i
< PARTITION_TBL_SIZE
; i
++)
1281 DPRINT1(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",
1283 PartitionSector
->Partition
[i
].BootFlags
,
1284 PartitionSector
->Partition
[i
].PartitionType
,
1285 PartitionSector
->Partition
[i
].StartingHead
,
1286 PartitionSector
->Partition
[i
].StartingSector
& 0x3f,
1287 (((PartitionSector
->Partition
[i
].StartingSector
) & 0xc0) << 2) +
1288 PartitionSector
->Partition
[i
].StartingCylinder
,
1289 PartitionSector
->Partition
[i
].EndingHead
,
1290 PartitionSector
->Partition
[i
].EndingSector
& 0x3f,
1291 (((PartitionSector
->Partition
[i
].EndingSector
) & 0xc0) << 2) +
1292 PartitionSector
->Partition
[i
].EndingCylinder
,
1293 PartitionSector
->Partition
[i
].StartingBlock
,
1294 PartitionSector
->Partition
[i
].SectorCount
);
1298 #if defined(__GNUC__)
1299 if (PartitionOffset
== 0ULL)
1301 if (PartitionOffset
== 0)
1304 LayoutBuffer
->Signature
= PartitionSector
->Signature
;
1305 DPRINT("Disk signature: %lx\n", LayoutBuffer
->Signature
);
1308 ExtendedFound
= FALSE
;
1310 for (i
= 0; i
< PARTITION_TBL_SIZE
; i
++)
1312 if (IsContainerPartition(PartitionSector
->Partition
[i
].PartitionType
))
1314 ExtendedFound
= TRUE
;
1315 if ((ULONGLONG
) containerOffset
== (ULONGLONG
) 0)
1317 containerOffset
= PartitionOffset
;
1319 nextPartitionOffset
= (ULONGLONG
) containerOffset
+
1320 (ULONGLONG
) PartitionSector
->Partition
[i
].StartingBlock
*
1321 (ULONGLONG
) SectorSize
;
1324 if ((ReturnRecognizedPartitions
== FALSE
) ||
1325 ((ReturnRecognizedPartitions
== TRUE
) &&
1326 !IsContainerPartition(PartitionSector
->Partition
[i
].PartitionType
) &&
1327 PartitionSector
->Partition
[i
].PartitionType
!= PARTITION_ENTRY_UNUSED
))
1329 /* handle normal partition */
1330 DPRINT("Partition %u: Normal Partition\n", i
);
1331 Count
= LayoutBuffer
->PartitionCount
;
1332 DPRINT("Logical Partition %u\n", Count
);
1334 if (PartitionSector
->Partition
[i
].StartingBlock
== 0)
1336 LayoutBuffer
->PartitionEntry
[Count
].StartingOffset
.QuadPart
= 0;
1338 else if (IsContainerPartition(PartitionSector
->Partition
[i
].PartitionType
))
1340 LayoutBuffer
->PartitionEntry
[Count
].StartingOffset
.QuadPart
=
1341 (ULONGLONG
) containerOffset
+
1342 (ULONGLONG
) PartitionSector
->Partition
[i
].StartingBlock
*
1343 (ULONGLONG
) SectorSize
;
1347 LayoutBuffer
->PartitionEntry
[Count
].StartingOffset
.QuadPart
=
1348 (ULONGLONG
)PartitionOffset
+
1349 ((ULONGLONG
)PartitionSector
->Partition
[i
].StartingBlock
* (ULONGLONG
)SectorSize
);
1351 LayoutBuffer
->PartitionEntry
[Count
].PartitionLength
.QuadPart
=
1352 (ULONGLONG
)PartitionSector
->Partition
[i
].SectorCount
* (ULONGLONG
)SectorSize
;
1353 LayoutBuffer
->PartitionEntry
[Count
].HiddenSectors
=
1354 PartitionSector
->Partition
[i
].StartingBlock
;
1356 if (!IsContainerPartition(PartitionSector
->Partition
[i
].PartitionType
) &&
1357 PartitionSector
->Partition
[i
].PartitionType
!= PARTITION_ENTRY_UNUSED
)
1359 LayoutBuffer
->PartitionEntry
[Count
].RecognizedPartition
= TRUE
;
1360 /* WinXP returns garbage as PartitionNumber */
1361 LayoutBuffer
->PartitionEntry
[Count
].PartitionNumber
= Number
;
1366 LayoutBuffer
->PartitionEntry
[Count
].RecognizedPartition
= FALSE
;
1367 LayoutBuffer
->PartitionEntry
[Count
].PartitionNumber
= 0;
1370 LayoutBuffer
->PartitionEntry
[Count
].PartitionType
=
1371 PartitionSector
->Partition
[i
].PartitionType
;
1372 LayoutBuffer
->PartitionEntry
[Count
].BootIndicator
=
1373 (PartitionSector
->Partition
[i
].BootFlags
& 0x80)?TRUE
:FALSE
;
1374 LayoutBuffer
->PartitionEntry
[Count
].RewritePartition
= FALSE
;
1376 DPRINT(" %ld: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x rec: %d\n",
1378 LayoutBuffer
->PartitionEntry
[Count
].PartitionNumber
,
1379 LayoutBuffer
->PartitionEntry
[Count
].BootIndicator
,
1380 LayoutBuffer
->PartitionEntry
[Count
].PartitionType
,
1381 LayoutBuffer
->PartitionEntry
[Count
].StartingOffset
.QuadPart
,
1382 LayoutBuffer
->PartitionEntry
[Count
].PartitionLength
.QuadPart
,
1383 LayoutBuffer
->PartitionEntry
[Count
].RecognizedPartition
);
1385 LayoutBuffer
->PartitionCount
++;
1389 PartitionOffset
= nextPartitionOffset
;
1391 while (ExtendedFound
== TRUE
);
1393 *PartitionBuffer
= LayoutBuffer
;
1394 ExFreePool(PartitionSector
);
1396 return(STATUS_SUCCESS
);
1401 xHalIoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject
,
1402 IN ULONG SectorSize
,
1403 IN ULONG PartitionNumber
,
1404 IN ULONG PartitionType
)
1406 PPARTITION_SECTOR PartitionSector
;
1407 LARGE_INTEGER RealPartitionOffset
;
1408 ULONGLONG PartitionOffset
;
1409 #if defined(__GNUC__)
1410 ULONGLONG nextPartitionOffset
= 0LL;
1412 ULONGLONG nextPartitionOffset
= 0;
1414 ULONGLONG containerOffset
;
1418 BOOLEAN ExtendedFound
= FALSE
;
1419 DISK_MANAGER DiskManager
= NoDiskManager
;
1421 DPRINT ("xHalIoSetPartitionInformation(%p %lu %lu %lu)\n",
1427 /* Check sector size */
1428 if (SectorSize
< 512)
1430 if (SectorSize
> 4096)
1433 /* Check for 'Ontrack Disk Manager' */
1434 HalExamineMBR (DeviceObject
,
1437 (PVOID
*)(PVOID
)&PartitionSector
);
1438 if (PartitionSector
!= NULL
)
1440 DPRINT ("Found 'Ontrack Disk Manager'\n");
1441 DiskManager
= OntrackDiskManager
;
1442 ExFreePool (PartitionSector
);
1445 /* Check for 'EZ-Drive' */
1446 HalExamineMBR (DeviceObject
,
1449 (PVOID
*)(PVOID
)&PartitionSector
);
1450 if (PartitionSector
!= NULL
)
1452 DPRINT ("Found 'EZ-Drive'\n");
1453 DiskManager
= EZ_Drive
;
1454 ExFreePool (PartitionSector
);
1457 /* Allocate partition sector */
1458 PartitionSector
= (PPARTITION_SECTOR
) ExAllocatePool (PagedPool
,
1460 if (PartitionSector
== NULL
)
1462 return STATUS_INSUFFICIENT_RESOURCES
;
1465 #if defined(__GNUC__)
1466 PartitionOffset
= 0ULL;
1467 containerOffset
= 0ULL;
1469 PartitionOffset
= 0;
1470 containerOffset
= 0;
1475 DPRINT ("PartitionOffset: %I64u\n", PartitionOffset
/ SectorSize
);
1477 /* Handle disk managers */
1478 if (DiskManager
== OntrackDiskManager
)
1480 /* Shift offset by 63 sectors */
1481 RealPartitionOffset
.QuadPart
= PartitionOffset
+ (ULONGLONG
)(63 * SectorSize
);
1483 #if defined(__GNUC__)
1484 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0ULL)
1486 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0)
1489 /* Use sector 1 instead of sector 0 */
1490 RealPartitionOffset
.QuadPart
= (ULONGLONG
)SectorSize
;
1494 RealPartitionOffset
.QuadPart
= PartitionOffset
;
1497 DPRINT ("RealPartitionOffset: %I64u\n",
1498 RealPartitionOffset
.QuadPart
/ SectorSize
);
1500 Status
= xHalpReadSector (DeviceObject
,
1502 &RealPartitionOffset
,
1504 if (!NT_SUCCESS (Status
))
1506 DPRINT ("Failed to read partition table sector (Status = 0x%08lx)\n",
1508 ExFreePool (PartitionSector
);
1512 /* Check the boot sector id */
1513 DPRINT("Magic %x\n", PartitionSector
->Magic
);
1514 if (PartitionSector
->Magic
!= PARTITION_MAGIC
)
1516 DPRINT ("Invalid partition sector magic\n");
1517 ExFreePool (PartitionSector
);
1518 return STATUS_UNSUCCESSFUL
;
1522 for (i
= 0; i
< PARTITION_TBL_SIZE
; i
++)
1524 DPRINT1(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",
1526 PartitionSector
->Partition
[i
].BootFlags
,
1527 PartitionSector
->Partition
[i
].PartitionType
,
1528 PartitionSector
->Partition
[i
].StartingHead
,
1529 PartitionSector
->Partition
[i
].StartingSector
& 0x3f,
1530 (((PartitionSector
->Partition
[i
].StartingSector
) & 0xc0) << 2) +
1531 PartitionSector
->Partition
[i
].StartingCylinder
,
1532 PartitionSector
->Partition
[i
].EndingHead
,
1533 PartitionSector
->Partition
[i
].EndingSector
& 0x3f,
1534 (((PartitionSector
->Partition
[i
].EndingSector
) & 0xc0) << 2) +
1535 PartitionSector
->Partition
[i
].EndingCylinder
,
1536 PartitionSector
->Partition
[i
].StartingBlock
,
1537 PartitionSector
->Partition
[i
].SectorCount
);
1541 ExtendedFound
= FALSE
;
1542 for (i
= 0; i
< PARTITION_TBL_SIZE
; i
++)
1544 if (IsContainerPartition (PartitionSector
->Partition
[i
].PartitionType
))
1546 ExtendedFound
= TRUE
;
1547 #if defined(__GNUC__)
1548 if (containerOffset
== 0ULL)
1550 if (containerOffset
== 0)
1553 containerOffset
= PartitionOffset
;
1555 nextPartitionOffset
= containerOffset
+
1556 (ULONGLONG
) PartitionSector
->Partition
[i
].StartingBlock
*
1557 (ULONGLONG
) SectorSize
;
1560 /* Handle recognized partition */
1561 if (IsRecognizedPartition (PartitionSector
->Partition
[i
].PartitionType
))
1563 if (Number
== PartitionNumber
)
1565 /* Set partition type */
1566 PartitionSector
->Partition
[i
].PartitionType
= PartitionType
;
1568 /* Write partition sector */
1569 Status
= xHalpWriteSector (DeviceObject
,
1571 &RealPartitionOffset
,
1573 if (!NT_SUCCESS(Status
))
1575 DPRINT1("xHalpWriteSector() failed (Status %lx)\n", Status
);
1578 ExFreePool (PartitionSector
);
1585 PartitionOffset
= nextPartitionOffset
;
1587 while (ExtendedFound
== TRUE
);
1589 ExFreePool(PartitionSector
);
1591 return STATUS_UNSUCCESSFUL
;
1596 xHalIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject
,
1597 IN ULONG SectorSize
,
1598 IN ULONG SectorsPerTrack
,
1599 IN ULONG NumberOfHeads
,
1600 IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer
)
1602 PPARTITION_SECTOR PartitionSector
;
1603 LARGE_INTEGER RealPartitionOffset
;
1604 ULONGLONG PartitionOffset
;
1605 #if defined(__GNUC__)
1606 ULONGLONG NextPartitionOffset
= 0LL;
1608 ULONGLONG NextPartitionOffset
= 0;
1610 ULONGLONG ContainerOffset
;
1611 BOOLEAN ContainerEntry
;
1612 DISK_MANAGER DiskManager
;
1617 ULONG StartCylinder
;
1627 DPRINT ("xHalIoWritePartitionTable(%p %lu %lu %lu %p)\n",
1634 ASSERT(DeviceObject
);
1635 ASSERT(PartitionBuffer
);
1637 DiskManager
= NoDiskManager
;
1639 /* Check sector size */
1640 if (SectorSize
< 512)
1642 if (SectorSize
> 4096)
1645 /* Check for 'Ontrack Disk Manager' */
1646 HalExamineMBR (DeviceObject
,
1649 (PVOID
*)(PVOID
)&PartitionSector
);
1650 if (PartitionSector
!= NULL
)
1652 DPRINT ("Found 'Ontrack Disk Manager'\n");
1653 DiskManager
= OntrackDiskManager
;
1654 ExFreePool (PartitionSector
);
1657 /* Check for 'EZ-Drive' */
1658 HalExamineMBR (DeviceObject
,
1661 (PVOID
*)(PVOID
)&PartitionSector
);
1662 if (PartitionSector
!= NULL
)
1664 DPRINT ("Found 'EZ-Drive'\n");
1665 DiskManager
= EZ_Drive
;
1666 ExFreePool (PartitionSector
);
1669 /* Allocate partition sector */
1670 PartitionSector
= (PPARTITION_SECTOR
)ExAllocatePool(PagedPool
,
1672 if (PartitionSector
== NULL
)
1674 return STATUS_INSUFFICIENT_RESOURCES
;
1677 Status
= STATUS_SUCCESS
;
1678 #if defined(__GNUC__)
1679 PartitionOffset
= 0ULL;
1680 ContainerOffset
= 0ULL;
1682 PartitionOffset
= 0;
1683 ContainerOffset
= 0;
1685 for (i
= 0; i
< PartitionBuffer
->PartitionCount
; i
+= 4)
1687 DPRINT ("PartitionOffset: %I64u\n", PartitionOffset
);
1688 DPRINT ("ContainerOffset: %I64u\n", ContainerOffset
);
1690 /* Handle disk managers */
1691 if (DiskManager
== OntrackDiskManager
)
1693 /* Shift offset by 63 sectors */
1694 RealPartitionOffset
.QuadPart
= PartitionOffset
+ (ULONGLONG
)(63 * SectorSize
);
1696 #if defined(__GNUC__)
1697 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0ULL)
1699 else if (DiskManager
== EZ_Drive
&& PartitionOffset
== 0)
1702 /* Use sector 1 instead of sector 0 */
1703 RealPartitionOffset
.QuadPart
= (ULONGLONG
)SectorSize
;
1707 RealPartitionOffset
.QuadPart
= PartitionOffset
;
1710 /* Write modified partition tables */
1711 if (PartitionBuffer
->PartitionEntry
[i
].RewritePartition
== TRUE
||
1712 PartitionBuffer
->PartitionEntry
[i
+ 1].RewritePartition
== TRUE
||
1713 PartitionBuffer
->PartitionEntry
[i
+ 2].RewritePartition
== TRUE
||
1714 PartitionBuffer
->PartitionEntry
[i
+ 3].RewritePartition
== TRUE
)
1716 /* Read partition sector */
1717 Status
= xHalpReadSector (DeviceObject
,
1719 &RealPartitionOffset
,
1721 if (!NT_SUCCESS(Status
))
1723 DPRINT1 ("xHalpReadSector() failed (Status %lx)\n", Status
);
1727 /* Initialize a new partition sector */
1728 if (PartitionSector
->Magic
!= PARTITION_MAGIC
)
1730 /* Create empty partition sector */
1731 RtlZeroMemory (PartitionSector
,
1733 PartitionSector
->Magic
= PARTITION_MAGIC
;
1736 PartitionSector
->Signature
= PartitionBuffer
->Signature
;
1737 /* Update partition sector entries */
1738 for (j
= 0; j
< 4; j
++)
1740 if (PartitionBuffer
->PartitionEntry
[i
+ j
].RewritePartition
== TRUE
)
1742 /* Set partition boot flag */
1743 if (PartitionBuffer
->PartitionEntry
[i
+ j
].BootIndicator
)
1745 PartitionSector
->Partition
[j
].BootFlags
|= 0x80;
1749 PartitionSector
->Partition
[j
].BootFlags
&= ~0x80;
1752 /* Set partition type */
1753 PartitionSector
->Partition
[j
].PartitionType
=
1754 PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionType
;
1756 /* Set partition data */
1757 #if defined(__GNUC__)
1758 if (PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
== 0ULL &&
1759 PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionLength
.QuadPart
== 0ULL)
1761 if (PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
== 0 &&
1762 PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionLength
.QuadPart
== 0)
1765 PartitionSector
->Partition
[j
].StartingBlock
= 0;
1766 PartitionSector
->Partition
[j
].SectorCount
= 0;
1767 PartitionSector
->Partition
[j
].StartingCylinder
= 0;
1768 PartitionSector
->Partition
[j
].StartingHead
= 0;
1769 PartitionSector
->Partition
[j
].StartingSector
= 0;
1770 PartitionSector
->Partition
[j
].EndingCylinder
= 0;
1771 PartitionSector
->Partition
[j
].EndingHead
= 0;
1772 PartitionSector
->Partition
[j
].EndingSector
= 0;
1778 * x = LBA DIV SectorsPerTrack
1779 * cylinder = (x DIV NumberOfHeads) % 1024
1780 * head = x MOD NumberOfHeads
1781 * sector = (LBA MOD SectorsPerTrack) + 1
1784 /* Compute starting CHS values */
1785 lba
= (ULONG
)((PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
) / SectorSize
);
1786 x
= lba
/ SectorsPerTrack
;
1787 StartCylinder
= (x
/ NumberOfHeads
) %1024;
1788 StartHead
= x
% NumberOfHeads
;
1789 StartSector
= (lba
% SectorsPerTrack
) + 1;
1790 DPRINT ("StartingOffset (LBA:%d C:%d H:%d S:%d)\n",
1791 lba
, StartCylinder
, StartHead
, StartSector
);
1793 /* Compute ending CHS values */
1794 lba
= (ULONG
)((PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
+
1795 (PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionLength
.QuadPart
- 1)) / SectorSize
);
1796 x
= lba
/ SectorsPerTrack
;
1797 EndCylinder
= (x
/ NumberOfHeads
) % 1024;
1798 EndHead
= x
% NumberOfHeads
;
1799 EndSector
= (lba
% SectorsPerTrack
) + 1;
1800 DPRINT ("EndingOffset (LBA:%d C:%d H:%d S:%d)\n",
1801 lba
, EndCylinder
, EndHead
, EndSector
);
1803 /* Set starting CHS values */
1804 PartitionSector
->Partition
[j
].StartingCylinder
= StartCylinder
& 0xff;
1805 PartitionSector
->Partition
[j
].StartingHead
= StartHead
;
1806 PartitionSector
->Partition
[j
].StartingSector
=
1807 ((StartCylinder
& 0x0300) >> 2) + (StartSector
& 0x3f);
1809 /* Set ending CHS values */
1810 PartitionSector
->Partition
[j
].EndingCylinder
= EndCylinder
& 0xff;
1811 PartitionSector
->Partition
[j
].EndingHead
= EndHead
;
1812 PartitionSector
->Partition
[j
].EndingSector
=
1813 ((EndCylinder
& 0x0300) >> 2) + (EndSector
& 0x3f);
1815 /* Calculate start sector and sector count */
1816 if (IsContainerPartition (PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionType
))
1819 (PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
- ContainerOffset
) / SectorSize
;
1824 (PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
- NextPartitionOffset
) / SectorSize
;
1827 PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionLength
.QuadPart
/ SectorSize
;
1828 DPRINT ("LBA (StartBlock:%lu SectorCount:%lu)\n",
1829 StartBlock
, SectorCount
);
1831 /* Set start sector and sector count */
1832 PartitionSector
->Partition
[j
].StartingBlock
= StartBlock
;
1833 PartitionSector
->Partition
[j
].SectorCount
= SectorCount
;
1838 /* Write partition sector */
1839 Status
= xHalpWriteSector (DeviceObject
,
1841 &RealPartitionOffset
,
1843 if (!NT_SUCCESS(Status
))
1845 DPRINT1("xHalpWriteSector() failed (Status %lx)\n", Status
);
1850 ContainerEntry
= FALSE
;
1851 for (j
= 0; j
< 4; j
++)
1853 if (IsContainerPartition (PartitionBuffer
->PartitionEntry
[i
+ j
].PartitionType
))
1855 ContainerEntry
= TRUE
;
1856 NextPartitionOffset
=
1857 PartitionBuffer
->PartitionEntry
[i
+ j
].StartingOffset
.QuadPart
;
1859 #if defined(__GNUC__)
1860 if (ContainerOffset
== 0ULL)
1862 if (ContainerOffset
== 0)
1865 ContainerOffset
= NextPartitionOffset
;
1870 if (ContainerEntry
== FALSE
)
1872 DPRINT ("No container entry in partition sector!\n");
1876 PartitionOffset
= NextPartitionOffset
;
1879 ExFreePool (PartitionSector
);
1889 IoAssignDriveLetters(
1890 IN PLOADER_PARAMETER_BLOCK LoaderBlock,
1891 IN PSTRING NtDeviceName,
1892 OUT PUCHAR NtSystemPath,
1893 OUT PSTRING NtSystemPathString
1905 IN PDEVICE_OBJECT DeviceObject
,
1906 IN
struct _CREATE_DISK
* Disk
1910 return STATUS_NOT_IMPLEMENTED
;
1918 IoGetBootDiskInformation(
1919 IN OUT PBOOTDISK_INFORMATION BootDiskInformation
,
1924 return STATUS_NOT_IMPLEMENTED
;
1933 IoReadDiskSignature(
1934 IN PDEVICE_OBJECT DeviceObject
,
1935 IN ULONG BytesPerSector
,
1936 OUT PDISK_SIGNATURE Signature
1940 return STATUS_NOT_IMPLEMENTED
;
1948 IoReadPartitionTableEx(
1949 IN PDEVICE_OBJECT DeviceObject
,
1950 IN
struct _DRIVE_LAYOUT_INFORMATION_EX
** DriveLayout
1954 return STATUS_NOT_IMPLEMENTED
;
1962 IoSetPartitionInformationEx(
1963 IN PDEVICE_OBJECT DeviceObject
,
1964 IN ULONG PartitionNumber
,
1965 IN
struct _SET_PARTITION_INFORMATION_EX
* PartitionInfo
1969 return STATUS_NOT_IMPLEMENTED
;
1977 IoSetSystemPartition(
1978 PUNICODE_STRING VolumeNameString
1982 return STATUS_NOT_IMPLEMENTED
;
1990 IoVerifyPartitionTable(
1991 IN PDEVICE_OBJECT DeviceObject
,
1992 IN BOOLEAN FixErrors
1996 return STATUS_NOT_IMPLEMENTED
;
2004 IoVolumeDeviceToDosName(
2005 IN PVOID VolumeDeviceObject
,
2006 OUT PUNICODE_STRING DosName
2010 return STATUS_NOT_IMPLEMENTED
;
2018 IoWritePartitionTableEx(
2019 IN PDEVICE_OBJECT DeviceObject
,
2020 IN
struct _DRIVE_LAYOUT_INFORMATION_EX
* DriveLayfout
2024 return STATUS_NOT_IMPLEMENTED
;
2031 IoReadPartitionTable(PDEVICE_OBJECT DeviceObject
,
2033 BOOLEAN ReturnRecognizedPartitions
,
2034 PDRIVE_LAYOUT_INFORMATION
*PartitionBuffer
)
2036 return(HalIoReadPartitionTable(DeviceObject
,
2038 ReturnRecognizedPartitions
,
2044 IoSetPartitionInformation(PDEVICE_OBJECT DeviceObject
,
2046 ULONG PartitionNumber
,
2047 ULONG PartitionType
)
2049 return(HalIoSetPartitionInformation(DeviceObject
,
2057 IoWritePartitionTable(PDEVICE_OBJECT DeviceObject
,
2059 ULONG SectorsPerTrack
,
2060 ULONG NumberOfHeads
,
2061 PDRIVE_LAYOUT_INFORMATION PartitionBuffer
)
2063 return(HalIoWritePartitionTable(DeviceObject
,