ReactOS 0.4.15-dev-7906-g1b85a5f
disk.c File Reference
#include "disk.h"
#include "initguid.h"
#include "ntddstor.h"
#include "ntddvol.h"
#include "ioevent.h"
Include dependency graph for disk.c:

Go to the source code of this file.

Classes

struct  _DISK_GEOMETRY_EX_INTERNAL
 

Macros

#define DEBUG_MAIN_SOURCE   1
 
#define DiskCompareGuid(_First, _Second)    (memcmp ((_First),(_Second), sizeof (GUID)))
 
#define TRANSLATE_RETENTION_PRIORITY(_x)
 
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS_ADMIN   CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_READ_ACCESS)
 

Typedefs

typedef struct _DISK_GEOMETRY_EX_INTERNAL DISK_GEOMETRY_EX_INTERNAL
 
typedef struct _DISK_GEOMETRY_EX_INTERNALPDISK_GEOMETRY_EX_INTERNAL
 

Functions

VOID NTAPI DiskDriverReinit (IN PDRIVER_OBJECT DriverObject, IN PVOID Nothing, IN ULONG Count)
 
VOID NTAPI DiskBootDriverReinit (IN PDRIVER_OBJECT DriverObject, IN PVOID Nothing, IN ULONG Count)
 
NTSTATUS NTAPI DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
 
VOID NTAPI DiskUnload (IN PDRIVER_OBJECT DriverObject)
 
NTSTATUS DiskCreateFdo (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PULONG DeviceCount, IN BOOLEAN DasdAccessOnly)
 
