ReactOS 0.4.16-dev-2613-g9533ad7
disksup.c File Reference
#include <ntoskrnl.h>
#include <internal/hal.h>
#include <debug.h>
Include dependency graph for disksup.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define EFI_PMBR_OSTYPE_EFI   0xEE
 

Typedefs

typedef enum _DISK_MANAGER DISK_MANAGER
 
typedef enum _PARTITION_TYPE PARTITION_TYPE
 
typedef enum _PARTITION_TYPEPPARTITION_TYPE
 

Enumerations

enum  _DISK_MANAGER { NoDiskManager , OntrackDiskManager , EZ_Drive }
 
enum  _PARTITION_TYPE {
  BootablePartition , PrimaryPartition , LogicalPartition , FtPartition ,
  UnknownPartition , DataPartition
}
 

Functions

static NTSTATUS HalpQueryDriveLayout (_In_ PUNICODE_STRING DeviceName, _Outptr_ PDRIVE_LAYOUT_INFORMATION *LayoutInfo)
 
static NTSTATUS HalpQueryPartitionType (_In_ PUNICODE_STRING DeviceName, _In_opt_ PDRIVE_LAYOUT_INFORMATION LayoutInfo, _Out_ PPARTITION_TYPE PartitionType)
 
static PULONG IopComputeHarddiskDerangements (_In_ ULONG DiskCount)
 
static NTSTATUS HalpNextMountLetter (_In_ PUNICODE_STRING DeviceName, _Out_ PUCHAR DriveLetter)
 
static NTSTATUS HalpSetMountLetter (_In_ PUNICODE_STRING DeviceName, _In_ UCHAR DriveLetter)
 
static UCHAR HalpNextDriveLetter (_In_ PUNICODE_STRING DeviceName, _In_ PSTRING NtDeviceName, _Out_ PUCHAR NtSystemPath, _In_ BOOLEAN IsRemovable)
 
static BOOLEAN HalpIsOldStyleFloppy (_In_ PUNICODE_STRING DeviceName)
 
static NTSTATUS HalpDeleteMountLetter (_In_ UCHAR DriveLetter)
 
static VOID HalpEnableAutomaticDriveLetterAssignment (VOID)
 
VOID FASTCALL xHalIoAssignDriveLetters (IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PSTRING NtDeviceName, OUT PUCHAR NtSystemPath, OUT PSTRING NtSystemPathString)
 
static NTSTATUS HalpGetFullGeometry (_In_ PDEVICE_OBJECT DeviceObject, _Out_ PDISK_GEOMETRY_EX Geometry)
 
static BOOLEAN HalpIsValidPartitionEntry (_In_ PPARTITION_DESCRIPTOR Entry, _In_ ULONGLONG MaxOffset, _In_ ULONGLONG MaxSector)
 
static VOID HalpCalculateChsValues (_In_ PLARGE_INTEGER PartitionOffset, _In_ PLARGE_INTEGER PartitionLength, _In_ CCHAR ShiftCount, _In_ ULONG SectorsPerTrack, _In_ ULONG NumberOfTracks, _In_ ULONG ConventionalCylinders, _Out_ PPARTITION_DESCRIPTOR PartitionDescriptor)
 
VOID FASTCALL xHalGetPartialGeometry (IN PDEVICE_OBJECT DeviceObject, IN PULONG ConventionalCylinders, IN PLONGLONG DiskSize)
 
VOID FASTCALL xHalExamineMBR (IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG MbrTypeIdentifier, OUT PVOID *MbrBuffer)
 
VOID NTAPI FstubFixupEfiPartition (IN PPARTITION_DESCRIPTOR PartitionDescriptor, IN ULONGLONG MaxOffset)
 
NTSTATUS FASTCALL xHalIoReadPartitionTable (IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN BOOLEAN ReturnRecognizedPartitions, OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
 
NTSTATUS FASTCALL xHalIoSetPartitionInformation (IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG PartitionNumber, IN ULONG PartitionType)
 
NTSTATUS FASTCALL xHalIoWritePartitionTable (IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG SectorsPerTrack, IN ULONG NumberOfHeads, IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
 
VOID FASTCALL HalExamineMBR (IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG MbrTypeIdentifier, OUT PVOID *MbrBuffer)
 
NTSTATUS FASTCALL IoReadPartitionTable (IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN BOOLEAN ReturnRecognizedPartitions, OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
 
NTSTATUS FASTCALL IoSetPartitionInformation (IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG PartitionNumber, IN ULONG PartitionType)
 
NTSTATUS FASTCALL IoWritePartitionTable (IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG SectorsPerTrack, IN ULONG NumberOfHeads, IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
 
VOID FASTCALL IoAssignDriveLetters (IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PSTRING NtDeviceName, OUT PUCHAR NtSystemPath, OUT PSTRING NtSystemPathString)
 

Variables

static const UNICODE_STRING FloppyPrefix = RTL_CONSTANT_STRING(L"\\Device\\Floppy")
 
static const UNICODE_STRING CdPrefix = RTL_CONSTANT_STRING(L"\\Device\\CdRom")
 

Macro Definition Documentation

◆ EFI_PMBR_OSTYPE_EFI

#define EFI_PMBR_OSTYPE_EFI   0xEE

Definition at line 21 of file disksup.c.

◆ NDEBUG

#define NDEBUG

Definition at line 17 of file disksup.c.

Typedef Documentation

◆ DISK_MANAGER

◆ PARTITION_TYPE

◆ PPARTITION_TYPE

Enumeration Type Documentation

◆ _DISK_MANAGER

Enumerator
NoDiskManager 
OntrackDiskManager 
EZ_Drive 

Definition at line 23 of file disksup.c.

24{
@ EZ_Drive
Definition: disksup.c:27
@ NoDiskManager
Definition: disksup.c:25
@ OntrackDiskManager
Definition: disksup.c:26
enum _DISK_MANAGER DISK_MANAGER

◆ _PARTITION_TYPE

Enumerator
BootablePartition 
PrimaryPartition 
LogicalPartition 
FtPartition 
UnknownPartition 
DataPartition 

Definition at line 30 of file disksup.c.

31{
enum _PARTITION_TYPE PARTITION_TYPE
enum _PARTITION_TYPE * PPARTITION_TYPE
@ UnknownPartition
Definition: disksup.c:36
@ DataPartition
Definition: disksup.c:37
@ PrimaryPartition
Definition: disksup.c:33
@ BootablePartition
Definition: disksup.c:32
@ LogicalPartition
Definition: disksup.c:34
@ FtPartition
Definition: disksup.c:35

Function Documentation

◆ FstubFixupEfiPartition()

VOID NTAPI FstubFixupEfiPartition ( IN PPARTITION_DESCRIPTOR  PartitionDescriptor,
IN ULONGLONG  MaxOffset 
)

Definition at line 1635 of file disksup.c.

1637{
1638 ULONG PartitionMaxOffset, PartitionLength;
1639 PAGED_CODE();
1640
1641 /* Compute partition length (according to MBR entry) */
1642 PartitionMaxOffset = GET_STARTING_SECTOR(PartitionDescriptor) + GET_PARTITION_LENGTH(PartitionDescriptor);
1643 /* In case the partition length goes beyond disk size... */
1644 if (PartitionMaxOffset > MaxOffset)
1645 {
1646 /* Resize partition to its maximum real length */
1647 PartitionLength = (ULONG)(PartitionMaxOffset - GET_STARTING_SECTOR(PartitionDescriptor));
1648 SET_PARTITION_LENGTH(PartitionDescriptor, PartitionLength);
1649 }
1650}
#define PAGED_CODE()
#define SET_PARTITION_LENGTH(p, l)
Definition: hal.h:268
#define GET_PARTITION_LENGTH(p)
Definition: hal.h:262
#define GET_STARTING_SECTOR(p)
Definition: hal.h:253
uint32_t ULONG
Definition: typedefs.h:59

Referenced by xHalIoReadPartitionTable().

◆ HalExamineMBR()

VOID FASTCALL HalExamineMBR ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  SectorSize,
IN ULONG  MbrTypeIdentifier,
OUT PVOID MbrBuffer 
)

Definition at line 2565 of file disksup.c.

2569{
2570 HALDISPATCH->HalExamineMBR(DeviceObject,
2571 SectorSize,
2572 MbrTypeIdentifier,
2573 MbrBuffer);
2574}
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ ULONG SectorSize
Definition: halfuncs.h:291
#define HALDISPATCH
Definition: haltypes.h:288

◆ HalpCalculateChsValues()

static VOID HalpCalculateChsValues ( _In_ PLARGE_INTEGER  PartitionOffset,
_In_ PLARGE_INTEGER  PartitionLength,
_In_ CCHAR  ShiftCount,
_In_ ULONG  SectorsPerTrack,
_In_ ULONG  NumberOfTracks,
_In_ ULONG  ConventionalCylinders,
_Out_ PPARTITION_DESCRIPTOR  PartitionDescriptor 
)
static

Definition at line 1366 of file disksup.c.

1374{
1375 LARGE_INTEGER FirstSector, SectorCount;
1376 ULONG LastSector, Remainder, SectorsPerCylinder;
1377 ULONG StartingCylinder, EndingCylinder;
1378 ULONG StartingTrack, EndingTrack;
1379 ULONG StartingSector, EndingSector;
1380
1381 PAGED_CODE();
1382
1383 /* Calculate the number of sectors for each cylinder */
1384 SectorsPerCylinder = SectorsPerTrack * NumberOfTracks;
1385
1386 /* Calculate the first sector, and the sector count */
1387 FirstSector.QuadPart = PartitionOffset->QuadPart >> ShiftCount;
1388 SectorCount.QuadPart = PartitionLength->QuadPart >> ShiftCount;
1389
1390 /* Now calculate the last sector */
1391 LastSector = FirstSector.LowPart + SectorCount.LowPart - 1;
1392
1393 /* Calculate the first and last cylinders */
1394 StartingCylinder = FirstSector.LowPart / SectorsPerCylinder;
1395 EndingCylinder = LastSector / SectorsPerCylinder;
1396
1397 /* Set the default number of cylinders */
1398 if (!ConventionalCylinders) ConventionalCylinders = 1024;
1399
1400 /* Normalize the values */
1401 if (StartingCylinder >= ConventionalCylinders)
1402 {
1403 /* Set the maximum to 1023 */
1404 StartingCylinder = ConventionalCylinders - 1;
1405 }
1406 if (EndingCylinder >= ConventionalCylinders)
1407 {
1408 /* Set the maximum to 1023 */
1409 EndingCylinder = ConventionalCylinders - 1;
1410 }
1411
1412 /* Calculate the starting head and sector that still remain */
1413 Remainder = FirstSector.LowPart % SectorsPerCylinder;
1414 StartingTrack = Remainder / SectorsPerTrack;
1415 StartingSector = Remainder % SectorsPerTrack;
1416
1417 /* Calculate the ending head and sector that still remain */
1418 Remainder = LastSector % SectorsPerCylinder;
1419 EndingTrack = Remainder / SectorsPerTrack;
1420 EndingSector = Remainder % SectorsPerTrack;
1421
1422 /* Set cylinder data for the MSB */
1423 PartitionDescriptor->StartingCylinderMsb = (UCHAR)StartingCylinder;
1424 PartitionDescriptor->EndingCylinderMsb = (UCHAR)EndingCylinder;
1425
1426 /* Set the track data */
1427 PartitionDescriptor->StartingTrack = (UCHAR)StartingTrack;
1428 PartitionDescriptor->EndingTrack = (UCHAR)EndingTrack;
1429
1430 /* Update cylinder data for the LSB */
1431 StartingCylinder = ((StartingSector + 1) & 0x3F) |
1432 ((StartingCylinder >> 2) & 0xC0);
1433 EndingCylinder = ((EndingSector + 1) & 0x3F) |
1434 ((EndingCylinder >> 2) & 0xC0);
1435
1436 /* Set the cylinder data for the LSB */
1437 PartitionDescriptor->StartingCylinderLsb = (UCHAR)StartingCylinder;
1438 PartitionDescriptor->EndingCylinderLsb = (UCHAR)EndingCylinder;
1439}
ULONG SectorCount
Definition: part_brfr.c:22
unsigned char UCHAR
Definition: typedefs.h:53
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
_In_ ULONG _In_ ULONG SectorsPerTrack
Definition: iofuncs.h:2071
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3062

Referenced by xHalIoWritePartitionTable().

◆ HalpDeleteMountLetter()

static NTSTATUS HalpDeleteMountLetter ( _In_ UCHAR  DriveLetter)
static

Definition at line 743 of file disksup.c.

745{
746 PIRP Irp;
749 WCHAR Buffer[30];
755 UNICODE_STRING DosDevice, MountMgr;
757
758 /* Setup the device name of the letter to delete */
759 swprintf(Buffer, L"\\DosDevices\\%c:", DriveLetter);
760 RtlInitUnicodeString(&DosDevice, Buffer);
761
762 /* Allocate the input buffer for the MountMgr */
763 InputBufferLength = DosDevice.Length + sizeof(MOUNTMGR_MOUNT_POINT);
765 if (InputBuffer == NULL)
766 {
768 }
769
770 /* Fill it in */
772 InputBuffer->SymbolicLinkNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
773 InputBuffer->SymbolicLinkNameLength = DosDevice.Length;
774 RtlCopyMemory(&InputBuffer[1], DosDevice.Buffer, DosDevice.Length);
775
776 /* Allocate big enough output buffer (we don't care about the output) */
778 if (OutputBuffer == NULL)
779 {
782 }
783
784 /* Get the device pointer to the MountMgr */
785 RtlInitUnicodeString(&MountMgr, L"\\Device\\MountPointManager");
788 &FileObject,
789 &DeviceObject);
790 if (!NT_SUCCESS(Status))
791 {
794 return Status;
795 }
796
797 /* Call the MountMgr to delete the drive letter */
804 0x1000,
805 FALSE,
806 &Event,
808 if (Irp == NULL)
809 {
814 }
815
817 if (Status == STATUS_PENDING)
818 {
820 Executive,
822 FALSE,
823 NULL);
825 }
826
830
831 return Status;
832}
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define swprintf
Definition: precomp.h:40
#define L(x)
Definition: resources.c:13
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define PagedPool
Definition: env_spec_w32.h:308
Status
Definition: gdiplustypes.h:25
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define IOCTL_MOUNTMGR_DELETE_POINTS
Definition: imports.h:122
struct _MOUNTMGR_MOUNT_POINT MOUNTMGR_MOUNT_POINT
#define KernelMode
Definition: asm.h:38
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
@ NotificationEvent
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1446
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IoCallDriver
Definition: irp.c:1225
short WCHAR
Definition: pedump.c:58
#define TAG_FSTUB
Definition: tag.h:54
#define STATUS_PENDING
Definition: telnetd.h:14
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
* PFILE_OBJECT
Definition: iotypes.h:1998
@ Executive
Definition: ketypes.h:467
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by xHalIoAssignDriveLetters().

◆ HalpEnableAutomaticDriveLetterAssignment()

static VOID HalpEnableAutomaticDriveLetterAssignment ( VOID  )
static

Definition at line 835 of file disksup.c.

836{
837 PIRP Irp;
840 UNICODE_STRING MountMgr;
844
845 /* Get the device pointer to the MountMgr */
846 RtlInitUnicodeString(&MountMgr, L"\\Device\\MountPointManager");
849 &FileObject,
850 &DeviceObject);
851 if (!NT_SUCCESS(Status))
852 {
853 return;
854 }
855
856 /* Just send an IOCTL to enable the feature */
860 NULL,
861 0,
862 NULL,
863 0,
864 FALSE,
865 &Event,
867 if (Irp == NULL)
868 {
869 return;
870 }
871
873 if (Status == STATUS_PENDING)
874 {
876 Executive,
878 FALSE,
879 NULL);
881 }
882
884
885 return;
886}
#define IOCTL_MOUNTMGR_AUTO_DL_ASSIGNMENTS
Definition: mountmgr.h:55

Referenced by xHalIoAssignDriveLetters().

◆ HalpGetFullGeometry()

static NTSTATUS HalpGetFullGeometry ( _In_ PDEVICE_OBJECT  DeviceObject,
_Out_ PDISK_GEOMETRY_EX  Geometry 
)
static

Definition at line 1271 of file disksup.c.

1274{
1275 PIRP Irp;
1277 PKEVENT Event;
1279
1280 PAGED_CODE();
1281
1282 /* Allocate a non-paged event */
1284 sizeof(KEVENT),
1287
1288 /* Initialize it */
1290
1291 /* Build the IRP */
1294 NULL,
1295 0UL,
1296 Geometry,
1297 sizeof(DISK_GEOMETRY_EX),
1298 FALSE,
1299 Event,
1300 &IoStatusBlock);
1301 if (!Irp)
1302 {
1303 /* Fail, free the event */
1306 }
1307
1308 /* Call the driver and check if it's pending */
1310 if (Status == STATUS_PENDING)
1311 {
1312 /* Wait on the driver */
1315 }
1316
1317 /* Free the event and return the Status */
1319 return Status;
1320}
#define NonPagedPool
Definition: env_spec_w32.h:307
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
#define TAG_FILE_SYSTEM
Definition: tag.h:64
#define UL
Definition: tui.h:164

