ReactOS 0.4.15-dev-6703-g6528ab8
disk.h File Reference
#include "ntddk.h"
#include "scsi.h"
#include <wmidata.h>
#include "classpnp.h"
#include <wmistr.h>
#include "ntstrsafe.h"
#include <storswtr.h>
Include dependency graph for disk.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _DISK_GROUP_CONTEXT
 
struct  _DISK_DATA
 
struct  _DISK_MEDIA_TYPES_LIST
 
struct  DISKREREGREQUEST
 
struct  _DISK_VERIFY_WORKITEM_CONTEXT
 

Macros

#define DEBUG_COMP_ID   DPFLTR_DISK_ID
 
#define WPP_GUID_DISK   (945186BF, 3DD6, 4f3f, 9C8E, 9EDD3FC9D558)
 
#define WPP_CONTROL_GUIDS   WPP_CONTROL_GUIDS_NORMAL_FLAGS(WPP_GUID_DISK)
 
#define DISK_TAG_GENERAL   ' DcS'
 
#define DISK_TAG_SMART   'aDcS'
 
#define DISK_TAG_INFO_EXCEPTION   'ADcS'
 
#define DISK_TAG_DISABLE_CACHE   'CDcS'
 
#define DISK_TAG_CCONTEXT   'cDcS'
 
#define DISK_TAG_DISK_GEOM   'GDcS'
 
#define DISK_TAG_UPDATE_GEOM   'gDcS'
 
#define DISK_TAG_SENSE_INFO   'IDcS'
 
#define DISK_TAG_PNP_ID   'iDcS'
 
#define DISK_TAG_MODE_DATA   'MDcS'
 
#define DISK_CACHE_MBR_CHECK   'mDcS'
 
#define DISK_TAG_NAME   'NDcS'
 
#define DISK_TAG_READ_CAP   'PDcS'
 
#define DISK_TAG_PART_LIST   'pDcS'
 
#define DISK_TAG_SRB   'SDcS'
 
#define DISK_TAG_START   'sDcS'
 
#define DISK_TAG_UPDATE_CAP   'UDcS'
 
#define DISK_TAG_WI_CONTEXT   'WDcS'
 
#define HackDisableTaggedQueuing   (0x01)
 
#define HackDisableSynchronousTransfers   (0x02)
 
#define HackDisableSpinDown   (0x04)
 
#define HackDisableWriteCache   (0x08)
 
#define HackCauseNotReportableHack   (0x10)
 
#define HackRequiresStartUnitCommand   (0x20)
 
#define DiskDeviceParameterSubkey   L"Disk"
 
#define DiskDeviceUserWriteCacheSetting   L"UserWriteCacheSetting"
 
#define DiskDeviceCacheIsPowerProtected   L"CacheIsPowerProtected"
 
#define FUNCTIONAL_EXTENSION_SIZE   sizeof(FUNCTIONAL_DEVICE_EXTENSION) + sizeof(DISK_DATA)
 
#define MODE_DATA_SIZE   192
 
#define VALUE_BUFFER_SIZE   2048
 
#define SCSI_DISK_TIMEOUT   10
 
#define PARTITION0_LIST_SIZE   4
 
#define MAX_MEDIA_TYPES   4
 
#define MAX_SECTORS_PER_VERIFY   0x100
 
#define ONE_MILLI_SECOND   ((ULONGLONG)10 * 1000)
 
#define DISK_DEFAULT_FAILURE_POLLING_PERIOD   1 * 60 * 60
 
#define CHECK_IRQL()
 
#define DiskIsValidSmartSelfTest(Subcommand)
 
#define DiskReadDriveCapacity(Fdo)   ClassReadDriveCapacity(Fdo)
 
#define DiskGetDetectInfo(FdoExtension, DetectInfo)   (STATUS_UNSUCCESSFUL)
 
#define DiskHashGuid(Guid)   (((PULONG) &Guid)[0] ^ ((PULONG) &Guid)[0] ^ ((PULONG) &Guid)[0] ^ ((PULONG) &Guid)[0])
 

Typedefs

typedef struct _DISK_GROUP_CONTEXT DISK_GROUP_CONTEXT
 
typedef struct _DISK_GROUP_CONTEXTPDISK_GROUP_CONTEXT
 
typedef enum _DISK_USER_WRITE_CACHE_SETTING DISK_USER_WRITE_CACHE_SETTING
 
typedef enum _DISK_USER_WRITE_CACHE_SETTINGPDISK_USER_WRITE_CACHE_SETTING
 
typedef struct _DISK_DATA DISK_DATA
 
typedef struct _DISK_DATAPDISK_DATA
 
typedef struct _DISK_MEDIA_TYPES_LIST DISK_MEDIA_TYPES_LIST
 
typedef struct _DISK_MEDIA_TYPES_LISTPDISK_MEDIA_TYPES_LIST
 
typedef struct DISKREREGREQUESTPDISKREREGREQUEST
 
typedef struct _DISK_VERIFY_WORKITEM_CONTEXT DISK_VERIFY_WORKITEM_CONTEXT
 
typedef struct _DISK_VERIFY_WORKITEM_CONTEXTPDISK_VERIFY_WORKITEM_CONTEXT
 

Enumerations

enum  _DISK_USER_WRITE_CACHE_SETTING { DiskWriteCacheDisable = 0 , DiskWriteCacheEnable = 1 , DiskWriteCacheDefault = -1 }
 

Functions

VOID NTAPI DiskUnload (IN PDRIVER_OBJECT DriverObject)
 
NTSTATUS NTAPI DiskAddDevice (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT Pdo)
 
NTSTATUS NTAPI DiskInitFdo (IN PDEVICE_OBJECT Fdo)
 
NTSTATUS NTAPI DiskStartFdo (IN PDEVICE_OBJECT Fdo)
 
NTSTATUS NTAPI DiskStopDevice (IN PDEVICE_OBJECT DeviceObject, IN UCHAR Type)
 
NTSTATUS NTAPI DiskRemoveDevice (IN PDEVICE_OBJECT DeviceObject, IN UCHAR Type)
 
