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 *
806 if (irpStack->
Parameters.DeviceIoControl.OutputBufferLength <
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;
967 ioctlCode = irpStack->
Parameters.DeviceIoControl.IoControlCode;
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) // pointer truncation from 'PVOID' to 'NTSTATUS' 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"));
2954 if (
length > (
ULONG) (modeData->ModeDataLength + 1)) {
2955 length = modeData->ModeDataLength + 1;
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"));
3097 if (
length > (
ULONG) (modeData->ModeDataLength + 1)) {
3098 length = modeData->ModeDataLength + 1;
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"));
3242 if (
length > (
ULONG) (modeData->ModeDataLength + 1)) {
3243 length = modeData->ModeDataLength + 1;
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;
4466 if (irpStack->
Parameters.DeviceIoControl.InputBufferLength <
sizeof(STORAGE_FAILURE_PREDICTION_CONFIG) ||
4467 irpStack->
Parameters.DeviceIoControl.OutputBufferLength <
sizeof(STORAGE_FAILURE_PREDICTION_CONFIG)) {
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);
4523 #endif //(NTDDI_VERSION >= NTDDI_WINBLUE) 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"));
5127 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlIsWritable: Unable to allocate memory.\n"));
5145 if (modeData ==
NULL) {
5146 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlIsWritable: Unable to allocate memory.\n"));
5168 srbEx->SrbLength = srbSize;
5172 srbEx->NumSrbExData = 1;
5195 srbExDataCdb16->CdbLength = 6;
5197 cdb = (
PCDB)srbExDataCdb16->Cdb;
5234 while (retries != 0) {
5414 TracePrint((
TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL,
"DiskIoctlUpdateDriveSize: Output buffer too small.\n"));