ReactOS  0.4.15-dev-1207-g698a8e6
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 2008 of file disk.c.

2013 {
2014  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = (PFUNCTIONAL_DEVICE_EXTENSION)Fdo->DeviceExtension;
2015  DISK_CACHE_INFORMATION cacheInfo = { 0 };
2016  NTSTATUS status;
2017  PIO_WORKITEM WorkItem = (PIO_WORKITEM)Context;
2018 
2019  PAGED_CODE();
2020 
2021  NT_ASSERT(WorkItem != NULL);
2022  _Analysis_assume_(WorkItem != NULL);
2023 
2024  status = DiskGetCacheInformation(fdoExtension, &cacheInfo);
2025 
2026  if (NT_SUCCESS(status) && (cacheInfo.WriteCacheEnabled == TRUE)) {
2027 
2028  cacheInfo.WriteCacheEnabled = FALSE;
2029 
2030  DiskSetCacheInformation(fdoExtension, &cacheInfo);
2031  }
2032 
2033  IoFreeWorkItem(WorkItem);
2034 }
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
#define FALSE
Definition: types.h:117
struct _FUNCTIONAL_DEVICE_EXTENSION * PFUNCTIONAL_DEVICE_EXTENSION
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI DiskGetCacheInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
Definition: disk.c:3015
#define _Analysis_assume_
Definition: no_sal2.h:388
NTSTATUS NTAPI DiskSetCacheInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
Definition: disk.c:3163
static SERVICE_STATUS status
Definition: service.c:31
struct _IO_WORKITEM * PIO_WORKITEM
Definition: iotypes.h:489
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