NTSTATUS NTAPI DiskReadWriteVerification (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI DiskDeviceControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID NTAPI DiskFdoProcessError (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
 
NTSTATUS NTAPI DiskShutdownFlush (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
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)
 
VOID DiskLogCacheInformation (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo, IN NTSTATUS Status)
 
NTSTATUS DiskIoctlGetCacheSetting (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS DiskIoctlSetCacheSetting (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID DiskFlushDispatch (IN PDEVICE_OBJECT Fdo, IN PDISK_GROUP_CONTEXT FlushContext)
 
NTSTATUS DiskModeSelect (IN PDEVICE_OBJECT DeviceObject, _In_reads_bytes_(Length) PCHAR ModeSelectBuffer, IN ULONG Length, IN BOOLEAN SavePage)
 
NTSTATUS DiskPerformSmartCommand (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN ULONG SrbControlCode, IN UCHAR Command, IN UCHAR Feature, IN UCHAR SectorCount, IN UCHAR SectorNumber, IN OUT PSRB_IO_CONTROL SrbControl, OUT PULONG BufferSize)
 
NTSTATUS DiskGetInfoExceptionInformation (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, OUT PMODE_INFO_EXCEPTIONS ReturnPageData)
 
NTSTATUS DiskSetInfoExceptionInformation (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMODE_INFO_EXCEPTIONS PageData)
 
NTSTATUS DiskGetModePage (_In_ PDEVICE_OBJECT Fdo, _In_ UCHAR PageMode, _In_ UCHAR PageControl, _In_ PMODE_PARAMETER_HEADER ModeData, _Inout_ PULONG ModeDataSize, _Out_ PVOID *PageData)
 
NTSTATUS DiskEnableInfoExceptions (_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ BOOLEAN Enable)
 
NTSTATUS DiskDetectFailurePrediction (PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PFAILURE_PREDICTION_METHOD FailurePredictCapability, BOOLEAN ScsiAddressAvailable)
 
NTSTATUS DiskCreateFdo (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT LowerDeviceObject, IN PULONG DeviceCount, IN BOOLEAN DasdAccessOnly)
 
VOID NTAPI DiskSetSpecialHacks (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN ULONG_PTR Data)
 
VOID ResetBus (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS DiskGenerateDeviceName (IN ULONG DeviceNumber, OUT PCCHAR *RawName)
 
VOID DiskCreateSymbolicLinks (IN PDEVICE_OBJECT DeviceObject)
 
VOID DiskDeleteSymbolicLinks (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI DiskFdoQueryWmiRegInfo (IN PDEVICE_OBJECT DeviceObject, OUT ULONG *RegFlags, OUT PUNICODE_STRING InstanceName)
 
NTSTATUS NTAPI DiskFdoQueryWmiRegInfoEx (IN PDEVICE_OBJECT DeviceObject, OUT ULONG *RegFlags, OUT PUNICODE_STRING InstanceName, OUT PUNICODE_STRING MofName)
 
NTSTATUS NTAPI DiskFdoQueryWmiDataBlock (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG BufferAvail, OUT PUCHAR Buffer)
 
NTSTATUS NTAPI DiskFdoSetWmiDataBlock (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG BufferSize, IN PUCHAR Buffer)
 
NTSTATUS NTAPI DiskFdoSetWmiDataItem (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG DataItemId, IN ULONG BufferSize, IN PUCHAR Buffer)
 
NTSTATUS NTAPI DiskFdoExecuteWmiMethod (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG MethodId, IN ULONG InBufferSize, IN ULONG OutBufferSize, IN PUCHAR Buffer)
 
NTSTATUS NTAPI DiskWmiFunctionControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN CLASSENABLEDISABLEFUNCTION Function, IN BOOLEAN Enable)
 
NTSTATUS DiskReadFailurePredictStatus (PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_STATUS DiskSmartStatus)
 
NTSTATUS DiskReadFailurePredictData (PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_DATA DiskSmartData)
 
NTSTATUS DiskEnableDisableFailurePrediction (PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable)
 
NTSTATUS DiskEnableDisableFailurePredictPolling (PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable, ULONG PollTimeInSeconds)
 
NTSTATUS DiskInitializeReregistration (VOID)
 
NTSTATUS DiskDetermineMediaTypes (IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN UCHAR MediumType, IN UCHAR DensityCode, IN BOOLEAN MediaPresent, IN BOOLEAN IsWritable)
 
NTSTATUS DiskIoctlGetLengthInfo (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS DiskIoctlGetDriveGeometry (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
 
NTSTATUS DiskIoctlGetDriveGeometryEx (IN PDEVICE_OBJECT DeviceObject, IN 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)
 
FORCEINLINE PCDB GetSrbScsiData (_In_ PSTORAGE_REQUEST_BLOCK SrbEx, _In_opt_ PUCHAR CdbLength8, _In_opt_ PULONG CdbLength32, _In_opt_ PUCHAR ScsiStatus, _In_opt_ PVOID *SenseInfoBuffer, _In_opt_ PUCHAR SenseInfoBufferLength)
 
FORCEINLINE VOID SetSrbScsiData (_In_ PSTORAGE_REQUEST_BLOCK SrbEx, _In_ UCHAR CdbLength8, _In_ ULONG CdbLength32, _In_ UCHAR ScsiStatus, _In_opt_ PVOID SenseInfoBuffer, _In_ UCHAR SenseInfoBufferLength)
 

Variables

CLASSPNP_SCAN_FOR_SPECIAL_INFO DiskBadControllers []
 
const DISK_MEDIA_TYPES_LIST DiskMediaTypes []
 
const DISK_MEDIA_TYPES_LIST DiskMediaTypesExclude []
 
DRIVER_INITIALIZE DriverEntry
 
IO_WORKITEM_ROUTINE DisableWriteCache
 
IO_WORKITEM_ROUTINE DiskIoctlVerifyThread
 
IO_COMPLETION_ROUTINE DiskFlushComplete
 
GUIDREGINFO DiskWmiFdoGuidList []
 

Macro Definition Documentation

◆ CHECK_IRQL

#define CHECK_IRQL ( )
Value:
NT_ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); \
}
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define STATUS_INVALID_LEVEL
Definition: ntstatus.h:564

Definition at line 458 of file disk.h.

◆ DEBUG_COMP_ID

#define DEBUG_COMP_ID   DPFLTR_DISK_ID

Definition at line 35 of file disk.h.

◆ DISK_CACHE_MBR_CHECK

#define DISK_CACHE_MBR_CHECK   'mDcS'

Definition at line 63 of file disk.h.

◆ DISK_DEFAULT_FAILURE_POLLING_PERIOD

#define DISK_DEFAULT_FAILURE_POLLING_PERIOD   1 * 60 * 60

Definition at line 456 of file disk.h.

◆ DISK_TAG_CCONTEXT

#define DISK_TAG_CCONTEXT   'cDcS'

Definition at line 57 of file disk.h.

◆ DISK_TAG_DISABLE_CACHE

#define DISK_TAG_DISABLE_CACHE   'CDcS'

Definition at line 56 of file disk.h.

◆ DISK_TAG_DISK_GEOM

#define DISK_TAG_DISK_GEOM   'GDcS'

Definition at line 58 of file disk.h.

◆ DISK_TAG_GENERAL

#define DISK_TAG_GENERAL   ' DcS'

Definition at line 53 of file disk.h.

◆ DISK_TAG_INFO_EXCEPTION

#define DISK_TAG_INFO_EXCEPTION   'ADcS'

Definition at line 55 of file disk.h.

◆ DISK_TAG_MODE_DATA

#define DISK_TAG_MODE_DATA   'MDcS'

Definition at line 62 of file disk.h.

◆ DISK_TAG_NAME

#define DISK_TAG_NAME   'NDcS'

Definition at line 64 of file disk.h.

◆ DISK_TAG_PART_LIST

#define DISK_TAG_PART_LIST   'pDcS'

Definition at line 66 of file disk.h.

◆ DISK_TAG_PNP_ID

#define DISK_TAG_PNP_ID   'iDcS'

Definition at line 61 of file disk.h.

◆ DISK_TAG_READ_CAP

#define DISK_TAG_READ_CAP   'PDcS'

Definition at line 65 of file disk.h.

◆ DISK_TAG_SENSE_INFO

#define DISK_TAG_SENSE_INFO   'IDcS'

Definition at line 60 of file disk.h.

◆ DISK_TAG_SMART

#define DISK_TAG_SMART   'aDcS'

Definition at line 54 of file disk.h.

◆ DISK_TAG_SRB

#define DISK_TAG_SRB   'SDcS'

Definition at line 67 of file disk.h.

◆ DISK_TAG_START

#define DISK_TAG_START   'sDcS'

Definition at line 68 of file disk.h.

◆ DISK_TAG_UPDATE_CAP

#define DISK_TAG_UPDATE_CAP   'UDcS'

Definition at line 69 of file disk.h.

◆ DISK_TAG_UPDATE_GEOM

#define DISK_TAG_UPDATE_GEOM   'gDcS'

Definition at line 59 of file disk.h.

◆ DISK_TAG_WI_CONTEXT

#define DISK_TAG_WI_CONTEXT   'WDcS'

Definition at line 70 of file disk.h.

◆ DiskDeviceCacheIsPowerProtected

#define DiskDeviceCacheIsPowerProtected   L"CacheIsPowerProtected"

Definition at line 405 of file disk.h.

◆ DiskDeviceParameterSubkey

#define DiskDeviceParameterSubkey   L"Disk"

Definition at line 403 of file disk.h.

◆ DiskDeviceUserWriteCacheSetting

#define DiskDeviceUserWriteCacheSetting   L"UserWriteCacheSetting"

Definition at line 404 of file disk.h.

◆ DiskGetDetectInfo

#define DiskGetDetectInfo (   FdoExtension,
  DetectInfo 
)    (STATUS_UNSUCCESSFUL)

Definition at line 861 of file disk.h.

◆ DiskHashGuid

#define DiskHashGuid (   Guid)    (((PULONG) &Guid)[0] ^ ((PULONG) &Guid)[0] ^ ((PULONG) &Guid)[0] ^ ((PULONG) &Guid)[0])

Definition at line 865 of file disk.h.

◆ DiskIsValidSmartSelfTest

#define DiskIsValidSmartSelfTest (   Subcommand)
Value:
( ((Subcommand) == SMART_OFFLINE_ROUTINE_OFFLINE) || \
((Subcommand) == SMART_SHORT_SELFTEST_OFFLINE) || \
((Subcommand) == SMART_EXTENDED_SELFTEST_OFFLINE) )
#define SMART_EXTENDED_SELFTEST_OFFLINE
Definition: ntdddisk.h:719
#define SMART_SHORT_SELFTEST_OFFLINE
Definition: ntdddisk.h:718
#define SMART_OFFLINE_ROUTINE_OFFLINE
Definition: ntdddisk.h:717

Definition at line 619 of file disk.h.

◆ DiskReadDriveCapacity

#define DiskReadDriveCapacity (   Fdo)    ClassReadDriveCapacity(Fdo)

Definition at line 818 of file disk.h.

◆ FUNCTIONAL_EXTENSION_SIZE

#define FUNCTIONAL_EXTENSION_SIZE   sizeof(FUNCTIONAL_DEVICE_EXTENSION) + sizeof(DISK_DATA)

Definition at line 408 of file disk.h.

◆ HackCauseNotReportableHack

#define HackCauseNotReportableHack   (0x10)

Definition at line 399 of file disk.h.

◆ HackDisableSpinDown

#define HackDisableSpinDown   (0x04)

Definition at line 397 of file disk.h.

◆ HackDisableSynchronousTransfers

#define HackDisableSynchronousTransfers   (0x02)

Definition at line 396 of file disk.h.

◆ HackDisableTaggedQueuing

#define HackDisableTaggedQueuing   (0x01)

Definition at line 395 of file disk.h.

◆ HackDisableWriteCache

#define HackDisableWriteCache   (0x08)

Definition at line 398 of file disk.h.

◆ HackRequiresStartUnitCommand

#define HackRequiresStartUnitCommand   (0x20)

Definition at line 400 of file disk.h.

◆ MAX_MEDIA_TYPES

#define MAX_MEDIA_TYPES   4

Definition at line 415 of file disk.h.

◆ MAX_SECTORS_PER_VERIFY

#define MAX_SECTORS_PER_VERIFY   0x100

Definition at line 435 of file disk.h.

◆ MODE_DATA_SIZE

#define MODE_DATA_SIZE   192

Definition at line 410 of file disk.h.

◆ ONE_MILLI_SECOND

#define ONE_MILLI_SECOND   ((ULONGLONG)10 * 1000)

Definition at line 440 of file disk.h.

◆ PARTITION0_LIST_SIZE

#define PARTITION0_LIST_SIZE   4

Definition at line 413 of file disk.h.

◆ SCSI_DISK_TIMEOUT

#define SCSI_DISK_TIMEOUT   10

Definition at line 412 of file disk.h.

◆ VALUE_BUFFER_SIZE

#define VALUE_BUFFER_SIZE   2048

Definition at line 411 of file disk.h.

◆ WPP_CONTROL_GUIDS

Definition at line 44 of file disk.h.

◆ WPP_GUID_DISK

#define WPP_GUID_DISK   (945186BF, 3DD6, 4f3f, 9C8E, 9EDD3FC9D558)

Definition at line 42 of file disk.h.

Typedef Documentation

◆ DISK_DATA

◆ DISK_GROUP_CONTEXT

◆ DISK_MEDIA_TYPES_LIST

◆ DISK_USER_WRITE_CACHE_SETTING

◆ DISK_VERIFY_WORKITEM_CONTEXT

◆ PDISK_DATA

◆ PDISK_GROUP_CONTEXT

◆ PDISK_MEDIA_TYPES_LIST

◆ PDISK_USER_WRITE_CACHE_SETTING

◆ PDISK_VERIFY_WORKITEM_CONTEXT

◆ PDISKREREGREQUEST

Enumeration Type Documentation

◆ _DISK_USER_WRITE_CACHE_SETTING

Enumerator
DiskWriteCacheDisable 
DiskWriteCacheEnable 
DiskWriteCacheDefault 

Definition at line 177 of file disk.h.

178{
182
enum _DISK_USER_WRITE_CACHE_SETTING DISK_USER_WRITE_CACHE_SETTING
enum _DISK_USER_WRITE_CACHE_SETTING * PDISK_USER_WRITE_CACHE_SETTING
@ DiskWriteCacheDefault
Definition: disk.h:181
@ DiskWriteCacheDisable
Definition: disk.h:179
@ DiskWriteCacheEnable
Definition: disk.h:180

Function Documentation

◆ DiskAddDevice()

NTSTATUS NTAPI DiskAddDevice ( IN PDRIVER_OBJECT  DriverObject,
IN PDEVICE_OBJECT  Pdo 
)

Definition at line 53 of file pnp.c.

78{
79 ULONG rootPartitionMountable = FALSE;
80
81 PCONFIGURATION_INFORMATION configurationInformation;
82 ULONG diskCount;
83
85
86 PAGED_CODE();
87
88 //
89 // See if we should be allowing file systems to mount on partition zero.
90 //
91
92 TRY {
93 HANDLE deviceKey = NULL;
94
95 UNICODE_STRING diskKeyName;
96 OBJECT_ATTRIBUTES objectAttributes = {0};
97 HANDLE diskKey;
98
99 RTL_QUERY_REGISTRY_TABLE queryTable[2] = { 0 };
100
103 KEY_READ,
104 &deviceKey);
105
106 if(!NT_SUCCESS(status)) {
107 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskAddDevice: Error %#08lx opening device key "
108 "for pdo %p\n",
110 LEAVE;
111 }
112
113 RtlInitUnicodeString(&diskKeyName, L"Disk");
114 InitializeObjectAttributes(&objectAttributes,
115 &diskKeyName,
117 deviceKey,
118 NULL);
119
120 status = ZwOpenKey(&diskKey, KEY_READ, &objectAttributes);
121 ZwClose(deviceKey);
122
123 if(!NT_SUCCESS(status)) {
124 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskAddDevice: Error %#08lx opening disk key "
125 "for pdo %p device key %p\n",
126 status, PhysicalDeviceObject, deviceKey));
127 LEAVE;
128 }
129
131 queryTable[0].Name = L"RootPartitionMountable";
132 queryTable[0].EntryContext = &(rootPartitionMountable);
134
135#ifdef _MSC_VER
136#pragma prefast(suppress:6309, "We don't have QueryRoutine so Context doesn't make any sense")
137#endif
139 diskKey,
140 queryTable,
141 NULL,
142 NULL);
143
144 if(!NT_SUCCESS(status)) {
145 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskAddDevice: Error %#08lx reading value from "
146 "disk key %p for pdo %p\n",
147 status, diskKey, PhysicalDeviceObject));
148 }
149
150 ZwClose(diskKey);
151
152 } FINALLY {
153
154 //
155 // Do nothing.
156 //
157
158 if(!NT_SUCCESS(status)) {
159 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_PNP, "DiskAddDevice: Will %sallow file system to mount on "
160 "partition zero of disk %p\n",
161 (rootPartitionMountable ? "" : "not "),
163 }
164 }
165
166 //
167 // Create device objects for disk
168 //
169
170 diskCount = 0;
171
175 &diskCount,
176 (BOOLEAN) !rootPartitionMountable
177 );
178
179 //
180 // Get the number of disks already initialized.
181 //
182
183 configurationInformation = IoGetConfigurationInformation();
184
185 if (NT_SUCCESS(status)) {
186
187 //
188 // Increment system disk device count.
189 //
190
191 configurationInformation->DiskCount++;
192
193 }
194
195 return status;
196
197} // end DiskAddDevice()
#define PAGED_CODE()
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
#define FINALLY
Definition: classpnp.h:116
#define LEAVE
Definition: classpnp.h:115
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS DiskCreateFdo(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PULONG DeviceCount, IN BOOLEAN DasdAccessOnly)
Definition: disk.c:307
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Returns a pointer to the I/O manager's global configuration information structure.
Definition: iorsrce.c:998
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define REG_NONE
Definition: nt_native.h:1492
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
Definition: pnpmgr.c:1621
#define REG_DWORD
Definition: sdbapi.c:596
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
Definition: ps.c:97
uint32_t ULONG
Definition: typedefs.h:59
#define TRY(sps, bps)
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define PLUGPLAY_REGKEY_DEVICE
Definition: iofuncs.h:2786
#define RTL_QUERY_REGISTRY_TYPECHECK
#define RTL_QUERY_REGISTRY_TYPECHECK_SHIFT