NTSTATUS NTAPI DiskReadWriteVerification (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS DiskDetermineMediaTypes (IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN UCHAR MediumType, IN UCHAR DensityCode, IN BOOLEAN MediaPresent, IN BOOLEAN IsWritable)
 
NTSTATUS NTAPI DiskDeviceControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS NTAPI DiskShutdownFlush (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID DiskFlushDispatch (IN PDEVICE_OBJECT Fdo, IN PDISK_GROUP_CONTEXT FlushContext)
 
NTSTATUS NTAPI DiskFlushComplete (IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS DiskModeSelect (IN PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSelectBuffer, IN ULONG Length, IN BOOLEAN SavePage)
 
VOID NTAPI DisableWriteCache (IN PDEVICE_OBJECT Fdo, IN PVOID Context)
 
VOID NTAPI DiskIoctlVerifyThread (IN PDEVICE_OBJECT Fdo, IN PVOID Context)
 
VOID NTAPI DiskFdoProcessError (PDEVICE_OBJECT Fdo, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
 
VOID NTAPI DiskSetSpecialHacks (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN ULONG_PTR Data)
 
VOID ResetBus (IN PDEVICE_OBJECT Fdo)
 
VOID DiskLogCacheInformation (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo, IN NTSTATUS Status)
 
NTSTATUS DiskGetInfoExceptionInformation (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMODE_INFO_EXCEPTIONS ReturnPageData)
 
NTSTATUS DiskSetInfoExceptionInformation (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMODE_INFO_EXCEPTIONS PageData)
 
NTSTATUS NTAPI DiskGetCacheInformation (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
 
NTSTATUS NTAPI DiskSetCacheInformation (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
 
NTSTATUS DiskIoctlGetCacheSetting (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS DiskIoctlSetCacheSetting (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS DiskIoctlGetLengthInfo (IN OUT PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlGetDriveGeometry (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlGetDriveGeometryEx (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlGetCacheInformation (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlSetCacheInformation (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlGetMediaTypesEx (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlPredictFailure (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlEnableFailurePrediction (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlVerify (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlReassignBlocks (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlReassignBlocksEx (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlIsWritable (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlSetVerify (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlClearVerify (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlUpdateDriveSize (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlGetVolumeDiskExtents (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlSmartGetVersion (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlSmartReceiveDriveData (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlSmartSendDriveCommand (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
VOID DiskEtwEnableCallback (_In_ LPCGUID SourceId, _In_ ULONG IsEnabled, _In_ UCHAR Level, _In_ ULONGLONG MatchAnyKeyword, _In_ ULONGLONG MatchAllKeyword, _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData, _In_opt_ PVOID CallbackContext)
 

Variables

BOOLEAN DiskETWEnabled = FALSE
 
BOOLEAN DiskIsPastReinit = FALSE
 
const GUID GUID_NULL = { 0 }
 

Macro Definition Documentation

◆ DEBUG_MAIN_SOURCE

#define DEBUG_MAIN_SOURCE   1

Definition at line 23 of file disk.c.

◆ DiskCompareGuid

#define DiskCompareGuid (   _First,
  _Second 
)     (memcmp ((_First),(_Second), sizeof (GUID)))

Definition at line 84 of file disk.c.

◆ IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS_ADMIN

#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS_ADMIN   CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_READ_ACCESS)

Definition at line 104 of file disk.c.

◆ TRANSLATE_RETENTION_PRIORITY

#define TRANSLATE_RETENTION_PRIORITY (   _x)
Value:
((_x) == 0xf ? 0x2 : \
((_x) == 0x2 ? 0xf : _x) \
)
#define _x(oid)

Definition at line 99 of file disk.c.

Typedef Documentation

◆ DISK_GEOMETRY_EX_INTERNAL

◆ PDISK_GEOMETRY_EX_INTERNAL

Function Documentation

◆ DisableWriteCache()

VOID NTAPI DisableWriteCache ( IN PDEVICE_OBJECT  Fdo,
IN PVOID  Context 
)

Definition at line 2012 of file disk.c.

2017{
2018 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = (PFUNCTIONAL_DEVICE_EXTENSION)Fdo->DeviceExtension;
2019 DISK_CACHE_INFORMATION cacheInfo = { 0 };
2022
2023 PAGED_CODE();
2024
2027
2028 status = DiskGetCacheInformation(fdoExtension, &cacheInfo);
2029
2030 if (NT_SUCCESS(status) && (cacheInfo.WriteCacheEnabled == TRUE)) {
2031
2032 cacheInfo.WriteCacheEnabled = FALSE;
2033
2034 DiskSetCacheInformation(fdoExtension, &cacheInfo);
2035 }
2036
2038}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
struct _FUNCTIONAL_DEVICE_EXTENSION * PFUNCTIONAL_DEVICE_EXTENSION
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI DiskGetCacheInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
Definition: disk.c:3019
NTSTATUS NTAPI DiskSetCacheInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
Definition: disk.c:3167
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
Definition: ps.c:97
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:115
struct _IO_WORKITEM * PIO_WORKITEM
Definition: iotypes.h:506
#define NT_ASSERT
Definition: rtlfuncs.h:3310

◆ DiskBootDriverReinit()

VOID NTAPI DiskBootDriverReinit ( IN PDRIVER_OBJECT  DriverObject,
IN PVOID  Nothing,
IN ULONG  Count 
)

Definition at line 123 of file disk.c.

128{
130
131#if defined(_X86_) || defined(_AMD64_)
132
133 DiskDriverReinitialization(DriverObject, Nothing, Count);
134
135#else
136
139
140#endif
141
142}
VOID NTAPI DiskDriverReinit(IN PDRIVER_OBJECT DriverObject, IN PVOID Nothing, IN ULONG Count)
Definition: disk.c:108
int Count
Definition: noreturn.cpp:7
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1797
@ Nothing
Definition: sacdrv.h:266
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213

Referenced by DriverEntry().

◆ DiskCreateFdo()

NTSTATUS DiskCreateFdo ( IN PDRIVER_OBJECT  DriverObject,
IN PDEVICE_OBJECT  PhysicalDeviceObject,
IN PULONG  DeviceCount,
IN BOOLEAN  DasdAccessOnly 
)

Definition at line 307 of file disk.c.

340{
341 PCCHAR deviceName = NULL;
343 PDEVICE_OBJECT lowerDevice = NULL;
345 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
347
348 PAGED_CODE();
349
350 *DeviceCount = 0;
351
352 //
353 // Set up an object directory to contain the objects for this
354 // device and all its partitions.
355 //
356
357 do {
358
359 WCHAR dirBuffer[64] = { 0 };
360 UNICODE_STRING dirName;
361 OBJECT_ATTRIBUTES objectAttribs;
362
363 status = RtlStringCchPrintfW(dirBuffer, sizeof(dirBuffer) / sizeof(dirBuffer[0]) - 1, L"\\Device\\Harddisk%d", *DeviceCount);
364 if (!NT_SUCCESS(status)) {
365 TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP, "DiskCreateFdo: Format symbolic link failed with error: 0x%X\n", status));
366 return status;
367 }
368
369 RtlInitUnicodeString(&dirName, dirBuffer);
370
371 InitializeObjectAttributes(&objectAttribs,
372 &dirName,
374 NULL,
375 NULL);
376
379 &objectAttribs);
380
381 (*DeviceCount)++;
382
385
386 if (!NT_SUCCESS(status)) {
387
388 TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP, "DiskCreateFdo: Could not create directory - %lx\n", status));
389
390 return(status);
391 }
392
393 //
394 // When this loop exits the count is inflated by one - fix that.
395 //
396
397 (*DeviceCount)--;
398
399 //
400 // Claim the device.
401 //
402
404
405 status = ClassClaimDevice(lowerDevice, FALSE);
406
407 if (!NT_SUCCESS(status)) {
410 ObDereferenceObject(lowerDevice);
411 return status;
412 }
413
414 //
415 // Create a device object for this device. Each physical disk will
416 // have at least one device object. The required device object
417 // describes the entire device. Its directory path is
418 // \Device\HarddiskN\Partition0, where N = device number.
419 //
420
422
423 if(!NT_SUCCESS(status)) {
424 TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP, "DiskCreateFdo - couldn't create name %lx\n", status));
425
426 goto DiskCreateFdoExit;
427
428 }
429
430 status = ClassCreateDeviceObject(DriverObject,
431 deviceName,
433 TRUE,
434 &deviceObject);
435
436 if (!NT_SUCCESS(status)) {
437 TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP, "DiskCreateFdo: Can not create device object %s\n", deviceName));
438 goto DiskCreateFdoExit;
439 }
440
441 FREE_POOL(deviceName);
442
443 //
444 // Indicate that IRPs should include MDLs for data transfers.
445 //
446
448
449 fdoExtension = deviceObject->DeviceExtension;
450
451 if(DasdAccessOnly) {
452
453 //
454 // Inidicate that only RAW should be allowed to mount on the root
455 // partition object. This ensures that a file system can't doubly
456 // mount on a super-floppy by mounting once on P0 and once on P1.
457 //
458
459#ifdef _MSC_VER
460#pragma prefast(suppress:28175);
461#endif
462 SET_FLAG(deviceObject->Vpb->Flags, VPB_RAW_MOUNT);
463 }
464
465 //
466 // Initialize lock count to zero. The lock count is used to
467 // disable the ejection mechanism on devices that support
468 // removable media. Only the lock count in the physical
469 // device extension is used.
470 //
471
472 fdoExtension->LockCount = 0;
473
474 //
475 // Save system disk number.
476 //
477
478 fdoExtension->DeviceNumber = *DeviceCount;
479
480 //
481 // Set the alignment requirements for the device based on the
482 // host adapter requirements
483 //
484
485 if (lowerDevice->AlignmentRequirement > deviceObject->AlignmentRequirement) {
486 deviceObject->AlignmentRequirement = lowerDevice->AlignmentRequirement;
487 }
488
489 //
490 // Finally, attach to the pdo
491 //
492
493 fdoExtension->LowerPdo = PhysicalDeviceObject;
494
495 fdoExtension->CommonExtension.LowerDeviceObject =
497
498
499 if(fdoExtension->CommonExtension.LowerDeviceObject == NULL) {
500
501 //
502 // Uh - oh, we couldn't attach
503 // cleanup and return
504 //
505
507 goto DiskCreateFdoExit;
508 }
509
510 //
511 // Clear the init flag.
512 //
513
515
516 //
517 // Store a handle to the device object directory for this disk
518 //
519
520 fdoExtension->DeviceDirectory = handle;
521
522 ObDereferenceObject(lowerDevice);
523
524 return STATUS_SUCCESS;
525
526DiskCreateFdoExit:
527
528 if (deviceObject != NULL)
529 {
531 }
532
533 FREE_POOL(deviceName);
534
535 ObDereferenceObject(lowerDevice);
536
539
540 return status;
541}
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define CLEAR_FLAG(Flags, Bit)
Definition: cdrom.h:1494
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
NTSTATUS DiskGenerateDeviceName(IN ULONG DeviceNumber, OUT PCCHAR *RawName)
Definition: pnp.c:612
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
MxDeviceObject deviceObject
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
ULONG DeviceCount
Definition: mpu401.c:26
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI NTSTATUS NTAPI ZwMakeTemporaryObject(_In_ HANDLE Handle)
NTSYSAPI NTSTATUS NTAPI ZwCreateDirectoryObject(_Out_ PHANDLE DirectoryHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
#define L(x)
Definition: ntvdm.h:50
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_FATAL
Definition: storswtr.h:26
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:598
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
PDEVICE_OBJECT LowerPdo
Definition: classpnp.h:875
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:873
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define VPB_RAW_MOUNT
Definition: iotypes.h:1811
#define ObDereferenceObject
Definition: obfuncs.h:203
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by DiskAddDevice().

◆ DiskDetermineMediaTypes()

NTSTATUS DiskDetermineMediaTypes ( IN PDEVICE_OBJECT  Fdo,
IN PIRP  Irp,
IN UCHAR  MediumType,
IN UCHAR  DensityCode,
IN BOOLEAN  MediaPresent,
IN BOOLEAN  IsWritable 
)

Definition at line 655 of file disk.c.

685{
686 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
688
689 PGET_MEDIA_TYPES mediaTypes = Irp->AssociatedIrp.SystemBuffer;
690 PDEVICE_MEDIA_INFO mediaInfo = &mediaTypes->MediaInfo[0];
691 BOOLEAN deviceMatched = FALSE;
692
693 PAGED_CODE();
694
695 //
696 // this should be checked prior to calling into this routine
697 // as we use the buffer as mediaTypes
698 //
699
700 NT_ASSERT(irpStack->Parameters.DeviceIoControl.OutputBufferLength >=
701 sizeof(GET_MEDIA_TYPES));
702
703 //
704 // Determine if this device is removable or fixed.
705 //
706
707 if (!TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
708
709 //
710 // Fixed disk.
711 //
712
713 mediaTypes->DeviceType = FILE_DEVICE_DISK;
714 mediaTypes->MediaInfoCount = 1;
715
716 mediaInfo->DeviceSpecific.DiskInfo.Cylinders.QuadPart = fdoExtension->DiskGeometry.Cylinders.QuadPart;
717 mediaInfo->DeviceSpecific.DiskInfo.MediaType = FixedMedia;
718 mediaInfo->DeviceSpecific.DiskInfo.TracksPerCylinder = fdoExtension->DiskGeometry.TracksPerCylinder;
719 mediaInfo->DeviceSpecific.DiskInfo.SectorsPerTrack = fdoExtension->DiskGeometry.SectorsPerTrack;
720 mediaInfo->DeviceSpecific.DiskInfo.BytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;
721 mediaInfo->DeviceSpecific.DiskInfo.NumberMediaSides = 1;
722 mediaInfo->DeviceSpecific.DiskInfo.MediaCharacteristics = (MEDIA_CURRENTLY_MOUNTED | MEDIA_READ_WRITE);
723
724 if (!IsWritable) {
725
726 SET_FLAG(mediaInfo->DeviceSpecific.DiskInfo.MediaCharacteristics,
728 }
729
730 } else {
731
732 PCCHAR vendorId = (PCCHAR) fdoExtension->DeviceDescriptor + fdoExtension->DeviceDescriptor->VendorIdOffset;
733 PCCHAR productId = (PCCHAR) fdoExtension->DeviceDescriptor + fdoExtension->DeviceDescriptor->ProductIdOffset;
734 PCCHAR productRevision = (PCCHAR) fdoExtension->DeviceDescriptor + fdoExtension->DeviceDescriptor->ProductRevisionOffset;
735 DISK_MEDIA_TYPES_LIST const *mediaListEntry;
736 ULONG currentMedia;
737 ULONG i;
738 ULONG j;
739 ULONG sizeNeeded;
740
741 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
742 "DiskDetermineMediaTypes: Vendor %s, Product %s\n",
743 vendorId,
744 productId));
745
746
747 //
748 // If there's an entry with such vendorId & ProductId in the DiskMediaTypesExclude list,
749 // this device shouldn't be looked up in the DiskMediaTypes list to determine a medium type.
750 // The exclude table allows to narrow down the set of devices described by the DiskMediaTypes
751 // list (e.g.: DiskMediaTypes says "all HP devices" and DiskMediaTypesExlclude says
752 // "except for HP RDX")
753 //
754
755 for (i = 0; DiskMediaTypesExclude[i].VendorId != NULL; i++) {
756 mediaListEntry = &DiskMediaTypesExclude[i];
757
758 if (strncmp(mediaListEntry->VendorId,vendorId,strlen(mediaListEntry->VendorId))) {
759 continue;
760 }
761
762 if ((mediaListEntry->ProductId != NULL) &&
763 strncmp(mediaListEntry->ProductId, productId, strlen(mediaListEntry->ProductId))) {
764 continue;
765 }
766
767 goto SkipTable;
768 }
769
770 //
771 // Run through the list until we find the entry with a NULL Vendor Id.
772 //
773
774 for (i = 0; DiskMediaTypes[i].VendorId != NULL; i++) {
775
776 mediaListEntry = &DiskMediaTypes[i];
777
778 if (strncmp(mediaListEntry->VendorId,vendorId,strlen(mediaListEntry->VendorId))) {
779 continue;
780 }
781
782 if ((mediaListEntry->ProductId != NULL) &&
783 strncmp(mediaListEntry->ProductId, productId, strlen(mediaListEntry->ProductId))) {
784 continue;
785 }
786
787 if ((mediaListEntry->Revision != NULL) &&
788 strncmp(mediaListEntry->Revision, productRevision, strlen(mediaListEntry->Revision))) {
789 continue;
790 }
791
792 deviceMatched = TRUE;
793
794 mediaTypes->DeviceType = FILE_DEVICE_DISK;
795 mediaTypes->MediaInfoCount = mediaListEntry->NumberOfTypes;
796
797 //
798 // Ensure that buffer is large enough.
799 //
800
801 sizeNeeded = FIELD_OFFSET(GET_MEDIA_TYPES, MediaInfo[0]) +
802 (mediaListEntry->NumberOfTypes *
803 sizeof(DEVICE_MEDIA_INFO)
804 );
805
806 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
807 sizeNeeded) {
808
809 //
810 // Buffer too small
811 //
812
813 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
815 }
816
817 for (j = 0; j < mediaListEntry->NumberOfTypes; j++) {
818
819 mediaInfo->DeviceSpecific.RemovableDiskInfo.Cylinders.QuadPart = fdoExtension->DiskGeometry.Cylinders.QuadPart;
820 mediaInfo->DeviceSpecific.RemovableDiskInfo.TracksPerCylinder = fdoExtension->DiskGeometry.TracksPerCylinder;
821 mediaInfo->DeviceSpecific.RemovableDiskInfo.SectorsPerTrack = fdoExtension->DiskGeometry.SectorsPerTrack;
822 mediaInfo->DeviceSpecific.RemovableDiskInfo.BytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;
823 mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = mediaListEntry->NumberOfSides;
824
825 //
826 // Set the type.
827 //
828
829 mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType = mediaListEntry->MediaTypes[j];
830
831 if (mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType == MO_5_WO) {
832 mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = MEDIA_WRITE_ONCE;
833 } else {
834 mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = MEDIA_READ_WRITE;
835 }
836
837 //
838 // Status will either be success, if media is present, or no media.
839 // It would be optimal to base from density code and medium type, but not all devices
840 // have values for these fields.
841 //
842
843 if (MediaPresent) {
844
845 //
846 // The usage of MediumType and DensityCode is device specific, so this may need
847 // to be extended to further key off of product/vendor ids.
848 // Currently, the MO units are the only devices that return this information.
849 //
850
851 if (MediumType == 2) {
852 currentMedia = MO_5_WO;
853 } else if (MediumType == 3) {
854 currentMedia = MO_5_RW;
855
856 if (DensityCode == 0x87) {
857
858 //
859 // Indicate that the pinnacle 4.6 G media
860 // is present. Other density codes will default to normal
861 // RW MO media.
862 //
863
864 currentMedia = PINNACLE_APEX_5_RW;
865 }
866 } else {
867 currentMedia = 0;
868 }
869
870 if (currentMedia) {
871 if (mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType == (STORAGE_MEDIA_TYPE)currentMedia) {
872 SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics, MEDIA_CURRENTLY_MOUNTED);
873 }
874
875 } else {
876 SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics, MEDIA_CURRENTLY_MOUNTED);
877 }
878 }
879
880 if (!IsWritable) {
881 SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics, MEDIA_WRITE_PROTECTED);
882 }
883
884 //
885 // Advance to next entry.
886 //
887
888 mediaInfo++;
889 }
890 }
891
892SkipTable:
893
894 if (!deviceMatched) {
895
896 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL,
897 "DiskDetermineMediaTypes: Unknown device. Vendor: %s Product: %s Revision: %s\n",
898 vendorId,
899 productId,
900 productRevision));
901 //
902 // Build an entry for unknown.
903 //
904
905 mediaTypes->DeviceType = FILE_DEVICE_DISK;
906 mediaTypes->MediaInfoCount = 1;
907
908 mediaInfo->DeviceSpecific.RemovableDiskInfo.Cylinders.QuadPart = fdoExtension->DiskGeometry.Cylinders.QuadPart;
909 mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType = RemovableMedia;
910 mediaInfo->DeviceSpecific.RemovableDiskInfo.TracksPerCylinder = fdoExtension->DiskGeometry.TracksPerCylinder;
911 mediaInfo->DeviceSpecific.RemovableDiskInfo.SectorsPerTrack = fdoExtension->DiskGeometry.SectorsPerTrack;
912 mediaInfo->DeviceSpecific.RemovableDiskInfo.BytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;
913 mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = 1;
914 mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = MEDIA_READ_WRITE;
915
916 if (MediaPresent) {
917
918 SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics, MEDIA_CURRENTLY_MOUNTED);
919 }
920
921 if (!IsWritable) {
922
923 SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics, MEDIA_WRITE_PROTECTED);
924 }
925 }
926 }
927
928 Irp->IoStatus.Information =
929 FIELD_OFFSET(GET_MEDIA_TYPES, MediaInfo[0]) +
930 (mediaTypes->MediaInfoCount * sizeof(DEVICE_MEDIA_INFO));
931
932 return STATUS_SUCCESS;
933}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
@ MediaPresent
Definition: cdromp.h:82
enum _STORAGE_MEDIA_TYPE STORAGE_MEDIA_TYPE
@ PINNACLE_APEX_5_RW
Definition: cdrw_usr.h:254
@ MO_5_RW
Definition: cdrw_usr.h:248
@ MO_5_WO
Definition: cdrw_usr.h:247
_In_ PIRP Irp
Definition: csq.h:116
DISK_MEDIA_TYPES_LIST const DiskMediaTypes[]
Definition: data.c:82
DISK_MEDIA_TYPES_LIST const DiskMediaTypesExclude[]
Definition: data.c:74
_Must_inspect_result_ _Out_ PBOOLEAN IsWritable
Definition: fltkernel.h:1743
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
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
#define MEDIA_CURRENTLY_MOUNTED
Definition: minitape.h:36
#define MEDIA_READ_WRITE
Definition: minitape.h:34
#define MEDIA_WRITE_PROTECTED
Definition: minitape.h:35
#define MEDIA_WRITE_ONCE
Definition: minitape.h:32
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
@ RemovableMedia
Definition: ntdddisk.h:387
@ FixedMedia
Definition: ntdddisk.h:388
struct _DEVICE_MEDIA_INFO DEVICE_MEDIA_INFO
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
struct _DEVICE_MEDIA_INFO::@3170::@3171 DiskInfo
union _DEVICE_MEDIA_INFO::@3170 DeviceSpecific
struct _DEVICE_MEDIA_INFO::@3170::@3172 RemovableDiskInfo
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:405
ULONG TracksPerCylinder
Definition: ntdddisk.h:407
ULONG SectorsPerTrack
Definition: ntdddisk.h:408
ULONG BytesPerSector
Definition: ntdddisk.h:409
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:888
PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: classpnp.h:876
ULONG DeviceType
Definition: ntddstor.h:494
DEVICE_MEDIA_INFO MediaInfo[1]
Definition: ntddstor.h:496
ULONG MediaInfoCount
Definition: ntddstor.h:495
struct _IO_STACK_LOCATION::@1564::@1565 DeviceIoControl
union _IO_STACK_LOCATION::@1564 Parameters
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by DiskIoctlGetMediaTypesEx().

◆ DiskDeviceControl()

NTSTATUS NTAPI DiskDeviceControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 937 of file disk.c.

959{
962 ULONG ioctlCode;
963
965
966 Irp->IoStatus.Information = 0;
967 ioctlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
968
969 TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_IOCTL, "DiskDeviceControl: Received IOCTL 0x%X for device %p through IRP %p\n",
970 ioctlCode, DeviceObject, Irp));
971
972
973 switch (ioctlCode) {
974
977 break;
978 }
979
982 break;
983 }
984
987 break;
988 }
989
992 break;
993 }
994
997 break;
998 }
999
1002 break;
1003 }
1004
1005 case IOCTL_DISK_VERIFY: {
1007 break;
1008 }
1009
1012 break;
1013 }
1014
1017 break;
1018 }
1019
1022 break;
1023 }
1024
1027 break;
1028 }
1029
1032 break;
1033 }
1034
1037 break;
1038 }
1039
1042 break;
1043 }
1044
1047 break;
1048 }
1049
1052 break;
1053 }
1054
1055 #if (NTDDI_VERSION >= NTDDI_WINBLUE)
1056 case IOCTL_STORAGE_FAILURE_PREDICTION_CONFIG : {
1058 break;
1059 }
1060 #endif
1061
1062 case SMART_GET_VERSION: {
1064 break;
1065 }
1066
1067 case SMART_RCV_DRIVE_DATA: {
1069 break;
1070 }
1071
1074 break;
1075 }
1076
1080 break;
1081 }
1082
1083 default: {
1084
1085 //
1086 // Pass the request to the common device control routine.
1087 //
1089 break;
1090 }
1091 } // end switch
1092
1093 if (!NT_SUCCESS(status)) {
1094
1095 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskDeviceControl: IOCTL 0x%X to device %p failed with error 0x%X\n",
1096 ioctlCode, DeviceObject, status));
1098 (Irp->Tail.Overlay.Thread != NULL)) {
1100 }
1101 }
1102
1103 //
1104 // DiskIoctlVerify() (IOCTL_DISK_VERIFY) function returns STATUS_PENDING
1105 // and completes the IRP in the work item. Do not touch or complete
1106 // the IRP if STATUS_PENDING is returned.
1107 //
1108
1109 if (status != STATUS_PENDING) {
1110
1111
1112 Irp->IoStatus.Status = status;
1115 }
1116
1117 return(status);
1118} // end DiskDeviceControl()
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
#define IOCTL_DISK_VERIFY
Definition: cdrw_usr.h:170
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX
Definition: cdrw_usr.h:190
VOID NTAPI ClassCompleteRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ CCHAR PriorityBoost)
Definition: lock.c:401
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
NTSTATUS DiskIoctlVerify(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4526
NTSTATUS DiskIoctlUpdateDriveSize(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5362
NTSTATUS DiskIoctlEnableFailurePrediction(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4419
NTSTATUS DiskIoctlSmartSendDriveCommand(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5890
NTSTATUS DiskIoctlIsWritable(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5063
NTSTATUS DiskIoctlReassignBlocks(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4648
NTSTATUS DiskIoctlSetCacheInformation(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3917
NTSTATUS DiskIoctlGetVolumeDiskExtents(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5461
NTSTATUS DiskIoctlReassignBlocksEx(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4855
NTSTATUS DiskIoctlSmartReceiveDriveData(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5663
NTSTATUS DiskIoctlClearVerify(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5313
NTSTATUS DiskIoctlGetCacheSetting(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: disk.c:3347
NTSTATUS DiskIoctlGetDriveGeometryEx(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3672
NTSTATUS DiskIoctlGetMediaTypesEx(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3994
NTSTATUS DiskIoctlGetDriveGeometry(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3582
NTSTATUS DiskIoctlGetCacheInformation(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3840
NTSTATUS DiskIoctlSetCacheSetting(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: disk.c:3415
NTSTATUS DiskIoctlGetLengthInfo(IN OUT PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3492
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS_ADMIN
Definition: disk.c:104
NTSTATUS DiskIoctlSetVerify(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5264
NTSTATUS DiskIoctlPredictFailure(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4268
NTSTATUS DiskIoctlSmartGetVersion(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5540
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
static DRIVER_DISPATCH ClassDeviceControl
Definition: kbdclass.c:22
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
#define IOCTL_DISK_INTERNAL_CLEAR_VERIFY
Definition: ntdddisk.h:133
#define IOCTL_DISK_GET_CACHE_INFORMATION
Definition: ntdddisk.h:73
#define SMART_GET_VERSION
Definition: ntdddisk.h:257
#define IOCTL_DISK_UPDATE_DRIVE_SIZE
Definition: ntdddisk.h:239
#define IOCTL_DISK_GET_CACHE_SETTING
Definition: ntdddisk.h:76
#define SMART_RCV_DRIVE_DATA
Definition: ntdddisk.h:260
#define SMART_SEND_DRIVE_COMMAND
Definition: ntdddisk.h:263
#define IOCTL_DISK_SET_CACHE_INFORMATION
Definition: ntdddisk.h:193
#define IOCTL_DISK_REASSIGN_BLOCKS
Definition: ntdddisk.h:157
#define IOCTL_DISK_INTERNAL_SET_VERIFY
Definition: ntdddisk.h:136
#define IOCTL_DISK_SET_CACHE_SETTING
Definition: ntdddisk.h:196
#define IOCTL_DISK_REASSIGN_BLOCKS_EX
Definition: ntdddisk.h:178
#define IOCTL_STORAGE_PREDICT_FAILURE
Definition: ntddstor.h:146
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Definition: ntddvol.h:41
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define STATUS_PENDING
Definition: ntstatus.h:82
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2817
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by DriverEntry().

◆ DiskDriverReinit()

VOID NTAPI DiskDriverReinit ( IN PDRIVER_OBJECT  DriverObject,
IN PVOID  Nothing,
IN ULONG  Count 
)

Definition at line 108 of file disk.c.

Referenced by DiskBootDriverReinit().

◆ DiskEtwEnableCallback()

VOID DiskEtwEnableCallback ( _In_ LPCGUID  SourceId,
_In_ ULONG  IsEnabled,
_In_ UCHAR  Level,
_In_ ULONGLONG  MatchAnyKeyword,
_In_ ULONGLONG  MatchAllKeyword,
_In_opt_ PEVENT_FILTER_DESCRIPTOR  FilterData,
_In_opt_ PVOID  CallbackContext 
)

Definition at line 6155 of file disk.c.

6180{
6181 //
6182 // Initialize locals.
6183 //
6184 UNREFERENCED_PARAMETER(SourceId);
6190
6191 //
6192 // Set the ETW tracing enable state.
6193 //
6195
6196 return;
6197}
BOOLEAN DiskETWEnabled
Definition: disk.c:79
return pProvider IsEnabled(ProviderControl)
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG _In_opt_ PEVENT_FILTER_DESCRIPTOR _Inout_opt_ PVOID CallbackContext
Definition: wmitypes.h:60
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG MatchAnyKeyword
Definition: wmitypes.h:57
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData
Definition: wmitypes.h:59
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG MatchAllKeyword
Definition: wmitypes.h:58
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56

◆ DiskFdoProcessError()

VOID NTAPI DiskFdoProcessError ( PDEVICE_OBJECT  Fdo,
PSCSI_REQUEST_BLOCK  Srb,
NTSTATUS Status,
BOOLEAN Retry 
)

Definition at line 2276 of file disk.c.

2306{
2307 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
2309 PCDB cdb = NULL;
2310 UCHAR scsiStatus = 0;
2311 UCHAR senseBufferLength = 0;
2312 PVOID senseBuffer = NULL;
2313 CDB noOp = {0};
2314
2315 //
2316 // Get relevant fields from SRB
2317 //
2319
2320 srbEx = (PSTORAGE_REQUEST_BLOCK)Srb;
2321
2322 //
2323 // Look for SCSI SRB specific fields
2324 //
2325 if ((srbEx->SrbFunction == SRB_FUNCTION_EXECUTE_SCSI) &&
2326 (srbEx->NumSrbExData > 0)) {
2327 cdb = GetSrbScsiData(srbEx, NULL, NULL, &scsiStatus, &senseBuffer, &senseBufferLength);
2328
2329 //
2330 // cdb and sense buffer should not be NULL
2331 //
2332 NT_ASSERT(cdb != NULL);
2333 NT_ASSERT(senseBuffer != NULL);
2334
2335 }
2336
2337 if (cdb == NULL) {
2338
2339 //
2340 // Use a cdb that is all 0s
2341 //
2342 cdb = &noOp;
2343 }
2344
2345 } else {
2346
2347 cdb = (PCDB)(Srb->Cdb);
2348 scsiStatus = Srb->ScsiStatus;
2349 senseBufferLength = Srb->SenseInfoBufferLength;
2350 senseBuffer = Srb->SenseInfoBuffer;
2351 }
2352
2353 if (*Status == STATUS_DATA_OVERRUN &&
2354 (cdb != NULL) &&
2355 (IS_SCSIOP_READWRITE(cdb->CDB10.OperationCode))) {
2356
2357 *Retry = TRUE;
2358
2359 //
2360 // Update the error count for the device.
2361 //
2362
2363 fdoExtension->ErrorCount++;
2364
2365 } else if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_ERROR &&
2366 scsiStatus == SCSISTAT_BUSY) {
2367
2368 //
2369 // a disk drive should never be busy this long. Reset the scsi bus
2370 // maybe this will clear the condition.
2371 //
2372
2373 ResetBus(Fdo);
2374
2375 //
2376 // Update the error count for the device.
2377 //
2378
2379 fdoExtension->ErrorCount++;
2380
2381 } else {
2382
2383 BOOLEAN invalidatePartitionTable = FALSE;
2384
2385 //
2386 // See if this might indicate that something on the drive has changed.
2387 //
2388
2390 (senseBuffer != NULL) && (cdb != NULL)) {
2391
2393 UCHAR senseKey = 0;
2394 UCHAR asc = 0;
2395 UCHAR ascq = 0;
2396
2397 validSense = ScsiGetSenseKeyAndCodes(senseBuffer,
2398 senseBufferLength,
2400 &senseKey,
2401 &asc,
2402 &ascq);
2403
2404 if (validSense) {
2405
2406 switch (senseKey) {
2407
2409
2410 switch (asc) {
2411
2413 {
2414 //
2415 // Look to see if this is an Io request with the ForceUnitAccess flag set
2416 //
2417 if (((cdb->CDB10.OperationCode == SCSIOP_WRITE) ||
2418 (cdb->CDB10.OperationCode == SCSIOP_WRITE16)) &&
2419 (cdb->CDB10.ForceUnitAccess))
2420 {
2421 PDISK_DATA diskData = (PDISK_DATA)fdoExtension->CommonExtension.DriverData;
2422
2424 {
2425 PIO_ERROR_LOG_PACKET logEntry = NULL;
2426
2427 //
2428 // The user has explicitly requested that write caching be turned on.
2429 // Warn the user that writes with FUA enabled are not working and that
2430 // they should disable write cache.
2431 //
2432
2433 logEntry = IoAllocateErrorLogEntry(fdoExtension->DeviceObject,
2434 sizeof(IO_ERROR_LOG_PACKET) + (4 * sizeof(ULONG)));
2435
2436 if (logEntry != NULL)
2437 {
2438 logEntry->FinalStatus = *Status;
2440 logEntry->SequenceNumber = 0;
2441 logEntry->MajorFunctionCode = IRP_MJ_SCSI;
2442 logEntry->IoControlCode = 0;
2443 logEntry->RetryCount = 0;
2444 logEntry->UniqueErrorValue = 0;
2445 logEntry->DumpDataSize = 4 * sizeof(ULONG);
2446
2447 logEntry->DumpData[0] = diskData->ScsiAddress.PortNumber;
2448 logEntry->DumpData[1] = diskData->ScsiAddress.PathId;
2449 logEntry->DumpData[2] = diskData->ScsiAddress.TargetId;
2450 logEntry->DumpData[3] = diskData->ScsiAddress.Lun;
2451
2452 //
2453 // Write the error log packet.
2454 //
2455
2456 IoWriteErrorLogEntry(logEntry);
2457 }
2458 }
2459 else
2460 {
2461 //
2462 // Turn off write caching on this device. This is so that future
2463 // critical requests need not be sent down with ForceUnitAccess
2464 //
2466
2467 if (workItem)
2468 {
2470 }
2471 }
2472
2474 ADJUST_FUA_FLAG(fdoExtension);
2475
2476
2477 cdb->CDB10.ForceUnitAccess = FALSE;
2478 *Retry = TRUE;
2479
2480 } else if ((cdb->CDB6FORMAT.OperationCode == SCSIOP_MODE_SENSE) &&
2481 (cdb->MODE_SENSE.PageCode == MODE_SENSE_RETURN_ALL)) {
2482
2483 //
2484 // Mode sense for all pages failed. This command could fail with
2485 // SCSI_SENSE_ILLEGAL_REQUEST / SCSI_ADSENSE_INVALID_CDB if the data
2486 // to be returned is more than 256 bytes. In which case, try to get
2487 // only MODE_PAGE_CACHING since we only need the block descriptor.
2488 //
2489 // Simply change the page code and retry the request
2490 //
2491
2492 cdb->MODE_SENSE.PageCode = MODE_PAGE_CACHING;
2493 *Retry = TRUE;
2494 }
2495
2496 break;
2497 }
2498 } // end switch(asc)
2499 break;
2500 }
2501
2502 case SCSI_SENSE_NOT_READY: {
2503
2504 switch (asc) {
2506 switch (ascq) {
2510 invalidatePartitionTable = TRUE;
2511 break;
2512 }
2513 } // end switch(ascq)
2514 break;
2515 }
2516
2518 invalidatePartitionTable = TRUE;
2519 break;
2520 }
2521 } // end switch(asc)
2522 break;
2523 }
2524
2526 invalidatePartitionTable = TRUE;
2527 break;
2528 }
2529
2531 invalidatePartitionTable = TRUE;
2532 break;
2533 }
2534
2536 {
2537 invalidatePartitionTable = TRUE;
2538 break;
2539 }
2540
2542 invalidatePartitionTable = TRUE;
2543 break;
2544 }
2545
2546 } // end switch(senseKey)
2547 } // end if (validSense)
2548 } else {
2549
2550 //
2551 // On any exceptional scsi condition which might indicate that the
2552 // device was changed we will flush out the state of the partition
2553 // table.
2554 //
2555
2556 switch (SRB_STATUS(Srb->SrbStatus)) {
2560 case SRB_STATUS_NO_HBA:
2563 case SRB_STATUS_TIMEOUT:
2568 {
2569 invalidatePartitionTable = TRUE;
2570 break;
2571 }
2572
2573 case SRB_STATUS_ERROR:
2574 {
2575 if (scsiStatus == SCSISTAT_RESERVATION_CONFLICT)
2576 {
2577 invalidatePartitionTable = TRUE;
2578 }
2579
2580 break;
2581 }
2582 } // end switch(Srb->SrbStatus)
2583 }
2584
2585 if (invalidatePartitionTable && TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
2586
2587 //
2588 // Inform the upper layers that the volume
2589 // on this disk is in need of verification
2590 //
2591
2592 SET_FLAG(Fdo->Flags, DO_VERIFY_VOLUME);
2593 }
2594 }
2595
2596 return;
2597}
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
#define IS_SCSIOP_READWRITE(opCode)
Definition: cdrom.h:803
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define SCSI_SENSEQ_MANUAL_INTERVENTION_REQUIRED
Definition: cdrw_hw.h:1315
#define SCSISTAT_RESERVATION_CONFLICT
Definition: cdrw_hw.h:1084
#define SCSISTAT_BUSY
Definition: cdrw_hw.h:1081
#define SCSI_ADSENSE_INVALID_CDB
Definition: cdrw_hw.h:1265
#define SCSI_SENSE_MEDIUM_ERROR
Definition: cdrw_hw.h:1190
#define MODE_PAGE_CACHING
Definition: cdrw_hw.h:846
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
#define SCSI_SENSEQ_CAUSE_NOT_REPORTABLE
Definition: cdrw_hw.h:1312
#define MODE_SENSE_RETURN_ALL
Definition: cdrw_hw.h:857
#define SCSI_SENSEQ_BECOMING_READY
Definition: cdrw_hw.h:1313
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
#define SCSI_SENSE_UNIT_ATTENTION
Definition: cdrw_hw.h:1193
#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
Definition: cdrw_hw.h:1221
union _CDB * PCDB
#define SCSI_SENSE_HARDWARE_ERROR
Definition: cdrw_hw.h:1191
#define SCSI_SENSE_RECOVERED_ERROR
Definition: cdrw_hw.h:1188
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:312
#define CLASS_SPECIAL_FUA_NOT_SUPPORTED
Definition: classpnp.h:174
#define ADJUST_FUA_FLAG(fdoExt)
Definition: classpnp.h:53
VOID ResetBus(IN PDEVICE_OBJECT Fdo)
Definition: disk.c:2705
IO_WORKITEM_ROUTINE DisableWriteCache
Definition: disk.h:589
struct _DISK_DATA * PDISK_DATA
FORCEINLINE PCDB GetSrbScsiData(_In_ PSTORAGE_REQUEST_BLOCK SrbEx, _In_opt_ PUCHAR CdbLength8, _In_opt_ PULONG CdbLength32, _In_opt_ PUCHAR ScsiStatus, _In_opt_ PVOID *SenseInfoBuffer, _In_opt_ PUCHAR SenseInfoBufferLength)
Definition: disk.h:994
@ DiskWriteCacheEnable
Definition: disk.h:180
#define SCSIOP_WRITE16
Definition: scsi.h:915
#define SRB_STATUS_INVALID_LUN
Definition: srb.h:362
#define SRB_STATUS_REQUEST_FLUSHED
Definition: srb.h:361
#define SRB_STATUS_NO_HBA
Definition: srb.h:356
#define SRB_STATUS_INVALID_TARGET_ID
Definition: srb.h:363
#define SRB_STATUS_UNEXPECTED_BUS_FREE
Definition: srb.h:358
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_STATUS_INVALID_PATH_ID
Definition: srb.h:347
#define SRB_STATUS_TIMEOUT
Definition: srb.h:349
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:387
#define SRB_STATUS_ERROR
Definition: srb.h:344
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:350
#define SRB_STATUS(Status)
Definition: srb.h:389
#define SRB_STATUS_COMMAND_TIMEOUT
Definition: srb.h:351
#define SRB_STATUS_PARITY_ERROR
Definition: srb.h:354
#define SRB_STATUS_NO_DEVICE
Definition: srb.h:348
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
Status
Definition: gdiplustypes.h:25
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
if(dx< 0)
Definition: linetemp.h:194
#define IO_WARNING_WRITE_FUA_PROBLEM
Definition: ntiologc.h:93
VOID NTAPI IoWriteErrorLogEntry(IN PVOID ElEntry)
Definition: error.c:628
PVOID NTAPI IoAllocateErrorLogEntry(IN PVOID IoObject, IN UCHAR EntrySize)
Definition: error.c:528
#define SCSI_SENSE_OPTIONS_FIXED_FORMAT_IF_UNKNOWN_FORMAT_INDICATED
Definition: scsi.h:3839
UCHAR senseKey
Definition: scsi.h:4019
BOOLEAN validSense
Definition: scsi.h:4018
#define SRB_FUNCTION_STORAGE_REQUEST_BLOCK
Definition: srb.h:108
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:661
DISK_USER_WRITE_CACHE_SETTING WriteCacheOverride
Definition: disk.h:385
SCSI_ADDRESS ScsiAddress
Definition: disk.h:325
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:871
NTSTATUS ErrorCode
Definition: iotypes.h:2007
NTSTATUS FinalStatus
Definition: iotypes.h:2009
UCHAR PathId
Definition: scsi_port.h:149
UCHAR TargetId
Definition: scsi_port.h:150
UCHAR PortNumber
Definition: scsi_port.h:148
UCHAR SenseInfoBufferLength
Definition: srb.h:259
UCHAR Cdb[16]
Definition: srb.h:279
PVOID SenseInfoBuffer
Definition: srb.h:264
UCHAR Function
Definition: srb.h:250
UCHAR ScsiStatus
Definition: srb.h:252
UCHAR SrbStatus
Definition: srb.h:251
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
Definition: cdrw_hw.h:28
struct _CDB::_CDB10 CDB10
struct _CDB::_CDB6FORMAT CDB6FORMAT
struct _CDB::_MODE_SENSE MODE_SENSE
@ CriticalWorkQueue
Definition: extypes.h:189
#define IRP_MJ_SCSI
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by DriverEntry().

◆ DiskFlushComplete()

NTSTATUS NTAPI DiskFlushComplete ( IN PDEVICE_OBJECT  Fdo,
IN PIRP  Irp,
IN PVOID  Context 
)

Definition at line 1699 of file disk.c.

1727{
1728 PDISK_GROUP_CONTEXT FlushContext;
1731 PDISK_DATA diskData;
1732#ifdef _MSC_VER
1733 #pragma warning(suppress:4311) // pointer truncation from 'PVOID' to 'NTSTATUS'
1734#endif
1735 NTSTATUS SyncCacheStatus = (NTSTATUS)(ULONG_PTR)Context;
1736
1737 TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_GENERAL, "DiskFlushComplete: %p %p\n", Fdo, Irp));
1738
1739 //
1740 // Get the flush context from the device extension
1741 //
1742 fdoExt = (PFUNCTIONAL_DEVICE_EXTENSION)Fdo->DeviceExtension;
1743 diskData = (PDISK_DATA)fdoExt->CommonExtension.DriverData;
1744 NT_ASSERT(diskData != NULL);
1745 _Analysis_assume_(diskData != NULL);
1746
1747 FlushContext = &diskData->FlushContext;
1748
1749 //
1750 // Make sure everything is in order
1751 //
1752 NT_ASSERT(Irp == FlushContext->CurrIrp);
1753
1754 TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI, "DiskFlushComplete: completing irp %p\n", Irp));
1755 status = ClassIoComplete(Fdo, Irp, &FlushContext->Srb.Srb);
1756
1757 //
1758 // Make sure that ClassIoComplete did not decide to retry this request
1759 //
1761
1762 //
1763 // If sync cache failed earlier, final status of the flush request needs to be failure
1764 // even if SRB_FUNCTION_FLUSH srb request succeeded
1765 //
1766 if (NT_SUCCESS(status) &&
1767 (!NT_SUCCESS(SyncCacheStatus))) {
1768 Irp->IoStatus.Status = status = SyncCacheStatus;
1769 }
1770
1771 //
1772 // Complete the flush requests tagged to this one
1773 //
1774
1775 while (!IsListEmpty(&FlushContext->CurrList)) {
1776
1777 PLIST_ENTRY listEntry = RemoveHeadList(&FlushContext->CurrList);
1778 PIRP tempIrp = CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry);
1779
1780 InitializeListHead(&tempIrp->Tail.Overlay.ListEntry);
1781 tempIrp->IoStatus = Irp->IoStatus;
1782
1783 ClassReleaseRemoveLock(Fdo, tempIrp);
1785 }
1786
1787
1788 //
1789 // Notify the next group's representative that it may go ahead now
1790 //
1791 KeSetEvent(&FlushContext->Event, IO_NO_INCREMENT, FALSE);
1792
1793
1794 TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI, "DiskFlushComplete: irp %p status = 0x%x\n", Irp, status));
1795
1796 return status;
1797}
#define NTSTATUS
Definition: precomp.h:21
NTSTATUS NTAPI ClassIoComplete(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
Definition: class.c:3768
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
DISK_GROUP_CONTEXT FlushContext
Definition: disk.h:379
SCSI_REQUEST_BLOCK Srb
Definition: disk.h:131
KEVENT Event
Definition: disk.h:148
LIST_ENTRY CurrList
Definition: disk.h:108
IO_STATUS_BLOCK IoStatus
Definition: typedefs.h:120
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

◆ DiskFlushDispatch()

VOID DiskFlushDispatch ( IN PDEVICE_OBJECT  Fdo,
IN PDISK_GROUP_CONTEXT  FlushContext 
)

Definition at line 1534 of file disk.c.

1558{
1559 PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
1560 PSCSI_REQUEST_BLOCK srb = &FlushContext->Srb.Srb;
1561 PSTORAGE_REQUEST_BLOCK srbEx = &FlushContext->Srb.SrbEx;
1563 PSTOR_ADDR_BTL8 storAddrBtl8;
1564 PSRBEX_DATA_SCSI_CDB16 srbExDataCdb16;
1565 NTSTATUS SyncCacheStatus = STATUS_SUCCESS;
1566
1567 //
1568 // Fill in the srb fields appropriately
1569 //
1570 if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1571 RtlZeroMemory(srbEx, sizeof(FlushContext->Srb.SrbExBuffer));
1572
1574 srbEx->Function = SRB_FUNCTION_STORAGE_REQUEST_BLOCK;
1575 srbEx->Signature = SRB_SIGNATURE;
1576 srbEx->Version = STORAGE_REQUEST_BLOCK_VERSION_1;
1577 srbEx->SrbLength = sizeof(FlushContext->Srb.SrbExBuffer);
1578 srbEx->RequestPriority = IoGetIoPriorityHint(FlushContext->CurrIrp);
1579 srbEx->AddressOffset = sizeof(STORAGE_REQUEST_BLOCK);
1580 srbEx->TimeOutValue = fdoExt->TimeOutValue * 4;
1581 srbEx->RequestTag = SP_UNTAGGED;
1582 srbEx->RequestAttribute = SRB_SIMPLE_TAG_REQUEST;
1583 srbEx->SrbFlags = fdoExt->SrbFlags;
1584
1585 //
1586 // Set up address fields
1587 //
1588
1589 storAddrBtl8 = (PSTOR_ADDR_BTL8) ((PUCHAR)srbEx + srbEx->AddressOffset);
1590 storAddrBtl8->Type = STOR_ADDRESS_TYPE_BTL8;
1591 storAddrBtl8->AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
1592
1593 } else {
1595
1597 srb->TimeOutValue = fdoExt->TimeOutValue * 4;
1598 srb->QueueTag = SP_UNTAGGED;
1600 srb->SrbFlags = fdoExt->SrbFlags;
1601 }
1602
1603 //
1604 // If write caching is enabled then send down a synchronize cache request
1605 //
1607 {
1608
1609 if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1610 srbEx->SrbFunction = SRB_FUNCTION_EXECUTE_SCSI;
1611 srbEx->NumSrbExData = 1;
1612
1613 //
1614 // Set up SCSI SRB extended data fields
1615 //
1616
1617 srbEx->SrbExDataOffset[0] = sizeof(STORAGE_REQUEST_BLOCK) +
1618 sizeof(STOR_ADDR_BTL8);
1619 if ((srbEx->SrbExDataOffset[0] + sizeof(SRBEX_DATA_SCSI_CDB16)) <= srbEx->SrbLength) {
1620 srbExDataCdb16 = (PSRBEX_DATA_SCSI_CDB16)((PUCHAR)srbEx + srbEx->SrbExDataOffset[0]);
1621 srbExDataCdb16->Type = SrbExDataTypeScsiCdb16;
1622 srbExDataCdb16->Length = SRBEX_DATA_SCSI_CDB16_LENGTH;
1623 srbExDataCdb16->CdbLength = 10;
1624 srbExDataCdb16->Cdb[0] = SCSIOP_SYNCHRONIZE_CACHE;
1625 } else {
1626 // Should not happen
1628 return;
1629 }
1630
1631 } else {
1633 srb->CdbLength = 10;
1634 srb->Cdb[0] = SCSIOP_SYNCHRONIZE_CACHE;
1635 }
1636
1637 TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI, "DiskFlushDispatch: sending sync cache\n"));
1638
1639 SyncCacheStatus = ClassSendSrbSynchronous(Fdo, srb, NULL, 0, TRUE);
1640 }
1641
1642 //
1643 // Set up a FLUSH SRB
1644 //
1645 if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1646 srbEx->SrbFunction = SRB_FUNCTION_FLUSH;
1647 srbEx->NumSrbExData = 0;
1648 srbEx->SrbExDataOffset[0] = 0;
1649 srbEx->OriginalRequest = FlushContext->CurrIrp;
1650 srbEx->SrbStatus = 0;
1651
1652 //
1653 // Make sure that this srb does not get freed
1654 //
1655 SET_FLAG(srbEx->SrbFlags, SRB_CLASS_FLAGS_PERSISTANT);
1656
1657 } else {
1659 srb->CdbLength = 0;
1660 srb->OriginalRequest = FlushContext->CurrIrp;
1661 srb->SrbStatus = 0;
1662 srb->ScsiStatus = 0;
1663
1664 //
1665 // Make sure that this srb does not get freed
1666 //
1668 }
1669
1670 //
1671 // Make sure that this request does not get retried
1672 //
1673 irpSp = IoGetCurrentIrpStackLocation(FlushContext->CurrIrp);
1674
1675 irpSp->Parameters.Others.Argument4 = (PVOID) 0;
1676
1677 //
1678 // Fill in the irp fields appropriately
1679 //
1680 irpSp = IoGetNextIrpStackLocation(FlushContext->CurrIrp);
1681
1682 irpSp->MajorFunction = IRP_MJ_SCSI;
1683 irpSp->Parameters.Scsi.Srb = srb;
1684
1685 IoSetCompletionRoutine(FlushContext->CurrIrp, DiskFlushComplete, (PVOID)(ULONG_PTR)SyncCacheStatus, TRUE, TRUE, TRUE);
1686
1687 TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI, "DiskFlushDispatch: sending srb flush on irp %p\n", FlushContext->CurrIrp));
1688
1689 //
1690 // Send down the flush request
1691 //
1692 IoCallDriver(((PCOMMON_DEVICE_EXTENSION)fdoExt)->LowerDeviceObject, FlushContext->CurrIrp);
1693}
#define SCSIOP_SYNCHRONIZE_CACHE
Definition: cdrw_hw.h:918
#define DEV_WRITE_CACHE
Definition: classpnp.h:178
_In_z_ PCCHAR _In_ PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:983
#define SRB_CLASS_FLAGS_PERSISTANT
Definition: classpnp.h:20
static const WCHAR Signature[]
Definition: parser.c:141
NTSTATUS NTAPI ClassSendSrbSynchronous(_In_ PDEVICE_OBJECT Fdo, _Inout_ PSCSI_REQUEST_BLOCK _Srb, _In_reads_bytes_opt_(BufferLength) PVOID BufferAddress, _In_ ULONG BufferLength, _In_ BOOLEAN WriteToDevice)
Definition: class.c:4042
IO_COMPLETION_ROUTINE DiskFlushComplete
Definition: disk.h:599
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:282
#define SP_UNTAGGED
Definition: srb.h:233
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:423
#define SRB_FUNCTION_FLUSH
Definition: srb.h:323
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define IoCallDriver
Definition: irp.c:1225
struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 * PSTOR_ADDR_BTL8
#define STOR_ADDRESS_TYPE_BTL8
Definition: scsi.h:3525
struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 STOR_ADDR_BTL8
#define STOR_ADDR_BTL8_ADDRESS_LENGTH
Definition: scsi.h:3528
#define SRB_SIGNATURE
Definition: srb.h:616
#define STORAGE_REQUEST_BLOCK_VERSION_1
Definition: srb.h:617
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 SRBEX_DATA_SCSI_CDB16
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:664
@ SrbExDataTypeScsiCdb16
Definition: srb.h:459
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 * PSRBEX_DATA_SCSI_CDB16
STORAGE_REQUEST_BLOCK
Definition: srb.h:661
#define SRBEX_DATA_SCSI_CDB16_LENGTH
Definition: srb.h:489
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
UCHAR QueueTag
Definition: srb.h:256
ULONG TimeOutValue
Definition: srb.h:262
PVOID OriginalRequest
Definition: srb.h:266
UCHAR QueueAction
Definition: srb.h:257
UCHAR CdbLength
Definition: srb.h:258
ULONG SrbFlags
Definition: srb.h:260
USHORT Length
Definition: srb.h:249
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
NTKRNLVISTAAPI IO_PRIORITY_HINT NTAPI IoGetIoPriorityHint(_In_ PIRP Irp)
Definition: io.c:123
irpSp
Definition: iofuncs.h:2719