◆ 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
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1759
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
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;
344  PDEVICE_OBJECT deviceObject = 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 
447  SET_FLAG(deviceObject->Flags, DO_DIRECT_IO);
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 
514  CLEAR_FLAG(deviceObject->Flags, DO_DEVICE_INITIALIZING);
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  {
530  IoDeleteDevice(deviceObject);
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
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#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
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
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
#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)
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS DiskGenerateDeviceName(IN ULONG DeviceNumber, OUT PCCHAR *RawName)
Definition: pnp.c:610
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define CLEAR_FLAG(Flags, Bit)
Definition: cdrom.h:1494
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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
#define VPB_RAW_MOUNT
Definition: iotypes.h:1791
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
return STATUS_SUCCESS
Definition: btrfs.c:3014
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:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:888
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
union _DEVICE_MEDIA_INFO::@3120 DeviceSpecific
DISK_MEDIA_TYPES_LIST const DiskMediaTypesExclude[]
Definition: data.c:67
ULONG BytesPerSector
Definition: ntdddisk.h:442
ULONG TracksPerCylinder
Definition: ntdddisk.h:440
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define MEDIA_WRITE_PROTECTED
Definition: minitape.h:35
struct _DEVICE_MEDIA_INFO::@3120::@3122 RemovableDiskInfo
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
enum _STORAGE_MEDIA_TYPE STORAGE_MEDIA_TYPE
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 FALSE
Definition: types.h:117
#define MEDIA_WRITE_ONCE
Definition: minitape.h:32
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _DEVICE_MEDIA_INFO::@3120::@3121 DiskInfo
#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:438
ULONG SectorsPerTrack
Definition: ntdddisk.h:441
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
ULONG DeviceType
Definition: ntddstor.h:494
DISK_MEDIA_TYPES_LIST const DiskMediaTypes[]
Definition: data.c:72
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:2789
#define MEDIA_CURRENTLY_MOUNTED
Definition: minitape.h:36
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_Must_inspect_result_ _Out_ PBOOLEAN IsWritable
Definition: fltkernel.h:1744
struct _DEVICE_MEDIA_INFO DEVICE_MEDIA_INFO
unsigned int ULONG
Definition: retypes.h:1
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
LONGLONG QuadPart
Definition: typedefs.h:114
DEVICE_MEDIA_INFO MediaInfo[1]
Definition: ntddstor.h:496
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3312

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 DiskIoctlReassignBlocksEx(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4851
#define IOCTL_DISK_INTERNAL_SET_VERIFY
Definition: ntdddisk.h:136
_In_ PIRP Irp
Definition: csq.h:116
#define SMART_GET_VERSION
Definition: ntdddisk.h:257
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2813
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS DiskIoctlGetVolumeDiskExtents(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5457
NTSTATUS DiskIoctlSmartGetVersion(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5536
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
#define IOCTL_DISK_UPDATE_DRIVE_SIZE
Definition: ntdddisk.h:239
NTSTATUS DiskIoctlEnableFailurePrediction(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4415
NTSTATUS DiskIoctlReassignBlocks(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4644
#define IOCTL_DISK_GET_CACHE_SETTING
Definition: ntdddisk.h:76
#define IOCTL_DISK_GET_CACHE_INFORMATION
Definition: ntdddisk.h:73
#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
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS DiskIoctlIsWritable(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5059
#define SMART_RCV_DRIVE_DATA
Definition: ntdddisk.h:260
NTSTATUS DiskIoctlSmartReceiveDriveData(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5659
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
NTSTATUS DiskIoctlSetCacheInformation(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3913
NTSTATUS DiskIoctlPredictFailure(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4264
#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX
Definition: cdrw_usr.h:190
#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 DiskIoctlGetDriveGeometryEx(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3668
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Definition: ntddvol.h:41
NTSTATUS DiskIoctlGetLengthInfo(IN OUT PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3488
#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
NTSTATUS DiskIoctlSmartSendDriveCommand(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5886
NTSTATUS DiskIoctlGetMediaTypesEx(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3990
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define IOCTL_STORAGE_PREDICT_FAILURE
Definition: ntddstor.h:146
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
NTSTATUS DiskIoctlGetCacheSetting(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: disk.c:3343
NTSTATUS DiskIoctlUpdateDriveSize(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5358
NTSTATUS DiskIoctlVerify(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:4522
#define IOCTL_DISK_SET_CACHE_INFORMATION
Definition: ntdddisk.h:193
NTSTATUS DiskIoctlSetCacheSetting(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: disk.c:3411
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
NTSTATUS DiskIoctlGetDriveGeometry(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3578
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define IOCTL_DISK_SET_CACHE_SETTING
Definition: ntdddisk.h:196
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
NTSTATUS DiskIoctlGetCacheInformation(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:3836
return STATUS_SUCCESS
Definition: btrfs.c:3014
NTSTATUS DiskIoctlSetVerify(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5260
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 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS_ADMIN
Definition: disk.c:104
#define SMART_SEND_DRIVE_COMMAND
Definition: ntdddisk.h:263
NTSTATUS DiskIoctlClearVerify(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: disk.c:5309
#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:3312
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
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
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 6151 of file disk.c.

6176 {
6177  //
6178  // Initialize locals.
6179  //
6180  UNREFERENCED_PARAMETER(SourceId);
6186 
6187  //
6188  // Set the ETW tracing enable state.
6189  //
6190  DiskETWEnabled = IsEnabled ? TRUE : FALSE;
6191 
6192  return;
6193 }
_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
_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
BOOLEAN DiskETWEnabled
Definition: disk.c:79

◆ DiskFdoProcessError()

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

Definition at line 2272 of file disk.c.

2302 {
2303  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
2304  PSTORAGE_REQUEST_BLOCK srbEx;
2305  PCDB cdb = NULL;
2306  UCHAR scsiStatus = 0;
2307  UCHAR senseBufferLength = 0;
2308  PVOID senseBuffer = NULL;
2309  CDB noOp = {0};
2310 
2311  //
2312  // Get relevant fields from SRB
2313  //
2314  if (Srb->Function == SRB_FUNCTION_STORAGE_REQUEST_BLOCK) {
2315 
2316  srbEx = (PSTORAGE_REQUEST_BLOCK)Srb;
2317 
2318  //
2319  // Look for SCSI SRB specific fields
2320  //
2321  if ((srbEx->SrbFunction == SRB_FUNCTION_EXECUTE_SCSI) &&
2322  (srbEx->NumSrbExData > 0)) {
2323  cdb = GetSrbScsiData(srbEx, NULL, NULL, &scsiStatus, &senseBuffer, &senseBufferLength);
2324 
2325  //
2326  // cdb and sense buffer should not be NULL
2327  //
2328  NT_ASSERT(cdb != NULL);
2329  NT_ASSERT(senseBuffer != NULL);
2330 
2331  }
2332 
2333  if (cdb == NULL) {
2334 
2335  //
2336  // Use a cdb that is all 0s
2337  //
2338  cdb = &noOp;
2339  }
2340 
2341  } else {
2342 
2343  cdb = (PCDB)(Srb->Cdb);
2344  scsiStatus = Srb->ScsiStatus;
2345  senseBufferLength = Srb->SenseInfoBufferLength;
2346  senseBuffer = Srb->SenseInfoBuffer;
2347  }
2348 
2349  if (*Status == STATUS_DATA_OVERRUN &&
2350  (cdb != NULL) &&
2351  (IS_SCSIOP_READWRITE(cdb->CDB10.OperationCode))) {
2352 
2353  *Retry = TRUE;
2354 
2355  //
2356  // Update the error count for the device.
2357  //
2358 
2359  fdoExtension->ErrorCount++;
2360 
2361  } else if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_ERROR &&
2362  scsiStatus == SCSISTAT_BUSY) {
2363 
2364  //
2365  // a disk drive should never be busy this long. Reset the scsi bus
2366  // maybe this will clear the condition.
2367  //
2368 
2369  ResetBus(Fdo);
2370 
2371  //
2372  // Update the error count for the device.
2373  //
2374 
2375  fdoExtension->ErrorCount++;
2376 
2377  } else {
2378 
2379  BOOLEAN invalidatePartitionTable = FALSE;
2380 
2381  //
2382  // See if this might indicate that something on the drive has changed.
2383  //
2384 
2385  if ((Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID) &&
2386  (senseBuffer != NULL) && (cdb != NULL)) {
2387 
2389  UCHAR senseKey = 0;
2390  UCHAR asc = 0;
2391  UCHAR ascq = 0;
2392 
2393  validSense = ScsiGetSenseKeyAndCodes(senseBuffer,
2394  senseBufferLength,
2396  &senseKey,
2397  &asc,
2398  &ascq);
2399 
2400  if (validSense) {
2401 
2402  switch (senseKey) {
2403 
2405 
2406  switch (asc) {
2407 
2409  {
2410  //
2411  // Look to see if this is an Io request with the ForceUnitAccess flag set
2412  //
2413  if (((cdb->CDB10.OperationCode == SCSIOP_WRITE) ||
2414  (cdb->CDB10.OperationCode == SCSIOP_WRITE16)) &&
2415  (cdb->CDB10.ForceUnitAccess))
2416  {
2417  PDISK_DATA diskData = (PDISK_DATA)fdoExtension->CommonExtension.DriverData;
2418 
2420  {
2421  PIO_ERROR_LOG_PACKET logEntry = NULL;
2422 
2423  //
2424  // The user has explicitly requested that write caching be turned on.
2425  // Warn the user that writes with FUA enabled are not working and that
2426  // they should disable write cache.
2427  //
2428 
2429  logEntry = IoAllocateErrorLogEntry(fdoExtension->DeviceObject,
2430  sizeof(IO_ERROR_LOG_PACKET) + (4 * sizeof(ULONG)));
2431 
2432  if (logEntry != NULL)
2433  {
2434  logEntry->FinalStatus = *Status;
2436  logEntry->SequenceNumber = 0;
2437  logEntry->MajorFunctionCode = IRP_MJ_SCSI;
2438  logEntry->IoControlCode = 0;
2439  logEntry->RetryCount = 0;
2440  logEntry->UniqueErrorValue = 0;
2441  logEntry->DumpDataSize = 4 * sizeof(ULONG);
2442 
2443  logEntry->DumpData[0] = diskData->ScsiAddress.PortNumber;
2444  logEntry->DumpData[1] = diskData->ScsiAddress.PathId;
2445  logEntry->DumpData[2] = diskData->ScsiAddress.TargetId;
2446  logEntry->DumpData[3] = diskData->ScsiAddress.Lun;
2447 
2448  //
2449  // Write the error log packet.
2450  //
2451 
2452  IoWriteErrorLogEntry(logEntry);
2453  }
2454  }
2455  else
2456  {
2457  //
2458  // Turn off write caching on this device. This is so that future
2459  // critical requests need not be sent down with ForceUnitAccess
2460  //
2461  PIO_WORKITEM workItem = IoAllocateWorkItem(Fdo);
2462 
2463  if (workItem)
2464  {
2465  IoQueueWorkItem(workItem, DisableWriteCache, CriticalWorkQueue, workItem);
2466  }
2467  }
2468 
2470  ADJUST_FUA_FLAG(fdoExtension);
2471 
2472 
2473  cdb->CDB10.ForceUnitAccess = FALSE;
2474  *Retry = TRUE;
2475 
2476  } else if ((cdb->CDB6FORMAT.OperationCode == SCSIOP_MODE_SENSE) &&
2477  (cdb->MODE_SENSE.PageCode == MODE_SENSE_RETURN_ALL)) {
2478 
2479  //
2480  // Mode sense for all pages failed. This command could fail with
2481  // SCSI_SENSE_ILLEGAL_REQUEST / SCSI_ADSENSE_INVALID_CDB if the data
2482  // to be returned is more than 256 bytes. In which case, try to get
2483  // only MODE_PAGE_CACHING since we only need the block descriptor.
2484  //
2485  // Simply change the page code and retry the request
2486  //
2487 
2488  cdb->MODE_SENSE.PageCode = MODE_PAGE_CACHING;
2489  *Retry = TRUE;
2490  }
2491 
2492  break;
2493  }
2494  } // end switch(asc)
2495  break;
2496  }
2497 
2498  case SCSI_SENSE_NOT_READY: {
2499 
2500  switch (asc) {
2502  switch (ascq) {
2506  invalidatePartitionTable = TRUE;
2507  break;
2508  }
2509  } // end switch(ascq)
2510  break;
2511  }
2512 
2514  invalidatePartitionTable = TRUE;
2515  break;
2516  }
2517  } // end switch(asc)
2518  break;
2519  }
2520 
2521  case SCSI_SENSE_MEDIUM_ERROR: {
2522  invalidatePartitionTable = TRUE;
2523  break;
2524  }
2525 
2527  invalidatePartitionTable = TRUE;
2528  break;
2529  }
2530 
2532  {
2533  invalidatePartitionTable = TRUE;
2534  break;
2535  }
2536 
2538  invalidatePartitionTable = TRUE;
2539  break;
2540  }
2541 
2542  } // end switch(senseKey)
2543  } // end if (validSense)
2544  } else {
2545 
2546  //
2547  // On any exceptional scsi condition which might indicate that the
2548  // device was changed we will flush out the state of the partition
2549  // table.
2550  //
2551 
2552  switch (SRB_STATUS(Srb->SrbStatus)) {
2555  case SRB_STATUS_NO_DEVICE:
2556  case SRB_STATUS_NO_HBA:
2559  case SRB_STATUS_TIMEOUT:
2564  {
2565  invalidatePartitionTable = TRUE;
2566  break;
2567  }
2568 
2569  case SRB_STATUS_ERROR:
2570  {
2571  if (scsiStatus == SCSISTAT_RESERVATION_CONFLICT)
2572  {
2573  invalidatePartitionTable = TRUE;
2574  }
2575 
2576  break;
2577  }
2578  } // end switch(Srb->SrbStatus)
2579  }
2580 
2581  if (invalidatePartitionTable && TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
2582 
2583  //
2584  // Inform the upper layers that the volume
2585  // on this disk is in need of verification
2586  //
2587 
2589  }
2590  }
2591 
2592  return;
2593 }
UCHAR PathId
Definition: scsi_port.h:149
UCHAR PortNumber
Definition: scsi_port.h:148
#define SCSISTAT_BUSY
Definition: cdrw_hw.h:1081
struct _DISK_DATA * PDISK_DATA
#define CLASS_SPECIAL_FUA_NOT_SUPPORTED
Definition: classpnp.h:174
UCHAR senseKey
Definition: scsi.h:4019
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
#define MODE_PAGE_CACHING
Definition: cdrw_hw.h:846
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:379
NTSTATUS FinalStatus
Definition: iotypes.h:1989
#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
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
#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:1987
#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
#define ADJUST_FUA_FLAG(fdoExt)
Definition: classpnp.h:53
#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
Definition: cdrw_hw.h:1221
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#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
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
#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
VOID NTAPI DisableWriteCache(IN PDEVICE_OBJECT DeviceObject, IN PSCSI_INQUIRY_DATA LunInfo)
Definition: disk.c:3552
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define SCSI_SENSEQ_BECOMING_READY
Definition: cdrw_hw.h:1313
#define SCSISTAT_RESERVATION_CONFLICT
Definition: cdrw_hw.h:1084
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:871
__inline 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:990
#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
Status
Definition: gdiplustypes.h:24
#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
#define IS_SCSIOP_READWRITE(opCode)
Definition: cdrom.h:803
#define SRB_STATUS_TIMEOUT
Definition: srb.h:341
#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
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
VOID ResetBus(IN PDEVICE_OBJECT Fdo)
Definition: disk.c:2701
#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
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by DriverEntry().

◆ DiskFlushComplete()

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

Definition at line 1695 of file disk.c.

1723 {
1724  PDISK_GROUP_CONTEXT FlushContext;
1725  NTSTATUS status;
1727  PDISK_DATA diskData;
1728 #ifdef _MSC_VER
1729  #pragma warning(suppress:4311) // pointer truncation from 'PVOID' to 'NTSTATUS'
1730 #endif
1731  NTSTATUS SyncCacheStatus = (NTSTATUS) Context;
1732 
1733  TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_GENERAL, "DiskFlushComplete: %p %p\n", Fdo, Irp));
1734 
1735  //
1736  // Get the flush context from the device extension
1737  //
1738  fdoExt = (PFUNCTIONAL_DEVICE_EXTENSION)Fdo->DeviceExtension;
1739  diskData = (PDISK_DATA)fdoExt->CommonExtension.DriverData;
1740  NT_ASSERT(diskData != NULL);
1741  _Analysis_assume_(diskData != NULL);
1742 
1743  FlushContext = &diskData->FlushContext;
1744 
1745  //
1746  // Make sure everything is in order
1747  //
1748  NT_ASSERT(Irp == FlushContext->CurrIrp);
1749 
1750  TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI, "DiskFlushComplete: completing irp %p\n", Irp));
1751  status = ClassIoComplete(Fdo, Irp, &FlushContext->Srb.Srb);
1752 
1753  //
1754  // Make sure that ClassIoComplete did not decide to retry this request
1755  //
1757 
1758  //
1759  // If sync cache failed earlier, final status of the flush request needs to be failure
1760  // even if SRB_FUNCTION_FLUSH srb request succeeded
1761  //
1762  if (NT_SUCCESS(status) &&
1763  (!NT_SUCCESS(SyncCacheStatus))) {
1764  Irp->IoStatus.Status = status = SyncCacheStatus;
1765  }
1766 
1767  //
1768  // Complete the flush requests tagged to this one
1769  //
1770 
1771  while (!IsListEmpty(&FlushContext->CurrList)) {
1772 
1773  PLIST_ENTRY listEntry = RemoveHeadList(&FlushContext->CurrList);
1774  PIRP tempIrp = CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry);
1775 
1776  InitializeListHead(&tempIrp->Tail.Overlay.ListEntry);
1777  tempIrp->IoStatus = Irp->IoStatus;
1778 
1779  ClassReleaseRemoveLock(Fdo, tempIrp);
1780  ClassCompleteRequest(Fdo, tempIrp, IO_NO_INCREMENT);
1781  }
1782 
1783 
1784  //
1785  // Notify the next group's representative that it may go ahead now
1786  //
1787  KeSetEvent(&FlushContext->Event, IO_NO_INCREMENT, FALSE);
1788 
1789 
1790  TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI, "DiskFlushComplete: irp %p status = 0x%x\n", Irp, status));
1791 
1792  return status;
1793 }
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
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
#define FALSE
Definition: types.h:117
#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
smooth NULL
Definition: ftsmooth.c:416
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
#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 _Analysis_assume_
Definition: no_sal2.h:388
SCSI_REQUEST_BLOCK Srb
Definition: disk.h:131
#define IO_NO_INCREMENT
Definition: iotypes.h:581
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:3312
Definition: ps.c:97

Referenced by DiskFlushDispatch().

◆ DiskFlushDispatch()

VOID DiskFlushDispatch ( IN PDEVICE_OBJECT  Fdo,
IN PDISK_GROUP_CONTEXT  FlushContext 
)

Definition at line 1530 of file disk.c.

1554 {
1555  PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
1556  PSCSI_REQUEST_BLOCK srb = &FlushContext->Srb.Srb;
1557  PSTORAGE_REQUEST_BLOCK srbEx = &FlushContext->Srb.SrbEx;
1559  PSTOR_ADDR_BTL8 storAddrBtl8;
1560  PSRBEX_DATA_SCSI_CDB16 srbExDataCdb16;
1561  NTSTATUS SyncCacheStatus = STATUS_SUCCESS;
1562 
1563  //
1564  // Fill in the srb fields appropriately
1565  //
1566  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1567  RtlZeroMemory(srbEx, sizeof(FlushContext->Srb.SrbExBuffer));
1568 
1569  srbEx->Length = FIELD_OFFSET(STORAGE_REQUEST_BLOCK, Signature);
1570  srbEx->Function = SRB_FUNCTION_STORAGE_REQUEST_BLOCK;
1571  srbEx->Signature = SRB_SIGNATURE;
1572  srbEx->Version = STORAGE_REQUEST_BLOCK_VERSION_1;
1573  srbEx->SrbLength = sizeof(FlushContext->Srb.SrbExBuffer);
1574  srbEx->RequestPriority = IoGetIoPriorityHint(FlushContext->CurrIrp);
1575  srbEx->AddressOffset = sizeof(STORAGE_REQUEST_BLOCK);
1576  srbEx->TimeOutValue = fdoExt->TimeOutValue * 4;
1577  srbEx->RequestTag = SP_UNTAGGED;
1578  srbEx->RequestAttribute = SRB_SIMPLE_TAG_REQUEST;
1579  srbEx->SrbFlags = fdoExt->SrbFlags;
1580 
1581  //
1582  // Set up address fields
1583  //
1584 
1585  storAddrBtl8 = (PSTOR_ADDR_BTL8) ((PUCHAR)srbEx + srbEx->AddressOffset);
1586  storAddrBtl8->Type = STOR_ADDRESS_TYPE_BTL8;
1587  storAddrBtl8->AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
1588 
1589  } else {
1591 
1593  srb->TimeOutValue = fdoExt->TimeOutValue * 4;
1594  srb->QueueTag = SP_UNTAGGED;
1596  srb->SrbFlags = fdoExt->SrbFlags;
1597  }
1598 
1599  //
1600  // If write caching is enabled then send down a synchronize cache request
1601  //
1602  if (TEST_FLAG(fdoExt->DeviceFlags, DEV_WRITE_CACHE))
1603  {
1604 
1605  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1606  srbEx->SrbFunction = SRB_FUNCTION_EXECUTE_SCSI;
1607  srbEx->NumSrbExData = 1;
1608 
1609  //
1610  // Set up SCSI SRB extended data fields
1611  //
1612 
1613  srbEx->SrbExDataOffset[0] = sizeof(STORAGE_REQUEST_BLOCK) +
1614  sizeof(STOR_ADDR_BTL8);
1615  if ((srbEx->SrbExDataOffset[0] + sizeof(SRBEX_DATA_SCSI_CDB16)) <= srbEx->SrbLength) {
1616  srbExDataCdb16 = (PSRBEX_DATA_SCSI_CDB16)((PUCHAR)srbEx + srbEx->SrbExDataOffset[0]);
1617  srbExDataCdb16->Type = SrbExDataTypeScsiCdb16;
1618  srbExDataCdb16->Length = SRBEX_DATA_SCSI_CDB16_LENGTH;
1619  srbExDataCdb16->CdbLength = 10;
1620  srbExDataCdb16->Cdb[0] = SCSIOP_SYNCHRONIZE_CACHE;
1621  } else {
1622  // Should not happen
1623  NT_ASSERT(FALSE);
1624  return;
1625  }
1626 
1627  } else {
1629  srb->CdbLength = 10;
1630  srb->Cdb[0] = SCSIOP_SYNCHRONIZE_CACHE;
1631  }
1632 
1633  TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI, "DiskFlushDispatch: sending sync cache\n"));
1634 
1635  SyncCacheStatus = ClassSendSrbSynchronous(Fdo, srb, NULL, 0, TRUE);
1636  }
1637 
1638  //
1639  // Set up a FLUSH SRB
1640  //
1641  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1642  srbEx->SrbFunction = SRB_FUNCTION_FLUSH;
1643  srbEx->NumSrbExData = 0;
1644  srbEx->SrbExDataOffset[0] = 0;
1645  srbEx->OriginalRequest = FlushContext->CurrIrp;
1646  srbEx->SrbStatus = 0;
1647 
1648  //
1649  // Make sure that this srb does not get freed
1650  //
1651  SET_FLAG(srbEx->SrbFlags, SRB_CLASS_FLAGS_PERSISTANT);
1652 
1653  } else {
1655  srb->CdbLength = 0;
1656  srb->OriginalRequest = FlushContext->CurrIrp;
1657  srb->SrbStatus = 0;
1658  srb->ScsiStatus = 0;
1659 
1660  //
1661  // Make sure that this srb does not get freed
1662  //
1664  }
1665 
1666  //
1667  // Make sure that this request does not get retried
1668  //
1669  irpSp = IoGetCurrentIrpStackLocation(FlushContext->CurrIrp);
1670 
1671  irpSp->Parameters.Others.Argument4 = (PVOID) 0;
1672 
1673  //
1674  // Fill in the irp fields appropriately
1675  //
1676  irpSp = IoGetNextIrpStackLocation(FlushContext->CurrIrp);
1677 
1678  irpSp->MajorFunction = IRP_MJ_SCSI;
1679  irpSp->Parameters.Scsi.Srb = srb;
1680 
1681  IoSetCompletionRoutine(FlushContext->CurrIrp, DiskFlushComplete, (PVOID)SyncCacheStatus, TRUE, TRUE, TRUE);
1682 
1683  TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI, "DiskFlushDispatch: sending srb flush on irp %p\n", FlushContext->CurrIrp));
1684 
1685  //
1686  // Send down the flush request
1687  //
1688  IoCallDriver(((PCOMMON_DEVICE_EXTENSION)fdoExt)->LowerDeviceObject, FlushContext->CurrIrp);
1689 }
#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 DEV_WRITE_CACHE
Definition: class2.h:21
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#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
smooth NULL
Definition: ftsmooth.c:416
* 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
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:2715
USHORT Length
Definition: srb.h:241
#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:2691
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
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
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
NTSTATUS NTAPI DiskFlushComplete(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
Definition: disk.c:1695
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
return STATUS_SUCCESS
Definition: btrfs.c:3014
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:3312

Referenced by DiskShutdownFlush().

◆ DiskGetCacheInformation()

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

Definition at line 3015 of file disk.c.

3040 {
3041  PMODE_PARAMETER_HEADER modeData;
3042  PMODE_CACHING_PAGE pageData;
3043 
3044  ULONG length;
3045 
3046  PAGED_CODE();
3047 
3048 
3049 
3050  modeData = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
3053 
3054  if (modeData == NULL) {
3055 
3056  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskGetSetCacheInformation: Unable to allocate mode "
3057  "data buffer\n"));
3059  }
3060 
3061  RtlZeroMemory(modeData, MODE_DATA_SIZE);
3062 
3063  length = ClassModeSense(FdoExtension->DeviceObject,
3064  (PCHAR) modeData,
3067 
3068  if (length < sizeof(MODE_PARAMETER_HEADER)) {
3069 
3070  //
3071  // Retry the request in case of a check condition.
3072  //
3073 
3074  length = ClassModeSense(FdoExtension->DeviceObject,
3075  (PCHAR) modeData,
3078 
3079  if (length < sizeof(MODE_PARAMETER_HEADER)) {
3080 
3081  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskGetCacheInformation: Mode Sense failed\n"));
3082 
3083  FREE_POOL(modeData);
3084  return STATUS_IO_DEVICE_ERROR;
3085  }
3086  }
3087 
3088  //
3089  // If the length is greater than length indicated by the mode data reset
3090  // the data to the mode data.
3091  //
3092 
3093  if (length > (ULONG) (modeData->ModeDataLength + 1)) {
3094  length = modeData->ModeDataLength + 1;
3095  }
3096 
3097  //
3098  // Check to see if the write cache is enabled.
3099  //
3100 
3101  pageData = ClassFindModePage((PCHAR) modeData,
3102  length,
3104  TRUE);
3105 
3106  //
3107  // Check if valid caching page exists.
3108  //
3109 
3110  if (pageData == NULL) {
3111  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskGetCacheInformation: Unable to find caching mode page.\n"));
3112  FREE_POOL(modeData);
3113  return STATUS_NOT_SUPPORTED;
3114  }
3115 
3116  //
3117  // Copy the parameters over.
3118  //
3119 
3120  RtlZeroMemory(CacheInfo, sizeof(DISK_CACHE_INFORMATION));
3121 
3122  CacheInfo->ParametersSavable = pageData->PageSavable;
3123 
3124  CacheInfo->ReadCacheEnabled = !(pageData->ReadDisableCache);
3125  CacheInfo->WriteCacheEnabled = pageData->WriteCacheEnable;
3126 
3127 
3128  //
3129  // Translate the values in the mode page into the ones defined in
3130  // ntdddisk.h.
3131  //
3132 
3133  CacheInfo->ReadRetentionPriority =
3135  CacheInfo->WriteRetentionPriority =
3137 
3138  CacheInfo->DisablePrefetchTransferLength =
3139  ((pageData->DisablePrefetchTransfer[0] << 8) +
3140  pageData->DisablePrefetchTransfer[1]);
3141 
3142  CacheInfo->ScalarPrefetch.Minimum =
3143  ((pageData->MinimumPrefetch[0] << 8) + pageData->MinimumPrefetch[1]);
3144 
3145  CacheInfo->ScalarPrefetch.Maximum =
3146  ((pageData->MaximumPrefetch[0] << 8) + pageData->MaximumPrefetch[1]);
3147 
3148  if(pageData->MultiplicationFactor) {
3149  CacheInfo->PrefetchScalar = TRUE;
3150  CacheInfo->ScalarPrefetch.MaximumBlocks =
3151  ((pageData->MaximumPrefetchCeiling[0] << 8) +
3152  pageData->MaximumPrefetchCeiling[1]);
3153  }
3154 
3155 
3156  FREE_POOL(modeData);
3157  return STATUS_SUCCESS;
3158 }
signed char * PCHAR
Definition: retypes.h:7
#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 STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define MODE_DATA_SIZE
Definition: disk.c:164
UCHAR MultiplicationFactor
Definition: cdrw_hw.h:2778
smooth NULL
Definition: ftsmooth.c:416
#define DISK_TAG_DISABLE_CACHE
Definition: disk.h:56
PVOID NTAPI ClassFindModePage(_In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode, _In_ BOOLEAN Use6Byte)
Definition: class.c:6798
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
UCHAR MinimumPrefetch[2]
Definition: cdrw_hw.h:2786
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
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
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
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
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define PAGED_CODE()

Referenced by DiskIoctlGetCacheInformation(), and DiskStartFdo().

◆ DiskGetInfoExceptionInformation()

NTSTATUS DiskGetInfoExceptionInformation ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN PMODE_INFO_EXCEPTIONS  ReturnPageData 
)