Referenced by DriverEntry().

◆ DiskCreateFdo()

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

Definition at line 307 of file disk.c.

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

Referenced by DiskAddDevice().

◆ DiskCreateSymbolicLinks()

VOID DiskCreateSymbolicLinks ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 676 of file pnp.c.

702{
703 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
704 PDISK_DATA diskData = commonExtension->DriverData;
705
706 WCHAR wideSourceName[64] = { 0 };
707 UNICODE_STRING unicodeSourceName;
708
710
711 PAGED_CODE();
712
713 //
714 // Build the destination for the link first using the device name
715 // stored in the device object
716 //
717
718 NT_ASSERT(commonExtension->DeviceName.Buffer);
719
720 if(!diskData->LinkStatus.WellKnownNameCreated) {
721 //
722 // Put together the source name using the partition and device number
723 // in the device extension and disk data segment
724 //
725
726 status = RtlStringCchPrintfW(wideSourceName, sizeof(wideSourceName) / sizeof(wideSourceName[0]) - 1,
727 L"\\Device\\Harddisk%d\\Partition0",
728 commonExtension->PartitionZeroExtension->DeviceNumber);
729
730 if (NT_SUCCESS(status)) {
731
732 RtlInitUnicodeString(&unicodeSourceName, wideSourceName);
733
734 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskCreateSymbolicLink: Linking %wZ to %wZ\n",
735 &unicodeSourceName,
736 &commonExtension->DeviceName));
737
738 status = IoCreateSymbolicLink(&unicodeSourceName,
739 &commonExtension->DeviceName);
740
741 if(NT_SUCCESS(status)){
742 diskData->LinkStatus.WellKnownNameCreated = TRUE;
743 }
744 }
745 }
746
747 if (!diskData->LinkStatus.PhysicalDriveLinkCreated) {
748
749 //
750 // Create a physical drive N link using the device number we saved
751 // away during AddDevice.
752 //
753
754 status = RtlStringCchPrintfW(wideSourceName, sizeof(wideSourceName) / sizeof(wideSourceName[0]) - 1,
755 L"\\DosDevices\\PhysicalDrive%d",
756 commonExtension->PartitionZeroExtension->DeviceNumber);
757 if (NT_SUCCESS(status)) {
758
759 RtlInitUnicodeString(&unicodeSourceName, wideSourceName);
760
761 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskCreateSymbolicLink: Linking %wZ to %wZ\n",
762 &unicodeSourceName,
763 &(commonExtension->DeviceName)));
764
765 status = IoCreateSymbolicLink(&unicodeSourceName,
766 &(commonExtension->DeviceName));
767
768 if(NT_SUCCESS(status)) {
769 diskData->LinkStatus.PhysicalDriveLinkCreated = TRUE;
770 }
771 }
772 }
773
774
775 return;
776}
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
UNICODE_STRING DeviceName
Definition: classpnp.h:615
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
struct _DISK_DATA::@1040 LinkStatus
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define NT_ASSERT
Definition: rtlfuncs.h:3310

Referenced by DiskInitFdo().

◆ DiskDeleteSymbolicLinks()

VOID DiskDeleteSymbolicLinks ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 780 of file pnp.c.

802{
803 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
804 PDISK_DATA diskData = commonExtension->DriverData;
805
806 WCHAR wideLinkName[64] = { 0 };
807 UNICODE_STRING unicodeLinkName;
809
810 PAGED_CODE();
811
812 if(diskData->LinkStatus.WellKnownNameCreated) {
813
814 status = RtlStringCchPrintfW(wideLinkName, sizeof(wideLinkName) / sizeof(wideLinkName[0]) - 1,
815 L"\\Device\\Harddisk%d\\Partition0",
816 commonExtension->PartitionZeroExtension->DeviceNumber);
817 if (NT_SUCCESS(status)) {
818 RtlInitUnicodeString(&unicodeLinkName, wideLinkName);
819 IoDeleteSymbolicLink(&unicodeLinkName);
820 }
821 diskData->LinkStatus.WellKnownNameCreated = FALSE;
822 }
823
824 if(diskData->LinkStatus.PhysicalDriveLinkCreated) {
825
826 status = RtlStringCchPrintfW(wideLinkName, sizeof(wideLinkName) / sizeof(wideLinkName[0]) - 1,
827 L"\\DosDevices\\PhysicalDrive%d",
828 commonExtension->PartitionZeroExtension->DeviceNumber);
829 if (NT_SUCCESS(status)) {
830 RtlInitUnicodeString(&unicodeLinkName, wideLinkName);
831 IoDeleteSymbolicLink(&unicodeLinkName);
832 }
833 diskData->LinkStatus.PhysicalDriveLinkCreated = FALSE;
834 }
835
836
837 return;
838}

Referenced by DiskRemoveDevice().

◆ DiskDetectFailurePrediction()

NTSTATUS DiskDetectFailurePrediction ( PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
PFAILURE_PREDICTION_METHOD  FailurePredictCapability,
BOOLEAN  ScsiAddressAvailable 
)

Definition at line 2230 of file diskwmi.c.