Referenced by xHalIoReadPartitionTable().

◆ HalpIsOldStyleFloppy()

static BOOLEAN HalpIsOldStyleFloppy ( _In_ PUNICODE_STRING  DeviceName)
static

Definition at line 683 of file disksup.c.

685{
686 PIRP Irp;
689 MOUNTDEV_NAME DevName;
693
694 PAGED_CODE();
695
696 /* Get the attached device object to our device */
699 &FileObject,
700 &DeviceObject);
701 if (!NT_SUCCESS(Status))
702 return FALSE;
703
706
707 /* Query its device name (verifies that the floppy driver
708 * for this device implements the MountMgr interface) */
712 NULL,
713 0,
714 &DevName,
715 sizeof(DevName),
716 FALSE,
717 &Event,
719 if (Irp == NULL)
720 {
722 return FALSE;
723 }
724
726 if (Status == STATUS_PENDING)
727 {
729 Executive,
731 FALSE,
732 NULL);
734 }
735
736 /* If status is not STATUS_BUFFER_OVERFLOW, it means
737 * it's a pre-MountMgr driver, aka "Old style" */
739 return (Status != STATUS_BUFFER_OVERFLOW);
740}
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:91
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1407
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3281

Referenced by xHalIoAssignDriveLetters().

◆ HalpIsValidPartitionEntry()

static BOOLEAN HalpIsValidPartitionEntry ( _In_ PPARTITION_DESCRIPTOR  Entry,
_In_ ULONGLONG  MaxOffset,
_In_ ULONGLONG  MaxSector 
)
static

Definition at line 1323 of file disksup.c.

1327{
1328 ULONGLONG EndingSector;
1329
1330 PAGED_CODE();
1331
1332 /* Unused partitions are considered valid */
1333 if (Entry->PartitionType == PARTITION_ENTRY_UNUSED)
1334 return TRUE;
1335
1336 /* Get the last sector of the partition */
1338
1339 /* Check if it's more than the maximum sector */
1340 if (EndingSector > MaxSector)
1341 {
1342 /* Invalid partition */
1343 DPRINT1("FSTUB: entry is invalid\n");
1344 DPRINT1("FSTUB: offset %#08lx\n", GET_STARTING_SECTOR(Entry));
1345 DPRINT1("FSTUB: length %#08lx\n", GET_PARTITION_LENGTH(Entry));
1346 DPRINT1("FSTUB: end %#I64x\n", EndingSector);
1347 DPRINT1("FSTUB: max %#I64x\n", MaxSector);
1348 return FALSE;
1349 }
1350 else if (GET_STARTING_SECTOR(Entry) > MaxOffset)
1351 {
1352 /* Invalid partition */
1353 DPRINT1("FSTUB: entry is invalid\n");
1354 DPRINT1("FSTUB: offset %#08lx\n", GET_STARTING_SECTOR(Entry));
1355 DPRINT1("FSTUB: length %#08lx\n", GET_PARTITION_LENGTH(Entry));
1356 DPRINT1("FSTUB: end %#I64x\n", EndingSector);
1357 DPRINT1("FSTUB: maxOffset %#I64x\n", MaxOffset);
1358 return FALSE;
1359 }
1360
1361 /* It's fine, return success */
1362 return TRUE;
1363}
#define DPRINT1
Definition: precomp.h:8
#define TRUE
Definition: types.h:120
#define PARTITION_ENTRY_UNUSED
Definition: part_mbr.h:50
Entry
Definition: section.c:5210
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by xHalIoReadPartitionTable().

◆ HalpNextDriveLetter()

static UCHAR HalpNextDriveLetter ( _In_ PUNICODE_STRING  DeviceName,
_In_ PSTRING  NtDeviceName,
_Out_ PUCHAR  NtSystemPath,
_In_ BOOLEAN  IsRemovable 
)
static

Definition at line 604 of file disksup.c.

609{
610 UCHAR i;
611 WCHAR Buffer[40];
612 UCHAR DriveLetter;
613 UNICODE_STRING NtDeviceNameU, DosDevice;
614
615 /* Quick path, ask directly the MountMgr
616 * to assign the next free drive letter */
617 if (NT_SUCCESS(HalpNextMountLetter(DeviceName, &DriveLetter)))
618 return DriveLetter;
619
620 /* We'll allow the MountMgr to fail only for non vital path */
621 if (NtDeviceName == NULL || NtSystemPath == NULL)
622 return 0xFF;
623
624 /* And for removable devices */
625 if (!IsRemovable)
626 return 0;
627
628 /* The removable device might be a floppy or CD-ROM */
629
631 DriveLetter = 'A'; /* If floppy, start at A */
633 DriveLetter = 'D'; /* If CD-ROM, start at D */
634 else
635 DriveLetter = 'C'; /* Otherwise, start at C */
636
637 /* Now, try to assign a drive letter manually with the MountMgr */
638 for (i = DriveLetter; i <= 'Z'; ++i)
639 {
641 {
642 /* If it worked, if we were managing system path, update manually */
643 if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&NtDeviceNameU, NtDeviceName, TRUE)))
644 {
645 if (RtlEqualUnicodeString(&NtDeviceNameU, DeviceName, TRUE))
646 *NtSystemPath = i;
647
648 RtlFreeUnicodeString(&NtDeviceNameU);
649 }
650
651 return i;
652 }
653 }
654
655 /* Last fall back, we're not on a PnP device... */
656 for (i = DriveLetter; i <= 'Z'; ++i)
657 {
658 /* We'll link manually, without the MountMgr knowing anything about the device */
659 swprintf(Buffer, L"\\DosDevices\\%c:", i);
660 RtlInitUnicodeString(&DosDevice, Buffer);
661
662 /* If linking worked, the letter was free ;-) */
664 {
665 /* If it worked, if we were managing system path, update manually */
666 if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&NtDeviceNameU, NtDeviceName, TRUE)))
667 {
668 if (RtlEqualUnicodeString(&NtDeviceNameU, DeviceName, TRUE))
669 *NtSystemPath = i;
670
671 RtlFreeUnicodeString(&NtDeviceNameU);
672 }
673
674 return i;
675 }
676 }
677
678 /* We're done, nothing happened */
679 return 0;
680}
static NTSTATUS HalpSetMountLetter(_In_ PUNICODE_STRING DeviceName, _In_ UCHAR DriveLetter)
Definition: disksup.c:518
static const UNICODE_STRING CdPrefix
Definition: disksup.c:41
static const UNICODE_STRING FloppyPrefix
Definition: disksup.c:40
static NTSTATUS HalpNextMountLetter(_In_ PUNICODE_STRING DeviceName, _Out_ PUCHAR DriveLetter)
Definition: disksup.c:436
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)