Referenced by DiskShutdownFlush().

◆ DiskGetCacheInformation()

NTSTATUS NTAPI DiskGetCacheInformation ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN PDISK_CACHE_INFORMATION  CacheInfo 
)

Definition at line 3019 of file disk.c.

3044{
3045 PMODE_PARAMETER_HEADER modeData;
3046 PMODE_CACHING_PAGE pageData;
3047
3048 ULONG length;
3049
3050 PAGED_CODE();
3051
3052
3053
3054 modeData = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
3057
3058 if (modeData == NULL) {
3059
3060 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskGetSetCacheInformation: Unable to allocate mode "
3061 "data buffer\n"));
3063 }
3064
3065 RtlZeroMemory(modeData, MODE_DATA_SIZE);
3066
3067 length = ClassModeSense(FdoExtension->DeviceObject,
3068 (PCHAR) modeData,
3071
3072 if (length < sizeof(MODE_PARAMETER_HEADER)) {
3073
3074 //
3075 // Retry the request in case of a check condition.
3076 //
3077
3078 length = ClassModeSense(FdoExtension->DeviceObject,
3079 (PCHAR) modeData,
3082
3083 if (length < sizeof(MODE_PARAMETER_HEADER)) {
3084
3085 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskGetCacheInformation: Mode Sense failed\n"));
3086
3087 FREE_POOL(modeData);
3089 }
3090 }
3091
3092 //
3093 // If the length is greater than length indicated by the mode data reset
3094 // the data to the mode data.
3095 //
3096
3097 if (length > (ULONG) (modeData->ModeDataLength + 1)) {
3098 length = modeData->ModeDataLength + 1;
3099 }
3100
3101 //
3102 // Check to see if the write cache is enabled.
3103 //
3104
3105 pageData = ClassFindModePage((PCHAR) modeData,
3106 length,
3108 TRUE);
3109
3110 //
3111 // Check if valid caching page exists.
3112 //
3113
3114 if (pageData == NULL) {
3115 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskGetCacheInformation: Unable to find caching mode page.\n"));
3116 FREE_POOL(modeData);
3117 return STATUS_NOT_SUPPORTED;
3118 }
3119
3120 //
3121 // Copy the parameters over.
3122 //
3123
3124 RtlZeroMemory(CacheInfo, sizeof(DISK_CACHE_INFORMATION));
3125
3126 CacheInfo->ParametersSavable = pageData->PageSavable;
3127
3128 CacheInfo->ReadCacheEnabled = !(pageData->ReadDisableCache);
3129 CacheInfo->WriteCacheEnabled = pageData->WriteCacheEnable;
3130
3131
3132 //
3133 // Translate the values in the mode page into the ones defined in
3134 // ntdddisk.h.
3135 //
3136
3137 CacheInfo->ReadRetentionPriority =
3139 CacheInfo->WriteRetentionPriority =
3141
3142 CacheInfo->DisablePrefetchTransferLength =
3143 ((pageData->DisablePrefetchTransfer[0] << 8) +
3144 pageData->DisablePrefetchTransfer[1]);
3145
3146 CacheInfo->ScalarPrefetch.Minimum =
3147 ((pageData->MinimumPrefetch[0] << 8) + pageData->MinimumPrefetch[1]);
3148
3149 CacheInfo->ScalarPrefetch.Maximum =
3150 ((pageData->MaximumPrefetch[0] << 8) + pageData->MaximumPrefetch[1]);
3151
3152 if(pageData->MultiplicationFactor) {
3153 CacheInfo->PrefetchScalar = TRUE;
3154 CacheInfo->ScalarPrefetch.MaximumBlocks =
3155 ((pageData->MaximumPrefetchCeiling[0] << 8) +
3156 pageData->MaximumPrefetchCeiling[1]);
3157 }
3158
3159
3160 FREE_POOL(modeData);
3161 return STATUS_SUCCESS;
3162}
#define MODE_DATA_SIZE
Definition: cdrom.h:691
PVOID NTAPI ClassFindModePage(_In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode, _In_ BOOLEAN Use6Byte)
Definition: class.c:6798
ULONG NTAPI ClassModeSense(_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode)
Definition: class.c:6637
#define TRANSLATE_RETENTION_PRIORITY(_x)
Definition: disk.c:99
#define DISK_TAG_DISABLE_CACHE
Definition: disk.h:56
@ FdoExtension
Definition: precomp.h:48
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
UCHAR MultiplicationFactor
Definition: cdrw_hw.h:2778
UCHAR WriteCacheEnable
Definition: cdrw_hw.h:2779
UCHAR MinimumPrefetch[2]
Definition: cdrw_hw.h:2786
UCHAR WriteRetensionPriority
Definition: cdrw_hw.h:2782
UCHAR ReadRetensionPriority
Definition: cdrw_hw.h:2783
UCHAR MaximumPrefetchCeiling[2]
Definition: cdrw_hw.h:2788
UCHAR DisablePrefetchTransfer[2]
Definition: cdrw_hw.h:2785
UCHAR ReadDisableCache
Definition: cdrw_hw.h:2777
UCHAR MaximumPrefetch[2]
Definition: cdrw_hw.h:2787
char * PCHAR
Definition: typedefs.h:51
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

Referenced by DiskIoctlGetCacheInformation(), and DiskStartFdo().

◆ DiskGetInfoExceptionInformation()

NTSTATUS DiskGetInfoExceptionInformation ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN PMODE_INFO_EXCEPTIONS  ReturnPageData 
)