2270{
2272 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
2273 BOOLEAN supportFP;
2275 STORAGE_PREDICT_FAILURE checkFailure;
2276 STORAGE_FAILURE_PREDICT_STATUS diskSmartStatus;
2277
2278 PAGED_CODE();
2279
2280 //
2281 // Assume no failure predict mechanisms
2282 //
2283 *FailurePredictCapability = FailurePredictionNone;
2284
2285 //
2286 // See if this is an IDE drive that supports SMART. If so enable SMART
2287 // and then ensure that it suports the SMART READ STATUS command
2288 //
2289
2290 if (ScsiAddressAvailable)
2291 {
2292 DiskGetIdentifyInfo(FdoExtension, &supportFP);
2293
2294 if (supportFP)
2295 {
2297 if (NT_SUCCESS(status))
2298 {
2299 *FailurePredictCapability = FailurePredictionSmart;
2300 diskData->FailurePredictionEnabled = TRUE;
2301
2303 &diskSmartStatus);
2304
2305 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: Device %p %s IDE SMART\n",
2306 FdoExtension->DeviceObject,
2307 NT_SUCCESS(status) ? "does" : "does not"));
2308
2309 if (!NT_SUCCESS(status))
2310 {
2311 *FailurePredictCapability = FailurePredictionNone;
2312 diskData->FailurePredictionEnabled = FALSE;
2313 }
2314 }
2315 return(status);
2316 }
2317 }
2318 //
2319 // See if there is a a filter driver to intercept
2320 // IOCTL_STORAGE_PREDICT_FAILURE
2321 //
2323 &checkFailure);
2324
2325 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: Device %p %s IOCTL_STORAGE_FAILURE_PREDICT\n",
2326 FdoExtension->DeviceObject,
2327 NT_SUCCESS(status) ? "does" : "does not"));
2328
2329 if (NT_SUCCESS(status))
2330 {
2331 *FailurePredictCapability = FailurePredictionIoctl;
2332 diskData->FailurePredictionEnabled = TRUE;
2333 if (checkFailure.PredictFailure)
2334 {
2335 checkFailure.PredictFailure = 512;
2336 ClassNotifyFailurePredicted(FdoExtension,
2337 (PUCHAR)&checkFailure,
2338 sizeof(checkFailure),
2339 (BOOLEAN)(FdoExtension->FailurePredicted == FALSE),
2340 0x11,
2341 diskData->ScsiAddress.PathId,
2342 diskData->ScsiAddress.TargetId,
2343 diskData->ScsiAddress.Lun);
2344
2345 FdoExtension->FailurePredicted = TRUE;
2346 }
2347 return(status);
2348 }
2349
2350 //
2351 // Finally we assume it will not be a scsi smart drive. but
2352 // we'll also send off an asynchronous mode sense so that if
2353 // it is SMART we'll reregister the device object
2354 //
2355
2356 *FailurePredictCapability = FailurePredictionNone;
2357
2359
2360 return(STATUS_SUCCESS);
2361}
@ FailurePredictionSmart
Definition: classpnp.h:236
@ FailurePredictionNone
Definition: classpnp.h:234
@ FailurePredictionIoctl
Definition: classpnp.h:235
NTSTATUS DiskSendFailurePredictIoctl(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_PREDICT_FAILURE checkFailure)
Definition: diskwmi.c:854
static NTSTATUS DiskEnableSmart(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: diskwmi.c:271
NTSTATUS DiskInfoExceptionCheck(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: diskwmi.c:1922
NTSTATUS DiskGetIdentifyInfo(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PBOOLEAN SupportSmart)
Definition: diskwmi.c:813
NTSTATUS DiskReadFailurePredictStatus(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_STATUS DiskSmartStatus)
Definition: diskwmi.c:1251
struct _COMMON_DEVICE_EXTENSION * PCOMMON_DEVICE_EXTENSION
struct _DISK_DATA * PDISK_DATA
@ FdoExtension
Definition: precomp.h:48
BOOLEAN FailurePredictionEnabled
Definition: disk.h:346
SCSI_ADDRESS ScsiAddress
Definition: disk.h:325
UCHAR PathId
Definition: scsi_port.h:149
UCHAR TargetId
Definition: scsi_port.h:150
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by DiskInitFdo().

◆ DiskDetermineMediaTypes()

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

Definition at line 655 of file disk.c.

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

Referenced by DiskIoctlGetMediaTypesEx().

◆ DiskDeviceControl()

NTSTATUS NTAPI DiskDeviceControl ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

◆ DiskEnableDisableFailurePrediction()

NTSTATUS DiskEnableDisableFailurePrediction ( PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
BOOLEAN  Enable 
)

Definition at line 1126 of file diskwmi.c.

1147{
1149 PCOMMON_DEVICE_EXTENSION commonExtension = &(FdoExtension->CommonExtension);
1150 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1151
1152 PAGED_CODE();
1153
1154 switch(diskData->FailurePredictionCapability)
1155 {
1157 {
1158 if (Enable)
1159 {
1161 } else {
1163 }
1164
1165 if (NT_SUCCESS(status)) {
1166 diskData->FailurePredictionEnabled = Enable;
1167 }
1168
1169 break;
1170 }
1171
1174 {
1175 //
1176 // We assume that the drive is already setup properly for
1177 // failure prediction
1178 //
1180 break;
1181 }
1182
1183 default:
1184 {
1186 }
1187 }
1188 return status;
1189}
@ FailurePredictionSense
Definition: classpnp.h:237
static NTSTATUS DiskDisableSmart(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: diskwmi.c:293
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
FAILURE_PREDICTION_METHOD FailurePredictionCapability
Definition: disk.h:331
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138

Referenced by DiskEnableDisableFailurePredictPolling(), DiskFdoExecuteWmiMethod(), DiskIoctlEnableFailurePrediction(), and DiskWmiFunctionControl().

◆ DiskEnableDisableFailurePredictPolling()

NTSTATUS DiskEnableDisableFailurePredictPolling ( PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
BOOLEAN  Enable,
ULONG  PollTimeInSeconds 
)

Definition at line 1193 of file diskwmi.c.

1217{
1220 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1221
1222 PAGED_CODE();
1223
1224 if (Enable)
1225 {
1227 Enable);
1228 } else {
1230 }
1231
1232 if (NT_SUCCESS(status))
1233 {
1234 status = ClassSetFailurePredictionPoll(FdoExtension,
1237 PollTimeInSeconds);
1238
1239 //
1240 // Even if this failed we do not want to disable FP on the
1241 // hardware. FP is only ever disabled on the hardware by
1242 // specific command of the user.
1243 //
1244 }
1245
1246 return status;
1247}
NTSTATUS DiskEnableDisableFailurePrediction(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable)
Definition: diskwmi.c:1126

Referenced by DiskFdoExecuteWmiMethod(), DiskInitFdo(), and DiskWmiFunctionControl().

◆ DiskEnableInfoExceptions()

NTSTATUS DiskEnableInfoExceptions ( _In_ PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
_In_ BOOLEAN  Enable 
)

Definition at line 979 of file diskwmi.c.

983{
984 PDISK_DATA diskData = (PDISK_DATA)(FdoExtension->CommonExtension.DriverData);
986 PMODE_PARAMETER_HEADER modeData;
987 PMODE_INFO_EXCEPTIONS pageData;
988 MODE_INFO_EXCEPTIONS changeablePageData;
989 ULONG modeDataSize;
990
991 PAGED_CODE();
992
993 modeDataSize = MODE_DATA_SIZE;
994
995 modeData = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
996 modeDataSize,
998
999 if (modeData == NULL) {
1000
1001 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_WMI, "DiskEnableInfoExceptions: Unable to allocate mode "
1002 "data buffer\n"));
1004 }
1005
1006 //
1007 // First see which data is actually changeable.
1008 //
1009 status = DiskGetModePage(FdoExtension->DeviceObject,
1011 1, // Page Control = 1 indicates we want changeable values.
1012 modeData,
1013 &modeDataSize,
1014 (PVOID*)&pageData);
1015
1016 if (!NT_SUCCESS(status) || pageData == NULL) {
1017 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskEnableInfoExceptions: does NOT support SMART for device %p\n",
1018 FdoExtension->DeviceObject));
1019 FREE_POOL(modeData);
1020 return STATUS_NOT_SUPPORTED;
1021 }
1022
1023 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskEnableInfoExceptions: DOES support SMART for device %p\n",
1024 FdoExtension->DeviceObject));
1025
1026 //
1027 // At the very least, the DEXCPT bit must be changeable.
1028 // If it's not, bail out now.
1029 //
1030 if (pageData->Dexcpt == 0) {
1031 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskEnableInfoExceptions: does NOT support DEXCPT bit for device %p\n",
1032 FdoExtension->DeviceObject));
1033 FREE_POOL(modeData);
1034 return STATUS_NOT_SUPPORTED;
1035 }
1036
1037 //
1038 // Cache away which values are changeable.
1039 //
1040 RtlCopyMemory(&changeablePageData, pageData, sizeof(MODE_INFO_EXCEPTIONS));
1041
1042 //
1043 // Now get the current values.
1044 //
1045 status = DiskGetModePage(FdoExtension->DeviceObject,
1047 0, // Page Control = 0 indicates we want current values.
1048 modeData,
1049 &modeDataSize,
1050 (PVOID*)&pageData);
1051
1052 if (!NT_SUCCESS(status) || pageData == NULL) {
1053 //
1054 // At this point we know the device supports this mode page so
1055 // assert if something goes wrong here.
1056 //
1057 NT_ASSERT(NT_SUCCESS(status) && pageData);
1058 FREE_POOL(modeData);
1059 return STATUS_NOT_SUPPORTED;
1060 }
1061
1062 //
1063 // If the device is currently configured to not report any informational
1064 // exceptions and we cannot change the value of that field, there's
1065 // nothing to be done.
1066 //
1067 if (pageData->ReportMethod == 0 && changeablePageData.ReportMethod == 0) {
1068 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskEnableInfoExceptions: MRIE field is 0 and is not changeable for device %p\n",
1069 FdoExtension->DeviceObject));
1070 FREE_POOL(modeData);
1071 return STATUS_NOT_SUPPORTED;
1072 }
1073
1074 //
1075 // If the PERF bit is changeable, set it now.
1076 //
1077 if (changeablePageData.Perf) {
1078 pageData->Perf = diskData->AllowFPPerfHit ? 0 : 1;
1079 }
1080
1081 //
1082 // If the MRIE field is changeable, set it to 4 so that informational
1083 // exceptions get reported with the "Recovered Error" sense key.
1084 //
1085 if (changeablePageData.ReportMethod) {
1086 pageData->ReportMethod = 4;
1087 }
1088
1089 //
1090 // Finally, set the DEXCPT bit appropriately to enable/disable
1091 // informational exception reporting and send the Mode Select.
1092 //
1093 pageData->Dexcpt = !Enable;
1094
1095 status = ClassModeSelect(FdoExtension->DeviceObject,
1096 (PCHAR)modeData,
1097 modeDataSize,
1098 pageData->PSBit);
1099
1100 //
1101 // Update the failure prediction state. Note that for this particular
1102 // mode FailurePredictionNone is used when it's not enabled.
1103 //
1104 if (NT_SUCCESS(status)) {
1105 if (Enable) {
1107 diskData->FailurePredictionEnabled = TRUE;
1108 } else {
1110 diskData->FailurePredictionEnabled = FALSE;
1111 }
1112 }
1113
1114 FREE_POOL(modeData);
1115
1116 return status;
1117}
#define MODE_DATA_SIZE
Definition: cdrom.h:691
NTSTATUS DiskGetModePage(_In_ PDEVICE_OBJECT Fdo, _In_ UCHAR PageMode, _In_ UCHAR PageControl, _In_ PMODE_PARAMETER_HEADER ModeData, _Inout_ PULONG ModeDataSize, _Out_ PVOID *PageData)
Definition: diskwmi.c:903
NTSTATUS NTAPI ClassModeSelect(_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSelectBuffer, _In_ ULONG Length, _In_ BOOLEAN SavePages)
Definition: class.c:6873
#define DISK_TAG_INFO_EXCEPTION
Definition: disk.h:55
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define MODE_PAGE_FAULT_REPORTING
Definition: scsi.h:218
BOOLEAN AllowFPPerfHit
Definition: disk.h:332
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

Referenced by DiskIoctlEnableFailurePrediction().

◆ DiskFdoExecuteWmiMethod()

NTSTATUS NTAPI DiskFdoExecuteWmiMethod ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN ULONG  GuidIndex,
IN ULONG  MethodId,
IN ULONG  InBufferSize,
IN ULONG  OutBufferSize,
IN PUCHAR  Buffer 
)

Definition at line 3045 of file diskwmi.c.