Referenced by xHalIoAssignDriveLetters().

◆ HalpNextMountLetter()

static NTSTATUS HalpNextMountLetter ( _In_ PUNICODE_STRING  DeviceName,
_Out_ PUCHAR  DriveLetter 
)
static

Definition at line 436 of file disksup.c.

439{
440 PIRP Irp;
443 UNICODE_STRING MountMgr;
449
450 /* To get next mount letter, we need the MountMgr */
451 RtlInitUnicodeString(&MountMgr, L"\\Device\\MountPointManager");
454 &FileObject,
455 &DeviceObject);
456 if (!NT_SUCCESS(Status))
457 {
458 return Status;
459 }
460
461 /* Allocate our input buffer */
464 TAG_FSTUB);
465 if (Target == NULL)
466 {
469 }
470
471 /* And fill it with the device hat needs a drive letter */
472 Target->DeviceNameLength = DeviceName->Length;
473 RtlCopyMemory(&Target->DeviceName[0], DeviceName->Buffer, DeviceName->Length);
474
475 /* Call the MountMgr */
479 Target,
481 &LetterInfo,
482 sizeof(LetterInfo),
483 FALSE,
484 &Event,
486 if (Irp == NULL)
487 {
491 }
492
494 if (Status == STATUS_PENDING)
495 {
497 Executive,
499 FALSE,
500 NULL);
502 }
503
506
507 DPRINT("Done: %d %c\n", LetterInfo.DriveLetterWasAssigned,
508 LetterInfo.CurrentDriveLetter);
509
510 /* Return the drive letter the MountMgr potentially assigned */
511 *DriveLetter = LetterInfo.CurrentDriveLetter;
512
513 /* Also return the success */
514 return Status;
515}
#define IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER
Definition: mountmgr.h:53
#define DPRINT
Definition: sndvol32.h:73
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306

Referenced by HalpNextDriveLetter().

◆ HalpQueryDriveLayout()

static NTSTATUS HalpQueryDriveLayout ( _In_ PUNICODE_STRING  DeviceName,
_Outptr_ PDRIVE_LAYOUT_INFORMATION LayoutInfo 
)
static

Definition at line 46 of file disksup.c.

49{
50 IO_STATUS_BLOCK StatusBlock;
54 PIRP Irp;
58
59 PAGED_CODE();
60
61 /* Get device pointers */
66 if (!NT_SUCCESS(Status))
67 {
68 return Status;
69 }
70
71 /* Get attached device object */
74
75 /* Do not handle removable media */
76 if (BooleanFlagOn(DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA))
77 {
79 return STATUS_NO_MEDIA;
80 }
81
82 /* We'll loop until our buffer is big enough */
83 Buffer = NULL;
84 BufferSize = 0x1000;
86 do
87 {
88 /* If we already had a buffer, it means it's not
89 * big enough, so free and multiply size by two */
90 if (Buffer != NULL)
91 {
93 BufferSize *= 2;
94 }
95
96 /* Allocate buffer for output buffer */
98 if (Buffer == NULL)
99 {
101 break;
102 }
103
104 /* Build the IRP to query drive layout */
107 NULL,
108 0,
109 Buffer,
111 FALSE,
112 &Event,
113 &StatusBlock);
114 if (Irp == NULL)
115 {
117 break;
118 }
119
120 /* Call the driver and wait if appropriate */
122 if (Status == STATUS_PENDING)
123 {
125 Executive,
127 FALSE,
128 NULL);
129 Status = StatusBlock.Status;
130 }
131 /* If buffer is too small, keep looping */
132 } while (Status == STATUS_BUFFER_TOO_SMALL);
133
134 /* We're done with the device */
136
137 /* If querying worked, return the buffer to the caller */
138 if (NT_SUCCESS(Status))
139 {
140 ASSERT(Buffer != NULL);
141 *LayoutInfo = Buffer;
142 }
143 /* Else, release the buffer if still allocated and fail */
144 else
145 {
146 if (Buffer != NULL)
147 {
149 }
150 }
151
152 return Status;
153}
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define BufferSize
Definition: mmc.h:75
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define ASSERT(a)
Definition: mode.c:44
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:91
#define STATUS_NO_MEDIA
Definition: ntstatus.h:704
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

Referenced by xHalIoAssignDriveLetters().

◆ HalpQueryPartitionType()

static NTSTATUS HalpQueryPartitionType ( _In_ PUNICODE_STRING  DeviceName,
_In_opt_ PDRIVE_LAYOUT_INFORMATION  LayoutInfo,
_Out_ PPARTITION_TYPE  PartitionType 
)
static

Definition at line 156 of file disksup.c.

160{
161 USHORT i;
162 PIRP Irp;
169
170 PAGED_CODE();
171
172 /* Get device pointers */
175 &FileObject,
176 &DeviceObject);
177 if (!NT_SUCCESS(Status))
178 {
179 return Status;
180 }
181
182 /* Get attached device object */
185
186 /* Assume logical partition for removable devices */
187 if (BooleanFlagOn(DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA))
188 {
191 return STATUS_SUCCESS;
192 }
193
194 /* For the others, query partition info */
198 NULL,
199 0,
201 sizeof(PartitionInfo),
202 FALSE,
203 &Event,
205 if (Irp == NULL)
206 {
209 }
210
212 if (Status == STATUS_PENDING)
213 {
215 Executive,
217 FALSE,
218 NULL);
220 }
221
222 /* We're done with the device */
224
225 /* If we failed querying partition info, try to return something
226 * if caller didn't provide a precise layout, assume logical
227 * partition and fake success. Otherwise, just fail. */
228 if (!NT_SUCCESS(Status))
229 {
230 if (LayoutInfo == NULL)
231 {
233 return STATUS_SUCCESS;
234 }
235
236 return Status;
237 }
238
239 /* First, handle non-MBR style (easy case) */
240 if (PartitionInfo.PartitionStyle != PARTITION_STYLE_MBR)
241 {
242 /* If not GPT, we don't know what it is */
243 if (PartitionInfo.PartitionStyle != PARTITION_STYLE_GPT)
244 {
246 return STATUS_SUCCESS;
247 }
248
249 /* Check whether this is a data partition */
250 if (IsEqualGUID(&PartitionInfo.Gpt.PartitionType, &PARTITION_BASIC_DATA_GUID))
251 {
253 return STATUS_SUCCESS;
254 }
255
256 /* Otherwise, we don't know */
258 return STATUS_SUCCESS;
259 }
260
261 /* If we don't recognize partition type, return unknown */
262 if (!IsRecognizedPartition(PartitionInfo.Mbr.PartitionType))
263 {
265 return STATUS_SUCCESS;
266 }
267
268 /* Check if that's a FT volume */
269 if (IsFTPartition(PartitionInfo.Mbr.PartitionType))
270 {
272 return STATUS_SUCCESS;
273 }
274
275 /* If the caller didn't provide the complete layout, just return */
276 if (LayoutInfo == NULL)
277 {
279 return STATUS_SUCCESS;
280 }
281
282 /* Now, evaluate the partition to those in the input layout */
283 for (i = 0; i < NUM_PARTITION_TABLE_ENTRIES; ++i)
284 {
285 /* If we find a partition matching */
286 if (LayoutInfo->PartitionEntry[i].StartingOffset.QuadPart == PartitionInfo.StartingOffset.QuadPart)
287 {
288 /* Return boot if boot flag is set */
289 if (PartitionInfo.Mbr.BootIndicator)
290 {
292 }
293 /* Primary otherwise */
294 else
295 {
297 }
298
299 return STATUS_SUCCESS;
300 }
301 }
302
303 /* Otherwise, assume logical */
305 return STATUS_SUCCESS;
306}
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
@ PARTITION_STYLE_GPT
Definition: imports.h:202
@ PARTITION_STYLE_MBR
Definition: imports.h:201
#define IsFTPartition(PartitionType)
Definition: ntdddisk.h:315
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
#define NUM_PARTITION_TABLE_ENTRIES
Definition: hal.h:248
UCHAR PartitionType
Definition: part_brfr.c:23
unsigned short USHORT
Definition: pedump.c:61
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105

Referenced by xHalIoAssignDriveLetters().

◆ HalpSetMountLetter()

static NTSTATUS HalpSetMountLetter ( _In_ PUNICODE_STRING  DeviceName,
_In_ UCHAR  DriveLetter 
)
static

Definition at line 518 of file disksup.c.

521{
522 PIRP Irp;
525 WCHAR Buffer[30];
530 UNICODE_STRING DosDevice, MountMgr;
532
533 /* Setup the DosDevice name */
534 swprintf(Buffer, L"\\DosDevices\\%c:", DriveLetter);
535 RtlInitUnicodeString(&DosDevice, Buffer);
536
537 /* Allocate the input buffer for the MountMgr */
538 InputBufferLength = DosDevice.Length + DeviceName->Length + sizeof(MOUNTMGR_CREATE_POINT_INPUT);
540 if (InputBuffer == NULL)
541 {
543 }
544
545 /* Fill the input buffer */
546 InputBuffer->SymbolicLinkNameOffset = sizeof(MOUNTMGR_CREATE_POINT_INPUT);
547 InputBuffer->SymbolicLinkNameLength = DosDevice.Length;
548 InputBuffer->DeviceNameOffset = DosDevice.Length + sizeof(MOUNTMGR_CREATE_POINT_INPUT);
549 InputBuffer->DeviceNameLength = DeviceName->Length;
550 RtlCopyMemory(&InputBuffer[1], DosDevice.Buffer, DosDevice.Length);
551 RtlCopyMemory((PVOID)((ULONG_PTR)InputBuffer + InputBuffer->DeviceNameOffset),
552 DeviceName->Buffer,
553 DeviceName->Length);
554
555 /* Get the MountMgr device pointer, to send the IOCTL */
556 RtlInitUnicodeString(&MountMgr, L"\\Device\\MountPointManager");
559 &FileObject,
560 &DeviceObject);
561 if (!NT_SUCCESS(Status))
562 {
564 return Status;
565 }
566
567 /* Call the MountMgr */
573 NULL,
574 0,
575 FALSE,
576 &Event,
578 if (Irp == NULL)
579 {
583 }
584
586 if (Status == STATUS_PENDING)
587 {
589 Executive,
591 FALSE,
592 NULL);
594 }
595
598
599 /* Return the MountMgr status */
600 return Status;
601}
struct _MOUNTMGR_CREATE_POINT_INPUT MOUNTMGR_CREATE_POINT_INPUT
#define IOCTL_MOUNTMGR_CREATE_POINT
Definition: imports.h:116
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by HalpNextDriveLetter(), and xHalIoAssignDriveLetters().

◆ IoAssignDriveLetters()

VOID FASTCALL IoAssignDriveLetters ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock,
IN PSTRING  NtDeviceName,
OUT PUCHAR  NtSystemPath,
OUT PSTRING  NtSystemPathString 
)

Definition at line 2631 of file disksup.c.

2635{
2636 HALDISPATCH->HalIoAssignDriveLetters(LoaderBlock,
2637 NtDeviceName,
2638 NtSystemPath,
2639 NtSystemPathString);
2640}