Definition at line 2896 of file disk.c.

2900{
2901 PMODE_PARAMETER_HEADER modeData;
2902 PMODE_INFO_EXCEPTIONS pageData;
2903 ULONG length;
2904
2906
2907 PAGED_CODE();
2908
2909 //
2910 // ReturnPageData is allocated by the caller
2911 //
2912
2913 modeData = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
2916
2917 if (modeData == NULL) {
2918
2919 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_WMI, "DiskGetInfoExceptionInformation: Unable to allocate mode "
2920 "data buffer\n"));
2922 }
2923
2924 RtlZeroMemory(modeData, MODE_DATA_SIZE);
2925
2926 length = ClassModeSense(FdoExtension->DeviceObject,
2927 (PCHAR) modeData,
2930
2931 if (length < sizeof(MODE_PARAMETER_HEADER)) {
2932
2933 //
2934 // Retry the request in case of a check condition.
2935 //
2936
2937 length = ClassModeSense(FdoExtension->DeviceObject,
2938 (PCHAR) modeData,
2941
2942 if (length < sizeof(MODE_PARAMETER_HEADER)) {
2943 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_WMI, "DiskGetInfoExceptionInformation: Mode Sense failed\n"));
2944 FREE_POOL(modeData);
2946 }
2947 }
2948
2949 //
2950 // If the length is greater than length indicated by the mode data reset
2951 // the data to the mode data.
2952 //
2953
2954 if (length > (ULONG) (modeData->ModeDataLength + 1)) {
2955 length = modeData->ModeDataLength + 1;
2956 }
2957
2958 //
2959 // Find the mode page for info exceptions
2960 //
2961
2962 pageData = ClassFindModePage((PCHAR) modeData,
2963 length,
2965 TRUE);
2966
2967 if (pageData != NULL) {
2968 RtlCopyMemory(ReturnPageData, pageData, sizeof(MODE_INFO_EXCEPTIONS));
2970 } else {
2972 }
2973
2974 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskGetInfoExceptionInformation: %s support SMART for device %p\n",
2975 NT_SUCCESS(status) ? "does" : "does not",
2976 FdoExtension->DeviceObject));
2977
2978 FREE_POOL(modeData);
2979
2980 return(status);
2981}
#define DISK_TAG_INFO_EXCEPTION
Definition: disk.h:55
#define MODE_PAGE_FAULT_REPORTING
Definition: scsi.h:218
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by DiskFdoExecuteWmiMethod(), and DiskFdoQueryWmiDataBlock().

◆ DiskIoctlClearVerify()

NTSTATUS DiskIoctlClearVerify ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 5313 of file disk.c.

5339{
5341
5342 //
5343 // Validate the request.
5344 //
5345
5346 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlClearVerify: DeviceObject %p Irp %p\n", DeviceObject, Irp));
5347
5348 //
5349 // If the caller is kernel mode, set the verify bit.
5350 //
5351
5352 if (Irp->RequestorMode == KernelMode) {
5353
5356
5357 }
5358 return status;
5359}
#define KernelMode
Definition: asm.h:34

Referenced by DiskDeviceControl().

◆ DiskIoctlEnableFailurePrediction()

NTSTATUS DiskIoctlEnableFailurePrediction ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 4419 of file disk.c.

4445{
4446 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
4447 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
4448 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
4451 PSTORAGE_FAILURE_PREDICTION_CONFIG enablePrediction;
4452
4453 //
4454 // This function must be called at less than dispatch level.
4455 // Fail if IRQL >= DISPATCH_LEVEL.
4456 //
4457 PAGED_CODE();
4458 CHECK_IRQL();
4459
4460 //
4461 // Validate the request.
4462 //
4463
4464 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlEnableFailurePrediction: DeviceObject %p Irp %p\n", DeviceObject, Irp));
4465
4466 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(STORAGE_FAILURE_PREDICTION_CONFIG) ||
4467 irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_FAILURE_PREDICTION_CONFIG)) {
4468
4469 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlEnableFailurePrediction: Buffer too small.\n"));
4471 }
4472
4473 enablePrediction = (PSTORAGE_FAILURE_PREDICTION_CONFIG)Irp->AssociatedIrp.SystemBuffer;
4474
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"));
4479 }
4480
4481 if (enablePrediction->Reserved != 0) {
4482 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlEnableFailurePrediction: Reserved bytes are not zero!\n"));
4484 }
4485
4486 //
4487 // Default to success. This might get overwritten on failure below.
4488 //
4490
4491 //
4492 // If this is a "set" and the current state (enabled/disabled) is
4493 // different from the sender's desired state,
4494 //
4495 if (enablePrediction->Set && enablePrediction->Enabled != diskData->FailurePredictionEnabled) {
4498 //
4499 // SMART or IOCTL based failure prediction is being used so call
4500 // the generic function that is normally called in the WMI path.
4501 //
4502 status = DiskEnableDisableFailurePrediction(fdoExtension, enablePrediction->Enabled);
4503 } else if (diskData->ScsiInfoExceptionsSupported) {
4504 //
4505 // If we know that the device supports the Informational Exceptions
4506 // mode page, try to enable/disable failure prediction that way.
4507 //
4508 status = DiskEnableInfoExceptions(fdoExtension, enablePrediction->Enabled);
4509 }
4510 }
4511
4512 //
4513 // Return the current state regardless if this was a "set" or a "get".
4514 //
4515 enablePrediction->Enabled = diskData->FailurePredictionEnabled;
4516
4517 if (NT_SUCCESS(status)) {
4518 Irp->IoStatus.Information = sizeof(STORAGE_FAILURE_PREDICTION_CONFIG);
4519 }
4520
4521 return status;
4522}
@ FailurePredictionSmart
Definition: classpnp.h:236
@ FailurePredictionIoctl
Definition: classpnp.h:235
NTSTATUS DiskEnableDisableFailurePrediction(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable)
Definition: diskwmi.c:1126
#define CHECK_IRQL()
Definition: disk.h:458
NTSTATUS DiskEnableInfoExceptions(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ BOOLEAN Enable)
Definition: diskwmi.c:979
BOOLEAN ScsiInfoExceptionsSupported
Definition: disk.h:340
FAILURE_PREDICTION_METHOD FailurePredictionCapability
Definition: disk.h:331
BOOLEAN FailurePredictionEnabled
Definition: disk.h:346
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by DiskDeviceControl().

◆ DiskIoctlGetCacheInformation()

NTSTATUS DiskIoctlGetCacheInformation ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 3840 of file disk.c.

3868{
3869 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
3871 PDISK_CACHE_INFORMATION cacheInfo = Irp->AssociatedIrp.SystemBuffer;
3873
3874 //
3875 // This function must be called at less than dispatch level.
3876 // Fail if IRQL >= DISPATCH_LEVEL.
3877 //
3878 PAGED_CODE();
3879 CHECK_IRQL();
3880
3881 //
3882 // Validate the request.
3883 //
3884
3885 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlGetCacheInformation: DeviceObject %p Irp %p\n", DeviceObject, Irp));
3886
3887 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_CACHE_INFORMATION)) {
3888
3889 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlGetCacheInformation: Output buffer too small.\n"));
3891 }
3892
3893 status = DiskGetCacheInformation(fdoExtension, cacheInfo);
3894
3895 if (NT_SUCCESS(status)) {
3896 Irp->IoStatus.Information = sizeof(DISK_CACHE_INFORMATION);
3897
3898 //
3899 // Make sure write cache setting is reflected in device extension
3900 //
3901 if (cacheInfo->WriteCacheEnabled)
3902 {
3903 SET_FLAG(fdoExtension->DeviceFlags, DEV_WRITE_CACHE);
3904 }
3905 else
3906 {
3907 CLEAR_FLAG(fdoExtension->DeviceFlags, DEV_WRITE_CACHE);
3908 }
3909 ADJUST_FUA_FLAG(fdoExtension);
3910
3911 }
3912 return status;
3913}
struct _DISK_CACHE_INFORMATION DISK_CACHE_INFORMATION

Referenced by DiskDeviceControl().

◆ DiskIoctlGetCacheSetting()

NTSTATUS DiskIoctlGetCacheSetting ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 3347 of file disk.c.

3371{
3372 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
3375
3376 PAGED_CODE();
3377
3378 if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_CACHE_SETTING))
3379 {
3381 }
3382 else
3383 {
3384 PDISK_CACHE_SETTING cacheSetting = (PDISK_CACHE_SETTING)Irp->AssociatedIrp.SystemBuffer;
3385
3386 cacheSetting->Version = sizeof(DISK_CACHE_SETTING);
3387 cacheSetting->State = DiskCacheNormal;
3388
3389 //
3390 // Determine whether it is safe to turn on the cache
3391 //
3393 {
3395 }
3396
3397 //
3398 // Determine whether it is possible to modify the cache setting
3399 //
3401 {
3402 cacheSetting->State = DiskCacheModifyUnsuccessful;
3403 }
3404
3405 cacheSetting->IsPowerProtected = TEST_FLAG(fdoExtension->DeviceFlags, DEV_POWER_PROTECTED);
3406
3407 Irp->IoStatus.Information = sizeof(DISK_CACHE_SETTING);
3408 }
3409
3410 return status;
3411}
#define DEV_POWER_PROTECTED
Definition: cdrom.h:143
#define CLASS_SPECIAL_MODIFY_CACHE_UNSUCCESSFUL
Definition: classpnp.h:173
struct _DISK_CACHE_SETTING * PDISK_CACHE_SETTING
@ DiskCacheModifyUnsuccessful
Definition: ntdddisk.h:831
@ DiskCacheWriteThroughNotSupported
Definition: ntdddisk.h:830
@ DiskCacheNormal
Definition: ntdddisk.h:829
struct _DISK_CACHE_SETTING DISK_CACHE_SETTING
DISK_CACHE_STATE State
Definition: ntdddisk.h:836
BOOLEAN IsPowerProtected
Definition: ntdddisk.h:837

Referenced by DiskDeviceControl().

◆ DiskIoctlGetDriveGeometry()

NTSTATUS DiskIoctlGetDriveGeometry ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 3582 of file disk.c.

3609{
3610 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
3611 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
3612 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
3615
3616 //
3617 // This function must be called at less than dispatch level.
3618 // Fail if IRQL >= DISPATCH_LEVEL.
3619 //
3620 PAGED_CODE();
3621 CHECK_IRQL();
3622
3623 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY)) {
3624
3625 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlGetDriveGeometry: Output buffer too small.\n"));
3627 }
3628
3629 if (TEST_FLAG(DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA)) {
3630
3631 //
3632 // Issue ReadCapacity to update device extension
3633 // with information for current media.
3634 //
3635
3636 status = DiskReadDriveCapacity(commonExtension->PartitionZeroExtension->DeviceObject);
3637
3638 //
3639 // Note whether the drive is ready.
3640 //
3641
3642 diskData->ReadyStatus = status;
3643
3644 if (!NT_SUCCESS(status)) {
3645 return status;
3646 }
3647 }
3648
3649 //
3650 // Copy drive geometry information from device extension.
3651 //
3652
3653 RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
3654 &(fdoExtension->DiskGeometry),
3655 sizeof(DISK_GEOMETRY));
3656
3657 if (((PDISK_GEOMETRY)Irp->AssociatedIrp.SystemBuffer)->BytesPerSector == 0) {
3658 ((PDISK_GEOMETRY)Irp->AssociatedIrp.SystemBuffer)->BytesPerSector = 512;
3659 }
3660 Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
3661 return STATUS_SUCCESS;
3662}
#define DiskReadDriveCapacity(Fdo)
Definition: disk.h:818
struct _DISK_GEOMETRY DISK_GEOMETRY
struct _DISK_GEOMETRY * PDISK_GEOMETRY
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
NTSTATUS ReadyStatus
Definition: disk.h:319
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

Referenced by DiskDeviceControl().

◆ DiskIoctlGetDriveGeometryEx()