Definition at line 2892 of file disk.c.

2896 {
2897  PMODE_PARAMETER_HEADER modeData;
2898  PMODE_INFO_EXCEPTIONS pageData;
2899  ULONG length;
2900 
2901  NTSTATUS status;
2902 
2903  PAGED_CODE();
2904 
2905  //
2906  // ReturnPageData is allocated by the caller
2907  //
2908 
2909  modeData = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
2912 
2913  if (modeData == NULL) {
2914 
2915  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_WMI, "DiskGetInfoExceptionInformation: Unable to allocate mode "
2916  "data buffer\n"));
2918  }
2919 
2920  RtlZeroMemory(modeData, MODE_DATA_SIZE);
2921 
2922  length = ClassModeSense(FdoExtension->DeviceObject,
2923  (PCHAR) modeData,
2926 
2927  if (length < sizeof(MODE_PARAMETER_HEADER)) {
2928 
2929  //
2930  // Retry the request in case of a check condition.
2931  //
2932 
2933  length = ClassModeSense(FdoExtension->DeviceObject,
2934  (PCHAR) modeData,
2937 
2938  if (length < sizeof(MODE_PARAMETER_HEADER)) {
2939  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_WMI, "DiskGetInfoExceptionInformation: Mode Sense failed\n"));
2940  FREE_POOL(modeData);
2941  return STATUS_IO_DEVICE_ERROR;
2942  }
2943  }
2944 
2945  //
2946  // If the length is greater than length indicated by the mode data reset
2947  // the data to the mode data.
2948  //
2949 
2950  if (length > (ULONG) (modeData->ModeDataLength + 1)) {
2951  length = modeData->ModeDataLength + 1;
2952  }
2953 
2954  //
2955  // Find the mode page for info exceptions
2956  //
2957 
2958  pageData = ClassFindModePage((PCHAR) modeData,
2959  length,
2961  TRUE);
2962 
2963  if (pageData != NULL) {
2964  RtlCopyMemory(ReturnPageData, pageData, sizeof(MODE_INFO_EXCEPTIONS));
2966  } else {
2968  }
2969 
2970  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskGetInfoExceptionInformation: %s support SMART for device %p\n",
2971  NT_SUCCESS(status) ? "does" : "does not",
2972  FdoExtension->DeviceObject));
2973 
2974  FREE_POOL(modeData);
2975 
2976  return(status);
2977 }
signed char * PCHAR
Definition: retypes.h:7
#define MODE_PAGE_FAULT_REPORTING
Definition: scsi.h:218
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#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 STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define DISK_TAG_INFO_EXCEPTION
Definition: disk.h:55
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define MODE_DATA_SIZE
Definition: disk.c:164
smooth NULL
Definition: ftsmooth.c:416
#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
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
ULONG NTAPI ClassModeSense(_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode)
Definition: class.c:6637
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
return STATUS_SUCCESS
Definition: btrfs.c:3014
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 5309 of file disk.c.