◆ IopComputeHarddiskDerangements()

static PULONG IopComputeHarddiskDerangements ( _In_ ULONG  DiskCount)
static

Definition at line 309 of file disksup.c.

311{
312 PIRP Irp;
314 ULONG i, j, k;
315 PULONG Devices;
317 WCHAR Buffer[100];
318 UNICODE_STRING ArcName;
323
324 /* No disks, nothing to do */
325 if (DiskCount == 0)
326 {
327 return NULL;
328 }
329
330 /* Allocate a buffer big enough to hold all the disks */
332 sizeof(ULONG) * DiskCount,
333 TAG_FSTUB);
334 if (Devices == NULL)
335 {
336 return NULL;
337 }
338
339 /* Now, we'll query all the disks */
340 for (i = 0; i < DiskCount; ++i)
341 {
342 /* Using their ARC name */
343 swprintf(Buffer, L"\\ArcName\\multi(0)disk(0)rdisk(%d)", i);
344 RtlInitUnicodeString(&ArcName, Buffer);
345
346 /* Get the attached DeviceObject */
349 &FileObject,
350 &DeviceObject);
351 if (NT_SUCCESS(Status))
352 {
355
356 /* And query it for device number */
360 NULL,
361 0,
363 sizeof(DeviceNumber),
364 FALSE,
365 &Event,
367 if (Irp != NULL)
368 {
370 if (Status == STATUS_PENDING)
371 {
373 Executive,
375 FALSE,
376 NULL);
378 }
379
381
382 /* In case of a success remember device number */
383 if (NT_SUCCESS(Status))
384 {
385 Devices[i] = DeviceNumber.DeviceNumber;
386 /* Move on, not to fall into our default case */
387 continue;
388 }
389 }
390 else
391 {
393 }
394
395 /* Default case, for failures, set -1 */
396 Devices[i] = -1;
397 }
398 }
399
400 /* Now, we'll check all device numbers */
401 for (i = 0; i < DiskCount; ++i)
402 {
403 /* First of all, check if we're at the right place */
404 for (j = 0; j < DiskCount; ++j)
405 {
406 if (Devices[j] == i)
407 {
408 break;
409 }
410 }
411
412 /* If not, perform the change */
413 if (j >= DiskCount)
414 {
415 k = 0;
416 while (Devices[k] != -1)
417 {
418 if (++k >= DiskCount)
419 {
420 break;
421 }
422 }
423
424 if (k < DiskCount)
425 {
426 Devices[k] = i;
427 }
428 }
429 }
430
431 /* Return our device derangement map */
432 return Devices;
433}
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1230
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
int k
Definition: mpi.c:3369
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
uint32_t * PULONG
Definition: typedefs.h:59
#define POOL_COLD_ALLOCATION

Referenced by xHalIoAssignDriveLetters().

◆ IoReadPartitionTable()

NTSTATUS FASTCALL IoReadPartitionTable ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  SectorSize,
IN BOOLEAN  ReturnRecognizedPartitions,
OUT PDRIVE_LAYOUT_INFORMATION PartitionBuffer 
)

Definition at line 2581 of file disksup.c.

2585{
2586 return HALDISPATCH->HalIoReadPartitionTable(DeviceObject,
2587 SectorSize,
2590}
_In_ ULONG _In_ BOOLEAN ReturnRecognizedPartitions
Definition: iofuncs.h:2051
_In_ ULONG _In_ BOOLEAN _Out_ struct _DRIVE_LAYOUT_INFORMATION ** PartitionBuffer
Definition: iofuncs.h:2052

◆ IoSetPartitionInformation()

NTSTATUS FASTCALL IoSetPartitionInformation ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  SectorSize,
IN ULONG  PartitionNumber,
IN ULONG  PartitionType 
)

Definition at line 2597 of file disksup.c.

2601{
2602 return HALDISPATCH->HalIoSetPartitionInformation(DeviceObject,
2603 SectorSize,
2606}
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2061

◆ IoWritePartitionTable()

NTSTATUS FASTCALL IoWritePartitionTable ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  SectorSize,
IN ULONG  SectorsPerTrack,
IN ULONG  NumberOfHeads,
IN PDRIVE_LAYOUT_INFORMATION  PartitionBuffer 
)

Definition at line 2613 of file disksup.c.

2618{
2619 return HALDISPATCH->HalIoWritePartitionTable(DeviceObject,
2620 SectorSize,
2624}
_In_ ULONG _In_ ULONG _In_ ULONG NumberOfHeads
Definition: iofuncs.h:2072

◆ xHalExamineMBR()

VOID FASTCALL xHalExamineMBR ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  SectorSize,
IN ULONG  MbrTypeIdentifier,
OUT PVOID MbrBuffer 
)

Definition at line 1529 of file disksup.c.

1533{
1535 PUCHAR Buffer;
1537 KEVENT Event;
1539 PIRP Irp;
1540 PPARTITION_DESCRIPTOR PartitionDescriptor;
1543
1544 Offset.QuadPart = 0;
1545
1546 /* Assume failure */
1547 *MbrBuffer = NULL;
1548
1549 /* Normalize the buffer size */
1550 BufferSize = max(512, SectorSize);
1551
1552 /* Allocate the buffer */
1556 if (!Buffer) return;
1557
1558 /* Initialize the Event */
1560
1561 /* Build the IRP */
1564 Buffer,
1565 BufferSize,
1566 &Offset,
1567 &Event,
1568 &IoStatusBlock);
1569 if (!Irp)
1570 {
1571 /* Failed */
1573 return;
1574 }
1575
1576 /* Make sure to override volume verification */
1579
1580 /* Call the driver */
1582 if (Status == STATUS_PENDING)
1583 {
1584 /* Wait for completion */
1587 }
1588
1589 /* Check driver status */
1590 if (NT_SUCCESS(Status))
1591 {
1592 /* Validate the MBR Signature */
1594 {
1595 /* Failed */
1597 return;
1598 }
1599
1600 /* Get the partition entry */
1601 PartitionDescriptor = (PPARTITION_DESCRIPTOR)&Buffer[PARTITION_TABLE_OFFSET];
1602
1603 /* Make sure it's what the caller wanted */
1604 if (PartitionDescriptor->PartitionType != MbrTypeIdentifier)
1605 {
1606 /* It's not, free our buffer */
1608 }
1609 else
1610 {
1611 /* Check for OnTrack Disk Manager 6.0 / EZ-Drive partitions */
1612
1613 if (PartitionDescriptor->PartitionType == PARTITION_DM)
1614 {
1615 /* Return our buffer, but at sector 63 */
1616 *(PULONG)Buffer = 63;
1617 *MbrBuffer = Buffer;
1618 }
1619 else if (PartitionDescriptor->PartitionType == PARTITION_EZDRIVE)
1620 {
1621 /* EZ-Drive, return the buffer directly */
1622 *MbrBuffer = Buffer;
1623 }
1624 else
1625 {
1626 /* Otherwise crash on debug builds */
1627 ASSERT(PartitionDescriptor->PartitionType == PARTITION_EZDRIVE);
1628 }
1629 }
1630 }
1631}
unsigned short * PUINT16
Definition: basetsd.h:186
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PARTITION_EZDRIVE
Definition: ntdddisk.h:289
#define PARTITION_DM
Definition: ntdddisk.h:288
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
struct _PARTITION_DESCRIPTOR * PPARTITION_DESCRIPTOR
#define PARTITION_TABLE_OFFSET
Definition: hal.h:244
#define BOOT_SIGNATURE_OFFSET
Definition: hal.h:245
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
#define BOOT_RECORD_SIGNATURE
Definition: parttest.c:17
#define IRP_MJ_READ
Definition: rdpdr.c:46
UCHAR PartitionType
Definition: hal.h:283
#define max(a, b)
Definition: svc.c:63
unsigned char * PUCHAR
Definition: typedefs.h:53
_In_ PIO_STACK_LOCATION IoStackLocation
Definition: usbdlib.h:265
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823

◆ xHalGetPartialGeometry()

VOID FASTCALL xHalGetPartialGeometry ( IN PDEVICE_OBJECT  DeviceObject,
IN PULONG  ConventionalCylinders,
IN PLONGLONG  DiskSize 
)

Definition at line 1443 of file disksup.c.

1446{
1447 PDISK_GEOMETRY DiskGeometry = NULL;
1449 PKEVENT Event = NULL;
1450 PIRP Irp;
1452
1453 /* Set defaults */
1454 *ConventionalCylinders = 0;
1455 *DiskSize = 0;
1456
1457 /* Allocate the structure in nonpaged pool */
1458 DiskGeometry = ExAllocatePoolWithTag(NonPagedPool,
1459 sizeof(DISK_GEOMETRY),
1461 if (!DiskGeometry) goto Cleanup;
1462
1463 /* Allocate the status block in nonpaged pool */
1465 sizeof(IO_STATUS_BLOCK),
1467 if (!IoStatusBlock) goto Cleanup;
1468
1469 /* Allocate the event in nonpaged pool too */
1471 sizeof(KEVENT),
1473 if (!Event) goto Cleanup;
1474
1475 /* Initialize the event */
1477
1478 /* Build the IRP */
1481 NULL,
1482 0,
1483 DiskGeometry,
1484 sizeof(DISK_GEOMETRY),
1485 FALSE,
1486 Event,
1488 if (!Irp) goto Cleanup;
1489
1490 /* Now call the driver */
1492 if (Status == STATUS_PENDING)
1493 {
1494 /* Wait for it to complete */
1497 }
1498
1499 /* Check driver status */
1500 if (NT_SUCCESS(Status))
1501 {
1502 /* Return the cylinder count */
1503 *ConventionalCylinders = DiskGeometry->Cylinders.LowPart;
1504
1505 /* Make sure it's not larger than 1024 */
1506 if (DiskGeometry->Cylinders.LowPart >= 1024)
1507 {
1508 /* Otherwise, normalize the value */
1509 *ConventionalCylinders = 1024;
1510 }
1511
1512 /* Calculate the disk size */
1513 *DiskSize = DiskGeometry->Cylinders.QuadPart *
1514 DiskGeometry->TracksPerCylinder *
1515 DiskGeometry->SectorsPerTrack *
1516 DiskGeometry->BytesPerSector;
1517 }
1518
1519Cleanup:
1520 /* Free all the pointers */
1523 if (DiskGeometry) ExFreePoolWithTag(DiskGeometry, TAG_FILE_SYSTEM);
1524 return;
1525}
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
static const WCHAR Cleanup[]
Definition: register.c:80
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:400
ULONG TracksPerCylinder
Definition: ntdddisk.h:402
ULONG SectorsPerTrack
Definition: ntdddisk.h:403
ULONG BytesPerSector
Definition: ntdddisk.h:404

Referenced by xHalIoWritePartitionTable().

◆ xHalIoAssignDriveLetters()

VOID FASTCALL xHalIoAssignDriveLetters ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock,
IN PSTRING  NtDeviceName,
OUT PUCHAR  NtSystemPath,
OUT PSTRING  NtSystemPathString 
)

Definition at line 890 of file disksup.c.