NTSTATUS DiskIoctlGetDriveGeometryEx ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 3672 of file disk.c.

3699{
3701 PIO_STACK_LOCATION irpStack;
3702 PCOMMON_DEVICE_EXTENSION commonExtension;
3703 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
3704 PDISK_DATA diskData;
3705 PDISK_GEOMETRY_EX_INTERNAL geometryEx;
3707
3708 //
3709 // This function must be called at less than dispatch level.
3710 // Fail if IRQL >= DISPATCH_LEVEL.
3711 //
3712 PAGED_CODE();
3713 CHECK_IRQL();
3714
3715 //
3716 // Setup parameters
3717 //
3718
3719 commonExtension = DeviceObject->DeviceExtension;
3720 fdoExtension = DeviceObject->DeviceExtension;
3721 diskData = (PDISK_DATA)(commonExtension->DriverData);
3722 irpStack = IoGetCurrentIrpStackLocation ( Irp );
3723 geometryEx = NULL;
3724 OutputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
3725
3726 //
3727 // Check that the buffer is large enough. It must be large enough
3728 // to hold at lest the Geometry and DiskSize fields of of the
3729 // DISK_GEOMETRY_EX structure.
3730 //
3731
3733
3734 //
3735 // Buffer too small. Bail out, telling the caller the required
3736 // size.
3737 //
3738
3739 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlGetDriveGeometryEx: Output buffer too small.\n"));
3741 return status;
3742 }
3743
3744 if (TEST_FLAG (DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA)) {
3745
3746 //
3747 // Issue a ReadCapacity to update device extension
3748 // with information for the current media.
3749 //
3750
3751 status = DiskReadDriveCapacity(commonExtension->PartitionZeroExtension->DeviceObject);
3752
3753 diskData->ReadyStatus = status;
3754
3755 if (!NT_SUCCESS (status)) {
3756 return status;
3757 }
3758 }
3759
3760 //
3761 // Copy drive geometry.
3762 //
3763
3764 geometryEx = (PDISK_GEOMETRY_EX_INTERNAL)Irp->AssociatedIrp.SystemBuffer;
3765 geometryEx->Geometry = fdoExtension->DiskGeometry;
3766 if (geometryEx->Geometry.BytesPerSector == 0) {
3767 geometryEx->Geometry.BytesPerSector = 512;
3768 }
3769 geometryEx->DiskSize = commonExtension->PartitionZeroExtension->CommonExtension.PartitionLength;
3770
3771 //
3772 // If the user buffer is large enough to hold the partition information
3773 // then add that as well.
3774 //
3775
3777
3778 geometryEx->Partition.SizeOfPartitionInfo = sizeof (geometryEx->Partition);
3779 geometryEx->Partition.PartitionStyle = diskData->PartitionStyle;
3780
3781 switch ( diskData->PartitionStyle ) {
3782
3784
3785 //
3786 // Copy GPT signature.
3787 //
3788
3789 geometryEx->Partition.Gpt.DiskId = diskData->Efi.DiskId;
3790 break;
3791
3793
3794 //
3795 // Copy MBR signature and checksum.
3796 //
3797
3798 geometryEx->Partition.Mbr.Signature = diskData->Mbr.Signature;
3799 geometryEx->Partition.Mbr.CheckSum = diskData->Mbr.MbrCheckSum;
3800 break;
3801
3802 default:
3803
3804 //
3805 // This is a raw disk. Zero out the signature area so
3806 // nobody gets confused.
3807 //
3808
3809 RtlZeroMemory(&geometryEx->Partition, sizeof (geometryEx->Partition));
3810 }
3811 }
3812
3813 //
3814 // If the buffer is large enough to hold the detection information,
3815 // then also add that.
3816 //
3817
3819
3820 geometryEx->Detection.SizeOfDetectInfo = sizeof (geometryEx->Detection);
3821
3822 status = DiskGetDetectInfo(fdoExtension, &geometryEx->Detection);
3823
3824 //
3825 // Failed to obtain detection information, set to none.
3826 //
3827
3828 if (!NT_SUCCESS (status)) {
3829 geometryEx->Detection.DetectionType = DetectNone;
3830 }
3831 }
3832
3834 Irp->IoStatus.Information = min (OutputBufferLength, sizeof (DISK_GEOMETRY_EX_INTERNAL));
3835
3836 return status;
3837}
struct _DISK_GEOMETRY_EX_INTERNAL * PDISK_GEOMETRY_EX_INTERNAL
#define DiskGetDetectInfo(FdoExtension, DetectInfo)
Definition: disk.h:861
@ PARTITION_STYLE_GPT
Definition: imports.h:202
@ PARTITION_STYLE_MBR
Definition: imports.h:201
#define min(a, b)
Definition: monoChain.cc:55
long LONG
Definition: pedump.c:60
PARTITION_STYLE PartitionStyle
Definition: disk.h:197
struct _DISK_DATA::@1055::@1059 Efi
struct _DISK_DATA::@1055::@1058 Mbr
LARGE_INTEGER DiskSize
Definition: disk.c:3666
DISK_PARTITION_INFO Partition
Definition: disk.c:3667
DISK_GEOMETRY Geometry
Definition: disk.c:3665
DISK_DETECTION_INFO Detection
Definition: disk.c:3668
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList

Referenced by DiskDeviceControl().

◆ DiskIoctlGetLengthInfo()

NTSTATUS DiskIoctlGetLengthInfo ( IN OUT PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 3492 of file disk.c.

3518{
3520 PIO_STACK_LOCATION irpStack;
3521 PGET_LENGTH_INFORMATION lengthInfo;
3522 PFUNCTIONAL_DEVICE_EXTENSION p0Extension;
3523 PCOMMON_DEVICE_EXTENSION commonExtension;
3524 PDISK_DATA partitionZeroData;
3525 NTSTATUS oldReadyStatus;
3526
3527 //
3528 // This function must be called at less than dispatch level.
3529 // Fail if IRQL >= DISPATCH_LEVEL.
3530 //
3531 PAGED_CODE();
3532 CHECK_IRQL();
3533
3534 //
3535 // Initialization
3536 //
3537
3538 commonExtension = DeviceObject->DeviceExtension;
3540 p0Extension = commonExtension->PartitionZeroExtension;
3541 partitionZeroData = ((PDISK_DATA) p0Extension->CommonExtension.DriverData);
3542
3543 //
3544 // Check that the buffer is large enough.
3545 //
3546
3547 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GET_LENGTH_INFORMATION)) {
3549 }
3550
3551 //
3552 // Update the geometry in case it has changed
3553 //
3554
3556
3557 //
3558 // Note whether the drive is ready. If the status has changed then
3559 // notify pnp.
3560 //
3561
3562 oldReadyStatus = InterlockedExchange(&(partitionZeroData->ReadyStatus), status);
3563
3564 if(partitionZeroData->ReadyStatus != oldReadyStatus) {
3566 }
3567
3568 if(!NT_SUCCESS(status)) {
3569 return status;
3570 }
3571 lengthInfo = (PGET_LENGTH_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
3572
3573 lengthInfo->Length = commonExtension->PartitionLength;
3574
3576 Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
3577
3578 return status;
3579}
#define InterlockedExchange
Definition: armddk.h:54
struct _GET_LENGTH_INFORMATION * PGET_LENGTH_INFORMATION
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:1772
LARGE_INTEGER PartitionLength
Definition: classpnp.h:618
LARGE_INTEGER Length
Definition: imports.h:232
@ BusRelations
Definition: iotypes.h:2152

Referenced by DiskDeviceControl().

◆ DiskIoctlGetMediaTypesEx()

NTSTATUS DiskIoctlGetMediaTypesEx ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 3994 of file disk.c.

4021{
4022 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
4025
4026 PMODE_PARAMETER_HEADER modeData;
4027 PMODE_PARAMETER_BLOCK blockDescriptor;
4029 PCDB cdb;
4030 ULONG modeLength;
4031 ULONG retries = 4;
4032 UCHAR densityCode = 0;
4033 BOOLEAN writable = TRUE;
4034 BOOLEAN mediaPresent = FALSE;
4035 ULONG srbSize;
4037 PSTOR_ADDR_BTL8 storAddrBtl8 = NULL;
4038 PSRBEX_DATA_SCSI_CDB16 srbExDataCdb16 = NULL;
4039
4040 //
4041 // This function must be called at less than dispatch level.
4042 // Fail if IRQL >= DISPATCH_LEVEL.
4043 //
4044 PAGED_CODE();
4045 CHECK_IRQL();
4046
4047 //
4048 // Validate the request.
4049 //
4050
4051 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlGetMediaTypesEx: DeviceObject %p Irp %p\n", DeviceObject, Irp));
4052
4053 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GET_MEDIA_TYPES)) {
4054
4055 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlGetMediaTypesEx: Output buffer too small.\n"));
4057 }
4058
4059 if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
4061 } else {
4062 srbSize = SCSI_REQUEST_BLOCK_SIZE;
4063 }
4064
4065 srb = ExAllocatePoolWithTag(NonPagedPoolNx,
4066 srbSize,
4067 DISK_TAG_SRB);
4068
4069 if (srb == NULL) {
4070 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlGetMediaTypesEx: Unable to allocate memory.\n"));
4072 }
4073
4074 RtlZeroMemory(srb, srbSize);
4075
4076 //
4077 // Send a TUR to determine if media is present.
4078 //
4079
4080 if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
4081 srbEx = (PSTORAGE_REQUEST_BLOCK)srb;
4082
4083 //
4084 // Set up STORAGE_REQUEST_BLOCK fields
4085 //
4086
4088 srbEx->Function = SRB_FUNCTION_STORAGE_REQUEST_BLOCK;
4089 srbEx->Signature = SRB_SIGNATURE;
4090 srbEx->Version = STORAGE_REQUEST_BLOCK_VERSION_1;
4091 srbEx->SrbLength = srbSize;
4092 srbEx->SrbFunction = SRB_FUNCTION_EXECUTE_SCSI;
4093 srbEx->RequestPriority = IoGetIoPriorityHint(Irp);
4094 srbEx->AddressOffset = sizeof(STORAGE_REQUEST_BLOCK);
4095 srbEx->NumSrbExData = 1;
4096
4097 // Set timeout value.
4098 srbEx->TimeOutValue = fdoExtension->TimeOutValue;
4099
4100 //
4101 // Set up address fields
4102 //
4103
4104 storAddrBtl8 = (PSTOR_ADDR_BTL8) ((PUCHAR)srbEx + srbEx->AddressOffset);
4105 storAddrBtl8->Type = STOR_ADDRESS_TYPE_BTL8;
4106 storAddrBtl8->AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
4107
4108 //
4109 // Set up SCSI SRB extended data fields
4110 //
4111
4112 srbEx->SrbExDataOffset[0] = sizeof(STORAGE_REQUEST_BLOCK) +
4113 sizeof(STOR_ADDR_BTL8);
4114 if ((srbEx->SrbExDataOffset[0] + sizeof(SRBEX_DATA_SCSI_CDB16)) <= srbEx->SrbLength) {
4115 srbExDataCdb16 = (PSRBEX_DATA_SCSI_CDB16)((PUCHAR)srbEx + srbEx->SrbExDataOffset[0]);
4116 srbExDataCdb16->Type = SrbExDataTypeScsiCdb16;
4117 srbExDataCdb16->Length = SRBEX_DATA_SCSI_CDB16_LENGTH;
4118 srbExDataCdb16->CdbLength = 6;
4119
4120 cdb = (PCDB)srbExDataCdb16->Cdb;
4121 } else {
4122 // Should not happen
4124
4125 FREE_POOL(srb);
4126 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlGetMediaTypesEx: Insufficient extended SRB size.\n"));
4127 return STATUS_INTERNAL_ERROR;
4128 }
4129
4130 } else {
4131
4134 srb->CdbLength = 6;
4135 cdb = (PCDB)srb->Cdb;
4136
4137 //
4138 // Set timeout value.
4139 //
4140
4141 srb->TimeOutValue = fdoExtension->TimeOutValue;
4142
4143 }
4144 cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
4145
4147 srb,
4148 NULL,
4149 0,
4150 FALSE);
4151
4152 if (NT_SUCCESS(status)) {
4153 mediaPresent = TRUE;
4154 }
4155
4156 modeLength = MODE_DATA_SIZE;
4157 modeData = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
4158 modeLength,
4160
4161 if (modeData == NULL) {
4162 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlGetMediaTypesEx: Unable to allocate memory.\n"));
4163 FREE_POOL(srb);
4165 }
4166
4167 RtlZeroMemory(modeData, modeLength);
4168
4169 //
4170 // Build the MODE SENSE CDB using previous SRB.
4171 //
4172
4173 if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
4174 srbEx->SrbStatus = 0;
4175 srbExDataCdb16->ScsiStatus = 0;
4176 srbExDataCdb16->CdbLength = 6;
4177
4178 //
4179 // Set timeout value from device extension.
4180 //
4181
4182 srbEx->TimeOutValue = fdoExtension->TimeOutValue;
4183 } else {
4184 srb->SrbStatus = 0;
4185 srb->ScsiStatus = 0;
4186 srb->CdbLength = 6;
4187
4188 //
4189 // Set timeout value from device extension.
4190 //
4191
4192 srb->TimeOutValue = fdoExtension->TimeOutValue;
4193 }
4194
4195 //
4196 // Page code of 0x3F will return all pages.
4197 // This command could fail if the data to be returned is
4198 // more than 256 bytes. In which case, we should get only
4199 // the caching page since we only need the block descriptor.
4200 // DiskFdoProcessError will change the page code to
4201 // MODE_PAGE_CACHING if there is an error.
4202 //
4203
4204 cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
4205 cdb->MODE_SENSE.PageCode = MODE_SENSE_RETURN_ALL;
4206 cdb->MODE_SENSE.AllocationLength = (UCHAR)modeLength;
4207
4208Retry:
4210 srb,
4211 modeData,
4212 modeLength,
4213 FALSE);
4214
4216
4217 if (retries--) {
4218
4219 //
4220 // Retry request.
4221 //
4222
4223 goto Retry;
4224 }
4225 } else if (SRB_STATUS(srb->SrbStatus) == SRB_STATUS_DATA_OVERRUN) {
4227 }
4228
4230
4231 //
4232 // Get the block descriptor.
4233 //
4234
4235 if (modeData->BlockDescriptorLength != 0) {
4236
4237 blockDescriptor = (PMODE_PARAMETER_BLOCK)((ULONG_PTR)modeData + sizeof(MODE_PARAMETER_HEADER));
4238 densityCode = blockDescriptor->DensityCode;
4239 }
4240
4241 if (TEST_FLAG(modeData->DeviceSpecificParameter,
4243
4244 writable = FALSE;
4245 }
4246
4248 Irp,
4249 modeData->MediumType,
4250 densityCode,
4251 mediaPresent,
4252 writable);
4253 //
4254 // If the buffer was too small, DetermineMediaTypes updated the status and information and the request will fail.
4255 //
4256
4257 } else {
4258 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlGetMediaTypesEx: Mode sense for header/bd failed. %lx\n", status));
4259 }
4260
4261 FREE_POOL(srb);
4262 FREE_POOL(modeData);
4263
4264 return status;
4265}
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
struct _MODE_PARAMETER_HEADER MODE_PARAMETER_HEADER
struct _MODE_PARAMETER_BLOCK * PMODE_PARAMETER_BLOCK
#define MODE_DSP_WRITE_PROTECT
Definition: cdrw_hw.h:2523
#define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE
Definition: classpnp.h:695
NTSTATUS DiskDetermineMediaTypes(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN UCHAR MediumType, IN UCHAR DensityCode, IN BOOLEAN MediaPresent, IN BOOLEAN IsWritable)
Definition: disk.c:655
#define DISK_TAG_SRB
Definition: disk.h:67
#define DISK_TAG_MODE_DATA
Definition: disk.h:62
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:357
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
UCHAR DeviceSpecificParameter
Definition: cdrw_hw.h:2507
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
struct _CDB::_CDB6GENERIC CDB6GENERIC

Referenced by DiskDeviceControl().

◆ DiskIoctlGetVolumeDiskExtents()

NTSTATUS DiskIoctlGetVolumeDiskExtents ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 5461 of file disk.c.

5488{
5489 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
5490 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
5493
5494 //
5495 // This function must be called at less than dispatch level.
5496 // Fail if IRQL >= DISPATCH_LEVEL.
5497 //
5498 PAGED_CODE();
5499 CHECK_IRQL();
5500
5501 //
5502 // Validate the request.
5503 //
5504
5505 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlGetVolumeDiskExtents: DeviceObject %p Irp %p\n", DeviceObject, Irp));
5506
5507
5508 if (TEST_FLAG(DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA)) {
5509
5510 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VOLUME_DISK_EXTENTS)) {
5511 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlGetVolumeDiskExtents: Output buffer too small.\n"));
5513 }
5514
5515 status = DiskReadDriveCapacity(commonExtension->PartitionZeroExtension->DeviceObject);
5516
5517 //
5518 // Note whether the drive is ready.
5519 //
5520
5521 diskData->ReadyStatus = status;
5522
5523 if (NT_SUCCESS(status)) {
5524
5525 PVOLUME_DISK_EXTENTS pVolExt = (PVOLUME_DISK_EXTENTS)Irp->AssociatedIrp.SystemBuffer;
5526
5527 pVolExt->NumberOfDiskExtents = 1;
5528 pVolExt->Extents[0].DiskNumber = commonExtension->PartitionZeroExtension->DeviceNumber;
5529 pVolExt->Extents[0].StartingOffset = commonExtension->StartingOffset;
5530 pVolExt->Extents[0].ExtentLength = commonExtension->PartitionLength;
5531
5532 Irp->IoStatus.Information = sizeof(VOLUME_DISK_EXTENTS);
5533 }
5534 }
5535
5536 return status;
5537}
struct _VOLUME_DISK_EXTENTS * PVOLUME_DISK_EXTENTS
LARGE_INTEGER StartingOffset
Definition: classpnp.h:619
ULONG DiskNumber
Definition: ntddvol.h:113
LARGE_INTEGER StartingOffset
Definition: ntddvol.h:114
LARGE_INTEGER ExtentLength
Definition: ntddvol.h:115
DISK_EXTENT Extents[1]
Definition: ntddvol.h:120
ULONG NumberOfDiskExtents
Definition: ntddvol.h:119
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138

Referenced by DiskDeviceControl().

◆ DiskIoctlIsWritable()

NTSTATUS DiskIoctlIsWritable ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 5063 of file disk.c.