3088{
3089 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
3090 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
3091 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
3092 ULONG sizeNeeded = 0;
3094
3095 PAGED_CODE();
3096
3097 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskExecuteWmiMethod, DeviceObject %p, Irp %p, Guid Id %d, MethodId %d\n"
3098 " InBufferSize %#x, OutBufferSize %#x, Buffer %p\n",
3101
3102 switch(GuidIndex)
3103 {
3105 {
3106
3109 (diskData->FailurePredictionCapability ==
3111 (diskData->FailurePredictionCapability ==
3113
3114
3115 switch(MethodId)
3116 {
3117 //
3118 // void AllowPerformanceHit([in] boolean Allow)
3119 //
3121 {
3122 BOOLEAN allowPerfHit;
3123
3124 sizeNeeded = 0;
3125 if (InBufferSize >= sizeof(BOOLEAN))
3126 {
3128
3129 allowPerfHit = *((PBOOLEAN)Buffer);
3130 if (diskData->AllowFPPerfHit != allowPerfHit)
3131 {
3132 diskData->AllowFPPerfHit = allowPerfHit;
3133 if (diskData->FailurePredictionCapability ==
3135 {
3136 MODE_INFO_EXCEPTIONS modeInfo;
3137
3139 &modeInfo);
3140 if (NT_SUCCESS(status))
3141 {
3142 modeInfo.Perf = allowPerfHit ? 0 : 1;
3144 &modeInfo);
3145 }
3146 }
3147 else
3148 {
3150 }
3151 }
3152
3153 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskFdoWmiExecuteMethod: AllowPerformanceHit %x for device %p --> %lx\n",
3154 allowPerfHit,
3155 fdoExtension->DeviceObject,
3156 status));
3157 } else {
3159 }
3160 break;
3161 }
3162
3163 //
3164 // void EnableDisableHardwareFailurePrediction([in] boolean Enable)
3165 //
3167 {
3169
3170 sizeNeeded = 0;
3171 if (InBufferSize >= sizeof(BOOLEAN))
3172 {
3174 enable = *((PBOOLEAN)Buffer);
3175 if (!enable)
3176 {
3177 //
3178 // If we are disabling we need to also disable
3179 // polling
3180 //
3182 fdoExtension,
3183 enable,
3184 0);
3185 }
3186
3188 fdoExtension,
3189 enable);
3190
3191 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskFdoWmiExecuteMethod: EnableDisableHardwareFailurePrediction: %x for device %p --> %lx\n",
3192 enable,
3193 fdoExtension->DeviceObject,
3194 status));
3195 } else {
3197 }
3198 break;
3199 }
3200
3201 //
3202 // void EnableDisableFailurePredictionPolling(
3203 // [in] uint32 Period,
3204 // [in] boolean Enable)
3205 //
3207 {
3209 ULONG period;
3210
3211 sizeNeeded = 0;
3212 if (InBufferSize >= (sizeof(ULONG) + sizeof(BOOLEAN)))
3213 {
3214 period = *((PULONG)Buffer);
3215 Buffer += sizeof(ULONG);
3216 enable = *((PBOOLEAN)Buffer);
3217
3219 fdoExtension,
3220 enable,
3221 period);
3222
3223 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskFdoWmiExecuteMethod: EnableDisableFailurePredictionPolling: %x %x for device %p --> %lx\n",
3224 enable,
3225 period,
3226 fdoExtension->DeviceObject,
3227 status));
3228 } else {
3230 }
3231 break;
3232 }
3233
3234 //
3235 // void GetFailurePredictionCapability([out] uint32 Capability)
3236 //
3238 {
3239 sizeNeeded = sizeof(ULONG);
3240 if (OutBufferSize >= sizeNeeded)
3241 {
3244 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskFdoWmiExecuteMethod: GetFailurePredictionCapability: %x for device %p --> %lx\n",
3246 fdoExtension->DeviceObject,
3247 status));
3248 } else {
3250 }
3251 break;
3252 }
3253
3254 //
3255 // void EnableOfflineDiags([out] boolean Success);
3256 //
3257 case EnableOfflineDiags:
3258 {
3259 sizeNeeded = sizeof(BOOLEAN);
3260 if (OutBufferSize >= sizeNeeded)
3261 {
3262 if (diskData->FailurePredictionCapability ==
3264 {
3265 //
3266 // Initiate or resume offline diagnostics.
3267 // This may cause a loss of performance
3268 // to the disk, but mayincrease the amount
3269 // of disk checking.
3270 //
3271 status = DiskExecuteSmartDiagnostics(fdoExtension,
3272 0);
3273
3274 } else {
3276 }
3277
3279
3280 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskFdoWmiExecuteMethod: EnableOfflineDiags for device %p --> %lx\n",
3281 fdoExtension->DeviceObject,
3282 status));
3283 } else {
3285 }
3286 break;
3287 }
3288
3289 //
3290 // void ReadLogSectors([in] uint8 LogAddress,
3291 // [in] uint8 SectorCount,
3292 // [out] uint32 Length,
3293 // [out, WmiSizeIs("Length")] uint8 LogSectors[]
3294 // );
3295 //
3296 case ReadLogSectors:
3297 {
3298 if (diskData->FailurePredictionCapability ==
3300 {
3301 if (InBufferSize >= sizeof(READ_LOG_SECTORS_IN))
3302 {
3303 PREAD_LOG_SECTORS_IN inParams;
3304 PREAD_LOG_SECTORS_OUT outParams;
3305 ULONG readSize;
3306
3307 inParams = (PREAD_LOG_SECTORS_IN)Buffer;
3308 readSize = inParams->SectorCount * SMART_LOG_SECTOR_SIZE;
3310 LogSectors) + readSize;
3311
3312 if (OutBufferSize >= sizeNeeded)
3313 {
3314 outParams = (PREAD_LOG_SECTORS_OUT)Buffer;
3315 status = DiskReadSmartLog(fdoExtension,
3316 inParams->SectorCount,
3317 inParams->LogAddress,
3318 outParams->LogSectors);
3319
3320 if (NT_SUCCESS(status))
3321 {
3322 outParams->Length = readSize;
3323 } else {
3324 //
3325 // SMART command failure is
3326 // indicated by successful
3327 // execution, but no data returned
3328 //
3329 outParams->Length = 0;
3331 }
3332 } else {
3334 }
3335
3336 } else {
3338 }
3339 } else {
3341 }
3342 break;
3343 }
3344
3345 // void WriteLogSectors([in] uint8 LogAddress,
3346 // [in] uint8 SectorCount,
3347 // [in] uint32 Length,
3348 // [in, WmiSizeIs("Length")] uint8 LogSectors[],
3349 // [out] boolean Success
3350 // );
3351 case WriteLogSectors:
3352 {
3353 if (diskData->FailurePredictionCapability ==
3355 {
3357 LogSectors))
3358 {
3359 PWRITE_LOG_SECTORS_IN inParams;
3360 PWRITE_LOG_SECTORS_OUT outParams;
3361 ULONG writeSize;
3362
3363 inParams = (PWRITE_LOG_SECTORS_IN)Buffer;
3364 writeSize = inParams->SectorCount * SMART_LOG_SECTOR_SIZE;
3366 LogSectors) +
3367 writeSize))
3368 {
3369 sizeNeeded = sizeof(WRITE_LOG_SECTORS_OUT);
3370
3371 if (OutBufferSize >= sizeNeeded)
3372 {
3373 outParams = (PWRITE_LOG_SECTORS_OUT)Buffer;
3374 status = DiskWriteSmartLog(fdoExtension,
3375 inParams->SectorCount,
3376 inParams->LogAddress,
3377 inParams->LogSectors);
3378
3379 if (NT_SUCCESS(status))
3380 {
3381 outParams->Success = TRUE;
3382 } else {
3383 outParams->Success = FALSE;
3385 }
3386 } else {
3388 }
3389 } else {
3391 }
3392 } else {
3394 }
3395 } else {
3397 }
3398 break;
3399 }
3400
3401 // void ExecuteSelfTest([in] uint8 Subcommand,
3402 // [out,
3403 // Values{"0", "1", "2"},
3404 // ValueMap{"Successful Completion",
3405 // "Captive Mode Required",
3406 // "Unsuccessful Completion"}
3407 // ]
3408 // uint32 ReturnCode);
3409 case ExecuteSelfTest:
3410 {
3411 if (diskData->FailurePredictionCapability ==
3413 {
3414 if (InBufferSize >= sizeof(EXECUTE_SELF_TEST_IN))
3415 {
3416 sizeNeeded = sizeof(EXECUTE_SELF_TEST_OUT);
3417 if (OutBufferSize >= sizeNeeded)
3418 {
3419 PEXECUTE_SELF_TEST_IN inParam;
3420 PEXECUTE_SELF_TEST_OUT outParam;
3421
3422 inParam = (PEXECUTE_SELF_TEST_IN)Buffer;
3423 outParam = (PEXECUTE_SELF_TEST_OUT)Buffer;
3424
3426 {
3427 status = DiskExecuteSmartDiagnostics(fdoExtension,
3428 inParam->Subcommand);
3429 if (NT_SUCCESS(status))
3430 {
3431 //
3432 // Return self test executed
3433 // without a problem
3434 //
3435 outParam->ReturnCode = 0;
3436 } else {
3437 //
3438 // Return Self test execution
3439 // failed status
3440 //
3441 outParam->ReturnCode = 2;
3443 }
3444 } else {
3445 //
3446 // If self test subcommand requires
3447 // captive mode then return that
3448 // status
3449 //
3450 outParam->ReturnCode = 1;
3452 }
3453
3454 } else {
3456 }
3457
3458 } else {
3460 }
3461 } else {
3463 }
3464
3465 break;
3466 }
3467
3468 default :
3469 {
3470 sizeNeeded = 0;
3472 break;
3473 }
3474 }
3475
3476 break;
3477 }
3478
3479 case DiskGeometryGuid:
3480 case SmartStatusGuid:
3481 case SmartDataGuid:
3482 case SmartEventGuid:
3485 {
3486 sizeNeeded = 0;
3488 break;
3489 }
3490
3491 default:
3492 {
3493 sizeNeeded = 0;
3495 }
3496 }
3497
3498 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskExecuteMethod Device %p, Irp %p returns %lx\n",
3500
3502 Irp,
3503 status,
3504 sizeNeeded,
3506
3507 return status;
3508}
Definition: bufpool.h:45
_In_ PIRP _In_ ULONG GuidIndex
Definition: classpnp.h:419
enum FAILURE_PREDICTION_METHOD * PFAILURE_PREDICTION_METHOD
SCSIPORT_API NTSTATUS NTAPI ClassWmiCompleteRequest(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _In_ NTSTATUS Status, _In_ ULONG BufferUsed, _In_ CCHAR PriorityBoost)
Definition: classwmi.c:1009
#define SmartDataGuid
Definition: diskwmi.c:142
#define ScsiInfoExceptionsGuid
Definition: diskwmi.c:152
#define SmartEventGuid
Definition: diskwmi.c:150
#define SmartPerformFunction
Definition: diskwmi.c:143
NTSTATUS DiskWriteSmartLog(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN UCHAR SectorCount, IN UCHAR LogAddress, IN PUCHAR Buffer)
Definition: diskwmi.c:429
#define GetFailurePredictionCapability
Definition: diskwmi.c:147
#define EnableDisableFailurePredictionPolling
Definition: diskwmi.c:146
#define EnableDisableHardwareFailurePrediction
Definition: diskwmi.c:145
#define EnableOfflineDiags
Definition: diskwmi.c:148
#define DiskGeometryGuid
Definition: diskwmi.c:140
#define SmartStatusGuid
Definition: diskwmi.c:141
static NTSTATUS DiskExecuteSmartDiagnostics(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, UCHAR Subcommand)
Definition: diskwmi.c:359
#define SmartThresholdsGuid
Definition: diskwmi.c:151
#define AllowDisallowPerformanceHit
Definition: diskwmi.c:144
NTSTATUS DiskEnableDisableFailurePredictPolling(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable, ULONG PollTimeInSeconds)
Definition: diskwmi.c:1193
NTSTATUS DiskReadSmartLog(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN UCHAR SectorCount, IN UCHAR LogAddress, OUT PUCHAR Buffer)
Definition: diskwmi.c:379
NTSTATUS DiskGetInfoExceptionInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMODE_INFO_EXCEPTIONS ReturnPageData)
Definition: disk.c:2896
NTSTATUS DiskSetInfoExceptionInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMODE_INFO_EXCEPTIONS PageData)
Definition: disk.c:2985
#define DiskIsValidSmartSelfTest(Subcommand)
Definition: disk.h:619
GLboolean enable
Definition: glext.h:11120
#define SMART_LOG_SECTOR_SIZE
Definition: ntdddisk.h:734
#define STATUS_WMI_ITEMID_NOT_FOUND
Definition: ntstatus.h:778
#define STATUS_WMI_GUID_NOT_FOUND
Definition: ntstatus.h:776
#define BOOLEAN
Definition: pedump.c:73
long LONG
Definition: pedump.c:60
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:871
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ ULONG OutBufferSize
Definition: wdfwmi.h:87
_In_ ULONG InBufferSize
Definition: wdfwmi.h:106
_In_ ULONG MethodId
Definition: wdfwmi.h:142
#define ReadLogSectors
Definition: wmidata.h:3374
struct _EXECUTE_SELF_TEST_IN * PEXECUTE_SELF_TEST_IN
#define ExecuteSelfTest
Definition: wmidata.h:3407
struct _WRITE_LOG_SECTORS_OUT WRITE_LOG_SECTORS_OUT
struct _WRITE_LOG_SECTORS_IN * PWRITE_LOG_SECTORS_IN
#define WriteLogSectors
Definition: wmidata.h:3387
struct _READ_LOG_SECTORS_IN * PREAD_LOG_SECTORS_IN
struct _EXECUTE_SELF_TEST_OUT * PEXECUTE_SELF_TEST_OUT
struct _EXECUTE_SELF_TEST_OUT EXECUTE_SELF_TEST_OUT
struct _WRITE_LOG_SECTORS_OUT * PWRITE_LOG_SECTORS_OUT
struct _READ_LOG_SECTORS_OUT * PREAD_LOG_SECTORS_OUT
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by DriverEntry().

