29#include "geometry.tmh"
32#if defined(_X86_) || defined(_AMD64_)
40DiskUpdateRemovableGeometry (
58DiskSaveGeometryDetectInfo(
69typedef struct _DISK_DETECT_INFO {
76} DISK_DETECT_INFO, *PDISK_DETECT_INFO;
83PDISK_DETECT_INFO DetectInfoList =
NULL;
84ULONG DetectInfoCount = 0;
85LONG DetectInfoUsedCount = 0;
87#define GET_STARTING_SECTOR(p) ( \
88 (ULONG) (p->StartingSectorLsb0) + \
89 (ULONG) (p->StartingSectorLsb1 << 8 ) + \
90 (ULONG) (p->StartingSectorMsb0 << 16) + \
91 (ULONG) (p->StartingSectorMsb1 << 24) )
93#define GET_ENDING_S_OF_CHS(p) ( \
94 (UCHAR) (p->EndingCylinderLsb & 0x3F) )
129#define NUM_PARTITION_TABLE_ENTRIES 4
135#define PARTITION_TABLE_OFFSET ( 0x1be / 2)
136#define BOOT_SIGNATURE_OFFSET ((0x200 / 2) - 1)
142#define BOOT_RECORD_SIGNATURE (0xaa55)
146#pragma alloc_text(INIT, DiskSaveDetectInfo)
147#pragma alloc_text(INIT, DiskScanBusDetectInfo)
148#pragma alloc_text(INIT, DiskSaveBusDetectInfo)
149#pragma alloc_text(INIT, DiskSaveGeometryDetectInfo)
151#pragma alloc_text(PAGE, DiskUpdateGeometry)
152#pragma alloc_text(PAGE, DiskUpdateRemovableGeometry)
153#pragma alloc_text(PAGE, DiskGetPortGeometry)
154#pragma alloc_text(PAGE, DiskIsNT4Geometry)
155#pragma alloc_text(PAGE, DiskGetDetectInfo)
156#pragma alloc_text(PAGE, DiskReadSignature)
211 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskSaveDetectInfo: Cannot open hardware data. "
220 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskSaveDetectInfo: Can't query configuration data "
238 status = ZwOpenKey(&busKey,
259 status = ZwOpenKey(&busKey,
264 TracePrint((
TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL,
"DiskSaveDetectInfo: Opened MultifunctionAdapter key\n"));
276DiskCleanupDetectInfo(
303DiskSaveGeometryDetectInfo(
316 ULONG numberOfDrives;
335 if(keyData ==
NULL) {
336 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskSaveGeometryDetectInfo: Can't allocate config "
341 status = ZwQueryValueKey(HardwareKey,
349 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskSaveGeometryDetectInfo: Can't query configuration "
361 (((
PUCHAR) keyData) + keyData->DataOffset);
371 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskSaveGeometryDetectInfo: BIOS header data too small "
384 buffer += keyData->DataOffset;
397 length =
sizeof(DISK_DETECT_INFO) * numberOfDrives;
402 if(DetectInfoList ==
NULL) {
403 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskSaveGeometryDetectInfo: Couldn't allocate %x bytes "
404 "for DetectInfoList\n",
411 DetectInfoCount = numberOfDrives;
420 for(
i = 0;
i < numberOfDrives;
i++) {
422#pragma warning(suppress: 6386)
424 DetectInfoList[
i].DriveParameters = driveParameters[
i];
433DiskScanBusDetectInfo(
460 for(busNumber = 0; ; busNumber++) {
472 TracePrint((
TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL,
"DiskScanBusDetectInfo: Scanning bus %d\n", busNumber));
480 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskScanBusDetectInfo: Format symbolic link failed with error: 0x%X\n",
status));
495 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskScanBusDetectInfo: Error %#08lx opening bus "
516 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskScanBusDetectInfo: Error %#08lx opening "
517 "DiskController key\n",
522 for(adapterNumber = 0; ; adapterNumber++) {
532 "%d\\DiskController\\%d\\DiskPeripheral\n",
533 busNumber, adapterNumber));
537 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskScanBusDetectInfo: Format symbolic link failed with error: 0x%X\n",
status));
552 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskScanBusDetectInfo: Error %#08lx opening "
558 for(diskNumber = 0; ; diskNumber++) {
563 "%d\\DiskController\\%d\\DiskPeripheral\\%d\n",
564 busNumber, adapterNumber, diskNumber));
568 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskScanBusDetectInfo: Format symbolic link failed with error: 0x%X\n",
status));
583 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskScanBusDetectInfo: Error %#08lx "
584 "opening target key\n",
589 DiskSaveBusDetectInfo(
DriverObject, targetKey, diskNumber);
605DiskSaveBusDetectInfo(
633 PDISK_DETECT_INFO diskInfo;
645 if (DiskNumber >= DetectInfoCount)
650 diskInfo = &(DetectInfoList[DiskNumber]);
652 if(diskInfo->Initialized) {
655 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskSaveBusDetectInfo: disk entry %#x already has a "
656 "signature of %#08lx and mbr checksum of %#08lx\n",
659 diskInfo->MbrCheckSum));
669 if(keyData ==
NULL) {
670 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskSaveBusDetectInfo: Couldn't allocate space for "
679 status = ZwQueryValueKey(TargetKey,
687 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskSaveBusDetectInfo: Error %#08lx getting "
698 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskSaveBusDetectInfo: Saved data was invalid, "
699 "not enough data in registry!\n"));
724 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskSaveBusDetectInfo: Error %#08lx converting "
725 "identifier %wZ into MBR xsum\n",
732 diskInfo->MbrCheckSum =
value;
745 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskSaveBusDetectInfo: Error %#08lx converting "
746 "identifier %wZ into disk signature\n",
752 diskInfo->Signature =
value;
763 diskInfo->Initialized =
TRUE;
803 PDISK_DETECT_INFO diskInfo =
NULL;
819 if(diskData->GeometrySource != DiskGeometryUnknown) {
820 return diskData->GeometrySource;
828 for(
i = 0;
i < DetectInfoCount;
i++) {
832 diskInfo = &(DetectInfoList[
i]);
834 if((diskData->
Mbr.Signature != 0) &&
835 (diskData->
Mbr.Signature == diskInfo->Signature)) {
838 diskData->
Mbr.Signature));
841 }
else if((diskData->
Mbr.Signature == 0) &&
842 (diskData->
Mbr.MbrCheckSum != 0) &&
843 (diskData->
Mbr.MbrCheckSum == diskInfo->MbrCheckSum)) {
845 diskData->
Mbr.MbrCheckSum));
854 ULONG sectorsPerTrack;
855 ULONG tracksPerCylinder;
863 cylinders = diskInfo->DriveParameters.MaxCylinders + 1;
864 sectorsPerTrack = diskInfo->DriveParameters.SectorsPerTrack;
865 tracksPerCylinder = diskInfo->DriveParameters.MaxHeads + 1;
873 length = tracksPerCylinder * sectorsPerTrack;
882 tracksPerCylinder, sectorsPerTrack));
883 return DiskGeometryUnknown;
899 diskData->RealGeometry.SectorsPerTrack = sectorsPerTrack;
900 diskData->RealGeometry.TracksPerCylinder = tracksPerCylinder;
901 diskData->RealGeometry.Cylinders.QuadPart = (
LONGLONG)cylinders;
905 sectorsPerTrack, tracksPerCylinder, cylinders));
907 diskData->GeometrySource = DiskGeometryFromBios;
918 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskUpdateGeometry: no match found for signature %#08lx\n", diskData->
Mbr.Signature));
921 if(diskData->GeometrySource == DiskGeometryUnknown) {
936 if((diskData->RealGeometry.TracksPerCylinder *
937 diskData->RealGeometry.SectorsPerTrack) != 0) {
939 diskData->GeometrySource = DiskGeometryFromPort;
942 if (diskData->RealGeometry.BytesPerSector == 0) {
944 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskDriverReinit: Port driver failed to "
945 "set BytesPerSector in the RealGeometry\n"));
946 diskData->RealGeometry.BytesPerSector =
948 if (diskData->RealGeometry.BytesPerSector == 0) {
949 NT_ASSERT(!
"BytesPerSector is still zero!");
962 if (diskData->GeometrySource != DiskGeometryUnknown) {
967 return diskData->GeometrySource;
972DiskUpdateRemovableGeometry (
1084 irp->AssociatedIrp.SystemBuffer = Geometry;
1223 partitionTableEntry++;
1273 DiskUpdateRemovableGeometry(fdoExtension);
1275 DiskUpdateGeometry(fdoExtension);
1285DiskDriverReinitialization(
1321 ULONG unmatchedDiskCount;
1325 PDISK_DETECT_INFO diskInfo =
NULL;
1330 TracePrint((
TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL,
"DiskDriverReinitialization: ignoring call %d\n",
1341 if(DetectInfoCount == 0) {
1342 TracePrint((
TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL,
"DiskDriverReinitialization: no detect info saved\n"));
1346 if((DetectInfoCount - DetectInfoUsedCount) != 1) {
1347 TracePrint((
TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL,
"DiskDriverReinitialization: %d of %d geometry entries "
1348 "used - will not attempt match\n", DetectInfoUsedCount, DetectInfoCount));
1363 unmatchedDiskCount = 0;
1367#pragma prefast(
suppress:28175,
"Need to access the opaque field to scan through the list of disks")
1384 if(diskData->GeometrySource != DiskGeometryUnknown) {
1390 TracePrint((
TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL,
"DiskDriverReinit: FDO %#p has no geometry\n",
1399 diskData->GeometrySource = DiskGeometryFromDefault;
1405 unmatchedDiskCount++;
1406 if(unmatchedDiskCount > 1) {
1408 TracePrint((
TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL,
"DiskDriverReinit: FDO %#p also has no geometry\n",
1410 unmatchedDisk =
NULL;
1422 if(unmatchedDiskCount != 1) {
1423 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
"DiskDriverReinit: Unable to match geometry\n"));
1437 for(
i = 0;
i < DetectInfoCount;
i++) {
1439 diskInfo = &(DetectInfoList[
i]);
1444 if (diskInfo !=
NULL)
1452 ULONG sectorsPerTrack;
1453 ULONG tracksPerCylinder;
1461 cylinders = diskInfo->DriveParameters.MaxCylinders + 1;
1462 sectorsPerTrack = diskInfo->DriveParameters.SectorsPerTrack;
1463 tracksPerCylinder = diskInfo->DriveParameters.MaxHeads + 1;
1471 length = tracksPerCylinder * sectorsPerTrack;
1480 tracksPerCylinder, sectorsPerTrack));
1497 diskData->RealGeometry.SectorsPerTrack = sectorsPerTrack;
1498 diskData->RealGeometry.TracksPerCylinder = tracksPerCylinder;
1499 diskData->RealGeometry.Cylinders.QuadPart = (
LONGLONG)cylinders;
1503 sectorsPerTrack, tracksPerCylinder, cylinders));
1505 diskData->GeometrySource = DiskGeometryGuessedFromBios;
1506 diskInfo->Device = unmatchedDisk;
1517 if (diskData->RealGeometry.BytesPerSector == 0) {
1526 NT_ASSERT(!
"RealGeometry not set to non-zero bps\n");
1537 OUT PDISK_DETECTION_INFO DetectInfo
1560 PDISK_DETECT_INFO diskInfo =
NULL;
1581 for(
i = 0;
i < DetectInfoCount;
i++) {
1586 diskInfo = &(DetectInfoList[
i]);
1588 if((diskData->
Mbr.Signature != 0) &&
1589 (diskData->
Mbr.Signature == diskInfo->Signature)) {
1592 diskData->
Mbr.Signature));
1595 }
else if((diskData->
Mbr.Signature == 0) &&
1596 (diskData->
Mbr.MbrCheckSum != 0) &&
1597 (diskData->
Mbr.MbrCheckSum == diskInfo->MbrCheckSum)) {
1599 diskData->
Mbr.MbrCheckSum));
1606 DetectInfo->DetectionType = DetectInt13;
1607 DetectInfo->Int13.DriveSelect = diskInfo->DriveParameters.DriveSelect;
1608 DetectInfo->Int13.MaxCylinders = diskInfo->DriveParameters.MaxCylinders;
1609 DetectInfo->Int13.SectorsPerTrack = diskInfo->DriveParameters.SectorsPerTrack;
1610 DetectInfo->Int13.MaxHeads = diskInfo->DriveParameters.MaxHeads;
1611 DetectInfo->Int13.NumberDrives = diskInfo->DriveParameters.NumberDrives;
#define InterlockedIncrement
#define FREE_POOL(_PoolPtr)
#define TEST_FLAG(Flags, Bit)
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
IO_COMPLETION_ROUTINE ClassSignalCompletion
#define STATUS_NOT_SUPPORTED
#define NT_SUCCESS(StatCode)
static const WCHAR Signature[]
_Must_inspect_result_ NTSTATUS NTAPI ClassReadDriveCapacity(_In_ PDEVICE_OBJECT Fdo)
#define DiskGetDetectInfo(FdoExtension, DetectInfo)
#define DiskReadDriveCapacity(Fdo)
#define DISK_TAG_UPDATE_GEOM
#define ExAllocatePoolWithTag(hernya, size, tag)
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
#define KeInitializeEvent(pEvt, foo, foo2)
NTSTATUS NTAPI IoReadDiskSignature(IN PDEVICE_OBJECT DeviceObject, IN ULONG BytesPerSector, OUT PDISK_SIGNATURE Signature)
MxDeviceObject deviceObject
GLuint GLsizei GLsizei * length
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
struct _CM_FULL_RESOURCE_DESCRIPTOR CM_FULL_RESOURCE_DESCRIPTOR
struct _CM_FULL_RESOURCE_DESCRIPTOR * PCM_FULL_RESOURCE_DESCRIPTOR
#define CmResourceTypeDeviceSpecific
#define OBJ_KERNEL_HANDLE
#define OBJ_CASE_INSENSITIVE
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
#define InitializeObjectAttributes(p, n, a, r, s)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ KeyValueFullInformation
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
#define FILE_REMOVABLE_MEDIA
#define UNREFERENCED_PARAMETER(P)
#define IsContainerPartition(PartitionType)
struct _DISK_GEOMETRY DISK_GEOMETRY
struct _PARTITION_DESCRIPTOR * PPARTITION_DESCRIPTOR
#define PARTITION_TABLE_OFFSET
#define BOOT_SIGNATURE_OFFSET
#define GET_ENDING_S_OF_CHS(p)
struct _PARTITION_DESCRIPTOR PARTITION_DESCRIPTOR
#define GET_STARTING_SECTOR(p)
#define NUM_PARTITION_TABLE_ENTRIES
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)
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
VOID NTAPI IoFreeIrp(IN PIRP Irp)
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
#define BOOT_RECORD_SIGNATURE
#define IRP_MJ_DEVICE_CONTROL
#define VALUE_BUFFER_SIZE
#define TRACE_LEVEL_WARNING
#define TRACE_LEVEL_ERROR
#define TRACE_LEVEL_INFORMATION
CM_PARTIAL_RESOURCE_LIST PartialResourceList
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@392::@401 DeviceSpecificData
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@392 u
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
PDEVICE_OBJECT LowerDeviceObject
struct _DISK_DATA::@1072::@1075 Mbr
struct _DISK_DATA::@1072::@1076 Efi
PARTITION_STYLE PartitionStyle
DISK_GEOMETRY DiskGeometry
COMMON_DEVICE_EXTENSION CommonExtension
struct _IO_STACK_LOCATION::@1583::@1584 DeviceIoControl
union _IO_STACK_LOCATION::@1583 Parameters
UCHAR PartitionLengthMsb0
UCHAR PartitionLengthLsb1
UCHAR PartitionLengthMsb1
UCHAR PartitionLengthLsb0
UCHAR StartingCylinderLsb
UCHAR StartingCylinderMsb
#define RtlZeroMemory(Destination, Length)
#define STATUS_INVALID_PARAMETER
#define STATUS_UNSUCCESSFUL
#define STATUS_INSUFFICIENT_RESOURCES
_Must_inspect_result_ _In_ WDFDEVICE Device
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
_Must_inspect_result_ _In_ WDFDEVICE Fdo
struct _CM_INT13_DRIVE_PARAMETER * PCM_INT13_DRIVE_PARAMETER
struct _CM_INT13_DRIVE_PARAMETER CM_INT13_DRIVE_PARAMETER
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define SL_OVERRIDE_VERIFY_VOLUME