5090{
5091 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
5093
5094 PMODE_PARAMETER_HEADER modeData;
5096 PCDB cdb = NULL;
5097 ULONG modeLength;
5098 ULONG retries = 4;
5099 ULONG srbSize;
5101 PSTOR_ADDR_BTL8 storAddrBtl8;
5102 PSRBEX_DATA_SCSI_CDB16 srbExDataCdb16;
5103
5104 //
5105 // This function must be called at less than dispatch level.
5106 // Fail if IRQL >= DISPATCH_LEVEL.
5107 //
5108 PAGED_CODE();
5109 CHECK_IRQL();
5110
5111 //
5112 // Validate the request.
5113 //
5114
5115 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlIsWritable: DeviceObject %p Irp %p\n", DeviceObject, Irp));
5116
5117 if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
5119 } else {
5120 srbSize = SCSI_REQUEST_BLOCK_SIZE;
5121 }
5122 srb = ExAllocatePoolWithTag(NonPagedPoolNx,
5123 srbSize,
5124 DISK_TAG_SRB);
5125
5126 if (srb == NULL) {
5127 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlIsWritable: Unable to allocate memory.\n"));
5129 }
5130
5131 RtlZeroMemory(srb, srbSize);
5132
5133 //
5134 // Allocate memory for a mode header and then some
5135 // for port drivers that need to convert to MODE10
5136 // or always return the MODE_PARAMETER_BLOCK (even
5137 // when memory was not allocated for this purpose)
5138 //
5139
5140 modeLength = MODE_DATA_SIZE;
5141 modeData = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
5142 modeLength,
5144
5145 if (modeData == NULL) {
5146 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlIsWritable: Unable to allocate memory.\n"));
5147 FREE_POOL(srb);
5149 }
5150
5151 RtlZeroMemory(modeData, modeLength);
5152
5153 //
5154 // Build the MODE SENSE CDB
5155 //
5156
5157 if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
5158 srbEx = (PSTORAGE_REQUEST_BLOCK)srb;
5159
5160 //
5161 // Set up STORAGE_REQUEST_BLOCK fields
5162 //
5163
5165 srbEx->Function = SRB_FUNCTION_STORAGE_REQUEST_BLOCK;
5166 srbEx->Signature = SRB_SIGNATURE;
5167 srbEx->Version = STORAGE_REQUEST_BLOCK_VERSION_1;
5168 srbEx->SrbLength = srbSize;
5169 srbEx->SrbFunction = SRB_FUNCTION_EXECUTE_SCSI;
5170 srbEx->RequestPriority = IoGetIoPriorityHint(Irp);
5171 srbEx->AddressOffset = sizeof(STORAGE_REQUEST_BLOCK);
5172 srbEx->NumSrbExData = 1;
5173
5174 // Set timeout value.
5175 srbEx->TimeOutValue = fdoExtension->TimeOutValue;
5176
5177 //
5178 // Set up address fields
5179 //
5180
5181 storAddrBtl8 = (PSTOR_ADDR_BTL8) ((PUCHAR)srbEx + srbEx->AddressOffset);
5182 storAddrBtl8->Type = STOR_ADDRESS_TYPE_BTL8;
5183 storAddrBtl8->AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
5184
5185 //
5186 // Set up SCSI SRB extended data fields
5187 //
5188
5189 srbEx->SrbExDataOffset[0] = sizeof(STORAGE_REQUEST_BLOCK) +
5190 sizeof(STOR_ADDR_BTL8);
5191 if ((srbEx->SrbExDataOffset[0] + sizeof(SRBEX_DATA_SCSI_CDB16)) <= srbEx->SrbLength) {
5192 srbExDataCdb16 = (PSRBEX_DATA_SCSI_CDB16)((PUCHAR)srbEx + srbEx->SrbExDataOffset[0]);
5193 srbExDataCdb16->Type = SrbExDataTypeScsiCdb16;
5194 srbExDataCdb16->Length = SRBEX_DATA_SCSI_CDB16_LENGTH;
5195 srbExDataCdb16->CdbLength = 6;
5196
5197 cdb = (PCDB)srbExDataCdb16->Cdb;
5198 } else {
5199 // Should not happen
5201
5202 FREE_POOL(srb);
5203 FREE_POOL(modeData);
5204 return STATUS_INTERNAL_ERROR;
5205 }
5206
5207 } else {
5210 srb->CdbLength = 6;
5211
5212 //
5213 // Set timeout value.
5214 //
5215
5216 srb->TimeOutValue = fdoExtension->TimeOutValue;
5217
5218 cdb = (PCDB)srb->Cdb;
5219 }
5220
5221 //
5222 // Page code of 0x3F will return all pages.
5223 // This command could fail if the data to be returned is
5224 // more than 256 bytes. In which case, we should get only
5225 // the caching page since we only need the block descriptor.
5226 // DiskFdoProcessError will change the page code to
5227 // MODE_PAGE_CACHING if there is an error.
5228 //
5229
5230 cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
5231 cdb->MODE_SENSE.PageCode = MODE_SENSE_RETURN_ALL;
5232 cdb->MODE_SENSE.AllocationLength = (UCHAR)modeLength;
5233
5234 while (retries != 0) {
5235
5237 srb,
5238 modeData,
5239 modeLength,
5240 FALSE);
5241
5245 }
5246 break;
5247 }
5248 retries--;
5249 }
5250
5251 if (NT_SUCCESS(status)) {
5252
5255 }
5256 }
5257
5258 FREE_POOL(srb);
5259 FREE_POOL(modeData);
5260 return status;
5261}
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161

Referenced by DiskDeviceControl().

◆ DiskIoctlPredictFailure()

NTSTATUS DiskIoctlPredictFailure ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 4268 of file disk.c.

4294{
4295 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
4296 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
4297 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
4300
4301 PSTORAGE_PREDICT_FAILURE checkFailure;
4302 STORAGE_FAILURE_PREDICT_STATUS diskSmartStatus;
4303 IO_STATUS_BLOCK ioStatus = { 0 };
4304 KEVENT event;
4305
4306 //
4307 // This function must be called at less than dispatch level.
4308 // Fail if IRQL >= DISPATCH_LEVEL.
4309 //
4310 PAGED_CODE();
4311 CHECK_IRQL();
4312
4313 //
4314 // Validate the request.
4315 //
4316
4317 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlPredictFailure: DeviceObject %p Irp %p\n", DeviceObject, Irp));
4318
4319 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_PREDICT_FAILURE)) {
4320
4321 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlPredictFailure: Output buffer too small.\n"));
4323 }
4324
4325 //
4326 // See if the disk is predicting failure
4327 //
4328
4329 checkFailure = (PSTORAGE_PREDICT_FAILURE)Irp->AssociatedIrp.SystemBuffer;
4330
4332 ULONG readBufferSize;
4333 PUCHAR readBuffer;
4334 PIRP readIrp;
4335 PDEVICE_OBJECT topOfStack;
4336
4337 checkFailure->PredictFailure = 0;
4338
4340
4342
4343 //
4344 // SCSI disks need to have a read sent down to provoke any
4345 // failures to be reported.
4346 //
4347 // Issue a normal read operation. The error-handling code in
4348 // classpnp will take care of a failure prediction by logging the
4349 // correct event.
4350 //
4351
4352 readBufferSize = fdoExtension->DiskGeometry.BytesPerSector;
4353 readBuffer = ExAllocatePoolWithTag(NonPagedPoolNx,
4354 readBufferSize,
4356
4357 if (readBuffer != NULL) {
4359
4360 offset.QuadPart = 0;
4362 topOfStack,
4363 readBuffer,
4364 readBufferSize,
4365 &offset,
4366 &event,
4367 &ioStatus);
4368
4369 if (readIrp != NULL) {
4370
4371 status = IoCallDriver(topOfStack, readIrp);
4372 if (status == STATUS_PENDING) {
4374 status = ioStatus.Status;
4375 }
4376
4377
4378 } else {
4380 }
4381
4382 FREE_POOL(readBuffer);
4383 } else {
4385 }
4386
4387 ObDereferenceObject(topOfStack);
4388 }
4389
4391 {
4394
4395 status = DiskReadFailurePredictStatus(fdoExtension, &diskSmartStatus);
4396
4397 if (NT_SUCCESS(status)) {
4398
4399 status = DiskReadFailurePredictData(fdoExtension,
4400 Irp->AssociatedIrp.SystemBuffer);
4401
4402 if (diskSmartStatus.PredictFailure) {
4403 checkFailure->PredictFailure = 1;
4404 } else {
4405 checkFailure->PredictFailure = 0;
4406 }
4407
4408 Irp->IoStatus.Information = sizeof(STORAGE_PREDICT_FAILURE);
4409 }
4410 } else {
4412 }
4413 }
4414 return status;
4415}
@ FailurePredictionSense
Definition: classpnp.h:237
NTSTATUS DiskReadFailurePredictStatus(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_STATUS DiskSmartStatus)
Definition: diskwmi.c:1251
#define DISK_TAG_SMART
Definition: disk.h:54
NTSTATUS DiskReadFailurePredictData(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_DATA DiskSmartData)
Definition: diskwmi.c:1327
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
struct _cl_event * event
Definition: glext.h:7739
GLintptr offset
Definition: glext.h:5920
struct _STORAGE_PREDICT_FAILURE STORAGE_PREDICT_FAILURE
struct _STORAGE_PREDICT_FAILURE * PSTORAGE_PREDICT_FAILURE
@ SynchronizationEvent
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 IRP_MJ_READ
Definition: rdpdr.c:46
@ Executive
Definition: ketypes.h:415

Referenced by DiskDeviceControl().

◆ DiskIoctlReassignBlocks()

NTSTATUS DiskIoctlReassignBlocks ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 4648 of file disk.c.

4675{
4676 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
4679 PREASSIGN_BLOCKS badBlocks = Irp->AssociatedIrp.SystemBuffer;
4681 PCDB cdb;
4683 ULONG blockNumber;
4684 ULONG blockCount;
4685 ULONG srbSize;
4687 PSTOR_ADDR_BTL8 storAddrBtl8;
4688 PSRBEX_DATA_SCSI_CDB16 srbExDataCdb16;
4689
4690 //
4691 // This function must be called at less than dispatch level.
4692 // Fail if IRQL >= DISPATCH_LEVEL.
4693 //
4694 PAGED_CODE();
4695 CHECK_IRQL();
4696
4697 //
4698 // Validate the request.
4699 //
4700
4701 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocks: DeviceObject %p Irp %p\n", DeviceObject, Irp));
4702
4703 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(REASSIGN_BLOCKS)) {
4704 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocks: Input buffer length mismatch.\n"));
4706 }
4707
4708 //
4709 // Make sure we have some data in the input buffer.
4710 //
4711
4712 if (badBlocks->Count == 0) {
4713 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocks: Invalid block count\n"));
4715 }
4716
4717 bufferSize = sizeof(REASSIGN_BLOCKS) + ((badBlocks->Count - 1) * sizeof(ULONG));
4718
4719 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < bufferSize) {
4720 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocks: Input buffer length mismatch for bad blocks.\n"));
4722 }
4723
4724 if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
4726 } else {
4727 srbSize = SCSI_REQUEST_BLOCK_SIZE;
4728 }
4729 srb = ExAllocatePoolWithTag(NonPagedPoolNx,
4730 srbSize,
4731 DISK_TAG_SRB);
4732
4733 if (srb == NULL) {
4734 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocks: Unable to allocate memory.\n"));
4736 }
4737
4738 RtlZeroMemory(srb, srbSize);
4739
4740 //
4741 // Build the data buffer to be transferred in the input buffer.
4742 // The format of the data to the device is:
4743 //
4744 // 2 bytes Reserved
4745 // 2 bytes Length
4746 // x * 4 btyes Block Address
4747 //
4748 // All values are big endian.
4749 //
4750
4751 badBlocks->Reserved = 0;
4752 blockCount = badBlocks->Count;
4753
4754 //
4755 // Convert # of entries to # of bytes.
4756 //
4757
4758 blockCount *= 4;
4759 badBlocks->Count = (USHORT) ((blockCount >> 8) & 0XFF);
4760 badBlocks->Count |= (USHORT) ((blockCount << 8) & 0XFF00);
4761
4762 //
4763 // Convert back to number of entries.
4764 //
4765
4766 blockCount /= 4;
4767
4768 for (; blockCount > 0; blockCount--) {
4769
4770 blockNumber = badBlocks->BlockNumber[blockCount-1];
4771 REVERSE_BYTES((PFOUR_BYTE) &badBlocks->BlockNumber[blockCount-1], (PFOUR_BYTE) &blockNumber);
4772 }
4773
4774 //
4775 // Build a SCSI SRB containing a SCSIOP_REASSIGN_BLOCKS cdb
4776 //
4777
4778 if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
4779 srbEx = (PSTORAGE_REQUEST_BLOCK)srb;
4780
4781 //
4782 // Set up STORAGE_REQUEST_BLOCK fields
4783 //
4784
4786 srbEx->Function = SRB_FUNCTION_STORAGE_REQUEST_BLOCK;
4787 srbEx->Signature = SRB_SIGNATURE;
4788 srbEx->Version = STORAGE_REQUEST_BLOCK_VERSION_1;
4789 srbEx->SrbLength = srbSize;
4790 srbEx->SrbFunction = SRB_FUNCTION_EXECUTE_SCSI;
4791 srbEx->RequestPriority = IoGetIoPriorityHint(Irp);
4792 srbEx->AddressOffset = sizeof(STORAGE_REQUEST_BLOCK);
4793 srbEx->NumSrbExData = 1;
4794
4795 // Set timeout value.
4796 srbEx->TimeOutValue = fdoExtension->TimeOutValue;
4797
4798 //
4799 // Set up address fields
4800 //
4801
4802 storAddrBtl8 = (PSTOR_ADDR_BTL8) ((PUCHAR)srbEx + srbEx->AddressOffset);
4803 storAddrBtl8->Type = STOR_ADDRESS_TYPE_BTL8;
4804 storAddrBtl8->AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
4805
4806 //
4807 // Set up SCSI SRB extended data fields
4808 //
4809
4810 srbEx->SrbExDataOffset[0] = sizeof(STORAGE_REQUEST_BLOCK) +
4811 sizeof(STOR_ADDR_BTL8);
4812 if ((srbEx->SrbExDataOffset[0] + sizeof(SRBEX_DATA_SCSI_CDB16)) <= srbEx->SrbLength) {
4813 srbExDataCdb16 = (PSRBEX_DATA_SCSI_CDB16)((PUCHAR)srbEx + srbEx->SrbExDataOffset[0]);
4814 srbExDataCdb16->Type = SrbExDataTypeScsiCdb16;
4815 srbExDataCdb16->Length = SRBEX_DATA_SCSI_CDB16_LENGTH;
4816 srbExDataCdb16->CdbLength = 6;
4817
4818 cdb = (PCDB)srbExDataCdb16->Cdb;
4819 } else {
4820 // Should not happen
4822
4823 FREE_POOL(srb);
4824 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocks: Insufficient extended SRB size.\n"));
4825 return STATUS_INTERNAL_ERROR;
4826 }
4827
4828 } else {
4831 srb->CdbLength = 6;
4832
4833 //
4834 // Set timeout value.
4835 //
4836
4837 srb->TimeOutValue = fdoExtension->TimeOutValue;
4838
4839 cdb = (PCDB)srb->Cdb;
4840 }
4841
4842 cdb->CDB6GENERIC.OperationCode = SCSIOP_REASSIGN_BLOCKS;
4843
4845 srb,
4846 badBlocks,
4847 bufferSize,
4848 TRUE);
4849
4850 FREE_POOL(srb);
4851 return status;
4852}
#define SCSIOP_REASSIGN_BLOCKS
Definition: cdrw_hw.h:873
size_t bufferSize
struct _REASSIGN_BLOCKS REASSIGN_BLOCKS
unsigned short USHORT
Definition: pedump.c:61
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:3465
ULONG BlockNumber[1]
Definition: ntdddisk.h:646
USHORT Reserved
Definition: ntdddisk.h:644
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133

Referenced by DiskDeviceControl().

◆ DiskIoctlReassignBlocksEx()

NTSTATUS DiskIoctlReassignBlocksEx ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 4855 of file disk.c.