894{
895 PULONG Devices;
898 UCHAR DriveLetter;
899 BOOLEAN BootableFound;
900 IO_STATUS_BLOCK StatusBlock;
902 PSTR LoadOptions;
904 PDRIVE_LAYOUT_INFORMATION LayoutInfo;
907 ULONG i, Increment, DiskCount, RealDiskCount, HarddiskCount, PartitionCount;
908 ULONG SkipPartition;
909 PWSTR Buffer2;
910 WCHAR Buffer[sizeof("\\Device\\Harddisk4294967295\\Partition4294967295")];
911
912 PAGED_CODE();
913
914 /* Get our disk count */
915 ConfigInfo = IoGetConfigurationInformation();
916 DiskCount = ConfigInfo->DiskCount;
917 RealDiskCount = 0;
918
919 /* Allocate a generic string buffer we'll use later on */
920 Buffer2 = ExAllocatePoolWithTag(NonPagedPool, 40 * sizeof(WCHAR), TAG_FSTUB);
921 if (Buffer2 == NULL)
922 {
923 /* We cannot fail */
924 KeBugCheck(ASSIGN_DRIVE_LETTERS_FAILED);
925 }
926
927 /* In case of a remote boot, setup the system path */
929 {
930 PSTR Last, Saved;
931
932 /* Find the last separator */
933 Last = strrchr(LoaderBlock->NtBootPathName, '\\');
934 Saved = NULL;
935 if (Last == NULL)
936 {
937 /* Misformed name, fail */
938 KeBugCheck(ASSIGN_DRIVE_LETTERS_FAILED);
939 }
940
941 /* In case the name was terminated by a separator... */
942 if (Last[1] == ANSI_NULL)
943 {
944 /* Erase it, save its position and find the previous separator */
945 *Last = ANSI_NULL;
946 Saved = Last;
947 Last = strrchr(LoaderBlock->NtBootPathName, '\\');
948 *Saved = '\\';
949 }
950
951 if (Last == NULL)
952 {
953 /* Misformed name, fail */
954 KeBugCheck(ASSIGN_DRIVE_LETTERS_FAILED);
955 }
956
957 /* For a remote boot, assign X drive letter */
958 NtSystemPath[0] = 'X';
959 NtSystemPath[1] = ':';
960 /* And copy the end of the boot path */
961 strcpy((PSTR)&NtSystemPath[2], Last);
962
963 /* If we had to remove the trailing separator, remove it here too */
964 if (Saved != NULL)
965 {
966 NtSystemPath[strlen((PSTR)NtSystemPath) - 1] = ANSI_NULL;
967 }
968
969 /* Setup the system path string */
970 RtlInitString(NtSystemPathString, (PSTR)NtSystemPath);
971 }
972
973 /* For each disk, create the physical drive DOS device */
974 Increment = 0;
975 for (i = 0; i < DiskCount; ++i)
976 {
977 /* Setup the device name */
978 swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition0", i);
980
981 /* Open the device */
983 &DeviceName,
985 NULL,
986 NULL);
990 &StatusBlock,
993 if (NT_SUCCESS(Status))
994 {
995 /* If we succeeded, create the link */
996 UNICODE_STRING LinkName;
997 swprintf(Buffer2, L"\\DosDevices\\PhysicalDrive%d", i);
998 RtlInitUnicodeString(&LinkName, Buffer2);
999
1000 IoCreateSymbolicLink(&LinkName, &DeviceName);
1002
1003 RealDiskCount = i + 1;
1004 }
1005 else
1006 {
1007 /* Try to cope with holes in the \Device\HarddiskX namespace */
1008 if (Increment < 50)
1009 {
1010 ++Increment;
1011 ++DiskCount;
1012 }
1013 }
1014 }
1015
1016 /* We are done with the buffer */
1017 ExFreePoolWithTag(Buffer2, TAG_FSTUB);
1018
1019 /* Upcase the load options, if any */
1020 if (LoaderBlock->LoadOptions != NULL)
1021 LoadOptions = _strupr(LoaderBlock->LoadOptions);
1022 else
1023 LoadOptions = NULL;
1024
1025 /* If we boot with MININT option (system hive as volatile),
1026 * assign the X letter to the OS boot volume. */
1027 if (LoadOptions != NULL &&
1028 strstr(LoadOptions, "MININT") != NULL &&
1030 {
1032 *NtSystemPath = 'X';
1033
1035 }
1036
1037 /* Compute the disks derangements */
1038 DiskCount -= Increment;
1039 DiskCount = max(DiskCount, RealDiskCount);
1040 Devices = IopComputeHarddiskDerangements(DiskCount);
1041
1042 /* Now, start browsing all the disks for assigning drive letters.
1043 * Here, we'll only handle the bootable and primary partitions. */
1044 for (i = 0; i < DiskCount; ++i)
1045 {
1046 /* Get the device ID from the derangements map */
1047 HarddiskCount = (Devices ? Devices[i] : i);
1048
1049 /* Query the disk layout */
1050 swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition0", HarddiskCount);
1052 Status = HalpQueryDriveLayout(&DeviceName, &LayoutInfo);
1053 if (!NT_SUCCESS(Status))
1054 LayoutInfo = NULL;
1055
1056 /* Assume we didn't find a bootable partition */
1057 BootableFound = FALSE;
1058 for (PartitionCount = 1; ; ++PartitionCount)
1059 {
1060 swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition%d", HarddiskCount, PartitionCount);
1063 if (!NT_SUCCESS(Status))
1064 {
1065 /* It failed, retry for all the partitions */
1066 break;
1067 }
1068
1069 /* If the partition is bootable (MBR) or data (GPT), we've found it */
1071 {
1072 BootableFound = TRUE;
1073
1074 /* Assign a drive letter and stop here if MBR */
1075 HalpNextDriveLetter(&DeviceName, NtDeviceName, NtSystemPath, FALSE);
1077 break;
1078 }
1079 /* Keep looping on all the partitions */
1080 }
1081
1082 /* Mount every primary partition if we didn't find a bootable partition */
1083 if (!BootableFound)
1084 {
1085 for (PartitionCount = 1; ; ++PartitionCount)
1086 {
1087 swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition%d", HarddiskCount, PartitionCount);
1090 if (!NT_SUCCESS(Status))
1091 break;
1092
1093 /* We found a primary partition, assign a drive letter */
1095 {
1096 HalpNextDriveLetter(&DeviceName, NtDeviceName, NtSystemPath, FALSE);
1097 break;
1098 }
1099 }
1100 }
1101
1102 /* Free the layout, we'll reallocate it for the next disk */
1103 if (LayoutInfo != NULL)
1104 ExFreePoolWithTag(LayoutInfo, TAG_FSTUB);
1105 }
1106
1107 /* Now, assign drive letters to logical partitions */
1108 for (i = 0; i < DiskCount; ++i)
1109 {
1110 /* Get the device ID from the derangements map */
1111 HarddiskCount = (Devices ? Devices[i] : i);
1112
1113 /* Query the disk layout */
1114 swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition0", HarddiskCount);
1116 Status = HalpQueryDriveLayout(&DeviceName, &LayoutInfo);
1117 if (!NT_SUCCESS(Status))
1118 LayoutInfo = NULL;
1119
1120 /* And assign drive letters to logical partitions */
1121 for (PartitionCount = 1; ; ++PartitionCount)
1122 {
1123 swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition%d", HarddiskCount, PartitionCount);
1126 if (!NT_SUCCESS(Status))
1127 break;
1128
1130 {
1131 HalpNextDriveLetter(&DeviceName, NtDeviceName, NtSystemPath, FALSE);
1132 }
1133 }
1134
1135 /* Free the layout, we'll reallocate it for the next disk */
1136 if (LayoutInfo != NULL)
1137 ExFreePoolWithTag(LayoutInfo, TAG_FSTUB);
1138 }
1139
1140 /* Now, assign drive letters to everything else */
1141 for (i = 0; i < DiskCount; ++i)
1142 {
1143 /* Get the device ID from the derangements map */
1144 HarddiskCount = (Devices ? Devices[i] : i);
1145
1146 /* Query the disk layout */
1147 swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition0", HarddiskCount);
1149 Status = HalpQueryDriveLayout(&DeviceName, &LayoutInfo);
1150 if (!NT_SUCCESS(Status))
1151 LayoutInfo = NULL;
1152
1153 /* Save the bootable or first primary (MBR) partition, if any */
1154 SkipPartition = 0;
1155 for (PartitionCount = 1; ; ++PartitionCount)
1156 {
1157 swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition%d", HarddiskCount, PartitionCount);
1160 if (!NT_SUCCESS(Status))
1161 break;
1162
1164 ((PartitionType == PrimaryPartition) && (SkipPartition == 0)))
1165 {
1166 SkipPartition = PartitionCount;
1167 }
1168 }
1169
1170 /* And assign a drive letter to anything but the bootable partition */
1171 for (PartitionCount = 1; ; ++PartitionCount)
1172 {
1173 if (PartitionCount == SkipPartition)
1174 continue;
1175
1176 swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition%d", HarddiskCount, PartitionCount);
1179 if (!NT_SUCCESS(Status))
1180 break;
1181
1183 {
1184 HalpNextDriveLetter(&DeviceName, NtDeviceName, NtSystemPath, FALSE);
1185 }
1186 }
1187
1188 /* Free the layout, we'll reallocate it for the next disk */
1189 if (LayoutInfo != NULL)
1190 ExFreePoolWithTag(LayoutInfo, TAG_FSTUB);
1191 }
1192
1193 /* We're done with the disks; free the derangements map */
1194 if (Devices != NULL)
1195 ExFreePoolWithTag(Devices, TAG_FSTUB);
1196
1197 /* Now, assign drive letters to floppy devices:
1198 * first for legacy, then for MountMgr-aware ones. */
1199 for (i = 0; i < ConfigInfo->FloppyCount; ++i)
1200 {
1201 swprintf(Buffer, L"\\Device\\Floppy%d", i);
1203 if (HalpIsOldStyleFloppy(&DeviceName)) // Legacy device
1204 HalpNextDriveLetter(&DeviceName, NtDeviceName, NtSystemPath, TRUE);
1205 }
1206 for (i = 0; i < ConfigInfo->FloppyCount; ++i)
1207 {
1208 swprintf(Buffer, L"\\Device\\Floppy%d", i);
1210 if (!HalpIsOldStyleFloppy(&DeviceName)) // MountMgr-aware device
1211 HalpNextDriveLetter(&DeviceName, NtDeviceName, NtSystemPath, TRUE);
1212 }
1213
1214 /* And CD-ROM drives */
1215 for (i = 0; i < ConfigInfo->CdRomCount; ++i)
1216 {
1217 swprintf(Buffer, L"\\Device\\CdRom%d", i);
1219 HalpNextDriveLetter(&DeviceName, NtDeviceName, NtSystemPath, TRUE);
1220 }
1221
1222 /* If not remote boot, handle NtDeviceName */
1224 {
1225 /* Assign it a drive letter */
1226 DriveLetter = HalpNextDriveLetter(&DeviceName, NULL, NULL, TRUE);
1227 if (DriveLetter != 0)
1228 {
1229 if (DriveLetter != 0xFF)
1230 *NtSystemPath = DriveLetter;
1231 }
1232 /* If it fails through the MountMgr, retry manually */
1233 else
1234 {
1236 DriveLetter = 'A'; /* If floppy, start at A */
1238 DriveLetter = 'D'; /* If CD-ROM, start at D */
1239 else
1240 DriveLetter = 'C'; /* Otherwise, start at C */
1241
1242 /* Try any drive letter */
1243 while (HalpSetMountLetter(&DeviceName, DriveLetter) != STATUS_SUCCESS)
1244 {
1245 ++DriveLetter;
1246 if (DriveLetter > 'Z')
1247 break;
1248 }
1249
1250 /* If we're beyond Z (no letter left), delete Z and
1251 * reuse it for the OS boot volume (SystemRoot) */
1252 if (DriveLetter > 'Z')
1253 {
1254 DriveLetter = 'Z';
1255 HalpDeleteMountLetter(DriveLetter);
1256 HalpSetMountLetter(&DeviceName, DriveLetter);
1257 }
1258
1259 /* Return the matching drive letter */
1260 *NtSystemPath = DriveLetter;
1261 }
1262
1264 }
1265
1266 /* Enable auto assignment for MountMgr */
1268}
unsigned char BOOLEAN
Definition: actypes.h:127
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1434
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
static NTSTATUS HalpQueryDriveLayout(_In_ PUNICODE_STRING DeviceName, _Outptr_ PDRIVE_LAYOUT_INFORMATION *LayoutInfo)
Definition: disksup.c:46
static VOID HalpEnableAutomaticDriveLetterAssignment(VOID)
Definition: disksup.c:835
static PULONG IopComputeHarddiskDerangements(_In_ ULONG DiskCount)
Definition: disksup.c:309
static BOOLEAN HalpIsOldStyleFloppy(_In_ PUNICODE_STRING DeviceName)
Definition: disksup.c:683
static NTSTATUS HalpDeleteMountLetter(_In_ UCHAR DriveLetter)
Definition: disksup.c:743
static NTSTATUS HalpQueryPartitionType(_In_ PUNICODE_STRING DeviceName, _In_opt_ PDRIVE_LAYOUT_INFORMATION LayoutInfo, _Out_ PPARTITION_TYPE PartitionType)
Definition: disksup.c:156
static UCHAR HalpNextDriveLetter(_In_ PUNICODE_STRING DeviceName, _In_ PSTRING NtDeviceName, _Out_ PUCHAR NtSystemPath, _In_ BOOLEAN IsRemovable)
Definition: disksup.c:604
#define FILE_SHARE_READ
Definition: compat.h:136
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP char *__cdecl strstr(const char *, const char *)
Definition: string.c:3415
_ACRTIMP char *__cdecl strrchr(const char *, int)
Definition: string.c:3298
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:46
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Returns a pointer to the I/O manager's global configuration information structure.
Definition: iorsrce.c:998
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_DATA
Definition: nt_native.h:628
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
#define ANSI_NULL
BOOLEAN IoRemoteBootClient
Definition: init.c:70
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_strupr
Definition: string.h:453
strcpy
Definition: string.h:131
uint16_t * PWSTR
Definition: typedefs.h:56
char * PSTR
Definition: typedefs.h:51