◆ DiskFdoProcessError()

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

Definition at line 2276 of file disk.c.

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

Referenced by DriverEntry().

◆ DiskFdoQueryWmiDataBlock()

NTSTATUS NTAPI DiskFdoQueryWmiDataBlock ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN ULONG  GuidIndex,
IN ULONG  BufferAvail,
OUT PUCHAR  Buffer 
)

Definition at line 2638 of file diskwmi.c.

2674{
2676 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
2677 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
2678 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
2679 ULONG sizeNeeded;
2680
2681 PAGED_CODE();
2682
2683 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskQueryWmiDataBlock, Device %p, Irp %p, GuiIndex %d\n"
2684 " BufferAvail %lx Buffer %p\n",
2687
2688 switch (GuidIndex)
2689 {
2690 case DiskGeometryGuid:
2691 {
2692 sizeNeeded = sizeof(DISK_GEOMETRY);
2693 if (BufferAvail >= sizeNeeded)
2694 {
2695 if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
2696 {
2697 //
2698 // Issue ReadCapacity to update device extension
2699 // with information for current media.
2700 status = DiskReadDriveCapacity(commonExtension->PartitionZeroExtension->DeviceObject);
2701
2702 //
2703 // Note whether the drive is ready.
2704 diskData->ReadyStatus = status;
2705
2706 if (!NT_SUCCESS(status))
2707 {
2708 break;
2709 }
2710 }
2711
2712 //
2713 // Copy drive geometry information from device extension.
2715 &(fdoExtension->DiskGeometry),
2716 sizeof(DISK_GEOMETRY));
2717
2719 } else {
2721 }
2722 break;
2723 }
2724
2725 case SmartStatusGuid:
2726 {
2727 PSTORAGE_FAILURE_PREDICT_STATUS diskSmartStatus;
2728
2730
2731 sizeNeeded = sizeof(STORAGE_FAILURE_PREDICT_STATUS);
2732 if (BufferAvail >= sizeNeeded)
2733 {
2734 STORAGE_PREDICT_FAILURE checkFailure;
2735
2736 diskSmartStatus = (PSTORAGE_FAILURE_PREDICT_STATUS)Buffer;
2737
2738 status = DiskSendFailurePredictIoctl(fdoExtension,
2739 &checkFailure);
2740
2741 if (NT_SUCCESS(status))
2742 {
2743 if (diskData->FailurePredictionCapability ==
2745 {
2746 diskSmartStatus->Reason = *((PULONG)checkFailure.VendorSpecific);
2747 } else {
2748 diskSmartStatus->Reason = 0; // unknown
2749 }
2750
2751 diskSmartStatus->PredictFailure = (checkFailure.PredictFailure != 0);
2752 }
2753 } else {
2755 }
2756 break;
2757 }
2758
2759 case SmartDataGuid:
2760 {
2761 PSTORAGE_FAILURE_PREDICT_DATA diskSmartData;
2762
2765 (diskData->FailurePredictionCapability ==
2767
2768 sizeNeeded = sizeof(STORAGE_FAILURE_PREDICT_DATA);
2769 if (BufferAvail >= sizeNeeded)
2770 {
2772
2773 diskSmartData = (PSTORAGE_FAILURE_PREDICT_DATA)Buffer;
2774
2775 status = DiskSendFailurePredictIoctl(fdoExtension,
2776 checkFailure);
2777
2778 if (NT_SUCCESS(status))
2779 {
2780 diskSmartData->Length = 512;
2781 }
2782 } else {
2784 }
2785
2786 break;
2787 }
2788
2790 {
2791 PSTORAGE_FAILURE_PREDICT_THRESHOLDS diskSmartThresholds;
2792
2795
2796 sizeNeeded = sizeof(STORAGE_FAILURE_PREDICT_THRESHOLDS);
2797 if (BufferAvail >= sizeNeeded)
2798 {
2799 diskSmartThresholds = (PSTORAGE_FAILURE_PREDICT_THRESHOLDS)Buffer;
2801 diskSmartThresholds);
2802 } else {
2804 }
2805
2806 break;
2807 }
2808
2810 {
2811 sizeNeeded = 0;
2813 break;
2814 }
2815
2817 {
2818 PSTORAGE_SCSI_INFO_EXCEPTIONS infoExceptions;
2819 MODE_INFO_EXCEPTIONS modeInfo;
2820
2823
2824 sizeNeeded = sizeof(STORAGE_SCSI_INFO_EXCEPTIONS);
2825 if (BufferAvail >= sizeNeeded)
2826 {
2827 infoExceptions = (PSTORAGE_SCSI_INFO_EXCEPTIONS)Buffer;
2829 &modeInfo);
2830 if (NT_SUCCESS(status))
2831 {
2832 infoExceptions->PageSavable = modeInfo.PSBit;
2833 infoExceptions->Flags = modeInfo.Flags;
2834 infoExceptions->MRIE = modeInfo.ReportMethod;
2835 infoExceptions->Padding = 0;
2836 REVERSE_BYTES(&infoExceptions->IntervalTimer,
2837 &modeInfo.IntervalTimer);
2838 REVERSE_BYTES(&infoExceptions->ReportCount,
2839 &modeInfo.ReportCount)
2840 }
2841 } else {
2843 }
2844
2845 break;
2846 }
2847
2848 default:
2849 {
2850 sizeNeeded = 0;
2852 }
2853 }
2854 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskQueryWmiDataBlock Device %p, Irp %p returns %lx\n",
2856
2858 Irp,
2859 status,
2860 sizeNeeded,
2862
2863 return status;
2864}
_In_ PIRP _In_ ULONG _In_ ULONG BufferAvail
Definition: classpnp.h:420
NTSTATUS DiskReadFailurePredictThresholds(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_THRESHOLDS DiskSmartThresholds)
Definition: diskwmi.c:1417
#define DiskReadDriveCapacity(Fdo)
Definition: disk.h:818
struct _DISK_GEOMETRY DISK_GEOMETRY
struct _STORAGE_PREDICT_FAILURE * PSTORAGE_PREDICT_FAILURE
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:3465
NTSTATUS ReadyStatus
Definition: disk.h:319
UCHAR ReportCount[4]
Definition: scsi.h:3029
UCHAR IntervalTimer[4]
Definition: scsi.h:3028
UCHAR VendorSpecific[512]
Definition: ntddstor.h:501
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
struct _STORAGE_FAILURE_PREDICT_DATA * PSTORAGE_FAILURE_PREDICT_DATA
struct _STORAGE_FAILURE_PREDICT_STATUS * PSTORAGE_FAILURE_PREDICT_STATUS
struct _STORAGE_SCSI_INFO_EXCEPTIONS * PSTORAGE_SCSI_INFO_EXCEPTIONS
struct _STORAGE_FAILURE_PREDICT_THRESHOLDS STORAGE_FAILURE_PREDICT_THRESHOLDS
struct _STORAGE_FAILURE_PREDICT_STATUS STORAGE_FAILURE_PREDICT_STATUS
struct _STORAGE_FAILURE_PREDICT_THRESHOLDS * PSTORAGE_FAILURE_PREDICT_THRESHOLDS
struct _STORAGE_FAILURE_PREDICT_DATA STORAGE_FAILURE_PREDICT_DATA
struct _STORAGE_SCSI_INFO_EXCEPTIONS STORAGE_SCSI_INFO_EXCEPTIONS

Referenced by DriverEntry().

◆ DiskFdoQueryWmiRegInfo()

NTSTATUS NTAPI DiskFdoQueryWmiRegInfo ( IN PDEVICE_OBJECT  DeviceObject,
OUT ULONG RegFlags,
OUT PUNICODE_STRING  InstanceName 
)

Definition at line 2479 of file diskwmi.c.

2517{
2518 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
2519 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
2520
2521 PAGED_CODE();
2523
2526
2527 switch (diskData->FailurePredictionCapability)
2528 {
2530 {
2532 //
2533 // Fall Through
2534 //
2535 }
2537 {
2542
2543 break;
2544 }
2545
2547 {
2553 break;
2554 }
2555
2556
2557 default:
2558 {
2563 break;
2564 }
2565 }
2566
2567 //
2568 // Use devnode for FDOs
2570
2571 return STATUS_SUCCESS;
2572}
_Out_ ULONG * RegFlags
Definition: classpnp.h:403
GUIDREGINFO DiskWmiFdoGuidList[]
Definition: diskwmi.c:92
_Must_inspect_result_ _Inout_ PFLT_VOLUME _In_opt_ PCUNICODE_STRING InstanceName
Definition: fltkernel.h:1163
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define WMIREG_FLAG_INSTANCE_PDO
Definition: wmistr.h:69
#define WMIREG_FLAG_REMOVE_GUID
Definition: wmistr.h:70
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by DiskFdoQueryWmiRegInfoEx(), and DriverEntry().

◆ DiskFdoQueryWmiRegInfoEx()

NTSTATUS NTAPI DiskFdoQueryWmiRegInfoEx ( IN PDEVICE_OBJECT  DeviceObject,
OUT ULONG RegFlags,
OUT PUNICODE_STRING  InstanceName,
OUT PUNICODE_STRING  MofName 
)

