23#define DEBUG_MAIN_SOURCE 1
42#pragma alloc_text(INIT, DriverEntry)
43#pragma alloc_text(PAGE, DiskUnload)
44#pragma alloc_text(PAGE, DiskCreateFdo)
45#pragma alloc_text(PAGE, DiskDetermineMediaTypes)
46#pragma alloc_text(PAGE, DiskModeSelect)
47#pragma alloc_text(PAGE, DisableWriteCache)
48#pragma alloc_text(PAGE, DiskSetSpecialHacks)
49#pragma alloc_text(PAGE, DiskGetCacheInformation)
50#pragma alloc_text(PAGE, DiskSetCacheInformation)
51#pragma alloc_text(PAGE, DiskLogCacheInformation)
52#pragma alloc_text(PAGE, DiskSetInfoExceptionInformation)
53#pragma alloc_text(PAGE, DiskGetInfoExceptionInformation)
54#pragma alloc_text(PAGE, DiskIoctlGetCacheSetting)
55#pragma alloc_text(PAGE, DiskIoctlSetCacheSetting)
56#pragma alloc_text(PAGE, DiskIoctlGetLengthInfo)
57#pragma alloc_text(PAGE, DiskIoctlGetDriveGeometry)
58#pragma alloc_text(PAGE, DiskIoctlGetDriveGeometryEx)
59#pragma alloc_text(PAGE, DiskIoctlGetCacheInformation)
60#pragma alloc_text(PAGE, DiskIoctlSetCacheInformation)
61#pragma alloc_text(PAGE, DiskIoctlGetMediaTypesEx)
62#pragma alloc_text(PAGE, DiskIoctlPredictFailure)
63#pragma alloc_text(PAGE, DiskIoctlEnableFailurePrediction)
64#pragma alloc_text(PAGE, DiskIoctlReassignBlocks)
65#pragma alloc_text(PAGE, DiskIoctlReassignBlocksEx)
66#pragma alloc_text(PAGE, DiskIoctlIsWritable)
67#pragma alloc_text(PAGE, DiskIoctlUpdateDriveSize)
68#pragma alloc_text(PAGE, DiskIoctlGetVolumeDiskExtents)
69#pragma alloc_text(PAGE, DiskIoctlSmartGetVersion)
70#pragma alloc_text(PAGE, DiskIoctlSmartReceiveDriveData)
71#pragma alloc_text(PAGE, DiskIoctlSmartSendDriveCommand)
72#pragma alloc_text(PAGE, DiskIoctlVerifyThread)
84#define DiskCompareGuid(_First,_Second) \
85 (memcmp ((_First),(_Second), sizeof (GUID)))
99#define TRANSLATE_RETENTION_PRIORITY(_x)\
100 ((_x) == 0xf ? 0x2 : \
101 ((_x) == 0x2 ? 0xf : _x) \
104#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS_ADMIN CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_READ_ACCESS)
131#if defined(_X86_) || defined(_AMD64_)
183#if defined(_X86_) || defined(_AMD64_)
258 &classQueryWmiRegInfoExList);
287#if defined(_X86_) || defined(_AMD64_)
341 PCCHAR deviceName =
NULL;
359 WCHAR dirBuffer[64] = { 0 };
365 TracePrint((
TRACE_LEVEL_FATAL, TRACE_FLAG_PNP,
"DiskCreateFdo: Format symbolic link failed with error: 0x%X\n",
status));
426 goto DiskCreateFdoExit;
437 TracePrint((
TRACE_LEVEL_FATAL, TRACE_FLAG_PNP,
"DiskCreateFdo: Can not create device object %s\n", deviceName));
438 goto DiskCreateFdoExit;
460#pragma prefast(suppress:28175);
507 goto DiskCreateFdoExit;
572 ULONG residualOffset;
582 residualOffset =
irpSp->Parameters.Read.ByteOffset.LowPart & (commonExtension->
PartitionZeroExtension->DiskGeometry.BytesPerSector - 1);
585 (
irpSp->Parameters.Read.ByteOffset.QuadPart < 0) ||
586 (residualBytes != 0) ||
587 (residualOffset != 0))
626 }
else if ((residualBytes == 0) && (residualOffset == 0)) {
742 "DiskDetermineMediaTypes: Vendor %s, Product %s\n",
758 if (
strncmp(mediaListEntry->VendorId,vendorId,
strlen(mediaListEntry->VendorId))) {
762 if ((mediaListEntry->ProductId !=
NULL) &&
763 strncmp(mediaListEntry->ProductId, productId,
strlen(mediaListEntry->ProductId))) {
778 if (
strncmp(mediaListEntry->VendorId,vendorId,
strlen(mediaListEntry->VendorId))) {
782 if ((mediaListEntry->ProductId !=
NULL) &&
783 strncmp(mediaListEntry->ProductId, productId,
strlen(mediaListEntry->ProductId))) {
787 if ((mediaListEntry->Revision !=
NULL) &&
788 strncmp(mediaListEntry->Revision, productRevision,
strlen(mediaListEntry->Revision))) {
792 deviceMatched =
TRUE;
802 (mediaListEntry->NumberOfTypes *
817 for (
j = 0;
j < mediaListEntry->NumberOfTypes;
j++) {
851 if (MediumType == 2) {
853 }
else if (MediumType == 3) {
856 if (DensityCode == 0x87) {
894 if (!deviceMatched) {
897 "DiskDetermineMediaTypes: Unknown device. Vendor: %s Product: %s Revision: %s\n",
928 Irp->IoStatus.Information =
966 Irp->IoStatus.Information = 0;
969 TracePrint((
TRACE_LEVEL_VERBOSE, TRACE_FLAG_IOCTL,
"DiskDeviceControl: Received IOCTL 0x%X for device %p through IRP %p\n",
1055 #if (NTDDI_VERSION >= NTDDI_WINBLUE)
1056 case IOCTL_STORAGE_FAILURE_PREDICTION_CONFIG : {
1095 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskDeviceControl: IOCTL 0x%X to device %p failed with error 0x%X\n",
1098 (
Irp->Tail.Overlay.Thread !=
NULL)) {
1187 TracePrint((
TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI,
"DiskShutdownFlush: IRP %p flags = 0x%x\n",
Irp, irpStack->Flags));
1238 TracePrint((
TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI,
"DiskShutdownFlush: waiting for event\n"));
1331 srbEx->SrbLength = srbSize;
1335 srbEx->NumSrbExData = 1;
1341 srbEx->SrbFlags = fdoExtension->
SrbFlags;
1362 cdb = (
PCDB)srbExDataCdb16->Cdb;
1392 srb->SrbFlags = fdoExtension->
SrbFlags;
1395 cdb = (
PCDB)srb->Cdb;
1405 srbExDataCdb16->CdbLength = 10;
1407 srb->CdbLength = 10;
1434 srbEx->SrbStatus = 0;
1435 srbExDataCdb16->ScsiStatus = 0;
1437 srbExDataCdb16->CdbLength = 6;
1452 srb->ScsiStatus = 0;
1464 cdb->MEDIA_REMOVAL.Prevent =
FALSE;
1480 srbEx->NumSrbExData = 0;
1481 srbEx->SrbExDataOffset[0] = 0;
1483 srbEx->OriginalRequest =
Irp;
1485 srbEx->SrbStatus = 0;
1490 srb->OriginalRequest =
Irp;
1497 irpStack->Parameters.Others.Argument4 = (
PVOID) 0;
1519 irpStack->Parameters.Scsi.Srb = srb;
1571 RtlZeroMemory(srbEx,
sizeof(FlushContext->Srb.SrbExBuffer));
1577 srbEx->SrbLength =
sizeof(FlushContext->Srb.SrbExBuffer);
1583 srbEx->SrbFlags = fdoExt->
SrbFlags;
1611 srbEx->NumSrbExData = 1;
1623 srbExDataCdb16->CdbLength = 10;
1637 TracePrint((
TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI,
"DiskFlushDispatch: sending sync cache\n"));
1647 srbEx->NumSrbExData = 0;
1648 srbEx->SrbExDataOffset[0] = 0;
1649 srbEx->OriginalRequest = FlushContext->CurrIrp;
1650 srbEx->SrbStatus = 0;
1675 irpSp->Parameters.Others.Argument4 = (
PVOID) 0;
1683 irpSp->Parameters.Scsi.Srb = srb;
1687 TracePrint((
TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI,
"DiskFlushDispatch: sending srb flush on irp %p\n", FlushContext->CurrIrp));
1733 #pragma warning(suppress:4311)
1768 Irp->IoStatus.Status =
status = SyncCacheStatus;
1854 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskModeSelect: Block length is not available. Unable to send mode select\n"));
1913 srbEx->SrbLength =
sizeof(srbExBuffer);
1917 srbEx->NumSrbExData = 1;
1940 srbExDataCdb16->CdbLength = 6;
1942 cdb = (
PCDB)srbExDataCdb16->Cdb;
1948 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskModeSelect: Insufficient extended SRB size\n"));
2032 cacheInfo.WriteCacheEnabled =
FALSE;
2133 srbEx->NumSrbExData = 1;
2154 Cdb = (
PCDB)srbExDataCdb16->Cdb;
2156 srbExDataCdb16->CdbLength = 16;
2159 srbExDataCdb16->CdbLength = 10;
2198 srbEx->SrbStatus = 0;
2199 srbExDataCdb16->ScsiStatus = 0;
2206 srbEx->TimeOutValue = ((numSectors + 0x7F) >> 7) *
FdoExtension->TimeOutValue;
2258 sectorOffset.
QuadPart += numSectors;
2264 Irp->IoStatus.Information = 0;
2310 UCHAR scsiStatus = 0;
2311 UCHAR senseBufferLength = 0;
2326 (srbEx->NumSrbExData > 0)) {
2390 (senseBuffer !=
NULL) && (cdb !=
NULL)) {
2397 validSense = ScsiGetSenseKeyAndCodes(senseBuffer,
2419 (cdb->
CDB10.ForceUnitAccess))
2436 if (logEntry !=
NULL)
2510 invalidatePartitionTable =
TRUE;
2518 invalidatePartitionTable =
TRUE;
2526 invalidatePartitionTable =
TRUE;
2531 invalidatePartitionTable =
TRUE;
2537 invalidatePartitionTable =
TRUE;
2542 invalidatePartitionTable =
TRUE;
2569 invalidatePartitionTable =
TRUE;
2577 invalidatePartitionTable =
TRUE;
2695 " START_UNITS\n", fdo));
2735 TracePrint((
TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL,
"Disk ResetBus: Sending reset bus request to port driver.\n"));
2774 srbEx->SrbLength =
sizeof(
context->Srb.SrbExBuffer);
2832 srbEx->OriginalRequest =
irp;
2868 if (logEntry !=
NULL)
2885 logEntry->
DumpData[3] = CacheInfo->WriteCacheEnabled;
2917 if (modeData ==
NULL) {
2919 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_WMI,
"DiskGetInfoExceptionInformation: Unable to allocate mode "
2943 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_WMI,
"DiskGetInfoExceptionInformation: Mode Sense failed\n"));
2967 if (pageData !=
NULL) {
2974 TracePrint((
TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI,
"DiskGetInfoExceptionInformation: %s support SMART for device %p\n",
3002 for (
i = 0;
i < 2;
i++)
3058 if (modeData ==
NULL) {
3060 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskGetSetCacheInformation: Unable to allocate mode "
3085 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskGetCacheInformation: Mode Sense failed\n"));
3114 if (pageData ==
NULL) {
3115 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskGetCacheInformation: Unable to find caching mode page.\n"));
3126 CacheInfo->ParametersSavable = pageData->
PageSavable;
3137 CacheInfo->ReadRetentionPriority =
3139 CacheInfo->WriteRetentionPriority =
3142 CacheInfo->DisablePrefetchTransferLength =
3146 CacheInfo->ScalarPrefetch.Minimum =
3149 CacheInfo->ScalarPrefetch.Maximum =
3153 CacheInfo->PrefetchScalar =
TRUE;
3154 CacheInfo->ScalarPrefetch.MaximumBlocks =
3203 if (modeData ==
NULL) {
3205 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskSetCacheInformation: Unable to allocate mode "
3230 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskSetCacheInformation: Mode Sense failed\n"));
3259 if (pageData ==
NULL) {
3282 (
UCHAR) (CacheInfo->DisablePrefetchTransferLength >> 8);
3284 (
UCHAR) (CacheInfo->DisablePrefetchTransferLength & 0x00ff);
3287 (
UCHAR) (CacheInfo->ScalarPrefetch.Minimum >> 8);
3289 (
UCHAR) (CacheInfo->ScalarPrefetch.Minimum & 0x00ff);
3292 (
UCHAR) (CacheInfo->ScalarPrefetch.Maximum >> 8);
3294 (
UCHAR) (CacheInfo->ScalarPrefetch.Maximum & 0x00ff);
3299 (
UCHAR) (CacheInfo->ScalarPrefetch.MaximumBlocks >> 8);
3301 (
UCHAR) (CacheInfo->ScalarPrefetch.MaximumBlocks & 0x00ff);
3308 for (
i = 0;
i < 2;
i++) {
3312 (pageData->PageLength + 2),
3313 CacheInfo->ParametersSavable);
3317 if (CacheInfo->WriteCacheEnabled)
3463 ULONG isPowerProtected;
3471 isPowerProtected = 1;
3476 isPowerProtected = 0;
3564 if(partitionZeroData->
ReadyStatus != oldReadyStatus) {
3625 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlGetDriveGeometry: Output buffer too small.\n"));
3739 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlGetDriveGeometryEx: Output buffer too small.\n"));
3789 geometryEx->
Partition.Gpt.DiskId = diskData->
Efi.DiskId;
3798 geometryEx->
Partition.Mbr.Signature = diskData->
Mbr.Signature;
3799 geometryEx->
Partition.Mbr.CheckSum = diskData->
Mbr.MbrCheckSum;
3829 geometryEx->
Detection.DetectionType = DetectNone;
3889 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlGetCacheInformation: Output buffer too small.\n"));
3970 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlSetCacheInformation: Input buffer length mismatch.\n"));
4032 UCHAR densityCode = 0;
4055 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlGetMediaTypesEx: Output buffer too small.\n"));
4070 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlGetMediaTypesEx: Unable to allocate memory.\n"));
4091 srbEx->SrbLength = srbSize;
4095 srbEx->NumSrbExData = 1;
4118 srbExDataCdb16->CdbLength = 6;
4120 cdb = (
PCDB)srbExDataCdb16->Cdb;
4126 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlGetMediaTypesEx: Insufficient extended SRB size.\n"));
4153 mediaPresent =
TRUE;
4161 if (modeData ==
NULL) {
4162 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlGetMediaTypesEx: Unable to allocate memory.\n"));
4174 srbEx->SrbStatus = 0;
4175 srbExDataCdb16->ScsiStatus = 0;
4176 srbExDataCdb16->CdbLength = 6;
4258 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlGetMediaTypesEx: Mode sense for header/bd failed. %lx\n",
status));
4321 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlPredictFailure: Output buffer too small.\n"));
4332 ULONG readBufferSize;
4357 if (readBuffer !=
NULL) {
4369 if (readIrp !=
NULL) {
4400 Irp->AssociatedIrp.SystemBuffer);
4417#if (NTDDI_VERSION >= NTDDI_WINBLUE)
4451 PSTORAGE_FAILURE_PREDICTION_CONFIG enablePrediction;
4469 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlEnableFailurePrediction: Buffer too small.\n"));
4473 enablePrediction = (PSTORAGE_FAILURE_PREDICTION_CONFIG)
Irp->AssociatedIrp.SystemBuffer;
4475 if (enablePrediction->Version != STORAGE_FAILURE_PREDICTION_CONFIG_V1 ||
4476 enablePrediction->Size <
sizeof(STORAGE_FAILURE_PREDICTION_CONFIG)) {
4477 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlEnableFailurePrediction: Buffer version or size is incorrect.\n"));
4481 if (enablePrediction->Reserved != 0) {
4482 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlEnableFailurePrediction: Reserved bytes are not zero!\n"));
4518 Irp->IoStatus.Information =
sizeof(STORAGE_FAILURE_PREDICTION_CONFIG);
4568 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlVerify: Input buffer length mismatch.\n"));
4582 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlVerify: Unable to allocate memory.\n"));
4602 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlVerify: Verify request to invalid sector.\n"));
4611 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlVerify: Verify request to invalid sector.\n"));
4704 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlReassignBlocks: Input buffer length mismatch.\n"));
4712 if (badBlocks->
Count == 0) {
4713 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlReassignBlocks: Invalid block count\n"));
4720 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlReassignBlocks: Input buffer length mismatch for bad blocks.\n"));
4734 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlReassignBlocks: Unable to allocate memory.\n"));
4752 blockCount = badBlocks->
Count;
4759 badBlocks->
Count = (
USHORT) ((blockCount >> 8) & 0XFF);
4760 badBlocks->
Count |= (
USHORT) ((blockCount << 8) & 0XFF00);
4768 for (; blockCount > 0; blockCount--) {
4770 blockNumber = badBlocks->
BlockNumber[blockCount-1];
4789 srbEx->SrbLength = srbSize;
4793 srbEx->NumSrbExData = 1;
4816 srbExDataCdb16->CdbLength = 6;
4818 cdb = (
PCDB)srbExDataCdb16->Cdb;
4824 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlReassignBlocks: Insufficient extended SRB size.\n"));
4911 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlReassignBlocksEx: Input buffer length mismatch.\n"));
4919 if (badBlocks->
Count == 0) {
4920 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlReassignBlocksEx: Invalid block count\n"));
4927 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlReassignBlocksEx: Input buffer length mismatch for bad blocks.\n"));
4941 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlReassignBlocks: Unable to allocate memory.\n"));
4959 blockCount = badBlocks->
Count;
4966 badBlocks->
Count = (
USHORT) ((blockCount >> 8) & 0XFF);
4967 badBlocks->
Count |= (
USHORT) ((blockCount << 8) & 0XFF00);
4975 for (; blockCount > 0; blockCount--) {
4977 blockNumber = badBlocks->
BlockNumber[blockCount-1];
4996 srbEx->SrbLength = srbSize;
5000 srbEx->NumSrbExData = 1;
5023 srbExDataCdb16->CdbLength = 6;
5025 cdb = (
PCDB)srbExDataCdb16->Cdb;
5031 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlReassignBlocks: Insufficient extended SRB size.\n"));