5335 {
5337 
5338  //
5339  // Validate the request.
5340  //
5341 
5342  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlClearVerify: DeviceObject %p Irp %p\n", DeviceObject, Irp));
5343 
5344  //
5345  // If the caller is kernel mode, set the verify bit.
5346  //
5347 
5348  if (Irp->RequestorMode == KernelMode) {
5349 
5352 
5353  }
5354  return status;
5355 }
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define CLEAR_FLAG(Flags, Bit)
Definition: cdrom.h:1494
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
return STATUS_SUCCESS
Definition: btrfs.c:3014
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 4415 of file disk.c.

4441 {
4442  PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
4443  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
4444  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
4447  PSTORAGE_FAILURE_PREDICTION_CONFIG enablePrediction;
4448 
4449  //
4450  // This function must be called at less than dispatch level.
4451  // Fail if IRQL >= DISPATCH_LEVEL.
4452  //
4453  PAGED_CODE();
4454  CHECK_IRQL();
4455 
4456  //
4457  // Validate the request.
4458  //
4459 
4460  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlEnableFailurePrediction: DeviceObject %p Irp %p\n", DeviceObject, Irp));
4461 
4462  if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(STORAGE_FAILURE_PREDICTION_CONFIG) ||
4463  irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_FAILURE_PREDICTION_CONFIG)) {
4464 
4465  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlEnableFailurePrediction: Buffer too small.\n"));
4466  return STATUS_BUFFER_TOO_SMALL;
4467  }
4468 
4469  enablePrediction = (PSTORAGE_FAILURE_PREDICTION_CONFIG)Irp->AssociatedIrp.SystemBuffer;
4470 
4471  if (enablePrediction->Version != STORAGE_FAILURE_PREDICTION_CONFIG_V1 ||
4472  enablePrediction->Size < sizeof(STORAGE_FAILURE_PREDICTION_CONFIG)) {
4473  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlEnableFailurePrediction: Buffer version or size is incorrect.\n"));
4475  }
4476 
4477  if (enablePrediction->Reserved != 0) {
4478  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlEnableFailurePrediction: Reserved bytes are not zero!\n"));
4480  }
4481 
4482  //
4483  // Default to success. This might get overwritten on failure below.
4484  //
4486 
4487  //
4488  // If this is a "set" and the current state (enabled/disabled) is
4489  // different from the sender's desired state,
4490  //
4491  if (enablePrediction->Set && enablePrediction->Enabled != diskData->FailurePredictionEnabled) {
4494  //
4495  // SMART or IOCTL based failure prediction is being used so call
4496  // the generic function that is normally called in the WMI path.
4497  //
4498  status = DiskEnableDisableFailurePrediction(fdoExtension, enablePrediction->Enabled);
4499  } else if (diskData->ScsiInfoExceptionsSupported) {
4500  //
4501  // If we know that the device supports the Informational Exceptions
4502  // mode page, try to enable/disable failure prediction that way.
4503  //
4504  status = DiskEnableInfoExceptions(fdoExtension, enablePrediction->Enabled);
4505  }
4506  }
4507 
4508  //
4509  // Return the current state regardless if this was a "set" or a "get".
4510  //
4511  enablePrediction->Enabled = diskData->FailurePredictionEnabled;
4512 
4513  if (NT_SUCCESS(status)) {
4514  Irp->IoStatus.Information = sizeof(STORAGE_FAILURE_PREDICTION_CONFIG);
4515  }
4516 
4517  return status;
4518 }
NTSTATUS DiskEnableDisableFailurePrediction(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable)
Definition: diskwmi.c:1126
struct _DISK_DATA * PDISK_DATA
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
NTSTATUS DiskEnableInfoExceptions(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ BOOLEAN Enable)
Definition: diskwmi.c:979
BOOLEAN FailurePredictionEnabled
Definition: disk.h:346
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN ScsiInfoExceptionsSupported
Definition: disk.h:340
#define CHECK_IRQL()
Definition: disk.h:458
FAILURE_PREDICTION_METHOD FailurePredictionCapability
Definition: disk.h:331
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DiskDeviceControl().

