29 #include "geometry.tmh" 32 #if defined(_X86_) || defined(_AMD64_) 40 DiskUpdateRemovableGeometry (
45 DiskScanBusDetectInfo(
51 DiskSaveBusDetectInfo(
58 DiskSaveGeometryDetectInfo(
69 typedef struct _DISK_DETECT_INFO {
76 } DISK_DETECT_INFO, *PDISK_DETECT_INFO;
83 PDISK_DETECT_INFO DetectInfoList =
NULL;
84 ULONG DetectInfoCount = 0;
85 LONG 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"));
276 DiskCleanupDetectInfo(
303 DiskSaveGeometryDetectInfo(
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) // PREFast bug means it doesn't correctly remember the size of DetectInfoList 424 DetectInfoList[
i].DriveParameters = driveParameters[
i];
433 DiskScanBusDetectInfo(
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);
605 DiskSaveBusDetectInfo(
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;
972 DiskUpdateRemovableGeometry (
1030 DiskGetPortGeometry(
1079 irpStack->
Parameters.DeviceIoControl.IoControlCode =
1081 irpStack->
Parameters.DeviceIoControl.OutputBufferLength =
1084 irp->AssociatedIrp.SystemBuffer = Geometry;
1223 partitionTableEntry++;
1273 DiskUpdateRemovableGeometry(fdoExtension);
1275 DiskUpdateGeometry(fdoExtension);
1285 DiskDriverReinitialization(
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;
1675 #endif // defined(_X86_) || defined(_AMD64_)
#define CmResourceTypeDeviceSpecific
struct _CM_INT13_DRIVE_PARAMETER CM_INT13_DRIVE_PARAMETER
return STATUS_NOT_SUPPORTED
#define GET_STARTING_SECTOR(p)
#define STATUS_INSUFFICIENT_RESOURCES
struct _DISK_DATA::@1016::@1020 Efi
#define OBJ_CASE_INSENSITIVE
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
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)
NTSTATUS NTAPI IoReadDiskSignature(IN PDEVICE_OBJECT DeviceObject, IN ULONG BytesPerSector, OUT PDISK_SIGNATURE Signature)
UCHAR PartitionLengthLsb0
DISK_GEOMETRY DiskGeometry
#define UNREFERENCED_PARAMETER(P)
#define STATUS_INVALID_PARAMETER
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
IO_COMPLETION_ROUTINE ClassSignalCompletion
COMMON_DEVICE_EXTENSION CommonExtension
#define PARTITION_TABLE_OFFSET
struct _CM_FULL_RESOURCE_DESCRIPTOR CM_FULL_RESOURCE_DESCRIPTOR
#define IsContainerPartition(PartitionType)
#define VALUE_BUFFER_SIZE
#define GET_ENDING_S_OF_CHS(p)
#define TRACE_LEVEL_INFORMATION
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
#define OBJ_KERNEL_HANDLE
UCHAR PartitionLengthLsb1
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@381::@390 DeviceSpecificData
_Must_inspect_result_ NTSTATUS NTAPI ClassReadDriveCapacity(_In_ PDEVICE_OBJECT Fdo)
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
CM_PARTIAL_RESOURCE_LIST PartialResourceList
#define FREE_POOL(_PoolPtr)
#define FILE_REMOVABLE_MEDIA
GLenum GLuint GLenum GLsizei length
struct _CM_FULL_RESOURCE_DESCRIPTOR * PCM_FULL_RESOURCE_DESCRIPTOR
UCHAR PartitionLengthMsb0
#define SL_OVERRIDE_VERIFY_VOLUME
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
#define TEST_FLAG(Flags, Bit)
PARTITION_STYLE PartitionStyle
struct _PARTITION_DESCRIPTOR PARTITION_DESCRIPTOR
#define DISK_TAG_UPDATE_GEOM
#define BOOT_RECORD_SIGNATURE
#define NT_SUCCESS(StatCode)
struct _PARTITION_DESCRIPTOR * PPARTITION_DESCRIPTOR
#define STATUS_UNSUCCESSFUL
#define ExAllocatePoolWithTag(hernya, size, tag)
_Must_inspect_result_ _In_ WDFDEVICE Fdo
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
#define BOOT_SIGNATURE_OFFSET
#define DiskGetDetectInfo(FdoExtension, DetectInfo)
GLsizei const GLfloat * value
_Must_inspect_result_ _In_ WDFDEVICE Device
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
UCHAR StartingCylinderLsb
MxDeviceObject deviceObject
#define TRACE_LEVEL_ERROR
#define TRACE_LEVEL_WARNING
struct _DISK_GEOMETRY DISK_GEOMETRY
#define KeInitializeEvent(pEvt, foo, foo2)
#define InterlockedIncrement
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
UCHAR StartingCylinderMsb
UCHAR PartitionLengthMsb1
struct _DISK_DATA::@1016::@1019 Mbr
PDEVICE_OBJECT LowerDeviceObject
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
#define DiskReadDriveCapacity(Fdo)
struct _CM_INT13_DRIVE_PARAMETER * PCM_INT13_DRIVE_PARAMETER
VOID NTAPI IoFreeIrp(IN PIRP Irp)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
#define NUM_PARTITION_TABLE_ENTRIES
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
#define InitializeObjectAttributes(p, n, a, r, s)
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@381 u
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
static const WCHAR Signature[]
static SERVICE_STATUS status
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
#define IRP_MJ_DEVICE_CONTROL