Definition at line 2577 of file diskwmi.c.

2620{
2622
2623 UNREFERENCED_PARAMETER(MofName);
2624
2626 RegFlags,
2627 InstanceName);
2628
2629 //
2630 // Leave MofName alone since disk doesn't have one
2631 //
2632 return(status);
2633}
NTSTATUS NTAPI DiskFdoQueryWmiRegInfo(IN PDEVICE_OBJECT DeviceObject, OUT ULONG *RegFlags, OUT PUNICODE_STRING InstanceName)
Definition: diskwmi.c:2479

Referenced by DriverEntry().

◆ DiskFdoSetWmiDataBlock()

NTSTATUS NTAPI DiskFdoSetWmiDataBlock ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN ULONG  GuidIndex,
IN ULONG  BufferSize,
IN PUCHAR  Buffer 
)

Definition at line 2869 of file diskwmi.c.

2904{
2906 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
2907 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
2908 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
2909
2910 PAGED_CODE();
2911
2912 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskSetWmiDataBlock, Device %p, Irp %p, GuiIndex %d\n"
2913 " BufferSize %#x Buffer %p\n",
2916
2918 {
2919 PSTORAGE_SCSI_INFO_EXCEPTIONS infoExceptions;
2920 MODE_INFO_EXCEPTIONS modeInfo = {0};
2921
2923 {
2924 infoExceptions = (PSTORAGE_SCSI_INFO_EXCEPTIONS)Buffer;
2925
2927 modeInfo.PageLength = sizeof(MODE_INFO_EXCEPTIONS) - 2;
2928
2929 modeInfo.PSBit = 0;
2930 modeInfo.Flags = infoExceptions->Flags;
2931
2932 modeInfo.ReportMethod = infoExceptions->MRIE;
2933
2934 REVERSE_BYTES(&modeInfo.IntervalTimer[0],
2935 &infoExceptions->IntervalTimer);
2936
2937 REVERSE_BYTES(&modeInfo.ReportCount[0],
2938 &infoExceptions->ReportCount);
2939
2940 if (modeInfo.Perf == 1)
2941 {
2942 diskData->AllowFPPerfHit = FALSE;
2943 } else {
2944 diskData->AllowFPPerfHit = TRUE;
2945 }
2946
2948 &modeInfo);
2949 } else {
2951 }
2952
2953 } else if (GuidIndex <= SmartThresholdsGuid)
2954 {
2956 } else {
2958 }
2959
2960 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskSetWmiDataBlock Device %p, Irp %p returns %lx\n",
2962
2964 Irp,
2965 status,
2966 0,
2968
2969 return status;
2970}
#define STATUS_WMI_READ_ONLY
Definition: ntstatus.h:818
struct _MODE_INFO_EXCEPTIONS MODE_INFO_EXCEPTIONS
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

Referenced by DriverEntry().

◆ DiskFdoSetWmiDataItem()

NTSTATUS NTAPI DiskFdoSetWmiDataItem ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN ULONG  GuidIndex,
IN ULONG  DataItemId,
IN ULONG  BufferSize,
IN PUCHAR  Buffer 
)

Definition at line 2975 of file diskwmi.c.

3013{
3015
3016 PAGED_CODE();
3017
3018 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskSetWmiDataItem, Device %p, Irp %p, GuiIndex %d, DataId %d\n"
3019 " BufferSize %#x Buffer %p\n",
3022
3024 {
3026 } else {
3028 }
3029
3030 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskSetWmiDataItem Device %p, Irp %p returns %lx\n",
3032
3034 Irp,
3035 status,
3036 0,
3038
3039 return status;
3040}
_In_ ULONG DataItemId
Definition: wdfwmi.h:123

Referenced by DriverEntry().

◆ DiskFlushDispatch()

VOID DiskFlushDispatch ( IN PDEVICE_OBJECT  Fdo,
IN PDISK_GROUP_CONTEXT  FlushContext 
)

Definition at line 1534 of file disk.c.

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

Referenced by DiskShutdownFlush().

◆ DiskGenerateDeviceName()

NTSTATUS DiskGenerateDeviceName ( IN ULONG  DeviceNumber,
OUT PCCHAR *  RawName 
)

Definition at line 612 of file pnp.c.