◆ DiskIoctlGetCacheInformation()

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

Definition at line 3836 of file disk.c.

3864 {
3865  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
3867  PDISK_CACHE_INFORMATION cacheInfo = Irp->AssociatedIrp.SystemBuffer;
3868  NTSTATUS status;
3869 
3870  //
3871  // This function must be called at less than dispatch level.
3872  // Fail if IRQL >= DISPATCH_LEVEL.
3873  //
3874  PAGED_CODE();
3875  CHECK_IRQL();
3876 
3877  //
3878  // Validate the request.
3879  //
3880 
3881  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlGetCacheInformation: DeviceObject %p Irp %p\n", DeviceObject, Irp));
3882 
3883  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_CACHE_INFORMATION)) {
3884 
3885  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlGetCacheInformation: Output buffer too small.\n"));
3886  return STATUS_BUFFER_TOO_SMALL;
3887  }
3888 
3889  status = DiskGetCacheInformation(fdoExtension, cacheInfo);
3890 
3891  if (NT_SUCCESS(status)) {
3892  Irp->IoStatus.Information = sizeof(DISK_CACHE_INFORMATION);
3893 
3894  //
3895  // Make sure write cache setting is reflected in device extension
3896  //
3897  if (cacheInfo->WriteCacheEnabled)
3898  {
3899  SET_FLAG(fdoExtension->DeviceFlags, DEV_WRITE_CACHE);
3900  }
3901  else
3902  {
3903  CLEAR_FLAG(fdoExtension->DeviceFlags, DEV_WRITE_CACHE);
3904  }
3905  ADJUST_FUA_FLAG(fdoExtension);
3906 
3907  }
3908  return status;
3909 }
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
struct _DISK_CACHE_INFORMATION DISK_CACHE_INFORMATION
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define DEV_WRITE_CACHE
Definition: class2.h:21
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define ADJUST_FUA_FLAG(fdoExt)
Definition: classpnp.h:53
#define CLEAR_FLAG(Flags, Bit)
Definition: cdrom.h:1494
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CHECK_IRQL()
Definition: disk.h:458
NTSTATUS NTAPI DiskGetCacheInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
Definition: disk.c:3015
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
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 3343 of file disk.c.

3367 {
3368  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
3371 
3372  PAGED_CODE();
3373 
3374  if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_CACHE_SETTING))
3375  {
3377  }
3378  else
3379  {
3380  PDISK_CACHE_SETTING cacheSetting = (PDISK_CACHE_SETTING)Irp->AssociatedIrp.SystemBuffer;
3381 
3382  cacheSetting->Version = sizeof(DISK_CACHE_SETTING);
3383  cacheSetting->State = DiskCacheNormal;
3384 
3385  //
3386  // Determine whether it is safe to turn on the cache
3387  //
3389  {
3390  cacheSetting->State = DiskCacheWriteThroughNotSupported;
3391  }
3392 
3393  //
3394  // Determine whether it is possible to modify the cache setting
3395  //
3397  {
3398  cacheSetting->State = DiskCacheModifyUnsuccessful;
3399  }
3400 
3401  cacheSetting->IsPowerProtected = TEST_FLAG(fdoExtension->DeviceFlags, DEV_POWER_PROTECTED);
3402 
3403  Irp->IoStatus.Information = sizeof(DISK_CACHE_SETTING);
3404  }
3405 
3406  return status;
3407 }
#define CLASS_SPECIAL_FUA_NOT_SUPPORTED
Definition: classpnp.h:174
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
struct _DISK_CACHE_SETTING * PDISK_CACHE_SETTING
BOOLEAN IsPowerProtected
Definition: ntdddisk.h:831
DISK_CACHE_STATE State
Definition: ntdddisk.h:830
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define CLASS_SPECIAL_MODIFY_CACHE_UNSUCCESSFUL
Definition: classpnp.h:173
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
irpSp
Definition: iofuncs.h:2715
#define DEV_POWER_PROTECTED
Definition: cdrom.h:143
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
struct _DISK_CACHE_SETTING DISK_CACHE_SETTING
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
return STATUS_SUCCESS
Definition: btrfs.c:3014
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 3578 of file disk.c.