◆ xHalIoReadPartitionTable()

NTSTATUS FASTCALL xHalIoReadPartitionTable ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  SectorSize,
IN BOOLEAN  ReturnRecognizedPartitions,
OUT PDRIVE_LAYOUT_INFORMATION PartitionBuffer 
)

Definition at line 1654 of file disksup.c.

1658{
1659 KEVENT Event;
1661 PIRP Irp;
1662 PPARTITION_DESCRIPTOR PartitionDescriptor;
1663 CCHAR Entry;
1666 PUCHAR Buffer = NULL;
1667 ULONG BufferSize = 2048, InputSize;
1668 PDRIVE_LAYOUT_INFORMATION DriveLayoutInfo = NULL;
1669 LONG j = -1, i = -1, k;
1670 DISK_GEOMETRY_EX DiskGeometryEx;
1671 LONGLONG EndSector, MaxSector, StartOffset;
1672 LARGE_INTEGER Offset, VolumeOffset;
1673 BOOLEAN IsPrimary = TRUE, IsEzDrive = FALSE, MbrFound = FALSE;
1674 BOOLEAN IsValid, IsEmpty = TRUE;
1675 PVOID MbrBuffer;
1678 LARGE_INTEGER HiddenSectors64;
1679
1680 PAGED_CODE();
1681
1682 VolumeOffset.QuadPart = Offset.QuadPart = 0;
1683
1684 /* Allocate the buffer */
1686 BufferSize,
1689
1690 /* Normalize the buffer size */
1691 InputSize = max(512, SectorSize);
1692
1693 /* Check for EZ-Drive */
1694 HalExamineMBR(DeviceObject, InputSize, PARTITION_EZDRIVE, &MbrBuffer);
1695 if (MbrBuffer)
1696 {
1697 /* EZ-Drive found, bias the offset */
1698 IsEzDrive = TRUE;
1700 Offset.QuadPart = 512;
1701 }
1702
1703 /* Get drive geometry */
1704 Status = HalpGetFullGeometry(DeviceObject, &DiskGeometryEx);
1705 if (!NT_SUCCESS(Status))
1706 {
1709 return Status;
1710 }
1711
1712 /* Get the end and maximum sector */
1713 EndSector = DiskGeometryEx.DiskSize.QuadPart / DiskGeometryEx.Geometry.BytesPerSector;
1714 MaxSector = EndSector << 1;
1715 DPRINT("FSTUB: DiskSize = %#I64x, MaxSector = %#I64x\n",
1716 DiskGeometryEx.DiskSize, MaxSector);
1717
1718 /* Allocate our buffer */
1720 if (!Buffer)
1721 {
1722 /* Fail, free the input buffer */
1726 }
1727
1728 /* Start partition loop */
1729 do
1730 {
1731 /* Assume the partition is valid */
1732 IsValid = TRUE;
1733
1734 /* Initialize the event */
1736
1737 /* Clear the buffer and build the IRP */
1738 RtlZeroMemory(Buffer, InputSize);
1741 Buffer,
1742 InputSize,
1743 &Offset,
1744 &Event,
1745 &IoStatusBlock);
1746 if (!Irp)
1747 {
1748 /* Failed */
1750 break;
1751 }
1752
1753 /* Make sure to disable volume verification */
1756
1757 /* Call the driver */
1759 if (Status == STATUS_PENDING)
1760 {
1761 /* Wait for completion */
1764 }
1765
1766 /* Normalize status code and check for failure */
1768 if (!NT_SUCCESS(Status)) break;
1769
1770 /* If we biased for EZ-Drive, unbias now */
1771 if (IsEzDrive && (Offset.QuadPart == 512)) Offset.QuadPart = 0;
1772
1773 /* Make sure this is a valid MBR */
1775 {
1776 /* It's not, fail */
1777 DPRINT1("FSTUB: (IoReadPartitionTable) No 0xaa55 found in "
1778 "partition table %d\n", j + 1);
1779 break;
1780 }
1781
1782 /* At this point we have a valid MBR */
1783 MbrFound = TRUE;
1784
1785 /* Check if we weren't given an offset */
1786 if (!Offset.QuadPart)
1787 {
1788 /* Then read the signature off the disk */
1789 (*PartitionBuffer)->Signature = *(PUINT32)&Buffer[DISK_SIGNATURE_OFFSET];
1790 }
1791
1792 /* Get the partition descriptor array */
1793 PartitionDescriptor = (PPARTITION_DESCRIPTOR)&Buffer[PARTITION_TABLE_OFFSET];
1794
1795 /* Start looping partitions */
1796 j++;
1797 DPRINT("FSTUB: Partition Table %d:\n", j);
1798 for (Entry = 1, k = 0; Entry <= NUM_PARTITION_TABLE_ENTRIES; Entry++, PartitionDescriptor++)
1799 {
1800 /* Get the partition type */
1801 PartitionType = PartitionDescriptor->PartitionType;
1802
1803 /* Print debug messages */
1804 DPRINT("Partition Entry %d,%d: type %#x %s\n",
1805 j,
1806 Entry,
1808 (PartitionDescriptor->ActiveFlag) ? "Active" : "");
1809 DPRINT("\tOffset %#08lx for %#08lx Sectors\n",
1810 GET_STARTING_SECTOR(PartitionDescriptor),
1811 GET_PARTITION_LENGTH(PartitionDescriptor));
1812
1813 /* Check whether we're facing a protective MBR */
1815 {
1816 /* Partition length might be bigger than disk size */
1817 FstubFixupEfiPartition(PartitionDescriptor, DiskGeometryEx.DiskSize.QuadPart);
1818 }
1819
1820 /* Make sure that the partition is valid, unless it's the first */
1821 if (!(HalpIsValidPartitionEntry(PartitionDescriptor,
1822 DiskGeometryEx.DiskSize.QuadPart,
1823 MaxSector)) && (j == 0))
1824 {
1825 /* It's invalid, so fail */
1826 IsValid = FALSE;
1827 break;
1828 }
1829
1830 /* Check if it's a container */
1832 {
1833 /* Increase the count of containers */
1834 if (++k != 1)
1835 {
1836 /* More than one table is invalid */
1837 DPRINT1("FSTUB: Multiple container partitions found in "
1838 "partition table %d\n - table is invalid\n",
1839 j);
1840 IsValid = FALSE;
1841 break;
1842 }
1843 }
1844
1845 /* Check if the partition is supposedly empty */
1846 if (IsEmpty)
1847 {
1848 /* But check if it actually has a start and/or length */
1849 if ((GET_STARTING_SECTOR(PartitionDescriptor)) ||
1850 (GET_PARTITION_LENGTH(PartitionDescriptor)))
1851 {
1852 /* So then it's not really empty */
1853 IsEmpty = FALSE;
1854 }
1855 }
1856
1857 /* Check if the caller wanted only recognized partitions */
1859 {
1860 /* Then check if this one is unused, or a container */
1863 {
1864 /* Skip it, since the caller doesn't want it */
1865 continue;
1866 }
1867 }
1868
1869 /* Increase the structure count and check if they can fit */
1870 if ((sizeof(DRIVE_LAYOUT_INFORMATION) +
1871 (++i * sizeof(PARTITION_INFORMATION))) >
1872 BufferSize)
1873 {
1874 /* Allocate a new buffer that's twice as big */
1875 DriveLayoutInfo = ExAllocatePoolWithTag(NonPagedPool,
1876 BufferSize << 1,
1878 if (!DriveLayoutInfo)
1879 {
1880 /* Out of memory, undo this extra structure */
1881 --i;
1883 break;
1884 }
1885
1886 /* Copy the contents of the old buffer */
1887 RtlMoveMemory(DriveLayoutInfo,
1889 BufferSize);
1890
1891 /* Free the old buffer and set this one as the new one */
1893 *PartitionBuffer = DriveLayoutInfo;
1894
1895 /* Double the size */
1896 BufferSize <<= 1;
1897 }
1898
1899 /* Now get the current structure being filled and initialize it */
1900 PartitionInfo = &(*PartitionBuffer)->PartitionEntry[i];
1901 PartitionInfo->PartitionType = PartitionType;
1902 PartitionInfo->RewritePartition = FALSE;
1903
1904 /* Check if we're dealing with a partition that's in use */
1906 {
1907 /* Check if it's bootable */
1908 PartitionInfo->BootIndicator = !!(PartitionDescriptor->ActiveFlag & 0x80);
1909
1910 /* Check if it's a container */
1912 {
1913 /* Then don't recognize it and use the volume offset */
1914 PartitionInfo->RecognizedPartition = FALSE;
1915 StartOffset = VolumeOffset.QuadPart;
1916 }
1917 else
1918 {
1919 /* Then recognize it and use the partition offset */
1920 PartitionInfo->RecognizedPartition = TRUE;
1921 StartOffset = Offset.QuadPart;
1922 }
1923
1924 /* Get the starting offset */
1925 PartitionInfo->StartingOffset.QuadPart =
1926 StartOffset +
1927 UInt32x32To64(GET_STARTING_SECTOR(PartitionDescriptor),
1928 SectorSize);
1929
1930 /* Calculate the number of hidden sectors */
1931 HiddenSectors64.QuadPart = (PartitionInfo->
1932 StartingOffset.QuadPart -
1933 StartOffset) /
1934 SectorSize;
1935 PartitionInfo->HiddenSectors = HiddenSectors64.LowPart;
1936
1937 /* Get the partition length */
1938 PartitionInfo->PartitionLength.QuadPart =
1939 UInt32x32To64(GET_PARTITION_LENGTH(PartitionDescriptor),
1940 SectorSize);
1941
1942 /* Get the partition number */
1943 /* FIXME: REACTOS HACK -- Needed for xHalIoAssignDriveLetters() */
1944 PartitionInfo->PartitionNumber = (!IsContainerPartition(PartitionType)) ? i + 1 : 0;
1945 }
1946 else
1947 {
1948 /* Otherwise, clear all the relevant fields */
1949 PartitionInfo->BootIndicator = FALSE;
1950 PartitionInfo->RecognizedPartition = FALSE;
1951 PartitionInfo->StartingOffset.QuadPart = 0;
1952 PartitionInfo->PartitionLength.QuadPart = 0;
1953 PartitionInfo->HiddenSectors = 0;
1954
1955 /* FIXME: REACTOS HACK -- Needed for xHalIoAssignDriveLetters() */
1956 PartitionInfo->PartitionNumber = 0;
1957 }
1958 }
1959
1960 /* Finish debug log, and check for failure */
1961 DPRINT("\n");
1962 if (!NT_SUCCESS(Status)) break;
1963
1964 /* Also check if we hit an invalid entry here */
1965 if (!IsValid)
1966 {
1967 /* We did, so break out of the loop minus one entry */
1968 j--;
1969 break;
1970 }
1971
1972 /* Reset the offset */
1973 Offset.QuadPart = 0;
1974
1975 /* Go back to the descriptor array and loop it */
1976 PartitionDescriptor = (PPARTITION_DESCRIPTOR)&Buffer[PARTITION_TABLE_OFFSET];
1977 for (Entry = 1; Entry <= NUM_PARTITION_TABLE_ENTRIES; Entry++, PartitionDescriptor++)
1978 {
1979 /* Check if this is a container partition, since we skipped them */
1980 if (IsContainerPartition(PartitionDescriptor->PartitionType))
1981 {
1982 /* Get its offset */
1983 Offset.QuadPart = VolumeOffset.QuadPart +
1985 GET_STARTING_SECTOR(PartitionDescriptor),
1986 SectorSize);
1987
1988 /* If this is a primary partition, this is the volume offset */
1989 if (IsPrimary) VolumeOffset = Offset;
1990
1991 /* Also update the maximum sector */
1992 MaxSector = GET_PARTITION_LENGTH(PartitionDescriptor);
1993 DPRINT1("FSTUB: MaxSector now = %I64d\n", MaxSector);
1994 break;
1995 }
1996 }
1997
1998 /* Loop the next partitions, which are not primary anymore */
1999 IsPrimary = FALSE;
2000 } while (Offset.HighPart | Offset.LowPart);
2001
2002 /* Check if this is a removable device that's probably a super-floppy */
2003 if ((DiskGeometryEx.Geometry.MediaType == RemovableMedia) &&
2004 (j == 0) && (MbrFound) && (IsEmpty))
2005 {
2006 PBOOT_SECTOR_INFO BootSectorInfo = (PBOOT_SECTOR_INFO)Buffer;
2007
2008 /* Read the jump bytes to detect super-floppy */
2009 if ((BootSectorInfo->JumpByte[0] == 0xeb) ||
2010 (BootSectorInfo->JumpByte[0] == 0xe9))
2011 {
2012 /* Super floppes don't have typical MBRs, so skip them */
2013 DPRINT1("FSTUB: Jump byte %#x found along with empty partition "
2014 "table - disk is a super floppy and has no valid MBR\n",
2015 BootSectorInfo->JumpByte);
2016 j = -1;
2017 }
2018 }
2019
2020 /* Check if we're still at partition -1 */
2021 if (j == -1)
2022 {
2023 /* The likely cause is the super floppy detection above */
2024 if ((MbrFound) || (DiskGeometryEx.Geometry.MediaType == RemovableMedia))
2025 {
2026 /* Print out debugging information */
2027 DPRINT1("FSTUB: Drive %#p has no valid MBR. Make it into a "
2028 "super-floppy\n",
2029 DeviceObject);
2030 DPRINT1("FSTUB: Drive has %I64d sectors and is %#016I64x "
2031 "bytes large\n",
2032 EndSector, DiskGeometryEx.DiskSize);
2033
2034 /* We should at least have some sectors */
2035 if (EndSector > 0)
2036 {
2037 /* Get the entry we'll use */
2038 PartitionInfo = &(*PartitionBuffer)->PartitionEntry[0];
2039
2040 /* Fill it out with data for a super-floppy */
2041 PartitionInfo->RewritePartition = FALSE;
2042 PartitionInfo->RecognizedPartition = TRUE;
2043 PartitionInfo->PartitionType = PARTITION_FAT_16;
2044 PartitionInfo->BootIndicator = FALSE;
2045 PartitionInfo->HiddenSectors = 0;
2046 PartitionInfo->StartingOffset.QuadPart = 0;
2047 PartitionInfo->PartitionLength = DiskGeometryEx.DiskSize;
2048
2049 /* FIXME: REACTOS HACK -- Needed for xHalIoAssignDriveLetters() */
2050 PartitionInfo->PartitionNumber = 0;
2051
2052 /* Set the signature and set the count back to 0 */
2053 (*PartitionBuffer)->Signature = 1;
2054 i = 0;
2055 }
2056 }
2057 else
2058 {
2059 /* Otherwise, this isn't a super floppy, so set an invalid count */
2060 i = -1;
2061 }
2062 }
2063
2064 /* Set the partition count */
2065 (*PartitionBuffer)->PartitionCount = ++i;
2066
2067 /* If we have no count, delete the signature */
2068 if (!i) (*PartitionBuffer)->Signature = 0;
2069
2070 /* Free the buffer and check for success */
2072 if (!NT_SUCCESS(Status))
2073 {
2076 }
2077
2078 /* Return status */
2079 return Status;
2080}
unsigned int * PUINT32
Definition: basetsd.h:119
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:291
static BOOLEAN HalpIsValidPartitionEntry(_In_ PPARTITION_DESCRIPTOR Entry, _In_ ULONGLONG MaxOffset, _In_ ULONGLONG MaxSector)
Definition: disksup.c:1323
VOID NTAPI FstubFixupEfiPartition(IN PPARTITION_DESCRIPTOR PartitionDescriptor, IN ULONGLONG MaxOffset)
Definition: disksup.c:1635
#define EFI_PMBR_OSTYPE_EFI
Definition: disksup.c:21
static NTSTATUS HalpGetFullGeometry(_In_ PDEVICE_OBJECT DeviceObject, _Out_ PDISK_GEOMETRY_EX Geometry)
Definition: disksup.c:1271
@ IsEmpty
Definition: atl_ax.c:995
#define NonPagedPoolCacheAligned
Definition: env_spec_w32.h:310
#define UInt32x32To64(a, b)
Definition: intsafe.h:252
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:321
@ RemovableMedia
Definition: ntdddisk.h:382
#define DISK_SIGNATURE_OFFSET
Definition: hal.h:243
struct _BOOT_SECTOR_INFO * PBOOT_SECTOR_INFO
#define PARTITION_FAT_16
Definition: part_mbr.h:54
#define HalExamineMBR
Definition: part_xbox.c:325
long LONG
Definition: pedump.c:60
UCHAR JumpByte[1]
Definition: hal.h:302
DISK_GEOMETRY Geometry
Definition: winioctl.h:530
LARGE_INTEGER DiskSize
Definition: winioctl.h:531
MEDIA_TYPE MediaType
Definition: ntdddisk.h:401
UCHAR ActiveFlag
Definition: hal.h:279
int64_t LONGLONG
Definition: typedefs.h:68
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
char CCHAR
Definition: typedefs.h:51
#define STATUS_NO_DATA_DETECTED
Definition: udferr_usr.h:131