4882{
4883 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
4886 PREASSIGN_BLOCKS_EX badBlocks = Irp->AssociatedIrp.SystemBuffer;
4888 PCDB cdb;
4889 LARGE_INTEGER blockNumber;
4891 ULONG blockCount;
4892 ULONG srbSize;
4894 PSTOR_ADDR_BTL8 storAddrBtl8;
4895 PSRBEX_DATA_SCSI_CDB16 srbExDataCdb16;
4896
4897 //
4898 // This function must be called at less than dispatch level.
4899 // Fail if IRQL >= DISPATCH_LEVEL.
4900 //
4901 PAGED_CODE();
4902 CHECK_IRQL();
4903
4904 //
4905 // Validate the request.
4906 //
4907
4908 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocksEx: DeviceObject %p Irp %p\n", DeviceObject, Irp));
4909
4910 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(REASSIGN_BLOCKS_EX)) {
4911 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocksEx: Input buffer length mismatch.\n"));
4913 }
4914
4915 //
4916 // Make sure we have some data in the input buffer.
4917 //
4918
4919 if (badBlocks->Count == 0) {
4920 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocksEx: Invalid block count\n"));
4922 }
4923
4924 bufferSize = sizeof(REASSIGN_BLOCKS_EX) + ((badBlocks->Count - 1) * sizeof(LARGE_INTEGER));
4925
4926 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < bufferSize) {
4927 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocksEx: Input buffer length mismatch for bad blocks.\n"));
4929 }
4930
4931 if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
4933 } else {
4934 srbSize = SCSI_REQUEST_BLOCK_SIZE;
4935 }
4936 srb = ExAllocatePoolWithTag(NonPagedPoolNx,
4937 srbSize,
4938 DISK_TAG_SRB);
4939
4940 if (srb == NULL) {
4941 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocks: Unable to allocate memory.\n"));
4943 }
4944
4945 RtlZeroMemory(srb, srbSize);
4946
4947 //
4948 // Build the data buffer to be transferred in the input buffer.
4949 // The format of the data to the device is:
4950 //
4951 // 2 bytes Reserved
4952 // 2 bytes Length
4953 // x * 8 btyes Block Address
4954 //
4955 // All values are big endian.
4956 //
4957
4958 badBlocks->Reserved = 0;
4959 blockCount = badBlocks->Count;
4960
4961 //
4962 // Convert # of entries to # of bytes.
4963 //
4964
4965 blockCount *= 8;
4966 badBlocks->Count = (USHORT) ((blockCount >> 8) & 0XFF);
4967 badBlocks->Count |= (USHORT) ((blockCount << 8) & 0XFF00);
4968
4969 //
4970 // Convert back to number of entries.
4971 //
4972
4973 blockCount /= 8;
4974
4975 for (; blockCount > 0; blockCount--) {
4976
4977 blockNumber = badBlocks->BlockNumber[blockCount-1];
4978 REVERSE_BYTES_QUAD(&badBlocks->BlockNumber[blockCount-1], &blockNumber);
4979 }
4980
4981 //
4982 // Build a SCSI SRB containing a SCSIOP_REASSIGN_BLOCKS cdb
4983 //
4984
4985 if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
4986 srbEx = (PSTORAGE_REQUEST_BLOCK)srb;
4987
4988 //
4989 // Set up STORAGE_REQUEST_BLOCK fields
4990 //
4991
4993 srbEx->Function = SRB_FUNCTION_STORAGE_REQUEST_BLOCK;
4994 srbEx->Signature = SRB_SIGNATURE;
4995 srbEx->Version = STORAGE_REQUEST_BLOCK_VERSION_1;
4996 srbEx->SrbLength = srbSize;
4997 srbEx->SrbFunction = SRB_FUNCTION_EXECUTE_SCSI;
4998 srbEx->RequestPriority = IoGetIoPriorityHint(Irp);
4999 srbEx->AddressOffset = sizeof(STORAGE_REQUEST_BLOCK);
5000 srbEx->NumSrbExData = 1;
5001
5002 // Set timeout value.
5003 srbEx->TimeOutValue = fdoExtension->TimeOutValue;
5004
5005 //
5006 // Set up address fields
5007 //
5008
5009 storAddrBtl8 = (PSTOR_ADDR_BTL8) ((PUCHAR)srbEx + srbEx->AddressOffset);
5010 storAddrBtl8->Type = STOR_ADDRESS_TYPE_BTL8;
5011 storAddrBtl8->AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
5012
5013 //
5014 // Set up SCSI SRB extended data fields
5015 //
5016
5017 srbEx->SrbExDataOffset[0] = sizeof(STORAGE_REQUEST_BLOCK) +
5018 sizeof(STOR_ADDR_BTL8);
5019 if ((srbEx->SrbExDataOffset[0] + sizeof(SRBEX_DATA_SCSI_CDB16)) <= srbEx->SrbLength) {
5020 srbExDataCdb16 = (PSRBEX_DATA_SCSI_CDB16)((PUCHAR)srbEx + srbEx->SrbExDataOffset[0]);
5021 srbExDataCdb16->Type = SrbExDataTypeScsiCdb16;
5022 srbExDataCdb16->Length = SRBEX_DATA_SCSI_CDB16_LENGTH;
5023 srbExDataCdb16->CdbLength = 6;
5024
5025 cdb = (PCDB)srbExDataCdb16->Cdb;
5026 } else {
5027 // Should not happen
5029
5030 FREE_POOL(srb);
5031 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocks: Insufficient extended SRB size.\n"));
5032 return STATUS_INTERNAL_ERROR;
5033 }
5034
5035 } else {
5038 srb->CdbLength = 6;
5039
5040 //
5041 // Set timeout value.
5042 //
5043
5044 srb->TimeOutValue = fdoExtension->TimeOutValue;
5045
5046 cdb = (PCDB)srb->Cdb;
5047 }
5048
5049 cdb->CDB6GENERIC.OperationCode = SCSIOP_REASSIGN_BLOCKS;
5050 cdb->CDB6GENERIC.CommandUniqueBits = 1; // LONGLBA
5051
5053 srb,
5054 badBlocks,
5055 bufferSize,
5056 TRUE);
5057
5058 FREE_POOL(srb);
5059 return status;
5060}
struct _REASSIGN_BLOCKS_EX REASSIGN_BLOCKS_EX
#define REVERSE_BYTES_QUAD(Destination, Source)
Definition: scsi.h:3452
LARGE_INTEGER BlockNumber[1]
Definition: ntdddisk.h:652
union _LARGE_INTEGER LARGE_INTEGER

Referenced by DiskDeviceControl().

◆ DiskIoctlSetCacheInformation()

NTSTATUS DiskIoctlSetCacheInformation ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 3917 of file disk.c.

3946{
3947 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
3948 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
3949 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
3951 PDISK_CACHE_INFORMATION cacheInfo = Irp->AssociatedIrp.SystemBuffer;
3953
3954 //
3955 // This function must be called at less than dispatch level.
3956 // Fail if IRQL is equal or above DISPATCH_LEVEL.
3957 //
3958
3959 PAGED_CODE();
3960 CHECK_IRQL();
3961
3962 //
3963 // Validate the request.
3964 //
3965
3966 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlSetCacheInformation: DeviceObject %p Irp %p\n", DeviceObject, Irp));
3967
3968 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(DISK_CACHE_INFORMATION)) {
3969
3970 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSetCacheInformation: Input buffer length mismatch.\n"));
3972 }
3973
3974 status = DiskSetCacheInformation(fdoExtension, cacheInfo);
3975
3976 //
3977 // Save away the user-defined override in our extension and the registry
3978 //
3979 if (cacheInfo->WriteCacheEnabled) {
3981 } else {
3983 }
3984
3985 ClassSetDeviceParameter(fdoExtension, DiskDeviceParameterSubkey,
3987
3988 DiskLogCacheInformation(fdoExtension, cacheInfo, status);
3989
3990 return status;
3991}
VOID DiskLogCacheInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo, IN NTSTATUS Status)
Definition: disk.c:2856
#define DiskDeviceParameterSubkey
Definition: disk.h:403
#define DiskDeviceUserWriteCacheSetting
Definition: disk.h:404
@ DiskWriteCacheDisable
Definition: disk.h:179

Referenced by DiskDeviceControl().

◆ DiskIoctlSetCacheSetting()

NTSTATUS DiskIoctlSetCacheSetting ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 3415 of file disk.c.

3441{
3442 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
3445
3446 //
3447 // This function must be called at less than dispatch level.
3448 // Fail if IRQL >= DISPATCH_LEVEL.
3449 //
3450 PAGED_CODE();
3451 CHECK_IRQL();
3452
3453 if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(DISK_CACHE_SETTING))
3454 {
3456 }
3457 else
3458 {
3459 PDISK_CACHE_SETTING cacheSetting = (PDISK_CACHE_SETTING)Irp->AssociatedIrp.SystemBuffer;
3460
3461 if (cacheSetting->Version == sizeof(DISK_CACHE_SETTING))
3462 {
3463 ULONG isPowerProtected;
3464
3465 //
3466 // Save away the user-defined override in our extension and the registry
3467 //
3468 if (cacheSetting->IsPowerProtected)
3469 {
3471 isPowerProtected = 1;
3472 }
3473 else
3474 {
3476 isPowerProtected = 0;
3477 }
3478 ADJUST_FUA_FLAG(fdoExtension);
3479
3480 ClassSetDeviceParameter(fdoExtension, DiskDeviceParameterSubkey, DiskDeviceCacheIsPowerProtected, isPowerProtected);
3481 }
3482 else
3483 {
3485 }
3486 }
3487
3488 return status;
3489}
#define DiskDeviceCacheIsPowerProtected
Definition: disk.h:405

Referenced by DiskDeviceControl().

◆ DiskIoctlSetVerify()

NTSTATUS DiskIoctlSetVerify ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 5264 of file disk.c.

5290{
5292
5293 //
5294 // Validate the request.
5295 //
5296
5297 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlSetVerify: DeviceObject %p Irp %p\n", DeviceObject, Irp));
5298
5299 //
5300 // If the caller is kernel mode, set the verify bit.
5301 //
5302
5303 if (Irp->RequestorMode == KernelMode) {
5304
5307
5308 }
5309 return status;
5310}

Referenced by DiskDeviceControl().

◆ DiskIoctlSmartGetVersion()

NTSTATUS DiskIoctlSmartGetVersion ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 5540 of file disk.c.

5566{
5567 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
5568 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
5569 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
5572
5573 PGETVERSIONINPARAMS versionParams;
5574 PSRB_IO_CONTROL srbControl;
5575 IO_STATUS_BLOCK ioStatus = { 0 };
5576 PUCHAR buffer;
5577
5578 //
5579 // This function must be called at less than dispatch level.
5580 // Fail if IRQL >= DISPATCH_LEVEL.
5581 //
5582 PAGED_CODE();
5583 CHECK_IRQL();
5584
5585 //
5586 // Validate the request.
5587 //
5588
5589 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlSmartGetVersion: DeviceObject %p Irp %p\n", DeviceObject, Irp));
5590
5591
5592 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GETVERSIONINPARAMS)) {
5593 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartGetVersion: Output buffer too small.\n"));
5595 }
5596
5597 srbControl = ExAllocatePoolWithTag(NonPagedPoolNx,
5598 sizeof(SRB_IO_CONTROL) +
5599 sizeof(GETVERSIONINPARAMS),
5601
5602 if (srbControl == NULL) {
5603 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartGetVersion: Unable to allocate memory.\n"));
5605 }
5606
5607 RtlZeroMemory(srbControl, sizeof(SRB_IO_CONTROL) + sizeof(GETVERSIONINPARAMS));
5608
5609 //
5610 // fill in srbControl fields
5611 //
5612
5613 srbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
5614 RtlMoveMemory (srbControl->Signature, "SCSIDISK", 8);
5615 srbControl->Timeout = fdoExtension->TimeOutValue;
5616 srbControl->Length = sizeof(GETVERSIONINPARAMS);
5618
5619 //
5620 // Point to the 'buffer' portion of the SRB_CONTROL
5621 //
5622
5623 buffer = (PUCHAR)srbControl + srbControl->HeaderLength;
5624
5625 //
5626 // Ensure correct target is set in the cmd parameters.
5627 //
5628
5629 versionParams = (PGETVERSIONINPARAMS)buffer;
5630 versionParams->bIDEDeviceMap = diskData->ScsiAddress.TargetId;
5631
5634 commonExtension->LowerDeviceObject,
5635 srbControl,
5636 sizeof(SRB_IO_CONTROL) + sizeof(GETVERSIONINPARAMS),
5637 sizeof(SRB_IO_CONTROL) + sizeof(GETVERSIONINPARAMS),
5638 FALSE,
5639 &ioStatus);
5640
5641 status = ioStatus.Status;
5642
5643 //
5644 // If successful, copy the data received into the output buffer.
5645 // This should only fail in the event that the IDE driver is older
5646 // than this driver.
5647 //
5648
5649 if (NT_SUCCESS(status)) {
5650
5651 buffer = (PUCHAR)srbControl + srbControl->HeaderLength;
5652
5653 RtlMoveMemory (Irp->AssociatedIrp.SystemBuffer, buffer, sizeof(GETVERSIONINPARAMS));
5654 Irp->IoStatus.Information = sizeof(GETVERSIONINPARAMS);
5655 }
5656
5657 FREE_POOL(srbControl);
5658
5659 return status;
5660}
#define IOCTL_SCSI_MINIPORT_SMART_VERSION
Definition: cdrw_hw.h:1457
VOID NTAPI ClassSendDeviceIoControlSynchronous(_In_ ULONG IoControlCode, _In_ PDEVICE_OBJECT TargetDeviceObject, _Inout_updates_opt_(_Inexpressible_(max(InputBufferLength, OutputBufferLength))) PVOID Buffer, _In_ ULONG InputBufferLength, _In_ ULONG OutputBufferLength, _In_ BOOLEAN InternalDeviceIoControl, _Out_ PIO_STATUS_BLOCK IoStatus)
Definition: class.c:11065
GLuint buffer
Definition: glext.h:5915
struct _GETVERSIONINPARAMS GETVERSIONINPARAMS
#define IOCTL_SCSI_MINIPORT
Definition: scsi_port.h:48
struct _SRB_IO_CONTROL SRB_IO_CONTROL
UCHAR Signature[8]
Definition: scsi_port.h:126
ULONG ControlCode
Definition: scsi_port.h:128
ULONG HeaderLength
Definition: scsi_port.h:125

Referenced by DiskDeviceControl().

◆ DiskIoctlSmartReceiveDriveData()

NTSTATUS DiskIoctlSmartReceiveDriveData ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 5663 of file disk.c.

5689{
5690 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
5691 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
5692 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
5695
5696 PSENDCMDINPARAMS cmdInParameters = ((PSENDCMDINPARAMS)Irp->AssociatedIrp.SystemBuffer);
5697 PSRB_IO_CONTROL srbControl;
5698 IO_STATUS_BLOCK ioStatus = { 0 };
5699 ULONG controlCode = 0;
5700 PUCHAR buffer;
5701 PIRP irp2;
5702 KEVENT event;
5703 ULONG length = 0;
5704
5705 //
5706 // This function must be called at less than dispatch level.
5707 // Fail if IRQL >= DISPATCH_LEVEL.
5708 //
5709 PAGED_CODE();
5710 CHECK_IRQL();
5711
5712 //
5713 // Validate the request.
5714 //
5715
5716 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlSmartReceiveDriveData: DeviceObject %p Irp %p\n", DeviceObject, Irp));
5717
5718 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < (sizeof(SENDCMDINPARAMS) - 1)) {
5719 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartReceiveDriveData: Input buffer length invalid.\n"));
5721 }
5722
5723 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < (sizeof(SENDCMDOUTPARAMS) + 512 - 1)) {
5724 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartReceiveDriveData: Output buffer too small.\n"));
5726 }
5727
5728 //
5729 // Create notification event object to be used to signal the
5730 // request completion.
5731 //
5732
5734
5735 //
5736 // use controlCode as a sort of 'STATUS_SUCCESS' to see if it's
5737 // a valid request type
5738 //
5739
5740 if (cmdInParameters->irDriveRegs.bCommandReg == ID_CMD) {
5741
5743 controlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
5744
5745 } else if (cmdInParameters->irDriveRegs.bCommandReg == SMART_CMD) {
5746
5747 switch (cmdInParameters->irDriveRegs.bFeaturesReg) {
5748
5749 case READ_ATTRIBUTES:
5752 break;
5753
5754 case READ_THRESHOLDS:
5757 break;
5758
5759 case SMART_READ_LOG: {
5760
5762 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartReceiveDriveData: SMART failure prediction not supported.\n"));
5764 }
5765
5766 //
5767 // Calculate additional length based on number of sectors to be read.
5768 // Then verify the output buffer is large enough.
5769 //
5770
5772
5773 //
5774 // Ensure at least 1 sector is going to be read
5775 //
5776 if (length == 0) {
5778 }
5779
5780 length += max(sizeof(SENDCMDOUTPARAMS), sizeof(SENDCMDINPARAMS));
5781
5782 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < length - 1) {
5783 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartReceiveDriveData: Output buffer too small for SMART_READ_LOG.\n"));
5785 }
5786
5788 break;
5789 }
5790 }
5791 }
5792
5793 if (controlCode == 0) {
5794 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartReceiveDriveData: Invalid request.\n"));
5796 }
5797
5798 srbControl = ExAllocatePoolWithTag(NonPagedPoolNx,
5799 sizeof(SRB_IO_CONTROL) + length,
5801
5802 if (srbControl == NULL) {
5803 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartReceiveDriveData: Unable to allocate memory.\n"));
5805 }
5806
5807 //
5808 // fill in srbControl fields
5809 //
5810
5811 srbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
5812 RtlMoveMemory (srbControl->Signature, "SCSIDISK", 8);
5813 srbControl->Timeout = fdoExtension->TimeOutValue;
5814 srbControl->Length = length;
5815 srbControl->ControlCode = controlCode;
5816
5817 //
5818 // Point to the 'buffer' portion of the SRB_CONTROL
5819 //
5820
5821 buffer = (PUCHAR)srbControl + srbControl->HeaderLength;
5822
5823 //
5824 // Ensure correct target is set in the cmd parameters.
5825 //
5826
5827 cmdInParameters->bDriveNumber = diskData->ScsiAddress.TargetId;
5828
5829 //
5830 // Copy the IOCTL parameters to the srb control buffer area.
5831 //
5832
5834 Irp->AssociatedIrp.SystemBuffer,
5835 sizeof(SENDCMDINPARAMS) - 1);
5836
5838 commonExtension->LowerDeviceObject,
5839 srbControl,
5840 sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS) - 1,
5841 srbControl,
5842 sizeof(SRB_IO_CONTROL) + length,
5843 FALSE,
5844 &event,
5845 &ioStatus);
5846
5847 if (irp2 == NULL) {
5848 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartReceiveDriveData: Unable to allocate IRP.\n"));
5849 FREE_POOL(srbControl);
5851 }
5852
5853 //
5854 // Call the port driver with the request and wait for it to complete.
5855 //
5856
5857 status = IoCallDriver(commonExtension->LowerDeviceObject, irp2);
5858
5859 if (status == STATUS_PENDING) {
5861 status = ioStatus.Status;
5862 }
5863
5864 //
5865 // Copy the data received into the output buffer. Since the status buffer
5866 // contains error information also, always perform this copy. IO will
5867 // either pass this back to the app, or zero it, in case of error.
5868 //
5869
5870 buffer = (PUCHAR)srbControl + srbControl->HeaderLength;
5871
5872 if (NT_SUCCESS(status)) {
5873
5874 RtlMoveMemory ( Irp->AssociatedIrp.SystemBuffer, buffer, length - 1);
5875 Irp->IoStatus.Information = length - 1;
5876
5877 } else {
5878
5879 RtlMoveMemory ( Irp->AssociatedIrp.SystemBuffer, buffer, (sizeof(SENDCMDOUTPARAMS) - 1));
5880 Irp->IoStatus.Information = sizeof(SENDCMDOUTPARAMS) - 1;
5881
5882 }
5883
5884 FREE_POOL(srbControl);
5885
5886 return status;
5887}
#define ID_CMD
Definition: helper.h:20
#define SMART_CMD
Definition: helper.h:21
struct _SENDCMDOUTPARAMS SENDCMDOUTPARAMS
struct _SENDCMDINPARAMS * PSENDCMDINPARAMS
#define IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS
Definition: cdrw_hw.h:1459
#define IOCTL_SCSI_MINIPORT_IDENTIFY
Definition: cdrw_hw.h:1458
#define IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS
Definition: cdrw_hw.h:1460
#define IOCTL_SCSI_MINIPORT_READ_SMART_LOG
Definition: scsi.h:1420
#define READ_ATTRIBUTE_BUFFER_SIZE
Definition: ntdddisk.h:731
#define READ_THRESHOLDS
Definition: ntdddisk.h:745
#define IDENTIFY_BUFFER_SIZE
Definition: ntdddisk.h:732
#define SMART_READ_LOG
Definition: ntdddisk.h:749
#define SMART_LOG_SECTOR_SIZE
Definition: ntdddisk.h:734
#define READ_ATTRIBUTES
Definition: ntdddisk.h:744
#define READ_THRESHOLD_BUFFER_SIZE
Definition: ntdddisk.h:733
@ NotificationEvent
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
UCHAR bSectorCountReg
Definition: helper.h:10
UCHAR bFeaturesReg
Definition: helper.h:9
UCHAR bCommandReg
Definition: helper.h:15
UCHAR bDriveNumber
Definition: helper.h:33
IDEREGS irDriveRegs
Definition: helper.h:32
#define max(a, b)
Definition: svc.c:63