3605 {
3606  PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
3607  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
3608  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
3610  NTSTATUS status;
3611 
3612  //
3613  // This function must be called at less than dispatch level.
3614  // Fail if IRQL >= DISPATCH_LEVEL.
3615  //
3616  PAGED_CODE();
3617  CHECK_IRQL();
3618 
3619  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY)) {
3620 
3621  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlGetDriveGeometry: Output buffer too small.\n"));
3622  return STATUS_BUFFER_TOO_SMALL;
3623  }
3624 
3625  if (TEST_FLAG(DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA)) {
3626 
3627  //
3628  // Issue ReadCapacity to update device extension
3629  // with information for current media.
3630  //
3631 
3632  status = DiskReadDriveCapacity(commonExtension->PartitionZeroExtension->DeviceObject);
3633 
3634  //
3635  // Note whether the drive is ready.
3636  //
3637 
3638  diskData->ReadyStatus = status;
3639 
3640  if (!NT_SUCCESS(status)) {
3641  return status;
3642  }
3643  }
3644 
3645  //
3646  // Copy drive geometry information from device extension.
3647  //
3648 
3649  RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
3650  &(fdoExtension->DiskGeometry),
3651  sizeof(DISK_GEOMETRY));
3652 
3653  if (((PDISK_GEOMETRY)Irp->AssociatedIrp.SystemBuffer)->BytesPerSector == 0) {
3654  ((PDISK_GEOMETRY)Irp->AssociatedIrp.SystemBuffer)->BytesPerSector = 512;
3655  }
3656  Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
3657  return STATUS_SUCCESS;
3658 }
struct _DISK_DATA * PDISK_DATA
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:888
_In_ PIRP Irp
Definition: csq.h:116
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
#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
#define DiskReadDriveCapacity(Fdo)
Definition: disk.h:814
#define CHECK_IRQL()
Definition: disk.h:458
struct _DISK_GEOMETRY * PDISK_GEOMETRY
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
struct _DISK_GEOMETRY DISK_GEOMETRY
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DiskDeviceControl().

◆ DiskIoctlGetDriveGeometryEx()

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

Definition at line 3668 of file disk.c.

3695 {
3696  NTSTATUS status;
3697  PIO_STACK_LOCATION irpStack;
3698  PCOMMON_DEVICE_EXTENSION commonExtension;
3699  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
3700  PDISK_DATA diskData;
3701  PDISK_GEOMETRY_EX_INTERNAL geometryEx;
3703 
3704  //
3705  // This function must be called at less than dispatch level.
3706  // Fail if IRQL >= DISPATCH_LEVEL.
3707  //
3708  PAGED_CODE();
3709  CHECK_IRQL();
3710 
3711  //
3712  // Setup parameters
3713  //
3714 
3715  commonExtension = DeviceObject->DeviceExtension;
3716  fdoExtension = DeviceObject->DeviceExtension;
3717  diskData = (PDISK_DATA)(commonExtension->DriverData);
3718  irpStack = IoGetCurrentIrpStackLocation ( Irp );
3719  geometryEx = NULL;
3720  OutputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
3721 
3722  //
3723  // Check that the buffer is large enough. It must be large enough
3724  // to hold at lest the Geometry and DiskSize fields of of the
3725  // DISK_GEOMETRY_EX structure.
3726  //
3727 
3729 
3730  //
3731  // Buffer too small. Bail out, telling the caller the required
3732  // size.
3733  //
3734 
3735  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlGetDriveGeometryEx: Output buffer too small.\n"));
3737  return status;
3738  }
3739 
3740  if (TEST_FLAG (DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA)) {
3741 
3742  //
3743  // Issue a ReadCapacity to update device extension
3744  // with information for the current media.
3745  //
3746 
3747  status = DiskReadDriveCapacity(commonExtension->PartitionZeroExtension->DeviceObject);
3748 
3749  diskData->ReadyStatus = status;
3750 
3751  if (!NT_SUCCESS (status)) {
3752  return status;
3753  }
3754  }
3755 
3756  //
3757  // Copy drive geometry.
3758  //
3759 
3760  geometryEx = (PDISK_GEOMETRY_EX_INTERNAL)Irp->AssociatedIrp.SystemBuffer;
3761  geometryEx->Geometry = fdoExtension->DiskGeometry;
3762  if (geometryEx->Geometry.BytesPerSector == 0) {
3763  geometryEx->Geometry.BytesPerSector = 512;
3764  }
3765  geometryEx->DiskSize = commonExtension->PartitionZeroExtension->CommonExtension.PartitionLength;
3766 
3767  //
3768  // If the user buffer is large enough to hold the partition information
3769  // then add that as well.
3770  //
3771 
3773 
3774  geometryEx->Partition.SizeOfPartitionInfo = sizeof (geometryEx->Partition);
3775  geometryEx->Partition.PartitionStyle = diskData->PartitionStyle;
3776 
3777  switch ( diskData->PartitionStyle ) {
3778 
3779  case PARTITION_STYLE_GPT:
3780 
3781  //
3782  // Copy GPT signature.
3783  //
3784 
3785  geometryEx->Partition.Gpt.DiskId = diskData->Efi.DiskId;
3786  break;
3787 
3788  case PARTITION_STYLE_MBR:
3789 
3790  //
3791  // Copy MBR signature and checksum.
3792  //
3793 
3794  geometryEx->Partition.Mbr.Signature = diskData->Mbr.Signature;
3795  geometryEx->Partition.Mbr.CheckSum = diskData->Mbr.MbrCheckSum;
3796  break;
3797 
3798  default:
3799 
3800  //
3801  // This is a raw disk. Zero out the signature area so
3802  // nobody gets confused.
3803  //
3804 
3805  RtlZeroMemory(&geometryEx->Partition, sizeof (geometryEx->Partition));
3806  }
3807  }
3808 
3809  //
3810  // If the buffer is large enough to hold the detection information,
3811  // then also add that.
3812  //
3813 
3815 
3816  geometryEx->Detection.SizeOfDetectInfo = sizeof (geometryEx->Detection);
3817 
3818  status = DiskGetDetectInfo(fdoExtension, &geometryEx->Detection);
3819 
3820  //
3821  // Failed to obtain detection information, set to none.
3822  //
3823 
3824  if (!NT_SUCCESS (status)) {
3825  geometryEx->Detection.DetectionType = DetectNone;
3826  }
3827  }
3828 
3830  Irp->IoStatus.Information = min (OutputBufferLength, sizeof (DISK_GEOMETRY_EX_INTERNAL));
3831 
3832  return status;
3833 }
#define DiskGetDetectInfo(FdoExtension, DetectInfo)
Definition: disk.h:857
struct _DISK_DATA * PDISK_DATA
DETECTION_TYPE DetectionType
Definition: ntdddisk.h:428
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
DISK_GEOMETRY Geometry
Definition: disk.c:3661
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:888
_In_ PIRP Irp
Definition: csq.h:116
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:442
struct _DISK_PARTITION_INFO::@3109::@3110 Mbr
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
LARGE_INTEGER DiskSize
Definition: disk.c:3662
struct _DISK_PARTITION_INFO::@3109::@3111 Gpt
long LONG
Definition: pedump.c:60
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
struct _DISK_GEOMETRY_EX_INTERNAL * PDISK_GEOMETRY_EX_INTERNAL
smooth NULL
Definition: ftsmooth.c:416
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
PARTITION_STYLE PartitionStyle
Definition: disk.h:197
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t OutputBufferLength
Definition: cdrom.h:1437
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DiskReadDriveCapacity(Fdo)
Definition: disk.h:814
#define CHECK_IRQL()
Definition: disk.h:458
struct _DISK_DATA::@1036::@1039 Mbr
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define min(a, b)
Definition: monoChain.cc:55
DISK_DETECTION_INFO Detection
Definition: disk.c:3664
DISK_PARTITION_INFO Partition
Definition: disk.c:3663
struct _DISK_DATA::@1036::@1040 Efi
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
ULONG SizeOfPartitionInfo
Definition: ntdddisk.h:496
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
PARTITION_STYLE PartitionStyle
Definition: ntdddisk.h:497
static SERVICE_STATUS status
Definition: service.c:31
#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 3488 of file disk.c.