641{
642 CHAR rawName[64] = { 0 };
644
645 PAGED_CODE();
646
647 status = RtlStringCchPrintfA(rawName, sizeof(rawName) - 1, FDO_NAME_FORMAT, DeviceNumber,
649 if (!NT_SUCCESS(status)) {
650 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskGenerateDeviceName: Format FDO name failed with error: 0x%X\n", status));
651 return status;
652 }
653
655 strlen(rawName) + 1,
657
658 if(*RawName == NULL) {
660 }
661
662 status = RtlStringCchCopyA(*RawName, strlen(rawName) + 1, rawName);
663 if (!NT_SUCCESS(status)) {
664 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskGenerateDeviceName: Device name copy failed with error: 0x%X\n", status));
665 FREE_POOL(*RawName);
666 return status;
667 }
668
669 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskGenerateDeviceName: generated \"%s\"\n", rawName));
670
671 return STATUS_SUCCESS;
672}
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1230
#define DISK_TAG_NAME
Definition: disk.h:64
#define FDO_NAME_FORMAT
ULONG diskDeviceSequenceNumber
Definition: pnp.c:35
#define PagedPool
Definition: env_spec_w32.h:308
NTSTRSAFEAPI RtlStringCchCopyA(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:110
NTSTRSAFEVAPI RtlStringCchPrintfA(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1085
char CHAR
Definition: xmlstorage.h:175

Referenced by DiskCreateFdo().

◆ DiskGetCacheInformation()

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

Definition at line 3019 of file disk.c.

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

Referenced by DiskIoctlGetCacheInformation(), and DiskStartFdo().

◆ DiskGetInfoExceptionInformation()

NTSTATUS DiskGetInfoExceptionInformation ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
OUT PMODE_INFO_EXCEPTIONS  ReturnPageData 
)

◆ DiskGetModePage()

NTSTATUS DiskGetModePage ( _In_ PDEVICE_OBJECT  Fdo,
_In_ UCHAR  PageMode,
_In_ UCHAR  PageControl,
_In_ PMODE_PARAMETER_HEADER  ModeData,
_Inout_ PULONG  ModeDataSize,
_Out_ PVOID PageData 
)

Definition at line 903 of file diskwmi.c.

911{
912 ULONG size = 0;
913 PVOID pageData = NULL;
914
915 PAGED_CODE();
916
917 if (ModeData == NULL ||
918 ModeDataSize == NULL ||
919 *ModeDataSize < sizeof(MODE_PARAMETER_HEADER) ||
920 PageData == NULL) {
922 }
923
924 RtlZeroMemory (ModeData, *ModeDataSize);
925
927 (PCHAR) ModeData,
928 *ModeDataSize,
929 PageMode,
931
932 if (size < sizeof(MODE_PARAMETER_HEADER)) {
933
934 //
935 // Retry the request in case of a check condition.
936 //
938 (PCHAR) ModeData,
939 *ModeDataSize,
940 PageMode,
942
943 if (size < sizeof(MODE_PARAMETER_HEADER)) {
944 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_WMI, "DiskGetModePage: Mode Sense for Page Mode %d with Page Control %d failed\n",
946 *ModeDataSize = 0;
948 }
949 }
950
951 //
952 // If the length is greater than length indicated by the mode data reset
953 // the data to the mode data.
954 //
955 if (size > (ULONG) (ModeData->ModeDataLength + 1)) {
956 size = ModeData->ModeDataLength + 1;
957 }
958
959 *ModeDataSize = size;
960
961 //
962 // Find the mode page
963 //
964 pageData = ClassFindModePage((PCHAR) ModeData,
965 size,
966 PageMode,
967 TRUE);
968
969 if (pageData) {
970 *PageData = pageData;
971 return STATUS_SUCCESS;
972 } else {
973 *PageData = NULL;
975 }
976}
_In_ size_t _In_ UCHAR PageMode
Definition: cdrom.h:1326
_In_ ULONG _In_ UCHAR _In_ UCHAR PageControl
Definition: cdrom.h:1319
ULONG NTAPI ClassModeSenseEx(_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode, _In_ UCHAR PageControl)
Definition: class.c:6656
GLsizeiptr size
Definition: glext.h:5919

Referenced by DiskEnableInfoExceptions().

◆ DiskInitFdo()

NTSTATUS NTAPI DiskInitFdo ( IN PDEVICE_OBJECT  Fdo)

Definition at line 202 of file pnp.c.

223{
224 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
225 PDISK_DATA diskData = (PDISK_DATA) fdoExtension->CommonExtension.DriverData;
226
227 ULONG srbFlags = 0;
228 ULONG timeOut = 0;
229 ULONG bytesPerSector;
230
231 PULONG dmSkew;
232
234
235 PAGED_CODE();
236
237 //
238 // Build the lookaside list for srb's for the physical disk. Should only
239 // need a couple. If this fails then we don't have an emergency SRB so
240 // fail the call to initialize.
241 //
242
243 ClassInitializeSrbLookasideList((PCOMMON_DEVICE_EXTENSION) fdoExtension,
245
246 if (fdoExtension->DeviceDescriptor->RemovableMedia)
247 {
248 SET_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA);
249 }
250
251 //
252 // Initialize the srb flags.
253 //
254
255 //
256 // Because all requests share a common sense buffer, it is possible
257 // for the buffer to be overwritten if the port driver completes
258 // multiple failed requests that require a request sense before the
259 // class driver's completion routine can consume the data in the buffer.
260 // To prevent this, we allow the port driver to allocate a unique sense
261 // buffer each time it needs one. We are responsible for freeing this
262 // buffer. This also allows the adapter to be configured to support
263 // additional sense data beyond the minimum 18 bytes.
264 //
265
267
268 if (fdoExtension->DeviceDescriptor->CommandQueueing &&
269 fdoExtension->AdapterDescriptor->CommandQueueing) {
270
272
273 }
274
275 //
276 // Look for controllers that require special flags.
277 //
278
279 ClassScanForSpecial(fdoExtension, DiskBadControllers, DiskSetSpecialHacks);
280
281 //
282 // Clear buffer for drive geometry.
283 //
284
285 RtlZeroMemory(&(fdoExtension->DiskGeometry),
286 sizeof(DISK_GEOMETRY));
287
288 //
289 // Allocate request sense buffer.
290 //
291
292 fdoExtension->SenseData = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
295
296 if (fdoExtension->SenseData == NULL) {
297
298 //
299 // The buffer can not be allocated.
300 //
301
302 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskInitFdo: Can not allocate request sense buffer\n"));
303
305 return status;
306 }
307
308 //
309 // Set the buffer size of SenseData
310 //
311
313
314 //
315 // Physical device object will describe the entire
316 // device, starting at byte offset 0.
317 //
318
319 fdoExtension->CommonExtension.StartingOffset.QuadPart = (LONGLONG)(0);
320
321 //
322 // Set timeout value in seconds.
323 //
324 if ( (fdoExtension->MiniportDescriptor != NULL) &&
325 (fdoExtension->MiniportDescriptor->IoTimeoutValue > 0) ) {
326 //
327 // use the value set by Storport miniport driver
328 //
329 fdoExtension->TimeOutValue = fdoExtension->MiniportDescriptor->IoTimeoutValue;
330 } else {
331 //
332 // get timeout value from registry
333 //
334 timeOut = ClassQueryTimeOutRegistryValue(Fdo);
335
336 if (timeOut) {
337 fdoExtension->TimeOutValue = timeOut;
338 } else {
339 fdoExtension->TimeOutValue = SCSI_DISK_TIMEOUT;
340 }
341 }
342 //
343 // If this is a removable drive, build an entry in devicemap\scsi
344 // indicating it's physicaldriveN name, set up the appropriate
345 // update partitions routine and set the flags correctly.
346 // note: only do this after the timeout value is set, above.
347 //
348
349 if (TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
350
351 ClassUpdateInformationInRegistry( Fdo,
352 "PhysicalDrive",
353 fdoExtension->DeviceNumber,
354 NULL,
355 0);
356 //
357 // Enable media change notification for removable disks
358 //
359 ClassInitializeMediaChangeDetection(fdoExtension,
360 (PUCHAR)"Disk");
361
362 } else {
363
366
367 }
368
369 //
370 // The commands we send during the init could cause the flags to change
371 // in case of any error. Save the SRB flags locally and restore it at
372 // the end of this function, so that the class driver can get it.
373 //
374
375 srbFlags = fdoExtension->SrbFlags;
376
377
378 //
379 // Read the drive capacity. Don't use the disk version of the routine here
380 // since we don't know the disk signature yet - the disk version will
381 // attempt to determine the BIOS reported geometry.
382 //
383
385
386 //
387 // Set up sector size fields.
388 //
389 // Stack variables will be used to update
390 // the partition device extensions.
391 //
392 // The device extension field SectorShift is
393 // used to calculate sectors in I/O transfers.
394 //
395 // The DiskGeometry structure is used to service
396 // IOCTls used by the format utility.
397 //
398
399 bytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;
400
401 //
402 // Make sure sector size is not zero.
403 //
404
405 if (bytesPerSector == 0) {
406
407 //
408 // Default sector size for disk is 512.
409 //
410
411 bytesPerSector = fdoExtension->DiskGeometry.BytesPerSector = 512;
412 fdoExtension->SectorShift = 9;
413 }
414
415 //
416 // Determine is DM Driver is loaded on an IDE drive that is
417 // under control of Atapi - this could be either a crashdump or
418 // an Atapi device is sharing the controller with an IDE disk.
419 //
420
422 fdoExtension->DiskGeometry.BytesPerSector,
423 (ULONG)0x54,
424 (PVOID *)&dmSkew);
425
426 if (dmSkew) {
427
428 //
429 // Update the device extension, so that the call to IoReadPartitionTable
430 // will get the correct information. Any I/O to this disk will have
431 // to be skewed by *dmSkew sectors aka DMByteSkew.
432 //
433
434 fdoExtension->DMSkew = *dmSkew;
435 fdoExtension->DMActive = TRUE;
436 fdoExtension->DMByteSkew = fdoExtension->DMSkew * bytesPerSector;
437
438 FREE_POOL(dmSkew);
439 }
440
441#if defined(_X86_) || defined(_AMD64_)
442
443 //
444 // Try to read the signature off the disk and determine the correct drive
445 // geometry based on that. This requires rereading the disk size to get
446 // the cylinder count updated correctly.
447 //
448
449 if(!TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
450
451 DiskReadSignature(Fdo);
453
454 if (diskData->GeometrySource == DiskGeometryUnknown)
455 {
456 //
457 // Neither the BIOS nor the port driver could provide us with a reliable
458 // geometry. Before we use the default, look to see if it was partitioned
459 // under Windows NT4 [or earlier] and apply the one that was used back then
460 //
461
462 if (DiskIsNT4Geometry(fdoExtension))
463 {
464 diskData->RealGeometry = fdoExtension->DiskGeometry;
465 diskData->RealGeometry.SectorsPerTrack = 0x20;
466 diskData->RealGeometry.TracksPerCylinder = 0x40;
467 fdoExtension->DiskGeometry = diskData->RealGeometry;
468
469 diskData->GeometrySource = DiskGeometryFromNT4;
470 }
471 }
472 }
473
474#endif
475
477
478 //
479 // Get the SCSI address if it's available for use with SMART ioctls.
480 // SMART ioctls are used for failure prediction, so we need to get
481 // the SCSI address before initializing failure prediction.
482 //
483
484 {
485 PIRP irp;
487 IO_STATUS_BLOCK statusBlock = { 0 };
488
490
493 NULL,
494 0L,
495 &(diskData->ScsiAddress),
496 sizeof(SCSI_ADDRESS),
497 FALSE,
498 &event,
499 &statusBlock);
500
502
503 if(irp != NULL) {
504
506
507 if(status == STATUS_PENDING) {
509 Executive,
511 FALSE,
512 NULL);
513 status = statusBlock.Status;
514 }
515 }
516 }
517
518 //
519 // Determine the type of disk and enable failure prediction in the hardware
520 // and enable failure prediction polling.
521 //
522
523 if (InitSafeBootMode == 0) // __REACTOS__
524 {
525 DiskDetectFailurePrediction(fdoExtension,
528
530 {
531 //
532 // Cool, we've got some sort of failure prediction, enable it
533 // at the hardware and then enable polling for it
534 //
535
536 //
537 // By default we allow performance to be degradeded if failure
538 // prediction is enabled.
539 //
540
541 diskData->AllowFPPerfHit = TRUE;
542
543 //
544 // Enable polling only after Atapi and SBP2 add support for the new
545 // SRB flag that indicates that the request should not reset the
546 // drive spin down idle timer.
547 //
548
550 TRUE,
552
553 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskInitFdo: Failure Prediction Poll enabled as "
554 "%d for device %p, Status = %lx\n",
556 Fdo,
557 status));
558 }
559 } else {
560
561 //
562 // In safe boot mode we do not enable failure prediction, as perhaps
563 // it is the reason why normal boot does not work
564 //
565
567
568 }
569
570 //
571 // Initialize the verify mutex
572 //
573
575
576 //
577 // Initialize the flush group context
578 //
579
580 RtlZeroMemory(&diskData->FlushContext, sizeof(DISK_GROUP_CONTEXT));
581
584
587
588
589 //
590 // Restore the saved value
591 //
592 fdoExtension->SrbFlags = srbFlags;
593
594 return STATUS_SUCCESS;
595
596} // end DiskInitFdo()
#define VOID
Definition: acefi.h:82
#define DEV_SAFE_START_UNIT
Definition: cdrom.h:139
_Must_inspect_result_ NTSTATUS NTAPI ClassReadDriveCapacity(_In_ PDEVICE_OBJECT Fdo)
Definition: class.c:2742
CLASSPNP_SCAN_FOR_SPECIAL_INFO DiskBadControllers[]
Definition: data.c:42
VOID NTAPI DiskSetSpecialHacks(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN ULONG_PTR Data)
Definition: disk.c:2602
NTSTATUS DiskDetectFailurePrediction(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PFAILURE_PREDICTION_METHOD FailurePredictCapability, BOOLEAN ScsiAddressAvailable)
Definition: diskwmi.c:2230
#define PARTITION0_LIST_SIZE
Definition: disk.h:413
#define DISK_TAG_START
Definition: disk.h:68
#define DISK_DEFAULT_FAILURE_POLLING_PERIOD
Definition: disk.h:456
#define MAX_SECTORS_PER_VERIFY
Definition: disk.h:435
#define SCSI_DISK_TIMEOUT
Definition: disk.h:412
NTSTATUS DiskEnableDisableFailurePredictPolling(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable, ULONG PollTimeInSeconds)
Definition: diskwmi.c:1193
VOID DiskCreateSymbolicLinks(IN PDEVICE_OBJECT DeviceObject)
Definition: pnp.c:676
PULONG InitSafeBootMode
Definition: init.c:71
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:395
#define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE
Definition: srb.h:413
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:404
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
FxIrp * irp
struct _cl_event * event
Definition: glext.h:7739
#define KernelMode
Definition: asm.h:34
@ SynchronizationEvent
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
VOID NTAPI KeInitializeMutex(IN PKMUTEX Mutex, IN ULONG Level)
Definition: mutex.c:67
#define STATUS_PENDING
Definition: ntstatus.h:82
#define HalExamineMBR
Definition: part_xbox.c:325
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
#define SENSE_BUFFER_SIZE_EX
Definition: scsi.h:596
LARGE_INTEGER StartingOffset
Definition: classpnp.h:619
PDEVICE_OBJECT DeviceObject
Definition: pci.h:46
DISK_GROUP_CONTEXT FlushContext
Definition: disk.h:379
KMUTEX VerifyMutex
Definition: disk.h:372
LIST_ENTRY NextList
Definition: disk.h:118
KSPIN_LOCK Spinlock
Definition: disk.h:143
KEVENT Event
Definition: disk.h:148
LIST_ENTRY CurrList
Definition: disk.h:108
int64_t LONGLONG
Definition: typedefs.h:68
@ Executive
Definition: ketypes.h:403

Referenced by DriverEntry().

◆ DiskInitializeReregistration()

NTSTATUS DiskInitializeReregistration ( VOID  )

Definition at line 1560 of file diskwmi.c.

1563{
1564 PAGED_CODE();
1565
1566 //
1567 // Initialize the spinlock used to manage the
1568 // list of disks reregistering their guids
1569 //
1571
1572 return(STATUS_SUCCESS);
1573}
KSPIN_LOCK DiskReregSpinlock
Definition: diskwmi.c:89

Referenced by DriverEntry().

◆ DiskIoctlClearVerify()

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

Definition at line 5313 of file disk.c.

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

Referenced by DiskDeviceControl().

◆ DiskIoctlEnableFailurePrediction()

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

Definition at line 4419 of file disk.c.

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

Referenced by DiskDeviceControl().

◆ DiskIoctlGetCacheInformation()

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

Definition at line 3840 of file disk.c.

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

Referenced by DiskDeviceControl().

◆ DiskIoctlGetCacheSetting()

NTSTATUS DiskIoctlGetCacheSetting ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 3347 of file disk.c.

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

Referenced by DiskDeviceControl().

◆ DiskIoctlGetDriveGeometry()

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

Definition at line 3582 of file disk.c.

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

Referenced by DiskDeviceControl().

◆ DiskIoctlGetDriveGeometryEx()

NTSTATUS DiskIoctlGetDriveGeometryEx ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

◆ DiskIoctlGetLengthInfo()

NTSTATUS DiskIoctlGetLengthInfo ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

◆ DiskIoctlGetMediaTypesEx()

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

Definition at line 3994 of file disk.c.

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