◆ xHalIoSetPartitionInformation()

NTSTATUS FASTCALL xHalIoSetPartitionInformation ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  SectorSize,
IN ULONG  PartitionNumber,
IN ULONG  PartitionType 
)

Definition at line 2084 of file disksup.c.

2088{
2089 PIRP Irp;
2090 KEVENT Event;
2093 LARGE_INTEGER Offset, VolumeOffset;
2094 PUCHAR Buffer = NULL;
2096 ULONG i = 0;
2097 ULONG Entry;
2098 PPARTITION_DESCRIPTOR PartitionDescriptor;
2099 BOOLEAN IsPrimary = TRUE, IsEzDrive = FALSE;
2100 PVOID MbrBuffer;
2102
2103 PAGED_CODE();
2104
2105 VolumeOffset.QuadPart = Offset.QuadPart = 0;
2106
2107 /* Normalize the buffer size */
2108 BufferSize = max(512, SectorSize);
2109
2110 /* Check for EZ-Drive */
2112 if (MbrBuffer)
2113 {
2114 /* EZ-Drive found, bias the offset */
2115 IsEzDrive = TRUE;
2117 Offset.QuadPart = 512;
2118 }
2119
2120 /* Allocate our partition buffer */
2123
2124 /* Initialize the event we'll use and loop partitions */
2126 do
2127 {
2128 /* Reset the event since we reuse it */
2130
2131 /* Build the read IRP */
2134 Buffer,
2135 BufferSize,
2136 &Offset,
2137 &Event,
2138 &IoStatusBlock);
2139 if (!Irp)
2140 {
2141 /* Fail */
2143 break;
2144 }
2145
2146 /* Make sure to disable volume verification */
2149
2150 /* Call the driver */
2152 if (Status == STATUS_PENDING)
2153 {
2154 /* Wait for completion */
2157 }
2158
2159 /* Check for failure */
2160 if (!NT_SUCCESS(Status)) break;
2161
2162 /* If we biased for EZ-Drive, unbias now */
2163 if (IsEzDrive && (Offset.QuadPart == 512)) Offset.QuadPart = 0;
2164
2165 /* Make sure this is a valid MBR */
2167 {
2168 /* It's not, fail */
2170 break;
2171 }
2172
2173 /* Get the partition descriptors and loop them */
2174 PartitionDescriptor = (PPARTITION_DESCRIPTOR)&Buffer[PARTITION_TABLE_OFFSET];
2175 for (Entry = 1; Entry <= NUM_PARTITION_TABLE_ENTRIES; Entry++, PartitionDescriptor++)
2176 {
2177 /* Check if it's unused or a container partition */
2178 if ((PartitionDescriptor->PartitionType == PARTITION_ENTRY_UNUSED) ||
2179 (IsContainerPartition(PartitionDescriptor->PartitionType)))
2180 {
2181 /* Go to the next one */
2182 continue;
2183 }
2184
2185 /* It's a valid partition, so increase the partition count */
2186 if (++i == PartitionNumber)
2187 {
2188 /* We found a match, set the type */
2189 PartitionDescriptor->PartitionType = (UCHAR)PartitionType;
2190
2191 /* Reset the reusable event */
2193
2194 /* Build the write IRP */
2197 Buffer,
2198 BufferSize,
2199 &Offset,
2200 &Event,
2201 &IoStatusBlock);
2202 if (!Irp)
2203 {
2204 /* Fail */
2206 break;
2207 }
2208
2209 /* Disable volume verification */
2212
2213 /* Call the driver */
2215 if (Status == STATUS_PENDING)
2216 {
2217 /* Wait for completion */
2219 Executive,
2220 KernelMode,
2221 FALSE,
2222 NULL);
2224 }
2225
2226 /* We're done, break out of the loop */
2227 break;
2228 }
2229 }
2230
2231 /* If we looped all the partitions, break out */
2232 if (Entry <= NUM_PARTITION_TABLE_ENTRIES) break;
2233
2234 /* Nothing found yet, get the partition array again */
2235 PartitionDescriptor = (PPARTITION_DESCRIPTOR)&Buffer[PARTITION_TABLE_OFFSET];
2236 for (Entry = 1; Entry <= NUM_PARTITION_TABLE_ENTRIES; Entry++, PartitionDescriptor++)
2237 {
2238 /* Check if this was a container partition (we skipped these) */
2239 if (IsContainerPartition(PartitionDescriptor->PartitionType))
2240 {
2241 /* Update the partition offset */
2242 Offset.QuadPart = VolumeOffset.QuadPart +
2243 GET_STARTING_SECTOR(PartitionDescriptor) *
2244 SectorSize;
2245
2246 /* If this was the primary partition, update the volume too */
2247 if (IsPrimary) VolumeOffset = Offset;
2248 break;
2249 }
2250 }
2251
2252 /* Check if we already searched all the partitions */
2254 {
2255 /* Then we failed to find a good MBR */
2257 break;
2258 }
2259
2260 /* Loop the next partitions, which are not primary anymore */
2261 IsPrimary = FALSE;
2262 } while (i < PartitionNumber);
2263
2264 /* Everything done, cleanup */
2266 return Status;
2267}
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define STATUS_BAD_MASTER_BOOT_RECORD
Definition: ntstatus.h:499
#define IRP_MJ_WRITE
Definition: rdpdr.c:47