3514 {
3515  NTSTATUS status;
3516  PIO_STACK_LOCATION irpStack;
3517  PGET_LENGTH_INFORMATION lengthInfo;
3518  PFUNCTIONAL_DEVICE_EXTENSION p0Extension;
3519  PCOMMON_DEVICE_EXTENSION commonExtension;
3520  PDISK_DATA partitionZeroData;
3521  NTSTATUS oldReadyStatus;
3522 
3523  //
3524  // This function must be called at less than dispatch level.
3525  // Fail if IRQL >= DISPATCH_LEVEL.
3526  //
3527  PAGED_CODE();
3528  CHECK_IRQL();
3529 
3530  //
3531  // Initialization
3532  //
3533 
3534  commonExtension = DeviceObject->DeviceExtension;
3535  irpStack = IoGetCurrentIrpStackLocation(Irp);
3536  p0Extension = commonExtension->PartitionZeroExtension;
3537  partitionZeroData = ((PDISK_DATA) p0Extension->CommonExtension.DriverData);
3538 
3539  //
3540  // Check that the buffer is large enough.
3541  //
3542 
3543  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GET_LENGTH_INFORMATION)) {
3544  return STATUS_BUFFER_TOO_SMALL;
3545  }
3546 
3547  //
3548  // Update the geometry in case it has changed
3549  //
3550 
3551  status = DiskReadDriveCapacity(p0Extension->DeviceObject);
3552 
3553  //
3554  // Note whether the drive is ready. If the status has changed then
3555  // notify pnp.
3556  //
3557 
3558  oldReadyStatus = InterlockedExchange(&(partitionZeroData->ReadyStatus), status);
3559 
3560  if(partitionZeroData->ReadyStatus != oldReadyStatus) {
3562  }
3563 
3564  if(!NT_SUCCESS(status)) {
3565  return status;
3566  }
3567  lengthInfo = (PGET_LENGTH_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
3568 
3569  lengthInfo->Length = commonExtension->PartitionLength;
3570 
3572  Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
3573 
3574  return status;
3575 }
LARGE_INTEGER PartitionLength
Definition: classpnp.h:618
struct _DISK_DATA * PDISK_DATA
_In_ PIRP Irp
Definition: csq.h:116
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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DiskReadDriveCapacity(Fdo)
Definition: disk.h:814
struct _GET_LENGTH_INFORMATION * PGET_LENGTH_INFORMATION
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:871
#define CHECK_IRQL()
Definition: disk.h:458
PDEVICE_OBJECT LowerPdo
Definition: classpnp.h:875
#define InterlockedExchange
Definition: armddk.h:54
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2486
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DiskDeviceControl().

◆ DiskIoctlGetMediaTypesEx()

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

Definition at line 3990 of file disk.c.

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

Referenced by DiskDeviceControl().

◆ DiskIoctlGetVolumeDiskExtents()

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

Definition at line 5457 of file disk.c.

5484 {
5485  PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
5486  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
5489 
5490  //
5491  // This function must be called at less than dispatch level.
5492  // Fail if IRQL >= DISPATCH_LEVEL.
5493  //
5494  PAGED_CODE();
5495  CHECK_IRQL();
5496 
5497  //
5498  // Validate the request.
5499  //
5500 
5501  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlGetVolumeDiskExtents: DeviceObject %p Irp %p\n", DeviceObject, Irp));
5502 
5503 
5504  if (TEST_FLAG(DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA)) {
5505 
5506  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VOLUME_DISK_EXTENTS)) {
5507  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlGetVolumeDiskExtents: Output buffer too small.\n"));
5508  return STATUS_BUFFER_TOO_SMALL;
5509  }
5510 
5511  status = DiskReadDriveCapacity(commonExtension->PartitionZeroExtension->DeviceObject);
5512 
5513  //
5514  // Note whether the drive is ready.
5515  //
5516 
5517  diskData->ReadyStatus = status;
5518 
5519  if (NT_SUCCESS(status)) {
5520 
5521  PVOLUME_DISK_EXTENTS pVolExt = (PVOLUME_DISK_EXTENTS)Irp->AssociatedIrp.SystemBuffer;
5522 
5523  pVolExt->NumberOfDiskExtents = 1;
5524  pVolExt->Extents[0].DiskNumber = commonExtension->PartitionZeroExtension->DeviceNumber;
5525  pVolExt->Extents[0].StartingOffset = commonExtension->StartingOffset;
5526  pVolExt->Extents[0].ExtentLength = commonExtension->PartitionLength;
5527 
5528  Irp->IoStatus.Information = sizeof(VOLUME_DISK_EXTENTS);
5529  }
5530  }
5531 
5532  return status;
5533 }
LARGE_INTEGER ExtentLength
Definition: ntddvol.h:115
LARGE_INTEGER PartitionLength
Definition: classpnp.h:618
struct _DISK_DATA * PDISK_DATA
struct _VOLUME_DISK_EXTENTS * PVOLUME_DISK_EXTENTS
_In_ PIRP Irp
Definition: csq.h:116
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
#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 DiskReadDriveCapacity(Fdo)
Definition: disk.h:814
#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:2789
ULONG NumberOfDiskExtents
Definition: ntddvol.h:119
LARGE_INTEGER StartingOffset
Definition: ntddvol.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DiskDeviceControl().

◆ DiskIoctlIsWritable()

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

Definition at line 5059 of file disk.c.

5086 {
5087  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
5089 
5090  PMODE_PARAMETER_HEADER modeData;
5091  PSCSI_REQUEST_BLOCK srb;
5092  PCDB cdb = NULL;
5093  ULONG modeLength;
5094  ULONG retries = 4;
5095  ULONG srbSize;
5096  PSTORAGE_REQUEST_BLOCK srbEx;
5097  PSTOR_ADDR_BTL8 storAddrBtl8;
5098  PSRBEX_DATA_SCSI_CDB16 srbExDataCdb16;
5099 
5100  //
5101  // This function must be called at less than dispatch level.
5102  // Fail if IRQL >= DISPATCH_LEVEL.
5103  //
5104  PAGED_CODE();
5105  CHECK_IRQL();
5106 
5107  //
5108  // Validate the request.
5109  //
5110 
5111  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlIsWritable: DeviceObject %p Irp %p\n", DeviceObject, Irp));
5112 
5113  if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
5115  } else {
5116  srbSize = SCSI_REQUEST_BLOCK_SIZE;
5117  }
5118  srb = ExAllocatePoolWithTag(NonPagedPoolNx,
5119  srbSize,
5120  DISK_TAG_SRB);
5121 
5122  if (srb == NULL) {
5123  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlIsWritable: Unable to allocate memory.\n"));
5125  }
5126 
5127  RtlZeroMemory(srb, srbSize);
5128 
5129  //
5130  // Allocate memory for a mode header and then some
5131  // for port drivers that need to convert to MODE10
5132  // or always return the MODE_PARAMETER_BLOCK (even
5133  // when memory was not allocated for this purpose)
5134  //
5135 
5136  modeLength = MODE_DATA_SIZE;
5137  modeData = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
5138  modeLength,
5140 
5141  if (modeData == NULL) {
5142  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlIsWritable: Unable to allocate memory.\n"));
5143  FREE_POOL(srb);
5145  }
5146 
5147  RtlZeroMemory(modeData, modeLength);
5148 
5149  //
5150  // Build the MODE SENSE CDB
5151  //
5152 
5153  if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
5154  srbEx = (PSTORAGE_REQUEST_BLOCK)srb;
5155 
5156  //
5157  // Set up STORAGE_REQUEST_BLOCK fields
5158  //
5159 
5160  srbEx->Length = FIELD_OFFSET(STORAGE_REQUEST_BLOCK, Signature);
5161  srbEx->Function = SRB_FUNCTION_STORAGE_REQUEST_BLOCK;
5162  srbEx->Signature = SRB_SIGNATURE;
5163  srbEx->Version = STORAGE_REQUEST_BLOCK_VERSION_1;
5164  srbEx->SrbLength = srbSize;
5165  srbEx->SrbFunction = SRB_FUNCTION_EXECUTE_SCSI;
5166  srbEx->RequestPriority = IoGetIoPriorityHint(Irp);
5167  srbEx->AddressOffset = sizeof(STORAGE_REQUEST_BLOCK);
5168  srbEx->NumSrbExData = 1;
5169 
5170  // Set timeout value.
5171  srbEx->TimeOutValue = fdoExtension->TimeOutValue;
5172 
5173  //
5174  // Set up address fields
5175  //
5176 
5177  storAddrBtl8 = (PSTOR_ADDR_BTL8) ((PUCHAR)srbEx + srbEx->AddressOffset);
5178  storAddrBtl8->Type = STOR_ADDRESS_TYPE_BTL8;
5179  storAddrBtl8->AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
5180 
5181  //
5182  // Set up SCSI SRB extended data fields
5183  //
5184 
5185  srbEx->SrbExDataOffset[0] = sizeof(STORAGE_REQUEST_BLOCK) +
5186  sizeof(STOR_ADDR_BTL8);
5187  if ((srbEx->SrbExDataOffset[0] + sizeof(SRBEX_DATA_SCSI_CDB16)) <= srbEx->SrbLength) {
5188  srbExDataCdb16 = (PSRBEX_DATA_SCSI_CDB16)((PUCHAR)srbEx + srbEx->SrbExDataOffset[0]);
5189  srbExDataCdb16->Type = SrbExDataTypeScsiCdb16;
5190  srbExDataCdb16->Length = SRBEX_DATA_SCSI_CDB16_LENGTH;
5191  srbExDataCdb16->CdbLength = 6;
5192 
5193  cdb = (PCDB)srbExDataCdb16->Cdb;
5194  } else {
5195  // Should not happen
5196  NT_ASSERT(FALSE);
5197 
5198  FREE_POOL(srb);
5199  FREE_POOL(modeData);
5200  return STATUS_INTERNAL_ERROR;
5201  }
5202 
5203  } else {
5206  srb->CdbLength = 6;
5207 
5208  //
5209  // Set timeout value.
5210  //
5211 
5212  srb->TimeOutValue = fdoExtension->TimeOutValue;
5213 
5214  cdb = (PCDB)srb->Cdb;
5215  }
5216 
5217  //
5218  // Page code of 0x3F will return all pages.
5219  // This command could fail if the data to be returned is
5220  // more than 256 bytes. In which case, we should get only
5221  // the caching page since we only need the block descriptor.
5222  // DiskFdoProcessError will change the page code to
5223  // MODE_PAGE_CACHING if there is an error.
5224  //
5225 
5226  cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
5227  cdb->MODE_SENSE.PageCode = MODE_SENSE_RETURN_ALL;
5228  cdb->MODE_SENSE.AllocationLength = (UCHAR)modeLength;
5229 
5230  while (retries != 0) {
5231 
5233  srb,
5234  modeData,
5235  modeLength,
5236  FALSE);
5237 
5238  if (status != STATUS_VERIFY_REQUIRED) {
5241  }
5242  break;
5243  }
5244  retries--;
5245  }
5246 
5247  if (NT_SUCCESS(status)) {
5248 
5251  }
5252  }
5253 
5254  FREE_POOL(srb);
5255  FREE_POOL(modeData);
5256  return status;
5257 }
#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
_In_ PIRP Irp
Definition: csq.h:116
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
#define MODE_DSP_WRITE_PROTECT
Definition: cdrw_hw.h:2523
#define DISK_TAG_MODE_DATA
Definition: disk.h:62
unsigned char * PUCHAR
Definition: retypes.h:3
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
#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
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 SRBEX_DATA_SCSI_CDB16
#define FALSE
Definition: types.h:117
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define MODE_DATA_SIZE
Definition: disk.c:164
#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
smooth NULL
Definition: ftsmooth.c:416
* 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 CHECK_IRQL()
Definition: disk.h:458
#define SRB_SIGNATURE
Definition: srb.h:607
#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
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define DISK_TAG_SRB
Definition: disk.h:67
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
return STATUS_SUCCESS
Definition: btrfs.c:3014
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:3312
Definition: ps.c:97

