ReactOS  0.4.15-dev-3181-g4acf100
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)
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706

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 };
2020  NTSTATUS status;
2022 
2023  PAGED_CODE();
2024 
2025  NT_ASSERT(WorkItem != NULL);
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 TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
#define FALSE
Definition: types.h:117
struct _FUNCTIONAL_DEVICE_EXTENSION * PFUNCTIONAL_DEVICE_EXTENSION
NTSTATUS NTAPI DiskSetCacheInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
Definition: disk.c:3167
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:110
NTSTATUS NTAPI DiskGetCacheInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
Definition: disk.c:3019
static SERVICE_STATUS status
Definition: service.c:31
struct _IO_WORKITEM * PIO_WORKITEM
Definition: iotypes.h:506
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3310
Definition: ps.c:97

Referenced by DiskFdoProcessError().

◆ 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 }
#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:1770
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
int Count
Definition: noreturn.cpp:7
#define NULL
Definition: types.h:112
VOID NTAPI DiskDriverReinit(IN PDRIVER_OBJECT DriverObject, IN PVOID Nothing, IN ULONG Count)
Definition: disk.c:108

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;
342  HANDLE handle = 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 
383  } while((status == STATUS_OBJECT_NAME_COLLISION) ||
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)) {
409  ZwClose(handle);
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 
421  status = DiskGenerateDeviceName(*DeviceCount, &deviceName);
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 
526 DiskCreateFdoExit:
527 
528  if (deviceObject != NULL)
529  {
531  }
532 
533  FREE_POOL(deviceName);
534 
535  ObDereferenceObject(lowerDevice);
536 
538  ZwClose(handle);
539 
540  return status;
541 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:873
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1155
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define FALSE
Definition: types.h:117
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define TRACE_LEVEL_FATAL
Definition: storswtr.h:26
ULONG DeviceCount
Definition: mpu401.c:26
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
NTSYSAPI NTSTATUS NTAPI ZwCreateDirectoryObject(_Out_ PHANDLE DirectoryHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define CLEAR_FLAG(Flags, Bit)
Definition: cdrom.h:1494
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static const WCHAR L[]
Definition: oid.c:1250
PDEVICE_OBJECT LowerPdo
Definition: classpnp.h:875
#define OBJ_PERMANENT
Definition: winternl.h:226
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
MxDeviceObject deviceObject
#define VPB_RAW_MOUNT
Definition: iotypes.h:1811
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS DiskGenerateDeviceName(IN ULONG DeviceNumber, OUT PCCHAR *RawName)
Definition: pnp.c:612
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
#define NULL
Definition: types.h:112
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
NTSYSAPI NTSTATUS NTAPI ZwMakeTemporaryObject(_In_ HANDLE Handle)
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
#define PAGED_CODE()
Definition: ps.c:97

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 
892 SkipTable:
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 }
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:888
#define TRUE
Definition: types.h:120
struct _DEVICE_MEDIA_INFO::@3083::@3085 RemovableDiskInfo
ULONG BytesPerSector
Definition: ntdddisk.h:409
ULONG TracksPerCylinder
Definition: ntdddisk.h:407
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define MEDIA_WRITE_PROTECTED
Definition: minitape.h:35
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
enum _STORAGE_MEDIA_TYPE STORAGE_MEDIA_TYPE
struct _DEVICE_MEDIA_INFO::@3083::@3084 DiskInfo
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define MEDIA_WRITE_ONCE
Definition: minitape.h:32
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
unsigned char BOOLEAN
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
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
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:405
ULONG SectorsPerTrack
Definition: ntdddisk.h:408
PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: classpnp.h:876
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define MEDIA_READ_WRITE
Definition: minitape.h:34
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
ULONG DeviceType
Definition: ntddstor.h:494
ULONG MediaInfoCount
Definition: ntddstor.h:495
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
union _DEVICE_MEDIA_INFO::@3083 DeviceSpecific
#define MEDIA_CURRENTLY_MOUNTED
Definition: minitape.h:36
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
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NULL
Definition: types.h:112
_Must_inspect_result_ _Out_ PBOOLEAN IsWritable
Definition: fltkernel.h:1743
struct _DEVICE_MEDIA_INFO DEVICE_MEDIA_INFO
unsigned int ULONG
Definition: retypes.h:1
DISK_MEDIA_TYPES_LIST const DiskMediaTypes[]
Definition: data.c:82
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
DISK_MEDIA_TYPES_LIST const DiskMediaTypesExclude[]
Definition: data.c:74
LONGLONG QuadPart
Definition: typedefs.h:114
DEVICE_MEDIA_INFO MediaInfo[1]
Definition: ntddstor.h:496
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3310

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 
1015  case IOCTL_DISK_IS_WRITABLE: {
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 
1072  case SMART_SEND_DRIVE_COMMAND: {
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_EX
Definition: ntddk_ex.h:208
NTSTATUS DiskIoctlEnableFailurePrediction(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4419
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
#define IOCTL_DISK_INTERNAL_SET_VERIFY
Definition: ntdddisk.h:136
NTSTATUS DiskIoctlGetCacheInformation(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3840
NTSTATUS DiskIoctlSmartReceiveDriveData(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5663
#define SMART_GET_VERSION
Definition: ntdddisk.h:257
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2817
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS DiskIoctlSmartGetVersion(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5540
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
#define IOCTL_DISK_UPDATE_DRIVE_SIZE
Definition: ntdddisk.h:239
NTSTATUS DiskIoctlGetMediaTypesEx(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3994
#define IOCTL_DISK_GET_CACHE_SETTING
Definition: ntdddisk.h:76
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS_ADMIN
Definition: disk.c:104
#define IOCTL_DISK_GET_CACHE_INFORMATION
Definition: ntdddisk.h:73
NTSTATUS DiskIoctlVerify(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4526
NTSTATUS DiskIoctlPredictFailure(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4268
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
NTSTATUS DiskIoctlGetVolumeDiskExtents(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5461
_In_ PIRP Irp
Definition: csq.h:116
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define IOCTL_DISK_VERIFY
Definition: cdrw_usr.h:170
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
#define SMART_RCV_DRIVE_DATA
Definition: ntdddisk.h:260
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
NTSTATUS DiskIoctlUpdateDriveSize(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5362
#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX
Definition: cdrw_usr.h:190
NTSTATUS DiskIoctlReassignBlocksEx(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4855
NTSTATUS DiskIoctlGetDriveGeometry(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3582
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IOCTL_DISK_INTERNAL_CLEAR_VERIFY
Definition: ntdddisk.h:133
NTSTATUS DiskIoctlIsWritable(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5063
NTSTATUS DiskIoctlSetVerify(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5264
NTSTATUS DiskIoctlGetCacheSetting(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: disk.c:3347
NTSTATUS DiskIoctlSmartSendDriveCommand(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5890
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Definition: ntddvol.h:41
NTSTATUS DiskIoctlSetCacheSetting(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: disk.c:3415
#define IOCTL_DISK_REASSIGN_BLOCKS
Definition: ntdddisk.h:157
#define IOCTL_DISK_REASSIGN_BLOCKS_EX
Definition: ntdddisk.h:178
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IOCTL_STORAGE_PREDICT_FAILURE
Definition: ntddstor.h:146
#define NULL
Definition: types.h:112
NTSTATUS DiskIoctlClearVerify(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5313
#define IOCTL_DISK_SET_CACHE_INFORMATION
Definition: ntdddisk.h:193
NTSTATUS DiskIoctlGetLengthInfo(IN OUT PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3492
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define IOCTL_DISK_SET_CACHE_SETTING
Definition: ntdddisk.h:196
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
NTSTATUS DiskIoctlGetDriveGeometryEx(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3672
VOID NTAPI ClassCompleteRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ CCHAR PriorityBoost)
Definition: lock.c:401
static SERVICE_STATUS status
Definition: service.c:31
#define SMART_SEND_DRIVE_COMMAND
Definition: ntdddisk.h:263
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
static DRIVER_DISPATCH ClassDeviceControl
Definition: kbdclass.c:22
#define NT_ASSERT
Definition: rtlfuncs.h:3310
Definition: ps.c:97

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.

113 {
117 
119 }
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
int Count
Definition: noreturn.cpp:7
BOOLEAN DiskIsPastReinit
Definition: disk.c:81

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 }
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG _In_opt_ PEVENT_FILTER_DESCRIPTOR _Inout_opt_ PVOID CallbackContext
Definition: wmitypes.h:55
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
#define FALSE
Definition: types.h:117
return pProvider IsEnabled(ProviderControl)
BOOLEAN DiskETWEnabled
Definition: disk.c:79
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG MatchAnyKeyword
Definition: wmitypes.h:55
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG MatchAllKeyword
Definition: wmitypes.h:55
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData
Definition: wmitypes.h:55

◆ 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;
2308  PSTORAGE_REQUEST_BLOCK srbEx;
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  //
2465  PIO_WORKITEM workItem = IoAllocateWorkItem(Fdo);
2466 
2467  if (workItem)
2468  {
2469  IoQueueWorkItem(workItem, DisableWriteCache, CriticalWorkQueue, workItem);
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 
2525  case SCSI_SENSE_MEDIUM_ERROR: {
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)) {
2559  case SRB_STATUS_NO_DEVICE:
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 }
UCHAR PathId
Definition: scsi_port.h:149
UCHAR PortNumber
Definition: scsi_port.h:148
#define SCSISTAT_BUSY
Definition: cdrw_hw.h:1081
#define CLASS_SPECIAL_FUA_NOT_SUPPORTED
Definition: classpnp.h:174
UCHAR senseKey
Definition: scsi.h:4019
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
UCHAR Cdb[16]
Definition: srb.h:271
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
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
#define MODE_PAGE_CACHING
Definition: cdrw_hw.h:846
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:379
NTSTATUS FinalStatus
Definition: iotypes.h:2009
#define TRUE
Definition: types.h:120
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
Definition: cdrw_hw.h:28
#define IO_WARNING_WRITE_FUA_PROBLEM
Definition: ntiologc.h:93
#define SRB_STATUS_REQUEST_FLUSHED
Definition: srb.h:353
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:873
struct _CDB::_CDB6FORMAT CDB6FORMAT
SCSI_ADDRESS ScsiAddress
Definition: disk.h:325
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define SRB_STATUS_COMMAND_TIMEOUT
Definition: srb.h:343
#define MODE_SENSE_RETURN_ALL
Definition: cdrw_hw.h:857
#define SRB_STATUS_NO_DEVICE
Definition: srb.h:340
#define SCSI_SENSE_OPTIONS_FIXED_FORMAT_IF_UNKNOWN_FORMAT_INDICATED
Definition: scsi.h:3839
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define SCSIOP_WRITE16
Definition: scsi.h:915
struct _CDB::_CDB10 CDB10
if(dx==0 &&dy==0)
Definition: linetemp.h:174
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
#define SRB_STATUS_INVALID_TARGET_ID
Definition: srb.h:355
UCHAR TargetId
Definition: scsi_port.h:150
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
VOID NTAPI IoWriteErrorLogEntry(IN PVOID ElEntry)
Definition: error.c:628
#define IRP_MJ_SCSI
#define SRB_STATUS_ERROR
Definition: srb.h:336
#define SCSI_SENSE_MEDIUM_ERROR
Definition: cdrw_hw.h:1190
NTSTATUS ErrorCode
Definition: iotypes.h:2007
#define SRB_STATUS_PARITY_ERROR
Definition: srb.h:346
#define SCSI_SENSEQ_MANUAL_INTERVENTION_REQUIRED
Definition: cdrw_hw.h:1315
#define FALSE
Definition: types.h:117
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
UCHAR ScsiStatus
Definition: srb.h:244
#define ADJUST_FUA_FLAG(fdoExt)
Definition: classpnp.h:53
#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
Definition: cdrw_hw.h:1221
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
unsigned char BOOLEAN
#define SRB_STATUS_NO_HBA
Definition: srb.h:348
DISK_USER_WRITE_CACHE_SETTING WriteCacheOverride
Definition: disk.h:385
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
union _CDB * PCDB
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
struct _CDB::_MODE_SENSE MODE_SENSE
PVOID NTAPI IoAllocateErrorLogEntry(IN PVOID IoObject, IN UCHAR EntrySize)
Definition: error.c:528
Status
Definition: gdiplustypes.h:24
#define SCSI_SENSEQ_BECOMING_READY
Definition: cdrw_hw.h:1313
UCHAR Function
Definition: srb.h:242
#define SCSISTAT_RESERVATION_CONFLICT
Definition: cdrw_hw.h:1084
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:871
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
#define SCSI_SENSE_HARDWARE_ERROR
Definition: cdrw_hw.h:1191
#define SRB_FUNCTION_STORAGE_REQUEST_BLOCK
Definition: srb.h:99
unsigned char UCHAR
Definition: xmlstorage.h:181
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:310
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:342
#define SCSI_SENSE_RECOVERED_ERROR
Definition: cdrw_hw.h:1188
#define SCSI_SENSEQ_CAUSE_NOT_REPORTABLE
Definition: cdrw_hw.h:1312
#define SRB_STATUS_INVALID_LUN
Definition: srb.h:354
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
UCHAR SenseInfoBufferLength
Definition: srb.h:251
#define IS_SCSIOP_READWRITE(opCode)
Definition: cdrom.h:803
#define SRB_STATUS_TIMEOUT
Definition: srb.h:341
#define NULL
Definition: types.h:112
VOID NTAPI DisableWriteCache(IN PDEVICE_OBJECT Fdo, IN PVOID Context)
Definition: disk.c:2012
PVOID SenseInfoBuffer
Definition: srb.h:256
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
#define SRB_STATUS_UNEXPECTED_BUS_FREE
Definition: srb.h:350
#define SRB_STATUS_INVALID_PATH_ID
Definition: srb.h:339
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
VOID ResetBus(IN PDEVICE_OBJECT Fdo)
Definition: disk.c:2705
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
#define SCSI_SENSE_UNIT_ATTENTION
Definition: cdrw_hw.h:1193
#define SCSI_ADSENSE_INVALID_CDB
Definition: cdrw_hw.h:1265
BOOLEAN validSense
Definition: scsi.h:4018
struct _DISK_DATA * PDISK_DATA
#define NT_ASSERT
Definition: rtlfuncs.h:3310

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;
1729  NTSTATUS status;
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 STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
LONG NTSTATUS
Definition: precomp.h:26
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:873
LIST_ENTRY CurrList
Definition: disk.h:108
IO_STATUS_BLOCK IoStatus
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
struct _FUNCTIONAL_DEVICE_EXTENSION * PFUNCTIONAL_DEVICE_EXTENSION
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
KEVENT Event
Definition: disk.h:148
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
NTSTATUS NTAPI ClassIoComplete(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
Definition: class.c:3768
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
#define NTSTATUS
Definition: precomp.h:20
Definition: typedefs.h:119
DISK_GROUP_CONTEXT FlushContext
Definition: disk.h:379
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
SCSI_REQUEST_BLOCK Srb
Definition: disk.h:131
struct tagContext Context
Definition: acpixf.h:1034
#define IO_NO_INCREMENT
Definition: iotypes.h:598
VOID NTAPI ClassCompleteRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ CCHAR PriorityBoost)
Definition: lock.c:401
static SERVICE_STATUS status
Definition: service.c:31
#define NT_ASSERT
Definition: rtlfuncs.h:3310
Definition: ps.c:97

Referenced by DiskFlushDispatch().

◆ 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 
1573  srbEx->Length = FIELD_OFFSET(STORAGE_REQUEST_BLOCK, Signature);
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  //
1606  if (TEST_FLAG(fdoExt->DeviceFlags, DEV_WRITE_CACHE))
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
1627  NT_ASSERT(FALSE);
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 STOR_ADDRESS_TYPE_BTL8
Definition: scsi.h:3525
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
#define SCSIOP_SYNCHRONIZE_CACHE
Definition: cdrw_hw.h:918
ULONG SrbFlags
Definition: srb.h:252
PVOID OriginalRequest
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:271
#define STORAGE_REQUEST_BLOCK_VERSION_1
Definition: srb.h:608
struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 * PSTOR_ADDR_BTL8
#define TRUE
Definition: types.h:120
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
UCHAR CdbLength
Definition: srb.h:250
UCHAR QueueAction
Definition: srb.h:249
ULONG TimeOutValue
Definition: srb.h:254
UCHAR SrbStatus
Definition: srb.h:243
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define SP_UNTAGGED
Definition: srb.h:225
#define IRP_MJ_SCSI
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 SRBEX_DATA_SCSI_CDB16
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
UCHAR ScsiStatus
Definition: srb.h:244
#define STOR_ADDR_BTL8_ADDRESS_LENGTH
Definition: scsi.h:3528
#define SRB_CLASS_FLAGS_PERSISTANT
Definition: classpnp.h:20
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 * PSRBEX_DATA_SCSI_CDB16
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
void * PVOID
Definition: retypes.h:9
UCHAR QueueTag
Definition: srb.h:248
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
#define SRB_FUNCTION_FLUSH
Definition: srb.h:315
#define DEV_WRITE_CACHE
Definition: classpnp.h:178
NTSTATUS NTAPI DiskFlushComplete(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
Definition: disk.c:1699
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
UCHAR Function
Definition: srb.h:242
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
irpSp
Definition: iofuncs.h:2719
USHORT Length
Definition: srb.h:241
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
#define SRB_FUNCTION_STORAGE_REQUEST_BLOCK
Definition: srb.h:99
_In_z_ PCCHAR _In_ PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:982
#define SRB_SIGNATURE
Definition: srb.h:607
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
STORAGE_REQUEST_BLOCK
Definition: srb.h:652
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
NTKRNLVISTAAPI IO_PRIORITY_HINT NTAPI IoGetIoPriorityHint(_In_ PIRP Irp)
Definition: io.c:123
struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 STOR_ADDR_BTL8
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
static const WCHAR Signature[]
Definition: parser.c:141
#define SRBEX_DATA_SCSI_CDB16_LENGTH
Definition: srb.h:480
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
#define NT_ASSERT
Definition: rtlfuncs.h:3310

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);
3088  return STATUS_IO_DEVICE_ERROR;
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 }
signed char * PCHAR
Definition: retypes.h:7
return STATUS_NOT_SUPPORTED
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
UCHAR WriteCacheEnable
Definition: cdrw_hw.h:2779
#define MODE_PAGE_CACHING
Definition: cdrw_hw.h:846
#define TRUE
Definition: types.h:120
#define TRANSLATE_RETENTION_PRIORITY(_x)
Definition: disk.c:99
UCHAR ReadDisableCache
Definition: cdrw_hw.h:2777
UCHAR ReadRetensionPriority
Definition: cdrw_hw.h:2783
UCHAR MaximumPrefetch[2]
Definition: cdrw_hw.h:2787
#define MODE_DATA_SIZE
Definition: cdrom.h:691
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
UCHAR MultiplicationFactor
Definition: cdrw_hw.h:2778
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
PVOID NTAPI ClassFindModePage(_In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode, _In_ BOOLEAN Use6Byte)
Definition: class.c:6798
UCHAR MinimumPrefetch[2]
Definition: cdrw_hw.h:2786
#define DISK_TAG_DISABLE_CACHE
Definition: disk.h:56
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define NULL
Definition: types.h:112
ULONG NTAPI ClassModeSense(_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode)
Definition: class.c:6637
UCHAR DisablePrefetchTransfer[2]
Definition: cdrw_hw.h:2785
unsigned int ULONG
Definition: retypes.h:1
UCHAR MaximumPrefetchCeiling[2]
Definition: cdrw_hw.h:2788
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
UCHAR WriteRetensionPriority
Definition: cdrw_hw.h:2782
#define STATUS_SUCCESS
Definition: shellext.h:65
#define PAGED_CODE()

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 
2905  NTSTATUS status;
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);
2945  return STATUS_IO_DEVICE_ERROR;
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 }
signed char * PCHAR
Definition: retypes.h:7
#define MODE_PAGE_FAULT_REPORTING
Definition: scsi.h:218
return STATUS_NOT_SUPPORTED
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define MODE_DATA_SIZE
Definition: cdrom.h:691
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define DISK_TAG_INFO_EXCEPTION
Definition: disk.h:55
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PVOID NTAPI ClassFindModePage(_In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode, _In_ BOOLEAN Use6Byte)
Definition: class.c:6798
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define NULL
Definition: types.h:112
ULONG NTAPI ClassModeSense(_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode)
Definition: class.c:6637
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
Definition: ps.c:97

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 }
return STATUS_NOT_SUPPORTED
LONG NTSTATUS
Definition: precomp.h:26
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
#define CLEAR_FLAG(Flags, Bit)
Definition: cdrom.h:1494
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

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"));
4470  return STATUS_BUFFER_TOO_SMALL;
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 }
NTSTATUS DiskEnableDisableFailurePrediction(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable)
Definition: diskwmi.c:1126
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
BOOLEAN FailurePredictionEnabled
Definition: disk.h:346
NTSTATUS DiskEnableInfoExceptions(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ BOOLEAN Enable)
Definition: diskwmi.c:979
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN ScsiInfoExceptionsSupported
Definition: disk.h:340
FAILURE_PREDICTION_METHOD FailurePredictionCapability
Definition: disk.h:331
#define CHECK_IRQL()
Definition: disk.h:458
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
static SERVICE_STATUS status
Definition: service.c:31
struct _DISK_DATA * PDISK_DATA
#define PAGED_CODE()
Definition: ps.c:97

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;
3872  NTSTATUS status;
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"));
3890  return STATUS_BUFFER_TOO_SMALL;
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 }
LONG NTSTATUS
Definition: precomp.h:26
struct _DISK_CACHE_INFORMATION DISK_CACHE_INFORMATION
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
#define ADJUST_FUA_FLAG(fdoExt)
Definition: classpnp.h:53
#define CLEAR_FLAG(Flags, Bit)
Definition: cdrom.h:1494
#define DEV_WRITE_CACHE
Definition: classpnp.h:178
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CHECK_IRQL()
Definition: disk.h:458
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
NTSTATUS NTAPI DiskGetCacheInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
Definition: disk.c:3019
static SERVICE_STATUS status
Definition: service.c:31
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
#define PAGED_CODE()
Definition: ps.c:97

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  {
3394  cacheSetting->State = DiskCacheWriteThroughNotSupported;
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 CLASS_SPECIAL_FUA_NOT_SUPPORTED
Definition: classpnp.h:174
LONG NTSTATUS
Definition: precomp.h:26
struct _DISK_CACHE_SETTING * PDISK_CACHE_SETTING
BOOLEAN IsPowerProtected
Definition: ntdddisk.h:837
DISK_CACHE_STATE State
Definition: ntdddisk.h:836
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
#define CLASS_SPECIAL_MODIFY_CACHE_UNSUCCESSFUL
Definition: classpnp.h:173
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
irpSp
Definition: iofuncs.h:2719
#define DEV_POWER_PROTECTED
Definition: cdrom.h:143
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
struct _DISK_CACHE_SETTING DISK_CACHE_SETTING
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
Definition: ps.c:97

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);
3614  NTSTATUS status;
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"));
3626  return STATUS_BUFFER_TOO_SMALL;
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 }
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:888
NTSTATUS ReadyStatus
Definition: disk.h:319
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
LONG NTSTATUS
Definition: precomp.h:26
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _DISK_GEOMETRY * PDISK_GEOMETRY
#define CHECK_IRQL()
Definition: disk.h:458
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
struct _DISK_GEOMETRY DISK_GEOMETRY
#define DiskReadDriveCapacity(Fdo)
Definition: disk.h:818
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
static SERVICE_STATUS status
Definition: service.c:31
struct _DISK_DATA * PDISK_DATA
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DiskDeviceControl().

◆ DiskIoctlGetDriveGeometryEx()

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

Definition at line 3672 of file disk.c.

3699 {
3700  NTSTATUS status;
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 
3783  case PARTITION_STYLE_GPT:
3784 
3785  //
3786  // Copy GPT signature.
3787  //
3788 
3789  geometryEx->Partition.Gpt.DiskId = diskData->Efi.DiskId;
3790  break;
3791 
3792  case PARTITION_STYLE_MBR:
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 }
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
struct _DISK_DATA::@1003::@1007 Efi
DISK_GEOMETRY Geometry
Definition: disk.c:3665
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:888
NTSTATUS ReadyStatus
Definition: disk.h:319
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
LONG NTSTATUS
Definition: precomp.h:26
ULONG BytesPerSector
Definition: ntdddisk.h:409
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
LARGE_INTEGER DiskSize
Definition: disk.c:3666
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:318
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
long LONG
Definition: pedump.c:60
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
struct _DISK_GEOMETRY_EX_INTERNAL * PDISK_GEOMETRY_EX_INTERNAL
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
PARTITION_STYLE PartitionStyle
Definition: disk.h:197
struct _DISK_DATA::@1003::@1006 Mbr
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CHECK_IRQL()
Definition: disk.h:458
#define DiskGetDetectInfo(FdoExtension, DetectInfo)
Definition: disk.h:861
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
#define DiskReadDriveCapacity(Fdo)
Definition: disk.h:818
DISK_DETECTION_INFO Detection
Definition: disk.c:3668
DISK_PARTITION_INFO Partition
Definition: disk.c:3667
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
static SERVICE_STATUS status
Definition: service.c:31
struct _DISK_DATA * PDISK_DATA
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DiskDeviceControl().

◆ DiskIoctlGetLengthInfo()

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

Definition at line 3492 of file disk.c.

3518 {
3519  NTSTATUS status;
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;
3539  irpStack = IoGetCurrentIrpStackLocation(Irp);
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)) {
3548  return STATUS_BUFFER_TOO_SMALL;
3549  }
3550 
3551  //
3552  // Update the geometry in case it has changed
3553  //
3554 
3555  status = DiskReadDriveCapacity(p0Extension->DeviceObject);
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 }
LARGE_INTEGER PartitionLength
Definition: classpnp.h:618
NTSTATUS ReadyStatus
Definition: disk.h:319
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
LONG NTSTATUS
Definition: precomp.h:26
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:873
LARGE_INTEGER Length
Definition: imports.h:232
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _GET_LENGTH_INFORMATION * PGET_LENGTH_INFORMATION
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:871
PDEVICE_OBJECT LowerPdo
Definition: classpnp.h:875
#define CHECK_IRQL()
Definition: disk.h:458
#define InterlockedExchange
Definition: armddk.h:54
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2342
#define DiskReadDriveCapacity(Fdo)
Definition: disk.h:818
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
static SERVICE_STATUS status
Definition: service.c:31
struct _DISK_DATA * PDISK_DATA
#define PAGED_CODE()
Definition: ps.c:97

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;
4024  NTSTATUS status;
4025 
4026  PMODE_PARAMETER_HEADER modeData;
4027  PMODE_PARAMETER_BLOCK blockDescriptor;
4028  PSCSI_REQUEST_BLOCK srb;
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;
4036  PSTORAGE_REQUEST_BLOCK srbEx = NULL;
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"));
4056  return STATUS_BUFFER_TOO_SMALL;
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 
4087  srbEx->Length = FIELD_OFFSET(STORAGE_REQUEST_BLOCK, Signature);
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
4123  NT_ASSERT(FALSE);
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 
4208 Retry:
4210  srb,
4211  modeData,
4212  modeLength,
4213  FALSE);
4214 
4215  if (status == STATUS_VERIFY_REQUIRED) {
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 STOR_ADDRESS_TYPE_BTL8
Definition: scsi.h:3525
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _MODE_PARAMETER_HEADER MODE_PARAMETER_HEADER
UCHAR Cdb[16]
Definition: srb.h:271
#define STORAGE_REQUEST_BLOCK_VERSION_1
Definition: srb.h:608
struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 * PSTOR_ADDR_BTL8
#define TRUE
Definition: types.h:120
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
#define MODE_DSP_WRITE_PROTECT
Definition: cdrw_hw.h:2523
unsigned char * PUCHAR
Definition: retypes.h:3
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
#define DISK_TAG_SRB
Definition: disk.h:67
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
#define MODE_SENSE_RETURN_ALL
Definition: cdrw_hw.h:857
UCHAR CdbLength
Definition: srb.h:250
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
ULONG TimeOutValue
Definition: srb.h:254
#define MODE_DATA_SIZE
Definition: cdrom.h:691
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define DISK_TAG_MODE_DATA
Definition: disk.h:62
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 SRBEX_DATA_SCSI_CDB16
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE
Definition: classpnp.h:695
UCHAR ScsiStatus
Definition: srb.h:244
#define STOR_ADDR_BTL8_ADDRESS_LENGTH
Definition: scsi.h:3528
unsigned char BOOLEAN
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 * PSRBEX_DATA_SCSI_CDB16
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
union _CDB * PCDB
UCHAR DeviceSpecificParameter
Definition: cdrw_hw.h:2507
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
struct _CDB::_MODE_SENSE MODE_SENSE
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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UCHAR Function
Definition: srb.h:242
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
USHORT Length
Definition: srb.h:241
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define SRB_FUNCTION_STORAGE_REQUEST_BLOCK
Definition: srb.h:99
unsigned char UCHAR
Definition: xmlstorage.h:181
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:310
#define SRB_SIGNATURE
Definition: srb.h:607
#define CHECK_IRQL()
Definition: disk.h:458
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
STORAGE_REQUEST_BLOCK
Definition: srb.h:652
struct _CDB::_CDB6GENERIC CDB6GENERIC
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
#define NULL
Definition: types.h:112
NTKRNLVISTAAPI IO_PRIORITY_HINT NTAPI IoGetIoPriorityHint(_In_ PIRP Irp)
Definition: io.c:123
struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 STOR_ADDR_BTL8
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
struct _MODE_PARAMETER_BLOCK * PMODE_PARAMETER_BLOCK
#define STATUS_SUCCESS
Definition: shellext.h:65
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
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
static const WCHAR Signature[]
Definition: parser.c:141
static SERVICE_STATUS status
Definition: service.c:31
#define SRBEX_DATA_SCSI_CDB16_LENGTH
Definition: srb.h:480
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3310
Definition: ps.c:97

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"));
5512  return STATUS_BUFFER_TOO_SMALL;
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 }
LARGE_INTEGER ExtentLength
Definition: ntddvol.h:115
LARGE_INTEGER PartitionLength
Definition: classpnp.h:618
struct _VOLUME_DISK_EXTENTS * PVOLUME_DISK_EXTENTS
NTSTATUS ReadyStatus
Definition: disk.h:319
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
DISK_EXTENT Extents[1]
Definition: ntddvol.h:120
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
ULONG DiskNumber
Definition: ntddvol.h:113
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
LARGE_INTEGER StartingOffset
Definition: classpnp.h:619
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CHECK_IRQL()
Definition: disk.h:458
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
ULONG NumberOfDiskExtents
Definition: ntddvol.h:119
LARGE_INTEGER StartingOffset
Definition: ntddvol.h:114
#define DiskReadDriveCapacity(Fdo)
Definition: disk.h:818
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
static SERVICE_STATUS status
Definition: service.c:31
struct _DISK_DATA * PDISK_DATA
#define PAGED_CODE()
Definition: ps.c:97

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;
5095  PSCSI_REQUEST_BLOCK srb;
5096  PCDB cdb = NULL;
5097  ULONG modeLength;
5098  ULONG retries = 4;
5099  ULONG srbSize;
5100  PSTORAGE_REQUEST_BLOCK srbEx;
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 
5164  srbEx->Length = FIELD_OFFSET(STORAGE_REQUEST_BLOCK, Signature);
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
5200  NT_ASSERT(FALSE);
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 
5242  if (status != STATUS_VERIFY_REQUIRED) {
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 STOR_ADDRESS_TYPE_BTL8
Definition: scsi.h:3525
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
UCHAR Cdb[16]
Definition: srb.h:271
#define STORAGE_REQUEST_BLOCK_VERSION_1
Definition: srb.h:608
struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 * PSTOR_ADDR_BTL8
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
#define MODE_DSP_WRITE_PROTECT
Definition: cdrw_hw.h:2523
unsigned char * PUCHAR
Definition: retypes.h:3
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
#define DISK_TAG_SRB
Definition: disk.h:67
#define MODE_SENSE_RETURN_ALL
Definition: cdrw_hw.h:857
UCHAR CdbLength
Definition: srb.h:250
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
ULONG TimeOutValue
Definition: srb.h:254
#define MODE_DATA_SIZE
Definition: cdrom.h:691
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define DISK_TAG_MODE_DATA
Definition: disk.h:62
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 SRBEX_DATA_SCSI_CDB16
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE
Definition: classpnp.h:695
#define STOR_ADDR_BTL8_ADDRESS_LENGTH
Definition: scsi.h:3528
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 * PSRBEX_DATA_SCSI_CDB16
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
union _CDB * PCDB
UCHAR DeviceSpecificParameter
Definition: cdrw_hw.h:2507
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
struct _CDB::_MODE_SENSE MODE_SENSE
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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UCHAR Function
Definition: srb.h:242
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
USHORT Length
Definition: srb.h:241
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define SRB_FUNCTION_STORAGE_REQUEST_BLOCK
Definition: srb.h:99
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SRB_SIGNATURE
Definition: srb.h:607
#define CHECK_IRQL()
Definition: disk.h:458
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
STORAGE_REQUEST_BLOCK
Definition: srb.h:652
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
#define NULL
Definition: types.h:112
NTKRNLVISTAAPI IO_PRIORITY_HINT NTAPI IoGetIoPriorityHint(_In_ PIRP Irp)
Definition: io.c:123
struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 STOR_ADDR_BTL8
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
static const WCHAR Signature[]
Definition: parser.c:141
static SERVICE_STATUS status
Definition: service.c:31
#define SRBEX_DATA_SCSI_CDB16_LENGTH
Definition: srb.h:480
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3310
Definition: ps.c:97

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"));
4322  return STATUS_BUFFER_TOO_SMALL;
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,
4355  DISK_TAG_SMART);
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 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
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
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:888
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
ULONG BytesPerSector
Definition: ntdddisk.h:409
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define DISK_TAG_SMART
Definition: disk.h:54
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
struct _STORAGE_PREDICT_FAILURE * PSTORAGE_PREDICT_FAILURE
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
GLintptr offset
Definition: glext.h:5920
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS DiskReadFailurePredictData(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_DATA DiskSmartData)
Definition: diskwmi.c:1327
FAILURE_PREDICTION_METHOD FailurePredictionCapability
Definition: disk.h:331
#define CHECK_IRQL()
Definition: disk.h:458
struct _cl_event * event
Definition: glext.h:7739
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
struct _STORAGE_PREDICT_FAILURE STORAGE_PREDICT_FAILURE
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
NTSTATUS DiskReadFailurePredictStatus(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_STATUS DiskSmartStatus)
Definition: diskwmi.c:1251
#define IRP_MJ_READ
Definition: rdpdr.c:46
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
static SERVICE_STATUS status
Definition: service.c:31
struct _DISK_DATA * PDISK_DATA
#define PAGED_CODE()
Definition: ps.c:97

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;
4678  NTSTATUS status;
4679  PREASSIGN_BLOCKS badBlocks = Irp->AssociatedIrp.SystemBuffer;
4680  PSCSI_REQUEST_BLOCK srb;
4681  PCDB cdb;
4682  ULONG bufferSize;
4683  ULONG blockNumber;
4684  ULONG blockCount;
4685  ULONG srbSize;
4686  PSTORAGE_REQUEST_BLOCK srbEx;
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"));
4714  return STATUS_INVALID_PARAMETER;
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 
4785  srbEx->Length = FIELD_OFFSET(STORAGE_REQUEST_BLOCK, Signature);
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
4821  NT_ASSERT(FALSE);
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 STOR_ADDRESS_TYPE_BTL8
Definition: scsi.h:3525
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
#define SCSIOP_REASSIGN_BLOCKS
Definition: cdrw_hw.h:873
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
UCHAR Cdb[16]
Definition: srb.h:271
#define STORAGE_REQUEST_BLOCK_VERSION_1
Definition: srb.h:608
struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 * PSTOR_ADDR_BTL8
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
unsigned char * PUCHAR
Definition: retypes.h:3
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
#define DISK_TAG_SRB
Definition: disk.h:67
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:3465
UCHAR CdbLength
Definition: srb.h:250
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
ULONG TimeOutValue
Definition: srb.h:254
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 SRBEX_DATA_SCSI_CDB16
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE
Definition: classpnp.h:695
#define STOR_ADDR_BTL8_ADDRESS_LENGTH
Definition: scsi.h:3528
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 * PSRBEX_DATA_SCSI_CDB16
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
struct _REASSIGN_BLOCKS REASSIGN_BLOCKS
union _CDB * PCDB
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
UCHAR Function
Definition: srb.h:242
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
USHORT Length
Definition: srb.h:241
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define SRB_FUNCTION_STORAGE_REQUEST_BLOCK
Definition: srb.h:99
size_t bufferSize
#define SRB_SIGNATURE
Definition: srb.h:607
#define CHECK_IRQL()
Definition: disk.h:458
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
unsigned short USHORT
Definition: pedump.c:61
STORAGE_REQUEST_BLOCK
Definition: srb.h:652
struct _CDB::_CDB6GENERIC CDB6GENERIC
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
#define NULL
Definition: types.h:112
NTKRNLVISTAAPI IO_PRIORITY_HINT NTAPI IoGetIoPriorityHint(_In_ PIRP Irp)
Definition: io.c:123
struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 STOR_ADDR_BTL8
USHORT Reserved
Definition: ntdddisk.h:644
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
ULONG BlockNumber[1]
Definition: ntdddisk.h:646
static const WCHAR Signature[]
Definition: parser.c:141
static SERVICE_STATUS status
Definition: service.c:31
#define SRBEX_DATA_SCSI_CDB16_LENGTH
Definition: srb.h:480
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3310
Definition: ps.c:97

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;
4885  NTSTATUS status;
4886  PREASSIGN_BLOCKS_EX badBlocks = Irp->AssociatedIrp.SystemBuffer;
4887  PSCSI_REQUEST_BLOCK srb;
4888  PCDB cdb;
4889  LARGE_INTEGER blockNumber;
4890  ULONG bufferSize;
4891  ULONG blockCount;
4892  ULONG srbSize;
4893  PSTORAGE_REQUEST_BLOCK srbEx;
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