◆ xHalIoWritePartitionTable()

NTSTATUS FASTCALL xHalIoWritePartitionTable ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  SectorSize,
IN ULONG  SectorsPerTrack,
IN ULONG  NumberOfHeads,
IN PDRIVE_LAYOUT_INFORMATION  PartitionBuffer 
)

Definition at line 2271 of file disksup.c.

2276{
2277 KEVENT Event;
2279 PIRP Irp;
2282 PUCHAR Buffer;
2283 PPTE Entry;
2284 PPARTITION_TABLE PartitionTable;
2285 LARGE_INTEGER Offset, NextOffset, ExtendedOffset, SectorOffset;
2286 LARGE_INTEGER StartOffset, PartitionLength;
2287 ULONG i, j;
2288 CCHAR k;
2289 BOOLEAN IsEzDrive = FALSE, IsSuperFloppy = FALSE, DoRewrite = FALSE, IsMbr;
2290 ULONG ConventionalCylinders;
2291 LONGLONG DiskSize;
2293 PVOID MbrBuffer;
2298
2299 PAGED_CODE();
2300
2301 ExtendedOffset.QuadPart = NextOffset.QuadPart = Offset.QuadPart = 0;
2302
2303 /* Normalize the buffer size */
2304 BufferSize = max(512, SectorSize);
2305
2306 /* Get the partial drive geometry */
2307 xHalGetPartialGeometry(DeviceObject, &ConventionalCylinders, &DiskSize);
2308
2309 /* Check for EZ-Drive */
2311 if (MbrBuffer)
2312 {
2313 /* EZ-Drive found, bias the offset */
2314 IsEzDrive = TRUE;
2316 Offset.QuadPart = 512;
2317 }
2318
2319 /* Get the number of bits to shift to multiply by the sector size */
2320 for (k = 0; k < 32; k++) if ((SectorSize >> k) == 1) break;
2321
2322 /* Check if there's only one partition */
2323 if (PartitionBuffer->PartitionCount == 1)
2324 {
2325 /* Check if it has no starting offset or hidden sectors */
2326 if (!(PartitionInfo->StartingOffset.QuadPart) &&
2327 !(PartitionInfo->HiddenSectors))
2328 {
2329 /* Then it's a super floppy */
2331
2332 /* Which also means it must be non-bootable FAT-16 */
2333 if ((PartitionInfo->PartitionNumber) ||
2334 (PartitionInfo->PartitionType != PARTITION_FAT_16) ||
2335 (PartitionInfo->BootIndicator))
2336 {
2337 /* It's not, so we fail */
2339 }
2340
2341 /* Check if it needs a rewrite, and disable EZ-Drive for sure */
2342 if (PartitionInfo->RewritePartition) DoRewrite = TRUE;
2343 IsEzDrive = FALSE;
2344 }
2345 }
2346
2347 /* Count the number of partition tables */
2349
2350 /* Allocate our partition buffer */
2353
2354 /* Loop the entries */
2356 for (i = 0; i < DiskLayout->TableCount; i++)
2357 {
2358 /* Set if this is the MBR partition */
2359 IsMbr= (BOOLEAN)!i;
2360
2361 /* Initialize th event */
2363
2364 /* Build the read IRP */
2367 Buffer,
2368 BufferSize,
2369 &Offset,
2370 &Event,
2371 &IoStatusBlock);
2372 if (!Irp)
2373 {
2374 /* Fail */
2376 break;
2377 }
2378
2379 /* Make sure to disable volume verification */
2382
2383 /* Call the driver */
2385 if (Status == STATUS_PENDING)
2386 {
2387 /* Wait for completion */
2390 }
2391
2392 /* Check for failure */
2393 if (!NT_SUCCESS(Status)) break;
2394
2395 /* If we biased for EZ-Drive, unbias now */
2396 if (IsEzDrive && (Offset.QuadPart == 512)) Offset.QuadPart = 0;
2397
2398 /* Check if this is a normal disk */
2399 if (!IsSuperFloppy)
2400 {
2401 /* Set the boot record signature */
2403
2404 /* By default, don't require a rewrite */
2405 DoRewrite = FALSE;
2406
2407 /* Check if we don't have an offset */
2408 if (!Offset.QuadPart)
2409 {
2410 /* Check if the signature doesn't match */
2412 {
2413 /* Then write the signature and now we need a rewrite */
2415 DoRewrite = TRUE;
2416 }
2417 }
2418
2419 /* Loop the partition table entries */
2420 PartitionTable = &DiskLayout->PartitionTable[i];
2421 for (j = 0; j < NUM_PARTITION_TABLE_ENTRIES; j++)
2422 {
2423 /* Get the current entry and type */
2424 TableEntry = &PartitionTable->PartitionEntry[j];
2425 PartitionType = TableEntry->PartitionType;
2426
2427 /* Check if the entry needs a rewrite */
2428 if (TableEntry->RewritePartition)
2429 {
2430 /* Then we need one too */
2431 DoRewrite = TRUE;
2432
2433 /* Save the type and if it's a bootable partition */
2434 Entry[j].PartitionType = TableEntry->PartitionType;
2435 Entry[j].ActiveFlag = TableEntry->BootIndicator ? 0x80 : 0;
2436
2437 /* Make sure it's used */
2439 {
2440 /* Make sure it's not a container (unless primary) */
2441 if ((IsMbr) || !(IsContainerPartition(PartitionType)))
2442 {
2443 /* Use the partition offset */
2444 StartOffset.QuadPart = Offset.QuadPart;
2445 }
2446 else
2447 {
2448 /* Use the extended logical partition offset */
2449 StartOffset.QuadPart = ExtendedOffset.QuadPart;
2450 }
2451
2452 /* Set the sector offset */
2453 SectorOffset.QuadPart = TableEntry->
2454 StartingOffset.QuadPart -
2455 StartOffset.QuadPart;
2456
2457 /* Now calculate the starting sector */
2458 StartOffset.QuadPart = SectorOffset.QuadPart >> k;
2459 Entry[j].StartingSector = StartOffset.LowPart;
2460
2461 /* As well as the length */
2462 PartitionLength.QuadPart = TableEntry->PartitionLength.
2463 QuadPart >> k;
2464 Entry[j].PartitionLength = PartitionLength.LowPart;
2465
2466 /* Calculate the CHS values */
2467 HalpCalculateChsValues(&TableEntry->StartingOffset,
2468 &TableEntry->PartitionLength,
2469 k,
2472 ConventionalCylinders,
2474 &Entry[j]);
2475 }
2476 else
2477 {
2478 /* Otherwise set up an empty entry */
2479 Entry[j].StartingSector = 0;
2480 Entry[j].PartitionLength = 0;
2481 Entry[j].StartingTrack = 0;
2482 Entry[j].EndingTrack = 0;
2483 Entry[j].StartingCylinder = 0;
2484 Entry[j].EndingCylinder = 0;
2485 }
2486 }
2487
2488 /* Check if this is a container partition */
2490 {
2491 /* Then update the offset to use */
2492 NextOffset = TableEntry->StartingOffset;
2493 }
2494 }
2495 }
2496
2497 /* Check if we need to write back the buffer */
2498 if (DoRewrite)
2499 {
2500 /* We don't need to do this again */
2501 DoRewrite = FALSE;
2502
2503 /* Initialize the event */
2505
2506 /* If we unbiased for EZ-Drive, rebias now */
2507 if (IsEzDrive && !Offset.QuadPart) Offset.QuadPart = 512;
2508
2509 /* Build the write IRP */
2512 Buffer,
2513 BufferSize,
2514 &Offset,
2515 &Event,
2516 &IoStatusBlock);
2517 if (!Irp)
2518 {
2519 /* Fail */
2521 break;
2522 }
2523
2524 /* Make sure to disable volume verification */
2527
2528 /* Call the driver */
2530 if (Status == STATUS_PENDING)
2531 {
2532 /* Wait for completion */
2534 Executive,
2535 KernelMode,
2536 FALSE,
2537 NULL);
2539 }
2540
2541 /* Check for failure */
2542 if (!NT_SUCCESS(Status)) break;
2543
2544 /* If we biased for EZ-Drive, unbias now */
2545 if (IsEzDrive && (Offset.QuadPart == 512)) Offset.QuadPart = 0;
2546 }
2547
2548 /* Update the partition offset and set the extended offset if needed */
2549 Offset = NextOffset;
2550 if (IsMbr) ExtendedOffset = NextOffset;
2551 }
2552
2553 /* If we had a buffer, free it, then return status */
2555 return Status;
2556}
#define SectorOffset(L)
Definition: cdprocs.h:1622
static VOID HalpCalculateChsValues(_In_ PLARGE_INTEGER PartitionOffset, _In_ PLARGE_INTEGER PartitionLength, _In_ CCHAR ShiftCount, _In_ ULONG SectorsPerTrack, _In_ ULONG NumberOfTracks, _In_ ULONG ConventionalCylinders, _Out_ PPARTITION_DESCRIPTOR PartitionDescriptor)
Definition: disksup.c:1366
VOID FASTCALL xHalGetPartialGeometry(IN PDEVICE_OBJECT DeviceObject, IN PULONG ConventionalCylinders, IN PLONGLONG DiskSize)
Definition: disksup.c:1443
struct _DISK_LAYOUT * PDISK_LAYOUT
struct _PTE * PPTE
#define BOOLEAN
Definition: pedump.c:73
BOOLEAN IsSuperFloppy(_In_ PDISKENTRY DiskEntry)
Definition: partlist.c:602
ULONG TableCount
Definition: hal.h:324
PARTITION_TABLE PartitionTable[1]
Definition: hal.h:326
PARTITION_INFORMATION PartitionEntry[4]
Definition: hal.h:319
Definition: hal.h:333
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ typedef _In_ ULONG TableEntry
Definition: iotypes.h:4306
ret QuadPart
Definition: rtlfuncs.h:3106

Variable Documentation

◆ CdPrefix

const UNICODE_STRING CdPrefix = RTL_CONSTANT_STRING(L"\\Device\\CdRom")
static

Definition at line 41 of file disksup.c.

Referenced by HalpNextDriveLetter(), and xHalIoAssignDriveLetters().

◆ FloppyPrefix

const UNICODE_STRING FloppyPrefix = RTL_CONSTANT_STRING(L"\\Device\\Floppy")
static

Definition at line 40 of file disksup.c.

Referenced by HalpNextDriveLetter(), and xHalIoAssignDriveLetters().