Referenced by DiskDeviceControl().

◆ DiskIoctlPredictFailure()

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

Definition at line 4264 of file disk.c.

4290 {
4291  PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
4292  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
4293  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
4296 
4297  PSTORAGE_PREDICT_FAILURE checkFailure;
4298  STORAGE_FAILURE_PREDICT_STATUS diskSmartStatus;
4299  IO_STATUS_BLOCK ioStatus = { 0 };
4300  KEVENT event;
4301 
4302  //
4303  // This function must be called at less than dispatch level.
4304  // Fail if IRQL >= DISPATCH_LEVEL.
4305  //
4306  PAGED_CODE();
4307  CHECK_IRQL();
4308 
4309  //
4310  // Validate the request.
4311  //
4312 
4313  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlPredictFailure: DeviceObject %p Irp %p\n", DeviceObject, Irp));
4314 
4315  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_PREDICT_FAILURE)) {
4316 
4317  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlPredictFailure: Output buffer too small.\n"));
4318  return STATUS_BUFFER_TOO_SMALL;
4319  }
4320 
4321  //
4322  // See if the disk is predicting failure
4323  //
4324 
4325  checkFailure = (PSTORAGE_PREDICT_FAILURE)Irp->AssociatedIrp.SystemBuffer;
4326 
4328  ULONG readBufferSize;
4329  PUCHAR readBuffer;
4330  PIRP readIrp;
4331  PDEVICE_OBJECT topOfStack;
4332 
4333  checkFailure->PredictFailure = 0;
4334 
4336 
4338 
4339  //
4340  // SCSI disks need to have a read sent down to provoke any
4341  // failures to be reported.
4342  //
4343  // Issue a normal read operation. The error-handling code in
4344  // classpnp will take care of a failure prediction by logging the
4345  // correct event.
4346  //
4347 
4348  readBufferSize = fdoExtension->DiskGeometry.BytesPerSector;
4349  readBuffer = ExAllocatePoolWithTag(NonPagedPoolNx,
4350  readBufferSize,
4351  DISK_TAG_SMART);
4352 
4353  if (readBuffer != NULL) {
4355 
4356  offset.QuadPart = 0;
4358  topOfStack,
4359  readBuffer,
4360  readBufferSize,
4361  &offset,
4362  &event,
4363  &ioStatus);
4364 
4365  if (readIrp != NULL) {
4366 
4367  status = IoCallDriver(topOfStack, readIrp);
4368  if (status == STATUS_PENDING) {
4370  status = ioStatus.Status;
4371  }
4372 
4373 
4374  } else {
4376  }
4377 
4378  FREE_POOL(readBuffer);
4379  } else {
4381  }
4382 
4383  ObDereferenceObject(topOfStack);
4384  }
4385 
4387  {
4390 
4391  status = DiskReadFailurePredictStatus(fdoExtension, &diskSmartStatus);
4392 
4393  if (NT_SUCCESS(status)) {
4394 
4395  status = DiskReadFailurePredictData(fdoExtension,
4396  Irp->AssociatedIrp.SystemBuffer);
4397 
4398  if (diskSmartStatus.PredictFailure) {
4399  checkFailure->PredictFailure = 1;
4400  } else {
4401  checkFailure->PredictFailure = 0;
4402  }
4403 
4404  Irp->IoStatus.Information = sizeof(STORAGE_PREDICT_FAILURE);
4405  }
4406  } else {
4408  }
4409  }
4410  return status;
4411 }
struct _DISK_DATA * PDISK_DATA
#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
_In_ PIRP Irp
Definition: csq.h:116
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
GLintptr offset
Definition: glext.h:5920
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
ULONG BytesPerSector
Definition: ntdddisk.h:442
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#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
#define FALSE
Definition: types.h:117
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
smooth NULL
Definition: ftsmooth.c:416
struct _STORAGE_PREDICT_FAILURE * PSTORAGE_PREDICT_FAILURE
NTSTATUS DiskReadFailurePredictData(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_DATA DiskSmartData)
Definition: diskwmi.c:1327
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
NTSTATUS DiskReadFailurePredictStatus(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_STATUS DiskSmartStatus)
Definition: diskwmi.c:1251
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define CHECK_IRQL()
Definition: disk.h:458
FAILURE_PREDICTION_METHOD FailurePredictionCapability
Definition: disk.h:331
struct _cl_event * event
Definition: glext.h:7739
#define DISK_TAG_SMART
Definition: disk.h:54
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
struct _STORAGE_PREDICT_FAILURE STORAGE_PREDICT_FAILURE
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MJ_READ
Definition: rdpdr.c:46
unsigned int ULONG
Definition: retypes.h:1
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DiskDeviceControl().

◆ DiskIoctlReassignBlocks()

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

Definition at line 4644 of file disk.c.

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

Referenced by DiskDeviceControl().

◆ DiskIoctlReassignBlocksEx()

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

Definition at line 4851 of file disk.c.

4878 {
4879  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
4881  NTSTATUS status;
4882  PREASSIGN_BLOCKS_EX badBlocks = Irp->AssociatedIrp.SystemBuffer;
4883  PSCSI_REQUEST_BLOCK srb;
4884  PCDB cdb;
4885  LARGE_INTEGER blockNumber;
4886  ULONG bufferSize;
4887  ULONG blockCount;
4888  ULONG srbSize;
4889  PSTORAGE_REQUEST_BLOCK srbEx;
4890  PSTOR_ADDR_BTL8 storAddrBtl8;
4891  PSRBEX_DATA_SCSI_CDB16 srbExDataCdb16;
4892 
4893  //
4894  // This function must be called at less than dispatch level.
4895  // Fail if IRQL >= DISPATCH_LEVEL.
4896  //
4897  PAGED_CODE();
4898  CHECK_IRQL();
4899 
4900  //
4901  // Validate the request.
4902  //
4903 
4904  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocksEx: DeviceObject %p Irp %p\n", DeviceObject, Irp));
4905 
4906  if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(REASSIGN_BLOCKS_EX)) {
4907  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocksEx: Input buffer length mismatch.\n"));
4909  }
4910 
4911  //
4912  // Make sure we have some data in the input buffer.
4913  //
4914 
4915  if (badBlocks->Count == 0) {
4916  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "DiskIoctlReassignBlocksEx: Invalid block count\n"));
4917  return STATUS_INVALID_PARAMETER;
4918  }
4919 
4920  bufferSize = sizeof(REASSIGN_BLOCKS_EX) + ((badBlocks->Count - 1) * sizeof(LARGE_INTEGER));
4921