Referenced by DiskDeviceControl().

◆ DiskIoctlSmartSendDriveCommand()

NTSTATUS DiskIoctlSmartSendDriveCommand ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 5890 of file disk.c.

5916{
5917 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
5918 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
5919 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
5922
5923 PSENDCMDINPARAMS cmdInParameters = ((PSENDCMDINPARAMS)Irp->AssociatedIrp.SystemBuffer);
5924 PSRB_IO_CONTROL srbControl;
5925 IO_STATUS_BLOCK ioStatus = { 0 };
5926 ULONG controlCode = 0;
5927 PUCHAR buffer;
5928 PIRP irp2;
5929 KEVENT event;
5930 ULONG length = 0;
5931
5932 //
5933 // This function must be called at less than dispatch level.
5934 // Fail if IRQL >= DISPATCH_LEVEL.
5935 //
5936 PAGED_CODE();
5937 CHECK_IRQL();
5938
5939 //
5940 // Validate the request.
5941 //
5942
5943 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlSmartSendDriveCommand: DeviceObject %p Irp %p\n", DeviceObject, Irp));
5944
5945 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < (sizeof(SENDCMDINPARAMS) - 1)) {
5946 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartSendDriveCommand: Input buffer size invalid.\n"));
5948 }
5949
5950 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < (sizeof(SENDCMDOUTPARAMS) - 1)) {
5951 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartSendDriveCommand: Output buffer too small.\n"));
5953 }
5954
5955 //
5956 // Create notification event object to be used to signal the
5957 // request completion.
5958 //
5959
5961
5962 if (cmdInParameters->irDriveRegs.bCommandReg == SMART_CMD) {
5963
5964 switch (cmdInParameters->irDriveRegs.bFeaturesReg) {
5965
5966 case SMART_WRITE_LOG: {
5967
5969
5970 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartSendDriveCommand: SMART failure prediction not supported.\n"));
5972 }
5973
5974 //
5975 // Calculate additional length based on number of sectors to be written.
5976 // Then verify the input buffer is large enough.
5977 //
5978
5980
5981 //
5982 // Ensure at least 1 sector is going to be written
5983 //
5984
5985 if (length == 0) {
5987 }
5988
5989 if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
5990 (sizeof(SENDCMDINPARAMS) - 1) + length) {
5991
5992 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartSendDriveCommand: Input buffer too small for SMART_WRITE_LOG.\n"));
5994 }
5995
5997 break;
5998 }
5999
6000 case ENABLE_SMART:
6002 break;
6003
6004 case DISABLE_SMART:
6006 break;
6007
6009
6010 //
6011 // Ensure bBuffer is at least 2 bytes (to hold the values of
6012 // cylinderLow and cylinderHigh).
6013 //
6014
6015 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
6016 (sizeof(SENDCMDOUTPARAMS) - 1 + sizeof(IDEREGS))) {
6017
6019 break;
6020 }
6021
6023 length = sizeof(IDEREGS);
6024 break;
6025
6028 break;
6029
6032 break;
6033
6035 //
6036 // Validate that this is an ok self test command
6037 //
6039
6041 }
6042 break;
6043
6046 break;
6047 }
6048 }
6049
6050 if (controlCode == 0) {
6051 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartSendDriveCommand: Invalid request.\n"));
6053 }
6054
6055 length += max(sizeof(SENDCMDOUTPARAMS), sizeof(SENDCMDINPARAMS));
6056 srbControl = ExAllocatePoolWithTag(NonPagedPoolNx,
6057 sizeof(SRB_IO_CONTROL) + length,
6059
6060 if (srbControl == NULL) {
6061 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartSendDriveCommand: Unable to allocate memory.\n"));
6063 }
6064
6065 //
6066 // fill in srbControl fields
6067 //
6068
6069 srbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
6070 RtlMoveMemory (srbControl->Signature, "SCSIDISK", 8);
6071 srbControl->Timeout = fdoExtension->TimeOutValue;
6072 srbControl->Length = length;
6073 srbControl->ControlCode = controlCode;
6074
6075 //
6076 // Point to the 'buffer' portion of the SRB_CONTROL
6077 //
6078
6079 buffer = (PUCHAR)srbControl + srbControl->HeaderLength;
6080
6081 //
6082 // Ensure correct target is set in the cmd parameters.
6083 //
6084
6085 cmdInParameters->bDriveNumber = diskData->ScsiAddress.TargetId;
6086
6087 //
6088 // Copy the IOCTL parameters to the srb control buffer area.
6089 //
6090
6091 if (cmdInParameters->irDriveRegs.bFeaturesReg == SMART_WRITE_LOG) {
6093 Irp->AssociatedIrp.SystemBuffer,
6094 sizeof(SENDCMDINPARAMS) - 1 +
6096 } else {
6097 RtlMoveMemory(buffer, Irp->AssociatedIrp.SystemBuffer, sizeof(SENDCMDINPARAMS) - 1);
6098 }
6099
6101 commonExtension->LowerDeviceObject,
6102 srbControl,
6103 sizeof(SRB_IO_CONTROL) + length,
6104 srbControl,
6105 sizeof(SRB_IO_CONTROL) + length,
6106 FALSE,
6107 &event,
6108 &ioStatus);
6109
6110 if (irp2 == NULL) {
6111 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlSmartSendDriveCommand: Unable to allocate IRP.\n"));
6112 FREE_POOL(srbControl);
6114 }
6115
6116 //
6117 // Call the port driver with the request and wait for it to complete.
6118 //
6119
6120 status = IoCallDriver(commonExtension->LowerDeviceObject, irp2);
6121
6122 if (status == STATUS_PENDING) {
6124 status = ioStatus.Status;
6125 }
6126
6127 //
6128 // Copy the data received into the output buffer. Since the status buffer
6129 // contains error information also, always perform this copy. IO will
6130 // either pass this back to the app, or zero it, in case of error.
6131 //
6132
6133 buffer = (PUCHAR)srbControl + srbControl->HeaderLength;
6134
6135 //
6136 // Update the return buffer size based on the sub-command.
6137 //
6138
6139 if (cmdInParameters->irDriveRegs.bFeaturesReg == RETURN_SMART_STATUS) {
6140 length = sizeof(SENDCMDOUTPARAMS) - 1 + sizeof(IDEREGS);
6141 } else {
6142 length = sizeof(SENDCMDOUTPARAMS) - 1;
6143 }
6144
6145 RtlMoveMemory ( Irp->AssociatedIrp.SystemBuffer, buffer, length);
6146 Irp->IoStatus.Information = length;
6147
6148 FREE_POOL(srbControl);
6149
6150 return status;
6151}
struct _IDEREGS IDEREGS
#define IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES
Definition: cdrw_hw.h:1465
#define IOCTL_SCSI_MINIPORT_DISABLE_SMART
Definition: cdrw_hw.h:1462
#define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE
Definition: cdrw_hw.h:1464
#define IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS
Definition: cdrw_hw.h:1466
#define IOCTL_SCSI_MINIPORT_ENABLE_SMART
Definition: cdrw_hw.h:1461
#define IOCTL_SCSI_MINIPORT_RETURN_STATUS
Definition: cdrw_hw.h:1463
#define DiskIsValidSmartSelfTest(Subcommand)
Definition: disk.h:619
#define IOCTL_SCSI_MINIPORT_WRITE_SMART_LOG
Definition: scsi.h:1421
#define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTO_OFFLINE
Definition: scsi.h:1419
#define SMART_WRITE_LOG
Definition: ntdddisk.h:750
#define EXECUTE_OFFLINE_DIAGS
Definition: ntdddisk.h:748
#define ENABLE_SMART
Definition: ntdddisk.h:751
#define SAVE_ATTRIBUTE_VALUES
Definition: ntdddisk.h:747
#define RETURN_SMART_STATUS
Definition: ntdddisk.h:753
#define DISABLE_SMART
Definition: ntdddisk.h:752
#define ENABLE_DISABLE_AUTO_OFFLINE
Definition: ntdddisk.h:754
#define ENABLE_DISABLE_AUTOSAVE
Definition: ntdddisk.h:746
Definition: helper.h:8
UCHAR bSectorNumberReg
Definition: helper.h:11

Referenced by DiskDeviceControl().

◆ DiskIoctlUpdateDriveSize()

NTSTATUS DiskIoctlUpdateDriveSize ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 5362 of file disk.c.

5391{
5392 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
5393 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
5394 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
5398
5399 //
5400 // This function must be called at less than dispatch level.
5401 // Fail if IRQL >= DISPATCH_LEVEL.
5402 //
5403 PAGED_CODE();
5404 CHECK_IRQL();
5405
5406 //
5407 // Validate the request.
5408 //
5409
5410 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlUpdateDriveSize: DeviceObject %p Irp %p\n", DeviceObject, Irp));
5411
5412 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY)) {
5413
5414 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlUpdateDriveSize: Output buffer too small.\n"));
5416 }
5417
5419
5420 //
5421 // Note whether the drive is ready.
5422 //
5423
5424 diskData->ReadyStatus = status;
5425
5426 if (NT_SUCCESS(status)) {
5427
5428 //
5429 // Copy drive geometry information from the device extension.
5430 //
5431
5432 RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
5433 &(fdoExtension->DiskGeometry),
5434 sizeof(DISK_GEOMETRY));
5435
5436 if (((PDISK_GEOMETRY)Irp->AssociatedIrp.SystemBuffer)->BytesPerSector == 0) {
5437 ((PDISK_GEOMETRY)Irp->AssociatedIrp.SystemBuffer)->BytesPerSector = 512;
5438 }
5439 Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
5441
5442 //
5443 // Notify everyone that the disk layout may have changed
5444 //
5445
5446 Notification.Event = GUID_IO_DISK_LAYOUT_CHANGE;
5447 Notification.Version = 1;
5449 Notification.FileObject = NULL;
5450 Notification.NameBufferOffset = -1;
5451
5453 &Notification,
5454 NULL,
5455 NULL);
5456 }
5457 return status;
5458}
NTSTATUS NTAPI IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL)
Definition: pnpreport.c:498
_In_ PWDFDEVICE_INIT _In_ PFN_WDF_DEVICE_SHUTDOWN_NOTIFICATION Notification
Definition: wdfcontrol.h:115

Referenced by DiskDeviceControl().

◆ DiskIoctlVerify()

NTSTATUS DiskIoctlVerify ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp 
)

Definition at line 4526 of file disk.c.

4551{
4552 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
4553 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
4555 PVERIFY_INFORMATION verifyInfo = Irp->AssociatedIrp.SystemBuffer;
4558 LARGE_INTEGER byteOffset;
4559 ULONG srbSize;
4560
4561 //
4562 // Validate the request.
4563 //
4564
4565 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlVerify: DeviceObject %p Irp %p\n", DeviceObject, Irp));
4566
4567 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(VERIFY_INFORMATION)) {
4568 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlVerify: Input buffer length mismatch.\n"));
4570 }
4571
4572 if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
4574 } else {
4575 srbSize = SCSI_REQUEST_BLOCK_SIZE;
4576 }
4577 srb = ExAllocatePoolWithTag(NonPagedPoolNx,
4578 srbSize,
4579 DISK_TAG_SRB);
4580
4581 if (srb == NULL) {
4582 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlVerify: Unable to allocate memory.\n"));
4584 }
4585
4586 RtlZeroMemory(srb, srbSize);
4587
4588 //
4589 // Add disk offset to starting sector.
4590 //
4591
4592 byteOffset.QuadPart = commonExtension->StartingOffset.QuadPart +
4593 verifyInfo->StartingOffset.QuadPart;
4594
4595 //
4596 // Perform a bounds check on the sector range
4597 //
4598
4599 if ((verifyInfo->StartingOffset.QuadPart > commonExtension->PartitionLength.QuadPart) ||
4600 (verifyInfo->StartingOffset.QuadPart < 0)) {
4601
4602 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlVerify: Verify request to invalid sector.\n"));
4603 FREE_POOL(srb)
4605 } else {
4606
4607 ULONGLONG bytesRemaining = commonExtension->PartitionLength.QuadPart - verifyInfo->StartingOffset.QuadPart;
4608
4609 if ((ULONGLONG)verifyInfo->Length > bytesRemaining) {
4610
4611 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlVerify: Verify request to invalid sector.\n"));
4612 FREE_POOL(srb)
4614 }
4615 }
4616
4617 Context = ExAllocatePoolWithTag(NonPagedPoolNx,
4620 if (Context) {
4621
4622 Context->Irp = Irp;
4623 Context->Srb = srb;
4625
4626 if (Context->WorkItem) {
4627
4628 //
4629 // Queue the work item and return.
4630 //
4631
4633
4634 IoQueueWorkItem(Context->WorkItem,
4637 Context);
4638
4639 return STATUS_PENDING;
4640 }
4642 }
4643 FREE_POOL(srb)
4645}
#define DISK_TAG_WI_CONTEXT
Definition: disk.h:70
IO_WORKITEM_ROUTINE DiskIoctlVerifyThread
Definition: disk.h:591
IoMarkIrpPending(Irp)
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:656
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_NONEXISTENT_SECTOR
Definition: udferr_usr.h:143
@ DelayedWorkQueue
Definition: extypes.h:190

Referenced by DiskDeviceControl().

◆ DiskIoctlVerifyThread()

VOID NTAPI DiskIoctlVerifyThread ( IN PDEVICE_OBJECT  Fdo,
IN PVOID  Context 
)

Definition at line 2046 of file disk.c.

2050{
2052 PIRP Irp = NULL;
2054 PDISK_DATA DiskData = (PDISK_DATA)FdoExtension->CommonExtension.DriverData;
2055 PVERIFY_INFORMATION verifyInfo = NULL;
2057 PCDB Cdb = NULL;
2058 LARGE_INTEGER byteOffset;
2059 LARGE_INTEGER sectorOffset;
2063 PSTOR_ADDR_BTL8 storAddrBtl8 = NULL;
2064 PSRBEX_DATA_SCSI_CDB16 srbExDataCdb16 = NULL;
2065
2066 PAGED_CODE();
2067
2068 NT_ASSERT(WorkContext != NULL);
2069 _Analysis_assume_(WorkContext != NULL);
2070
2071 Srb = WorkContext->Srb;
2072 Irp = WorkContext->Irp;
2073 verifyInfo = (PVERIFY_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2074
2075 //
2076 // We don't need to hold on to this memory as
2077 // the following operation may take some time
2078 //
2079
2080 IoFreeWorkItem(WorkContext->WorkItem);
2081
2082 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlVerifyThread: Spliting up the request\n"));
2083
2084 //
2085 // Add disk offset to starting the sector
2086 //
2087
2088 byteOffset.QuadPart = FdoExtension->CommonExtension.StartingOffset.QuadPart +
2089 verifyInfo->StartingOffset.QuadPart;
2090
2091 //
2092 // Convert byte offset to the sector offset
2093 //
2094
2095 sectorOffset.QuadPart = byteOffset.QuadPart >> FdoExtension->SectorShift;
2096
2097 //
2098 // Convert byte count to sector count.
2099 //
2100
2101 sectorCount = verifyInfo->Length >> FdoExtension->SectorShift;
2102
2103 //
2104 // Make sure that all previous verify requests have indeed completed
2105 // This greatly reduces the possibility of a Denial-of-Service attack
2106 //
2107
2108 KeWaitForMutexObject(&DiskData->VerifyMutex,
2109 Executive,
2110 KernelMode,
2111 FALSE,
2112 NULL);
2113
2114 //
2115 // Initialize SCSI SRB for a verify CDB
2116 //
2117 if (FdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
2119 srbEx = (PSTORAGE_REQUEST_BLOCK)Srb;
2120
2121 //
2122 // Set up STORAGE_REQUEST_BLOCK fields
2123 //
2124
2126 srbEx->Function = SRB_FUNCTION_STORAGE_REQUEST_BLOCK;
2127 srbEx->Signature = SRB_SIGNATURE;
2128 srbEx->Version = STORAGE_REQUEST_BLOCK_VERSION_1;
2129 srbEx->SrbLength = CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE;
2130 srbEx->SrbFunction = SRB_FUNCTION_EXECUTE_SCSI;
2131 srbEx->RequestPriority = IoGetIoPriorityHint(Irp);
2132 srbEx->AddressOffset = sizeof(STORAGE_REQUEST_BLOCK);
2133 srbEx->NumSrbExData = 1;
2134
2135 //
2136 // Set up address fields
2137 //
2138
2139 storAddrBtl8 = (PSTOR_ADDR_BTL8) ((PUCHAR)srbEx + srbEx->AddressOffset);
2140 storAddrBtl8->Type = STOR_ADDRESS_TYPE_BTL8;
2141 storAddrBtl8->AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
2142
2143 //
2144 // Set up SCSI SRB extended data fields
2145 //
2146
2147 srbEx->SrbExDataOffset[0] = sizeof(STORAGE_REQUEST_BLOCK) +
2148 sizeof(STOR_ADDR_BTL8);
2149 if ((srbEx->SrbExDataOffset[0] + sizeof(SRBEX_DATA_SCSI_CDB16)) <= srbEx->SrbLength) {
2150 srbExDataCdb16 = (PSRBEX_DATA_SCSI_CDB16)((PUCHAR)srbEx + srbEx->SrbExDataOffset[0]);
2151 srbExDataCdb16->Type = SrbExDataTypeScsiCdb16;
2152 srbExDataCdb16->Length = SRBEX_DATA_SCSI_CDB16_LENGTH;
2153
2154 Cdb = (PCDB)srbExDataCdb16->Cdb;
2155 if (TEST_FLAG(FdoExtension->DeviceFlags, DEV_USE_16BYTE_CDB)) {
2156 srbExDataCdb16->CdbLength = 16;
2157 Cdb->CDB16.OperationCode = SCSIOP_VERIFY16;
2158 } else {
2159 srbExDataCdb16->CdbLength = 10;
2160 Cdb->CDB10.OperationCode = SCSIOP_VERIFY;
2161 }
2162 } else {
2163 // Should not happen
2165
2166 FREE_POOL(Srb);
2167 FREE_POOL(WorkContext);
2169 }
2170
2171 } else {
2173
2174 Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
2175 Srb->Function =