ReactOS 0.4.15-dev-7788-g1ad9096
classpnp.h File Reference
#include <ntdddisk.h>
#include <ntddcdrm.h>
#include <ntddtape.h>
#include <ntddscsi.h>
#include <ntddstor.h>
#include <stdio.h>
#include <scsi.h>
Include dependency graph for classpnp.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _DICTIONARY
 
struct  _CLASSPNP_SCAN_FOR_SPECIAL_INFO
 
struct  _SRB_HISTORY_ITEM
 
struct  _SRB_HISTORY
 
struct  GUIDREGINFO
 
struct  _CLASS_WMI_INFO
 
struct  _CLASS_DEV_INFO
 
struct  _CLASS_INIT_DATA
 
struct  _FILE_OBJECT_EXTENSION
 
struct  _CLASS_WORKING_SET
 
struct  _CLASS_INTERPRET_SENSE_INFO2
 
struct  _CLASS_DRIVER_EXTENSION
 
struct  _COMMON_DEVICE_EXTENSION
 
struct  _PHYSICAL_DEVICE_EXTENSION
 
struct  _CLASS_POWER_OPTIONS
 
struct  _CLASS_POWER_CONTEXT
 
struct  _COMPLETION_CONTEXT
 
struct  _CLASS_QUERY_WMI_REGINFO_EX_LIST
 
struct  _CLASS_VPD_B1_DATA
 
struct  _CLASS_VPD_B0_DATA
 
struct  _CLASS_VPD_B2_DATA
 
struct  _CLASS_READ_CAPACITY16_DATA
 
struct  _CLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS
 
struct  _CLASS_FUNCTION_SUPPORT_INFO
 
struct  _FUNCTIONAL_DEVICE_EXTENSION
 

Macros

#define _CLASS_
 
#define max(a, b)   (((a) > (b)) ? (a) : (b))
 
#define min(a, b)   (((a) < (b)) ? (a) : (b))
 
#define SRB_CLASS_FLAGS_LOW_PRIORITY   0x10000000
 
#define SRB_CLASS_FLAGS_PERSISTANT   0x20000000
 
#define SRB_CLASS_FLAGS_PAGING   0x40000000
 
#define SRB_CLASS_FLAGS_FREE_MDL   0x80000000
 
#define ASSERT_FDO(x)    ASSERT(((PCOMMON_DEVICE_EXTENSION) (x)->DeviceExtension)->IsFdo)
 
#define ASSERT_PDO(x)    ASSERT(!(((PCOMMON_DEVICE_EXTENSION) (x)->DeviceExtension)->IsFdo))
 
#define IS_CLEANUP_REQUEST(majorFunction)
 
#define DO_MCD(fdoExtension)
 
#define IS_SCSIOP_READ(opCode)
 
#define IS_SCSIOP_WRITE(opCode)
 
#define IS_SCSIOP_READWRITE(opCode)   (IS_SCSIOP_READ(opCode) || IS_SCSIOP_WRITE(opCode))
 
#define ADJUST_FUA_FLAG(fdoExt)
 
#define FREE_POOL(_PoolPtr)
 
#define CLASS_TAG_AUTORUN_DISABLE   'ALcS'
 
#define CLASS_TAG_FILE_OBJECT_EXTENSION   'FLcS'
 
#define CLASS_TAG_MEDIA_CHANGE_DETECTION   'MLcS'
 
#define CLASS_TAG_MOUNT   'mLcS'
 
#define CLASS_TAG_RELEASE_QUEUE   'qLcS'
 
#define CLASS_TAG_POWER   'WLcS'
 
#define CLASS_TAG_WMI   'wLcS'
 
#define CLASS_TAG_FAILURE_PREDICT   'fLcS'
 
#define CLASS_TAG_DEVICE_CONTROL   'OIcS'
 
#define CLASS_TAG_MODE_DATA   'oLcS'
 
#define CLASS_TAG_MULTIPATH   'mPcS'
 
#define CLASS_TAG_LOCK_TRACKING   'TLcS'
 
#define CLASS_TAG_LB_PROVISIONING   'PLcS'
 
#define CLASS_TAG_MANAGE_DATASET   'MDcS'
 
#define MAXIMUM_RETRIES   4
 
#define CLASS_DRIVER_EXTENSION_KEY   ((PVOID) ClassInitialize)
 
#define NO_REMOVE   0
 
#define REMOVE_PENDING   1
 
#define REMOVE_COMPLETE   2
 
#define ClassAcquireRemoveLock(devobj, tag)    ClassAcquireRemoveLockEx(devobj, tag, __FILE__, __LINE__)
 
#define TRY
 
#define LEAVE   goto __tryLabel;
 
#define FINALLY   __tryLabel:
 
#define DebugPrint(x)
 
#define DEBUG_BUFFER_LENGTH   256
 
#define START_UNIT_TIMEOUT   (60 * 4)
 
#define MEDIA_CHANGE_DEFAULT_TIME   1
 
#define MEDIA_CHANGE_TIMEOUT_TIME   300
 
#define ClasspAllocateSrb(ext)
 
#define ClasspFreeSrb(ext, srb)
 
#define SET_FLAG(Flags, Bit)   ((Flags) |= (Bit))
 
#define CLEAR_FLAG(Flags, Bit)   ((Flags) &= ~(Bit))
 
#define TEST_FLAG(Flags, Bit)   (((Flags) & (Bit)) != 0)
 
#define CLASS_WORKING_SET_MAXIMUM   2048
 
#define CLASS_INTERPRET_SENSE_INFO2_MAXIMUM_HISTORY_COUNT   30000
 
#define CLASS_SPECIAL_DISABLE_SPIN_DOWN   0x00000001
 
#define CLASS_SPECIAL_DISABLE_SPIN_UP   0x00000002
 
#define CLASS_SPECIAL_NO_QUEUE_LOCK   0x00000008
 
#define CLASS_SPECIAL_DISABLE_WRITE_CACHE   0x00000010
 
#define CLASS_SPECIAL_CAUSE_NOT_REPORTABLE_HACK   0x00000020
 
#define CLASS_SPECIAL_DISABLE_WRITE_CACHE_NOT_SUPPORTED   0x00000040
 
#define CLASS_SPECIAL_MODIFY_CACHE_UNSUCCESSFUL   0x00000040
 
#define CLASS_SPECIAL_FUA_NOT_SUPPORTED   0x00000080
 
#define CLASS_SPECIAL_VALID_MASK   0x000000FB
 
#define CLASS_SPECIAL_RESERVED   (~CLASS_SPECIAL_VALID_MASK)
 
#define DEV_WRITE_CACHE   0x00000001
 
#define DEV_USE_SCSI1   0x00000002
 
#define DEV_SAFE_START_UNIT   0x00000004
 
#define DEV_NO_12BYTE_CDB   0x00000008
 
#define DEV_POWER_PROTECTED   0x00000010
 
#define DEV_USE_16BYTE_CDB   0x00000020
 
#define GUID_CLASSPNP_QUERY_REGINFOEX   {0x00e34b11, 0x2444, 0x4745, {0xa5, 0x3d, 0x62, 0x01, 0x00, 0xcd, 0x82, 0xf7}}
 
#define GUID_CLASSPNP_SENSEINFO2   {0x509a8c5f, 0x71d7, 0x48f6, {0x82, 0x1e, 0x17, 0x3c, 0x49, 0xbf, 0x2f, 0x18}}
 
#define GUID_CLASSPNP_WORKING_SET   {0x105701b0, 0x9e9b, 0x47cb, {0x97, 0x80, 0x81, 0x19, 0x8a, 0xf7, 0xb5, 0x24}}
 
#define GUID_CLASSPNP_SRB_SUPPORT   {0x0a483941, 0xbdfd, 0x4f7b, {0xbe, 0x95, 0xce, 0xe2, 0xa2, 0x16, 0x09, 0x0c}}
 
#define DEFAULT_FAILURE_PREDICTION_PERIOD   60 * 60 * 1
 
#define MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS   (0x3b9aca00)
 
#define CLASS_SRB_SCSI_REQUEST_BLOCK   0x1
 
#define CLASS_SRB_STORAGE_REQUEST_BLOCK   0x2
 
#define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE   (sizeof(STORAGE_REQUEST_BLOCK) + sizeof(STOR_ADDR_BTL8) + sizeof(SRBEX_DATA_SCSI_CDB16))
 
#define CLASS_SRBEX_NO_SRBEX_DATA_BUFFER_SIZE   (sizeof(STORAGE_REQUEST_BLOCK) + sizeof(STOR_ADDR_BTL8))
 

Typedefs

typedef enum _MEDIA_CHANGE_DETECTION_STATE MEDIA_CHANGE_DETECTION_STATE
 
typedef enum _MEDIA_CHANGE_DETECTION_STATEPMEDIA_CHANGE_DETECTION_STATE
 
typedef enum _CLASS_DEBUG_LEVEL CLASS_DEBUG_LEVEL
 
typedef enum _CLASS_DEBUG_LEVELPCLASS_DEBUG_LEVEL
 
typedef enum FAILURE_PREDICTION_METHODPFAILURE_PREDICTION_METHOD
 
typedef struct _CLASS_INIT_DATA CLASS_INIT_DATA
 
typedef struct _CLASS_INIT_DATAPCLASS_INIT_DATA
 
typedef struct _CLASS_PRIVATE_FDO_DATA CLASS_PRIVATE_FDO_DATA
 
typedef struct _CLASS_PRIVATE_FDO_DATAPCLASS_PRIVATE_FDO_DATA
 
typedef struct _CLASS_PRIVATE_PDO_DATA CLASS_PRIVATE_PDO_DATA
 
typedef struct _CLASS_PRIVATE_PDO_DATA * PCLASS_PRIVATE_PDO_DATA
 
typedef struct _CLASS_PRIVATE_COMMON_DATA CLASS_PRIVATE_COMMON_DATA
 
typedef struct _CLASS_PRIVATE_COMMON_DATAPCLASS_PRIVATE_COMMON_DATA
 
typedef struct _MEDIA_CHANGE_DETECTION_INFO MEDIA_CHANGE_DETECTION_INFO
 
typedef struct _MEDIA_CHANGE_DETECTION_INFOPMEDIA_CHANGE_DETECTION_INFO
 
typedef struct _DICTIONARY_HEADER DICTIONARY_HEADER
 
typedef struct _DICTIONARY_HEADERPDICTIONARY_HEADER
 
typedef struct _DICTIONARY DICTIONARY
 
typedef struct _DICTIONARYPDICTIONARY
 
typedef struct _CLASSPNP_SCAN_FOR_SPECIAL_INFO CLASSPNP_SCAN_FOR_SPECIAL_INFO
 
typedef struct _CLASSPNP_SCAN_FOR_SPECIAL_INFOPCLASSPNP_SCAN_FOR_SPECIAL_INFO
 
typedef NTSTATUS(NTAPIPCLASS_POWER_DEVICE) (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
typedef struct _SRB_HISTORY_ITEM SRB_HISTORY_ITEM
 
typedef struct _SRB_HISTORY_ITEMPSRB_HISTORY_ITEM
 
typedef struct _SRB_HISTORY SRB_HISTORY
 
typedef struct _SRB_HISTORYPSRB_HISTORY
 
typedef struct GUIDREGINFOPGUIDREGINFO
 
typedef struct _CLASS_WMI_INFO CLASS_WMI_INFO
 
typedef struct _CLASS_WMI_INFOPCLASS_WMI_INFO
 
typedef struct _CLASS_DEV_INFO CLASS_DEV_INFO
 
typedef struct _CLASS_DEV_INFOPCLASS_DEV_INFO
 
typedef struct _FILE_OBJECT_EXTENSION FILE_OBJECT_EXTENSION
 
typedef struct _FILE_OBJECT_EXTENSIONPFILE_OBJECT_EXTENSION
 
typedef struct _CLASS_WORKING_SET CLASS_WORKING_SET
 
typedef struct _CLASS_WORKING_SETPCLASS_WORKING_SET
 
typedef struct _CLASS_INTERPRET_SENSE_INFO2 CLASS_INTERPRET_SENSE_INFO2
 
typedef struct _CLASS_INTERPRET_SENSE_INFO2PCLASS_INTERPRET_SENSE_INFO2
 
typedef struct _CLASS_DRIVER_EXTENSION CLASS_DRIVER_EXTENSION
 
typedef struct _CLASS_DRIVER_EXTENSIONPCLASS_DRIVER_EXTENSION
 
typedef struct _COMMON_DEVICE_EXTENSION COMMON_DEVICE_EXTENSION
 
typedef struct _COMMON_DEVICE_EXTENSIONPCOMMON_DEVICE_EXTENSION
 
typedef struct _PHYSICAL_DEVICE_EXTENSION PHYSICAL_DEVICE_EXTENSION
 
typedef struct _PHYSICAL_DEVICE_EXTENSIONPPHYSICAL_DEVICE_EXTENSION
 
typedef struct _CLASS_POWER_OPTIONS CLASS_POWER_OPTIONS
 
typedef struct _CLASS_POWER_OPTIONSPCLASS_POWER_OPTIONS
 
typedef struct _CLASS_POWER_CONTEXT CLASS_POWER_CONTEXT
 
typedef struct _CLASS_POWER_CONTEXTPCLASS_POWER_CONTEXT
 
typedef struct _COMPLETION_CONTEXT COMPLETION_CONTEXT
 
typedef struct _COMPLETION_CONTEXTPCOMPLETION_CONTEXT
 
typedef struct _CLASS_QUERY_WMI_REGINFO_EX_LIST CLASS_QUERY_WMI_REGINFO_EX_LIST
 
typedef struct _CLASS_QUERY_WMI_REGINFO_EX_LISTPCLASS_QUERY_WMI_REGINFO_EX_LIST
 
typedef struct _CLASS_VPD_B1_DATA CLASS_VPD_B1_DATA
 
typedef struct _CLASS_VPD_B1_DATAPCLASS_VPD_B1_DATA
 
typedef struct _CLASS_VPD_B0_DATA CLASS_VPD_B0_DATA
 
typedef struct _CLASS_VPD_B0_DATAPCLASS_VPD_B0_DATA
 
typedef struct _CLASS_VPD_B2_DATA CLASS_VPD_B2_DATA
 
typedef struct _CLASS_VPD_B2_DATAPCLASS_VPD_B2_DATA
 
typedef struct _CLASS_READ_CAPACITY16_DATA CLASS_READ_CAPACITY16_DATA
 
typedef struct _CLASS_READ_CAPACITY16_DATAPCLASS_READ_CAPACITY16_DATA
 
typedef struct _CLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS CLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS
 
typedef struct _CLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITSPCLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS
 
typedef struct _CLASS_FUNCTION_SUPPORT_INFO CLASS_FUNCTION_SUPPORT_INFO
 
typedef struct _CLASS_FUNCTION_SUPPORT_INFOPCLASS_FUNCTION_SUPPORT_INFO
 
typedef struct _FUNCTIONAL_DEVICE_EXTENSION FUNCTIONAL_DEVICE_EXTENSION
 
typedef struct _FUNCTIONAL_DEVICE_EXTENSIONPFUNCTIONAL_DEVICE_EXTENSION
 

Enumerations

enum  _MEDIA_CHANGE_DETECTION_STATE {
  MediaUnknown , MediaPresent , MediaNotPresent , MediaUnavailable ,
  MediaUnknown , MediaPresent , MediaNotPresent , MediaUnavailable
}
 
enum  _CLASS_DEBUG_LEVEL {
  ClassDebugError = 0 , ClassDebugWarning = 1 , ClassDebugTrace = 2 , ClassDebugInfo = 3 ,
  ClassDebugMediaLocks = 8 , ClassDebugMCN = 9 , ClassDebugDelayedRetry = 10 , ClassDebugSenseInfo = 11 ,
  ClassDebugRemoveLock = 12 , ClassDebugExternal4 = 13 , ClassDebugExternal3 = 14 , ClassDebugExternal2 = 15 ,
  ClassDebugExternal1 = 16
}
 
enum  CLASSENABLEDISABLEFUNCTION { EventGeneration , DataBlockCollection }
 
enum  FAILURE_PREDICTION_METHOD { FailurePredictionNone = 0 , FailurePredictionIoctl , FailurePredictionSmart , FailurePredictionSense }
 
enum  CLASS_POWER_DOWN_STATE {
  PowerDownDeviceInitial , PowerDownDeviceLocked , PowerDownDeviceStopped , PowerDownDeviceOff ,
  PowerDownDeviceUnlocked
}
 
enum  CLASS_POWER_DOWN_STATE2 {
  PowerDownDeviceInitial2 , PowerDownDeviceLocked2 , PowerDownDeviceFlushed2 , PowerDownDeviceStopped2 ,
  PowerDownDeviceOff2 , PowerDownDeviceUnlocked2
}
 
enum  CLASS_POWER_DOWN_STATE3 {
  PowerDownDeviceInitial3 = 0 , PowerDownDeviceLocked3 , PowerDownDeviceQuiesced3 , PowerDownDeviceFlushed3 ,
  PowerDownDeviceStopped3 , PowerDownDeviceOff3 , PowerDownDeviceUnlocked3
}
 
enum  CLASS_POWER_UP_STATE {
  PowerUpDeviceInitial , PowerUpDeviceLocked , PowerUpDeviceOn , PowerUpDeviceStarted ,
  PowerUpDeviceUnlocked
}
 
enum  CLASS_FUNCTION_SUPPORT { SupportUnknown = 0 , Supported , NotSupported }
 

Functions

static ULONG CountOfSetBitsUChar (UCHAR _X)
 
static ULONG CountOfSetBitsULong (ULONG _X)
 
static ULONG CountOfSetBitsULong32 (ULONG32 _X)
 
static ULONG CountOfSetBitsULong64 (ULONG64 _X)
 
static ULONG CountOfSetBitsUlongPtr (ULONG_PTR _X)
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) typedef VOID(NTAPI *PCLASS_ERROR)(_In_ PDEVICE_OBJECT DeviceObject
 
 _IRQL_requires_max_ (PASSIVE_LEVEL) typedef NTSTATUS(NTAPI *PCLASS_ADD_DEVICE)(_In_ PDRIVER_OBJECT DriverObject
 Queries information details about a security descriptor.
 
 _IRQL_requires_ (DISPATCH_LEVEL) typedef VOID(NTAPI *PCLASS_TICK)(_In_ PDEVICE_OBJECT DeviceObject)
 
_In_ PIRP _In_ ULONG _In_ ULONG _Out_writes_bytes_ (BufferAvail) PUCHAR Buffer)
 
_In_ PIRP _In_ ULONG _In_ ULONG _In_reads_bytes_ (BufferSize) PUCHAR Buffer)
 
_In_ PIRP _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG _In_reads_ (_Inexpressible_(max(InBufferSize, OutBufferSize))) PUCHAR Buffer)
 
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR _In_ ULONG _In_ ULONG _In_opt_ SRB_HISTORY _Out_ NTSTATUS _Out_ _Deref_out_range_ (0, MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS) LONGLONG *RetryIn100nsUnits)
 
 C_ASSERT ((MAXULONG - sizeof(SRB_HISTORY))/30000 >=sizeof(SRB_HISTORY_ITEM))
 
_In_z_ PCCHAR _In_ PDEVICE_OBJECT _In_ BOOLEAN _Outptr_result_nullonfailure_ _At_DeviceObject (Mem) __drv_aliasesMem) PDEVICE_OBJECT *DeviceObject
 
_Must_inspect_result_ SCSIPORT_API NTSTATUS NTAPI ClassReadDriveCapacity (_In_ PDEVICE_OBJECT DeviceObject)
 
SCSIPORT_API VOID NTAPI ClassReleaseQueue (_In_ PDEVICE_OBJECT DeviceObject)
 
SCSIPORT_API VOID NTAPI ClassSplitRequest (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ ULONG MaximumBytes)
 
SCSIPORT_API NTSTATUS NTAPI ClassDeviceControl (_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
 
SCSIPORT_API NTSTATUS NTAPI ClassIoComplete (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
SCSIPORT_API NTSTATUS NTAPI ClassIoCompleteAssociated (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
SCSIPORT_API BOOLEAN NTAPI ClassInterpretSenseInfo (_In_ PDEVICE_OBJECT DeviceObject, _In_ PSCSI_REQUEST_BLOCK Srb, _In_ UCHAR MajorFunctionCode, _In_ ULONG IoDeviceCode, _In_ ULONG RetryCount, _Out_ NTSTATUS *Status, _Out_opt_ _Deref_out_range_(0, 100) ULONG *RetryInterval)
 
VOID NTAPI ClassSendDeviceIoControlSynchronous (_In_ ULONG IoControlCode, _In_ PDEVICE_OBJECT TargetDeviceObject, _Inout_updates_opt_(_Inexpressible_(max(InputBufferLength, OutputBufferLength))) PVOID Buffer, _In_ ULONG InputBufferLength, _In_ ULONG OutputBufferLength, _In_ BOOLEAN InternalDeviceIoControl, _Out_ PIO_STATUS_BLOCK IoStatus)
 
SCSIPORT_API NTSTATUS NTAPI ClassSendIrpSynchronous (_In_ PDEVICE_OBJECT TargetDeviceObject, _In_ PIRP Irp)
 
SCSIPORT_API NTSTATUS NTAPI ClassForwardIrpSynchronous (_In_ PCOMMON_DEVICE_EXTENSION CommonExtension, _In_ PIRP Irp)
 
SCSIPORT_API NTSTATUS NTAPI ClassSendSrbSynchronous (_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PSCSI_REQUEST_BLOCK Srb, _In_reads_bytes_opt_(BufferLength) PVOID BufferAddress, _In_ ULONG BufferLength, _In_ BOOLEAN WriteToDevice)
 
SCSIPORT_API NTSTATUS NTAPI ClassSendSrbAsynchronous (_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PSCSI_REQUEST_BLOCK Srb, _In_ PIRP Irp, _In_reads_bytes_opt_(BufferLength) __drv_aliasesMem PVOID BufferAddress, _In_ ULONG BufferLength, _In_ BOOLEAN WriteToDevice)
 
SCSIPORT_API NTSTATUS NTAPI ClassBuildRequest (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
SCSIPORT_API ULONG NTAPI ClassModeSense (_In_ PDEVICE_OBJECT DeviceObject, _In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode)
 
SCSIPORT_API PVOID NTAPI ClassFindModePage (_In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode, _In_ BOOLEAN Use6Byte)
 
SCSIPORT_API NTSTATUS NTAPI ClassInternalIoControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
SCSIPORT_API VOID ClassDebugPrint (_In_ CLASS_DEBUG_LEVEL DebugPrintLevel, _In_z_ PCCHAR DebugMessage,...)
 
SCSIPORT_API VOID NTAPI ClassCompleteRequest (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ CCHAR PriorityBoost)
 
SCSIPORT_API VOID NTAPI ClassReleaseRemoveLock (_In_ PDEVICE_OBJECT DeviceObject, PIRP Tag)
 
SCSIPORT_API ULONG NTAPI ClassAcquireRemoveLockEx (_In_ PDEVICE_OBJECT DeviceObject, PVOID Tag, _In_ PCSTR File, _In_ ULONG Line)
 
_In_ PCHAR _In_ ULONG _In_reads_bytes_opt_ (InquiryDataLength) PINQUIRYDATA InquiryData
 
SCSIPORT_API NTSTATUS NTAPI ClassWmiCompleteRequest (_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _In_ NTSTATUS Status, _In_ ULONG BufferUsed, _In_ CCHAR PriorityBoost)
 
_In_ LPGUID _In_ ULONG _In_ ULONG _In_reads_bytes_ (EventDataSize) PVOID EventData)
 
SCSIPORT_API VOID NTAPI ClassResetMediaChangeTimer (_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
SCSIPORT_API PVPB NTAPI ClassGetVpb (_In_ PDEVICE_OBJECT DeviceObject)
 
SCSIPORT_API NTSTATUS NTAPI ClassSpinDownPowerHandler (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
NTSTATUS NTAPI ClassStopUnitPowerHandler (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
SCSIPORT_API VOID NTAPI ClassReleaseChildLock (_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
VOID NTAPI ClassSendStartUnit (_In_ PDEVICE_OBJECT DeviceObject)
 
SCSIPORT_API NTSTATUS NTAPI ClassAsynchronousCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Event)
 
SCSIPORT_API VOID NTAPI ClassCheckMediaState (_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
SCSIPORT_API NTSTATUS NTAPI ClassCheckVerifyComplete (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
_In_ const GUID _In_ ULONG _In_reads_bytes_opt_ (ExtraDataSize) PVOID ExtraData)
 
FORCEINLINE UCHAR GET_FDO_EXTENSON_SENSE_DATA_LENGTH (_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
static __inline BOOLEAN PORT_ALLOCATED_SENSE (_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
 
static __inline VOID FREE_PORT_ALLOCATED_SENSE_BUFFER (_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
 

Variables

_In_ PSCSI_REQUEST_BLOCK Srb
 
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUSStatus
 
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEANRetry
 
_In_ PDEVICE_OBJECT Pdo
 
_In_ UCHAR Type
 
_In_ PIRP Irp
 
_In_ BUS_QUERY_ID_TYPE IdType
 
_In_ BUS_QUERY_ID_TYPE _In_ PUNICODE_STRING IdString
 
_In_ PDEVICE_CAPABILITIES Capabilities
 
_Out_ ULONGRegFlags
 
_Out_ ULONG _Out_ PUNICODE_STRING Name
 
_Out_ ULONG _Out_ PUNICODE_STRING _Out_ PUNICODE_STRING MofResourceName
 
_In_ PIRP _In_ ULONG GuidIndex
 
_In_ PIRP _In_ ULONG _In_ ULONG BufferAvail
 
_In_ PIRP _In_ ULONG _In_ ULONG BufferSize
 
_In_ PIRP _In_ ULONG _In_ ULONG DataItemId
 
_In_ PIRP _In_ ULONG _In_ ULONG MethodId
 
_In_ PIRP _In_ ULONG _In_ ULONG _In_ ULONG InBufferSize
 
_In_ PIRP _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG OutBufferSize
 
_In_ PIRP _In_ ULONG _In_ CLASSENABLEDISABLEFUNCTION Function
 
_In_ PIRP _In_ ULONG _In_ CLASSENABLEDISABLEFUNCTION _In_ BOOLEAN Enable
 
_In_opt_ PIRP OriginalRequest
 
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR MajorFunctionCode
 
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR _In_ ULONG IoDeviceCode
 
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR _In_ ULONG _In_ ULONG PreviousRetryCount
 
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR _In_ ULONG _In_ ULONG _In_opt_ SRB_HISTORYRequestHistory
 
_In_ PVOID Argument2
 
_In_ PVOID _In_ PCLASS_INIT_DATA InitializationData
 
_In_ LPGUID Guid
 
_In_ LPGUID _In_ PVOID Data
 
_In_z_ PCCHAR ObjectNameBuffer
 
_In_z_ PCCHAR _In_ PDEVICE_OBJECT LowerDeviceObject
 
_In_z_ PCCHAR _In_ PDEVICE_OBJECT _In_ BOOLEAN IsFdo
 
_In_ BOOLEAN Release
 
_In_ ULONG NumberElements
 
_In_ PSTORAGE_PROPERTY_ID PropertyId
 
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PVOIDDescriptor
 
_In_ BOOLEAN AcquireChildLock
 
_In_ PCHAR DeviceName
 
_In_ PCHAR _In_ ULONG DeviceNumber
 
_In_ PCHAR _In_ ULONG _In_ ULONG InquiryDataLength
 
_In_ LPGUID _In_ ULONG InstanceIndex
 
_In_ LPGUID _In_ ULONG _In_ ULONG EventDataSize
 
_In_ PUCHAR EventPrefix
 
_In_ BOOLEAN AllowDriveToSleep
 
_In_ FAILURE_PREDICTION_METHOD FailurePredictionMethod
 
_In_ FAILURE_PREDICTION_METHOD _In_ ULONG PollingPeriod
 
_In_ ULONG _In_ BOOLEAN LogError
 
_In_ ULONG _In_ BOOLEAN _In_ ULONG UniqueErrorValue
 
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
 
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
 
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
 
IO_COMPLETION_ROUTINE ClassSignalCompletion
 
_In_ UCHAR RemoveType
 
_In_ MEDIA_CHANGE_DETECTION_STATE State
 
_In_ MEDIA_CHANGE_DETECTION_STATE _In_ BOOLEAN Wait
 
_In_opt_ PWSTR SubkeyName
 
_In_opt_ PWSTR _In_ PWSTR ParameterName
 
_In_opt_ PWSTR _In_ PWSTR _Inout_ PULONG ParameterValue
 
_In_ PFILE_OBJECT FileObject
 
_In_ const GUID _In_ ULONG ExtraDataSize
 
_In_ CLASSPNP_SCAN_FOR_SPECIAL_INFO DeviceList []
 

Macro Definition Documentation

◆ _CLASS_

#define _CLASS_

Definition at line 4 of file classpnp.h.

◆ ADJUST_FUA_FLAG

#define ADJUST_FUA_FLAG (   fdoExt)
Value:
{ \
if (TEST_FLAG(fdoExt->DeviceFlags, DEV_WRITE_CACHE) && \
!TEST_FLAG(fdoExt->DeviceFlags, DEV_POWER_PROTECTED) && \
!TEST_FLAG(fdoExt->ScanForSpecialFlags, CLASS_SPECIAL_FUA_NOT_SUPPORTED) ) { \
fdoExt->CdbForceUnitAccess = TRUE; \
} else { \
fdoExt->CdbForceUnitAccess = FALSE; \
} \
}
#define CLASS_SPECIAL_FUA_NOT_SUPPORTED
Definition: classpnp.h:174
#define DEV_WRITE_CACHE
Definition: classpnp.h:178
#define DEV_POWER_PROTECTED
Definition: classpnp.h:182
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:159
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117

Definition at line 53 of file classpnp.h.

◆ ASSERT_FDO

#define ASSERT_FDO (   x)     ASSERT(((PCOMMON_DEVICE_EXTENSION) (x)->DeviceExtension)->IsFdo)

Definition at line 24 of file classpnp.h.

◆ ASSERT_PDO

#define ASSERT_PDO (   x)     ASSERT(!(((PCOMMON_DEVICE_EXTENSION) (x)->DeviceExtension)->IsFdo))

Definition at line 27 of file classpnp.h.

◆ CLASS_DRIVER_EXTENSION_KEY

#define CLASS_DRIVER_EXTENSION_KEY   ((PVOID) ClassInitialize)

Definition at line 94 of file classpnp.h.

◆ CLASS_INTERPRET_SENSE_INFO2_MAXIMUM_HISTORY_COUNT

#define CLASS_INTERPRET_SENSE_INFO2_MAXIMUM_HISTORY_COUNT   30000

Definition at line 163 of file classpnp.h.

◆ CLASS_SPECIAL_CAUSE_NOT_REPORTABLE_HACK

#define CLASS_SPECIAL_CAUSE_NOT_REPORTABLE_HACK   0x00000020

Definition at line 169 of file classpnp.h.

◆ CLASS_SPECIAL_DISABLE_SPIN_DOWN

#define CLASS_SPECIAL_DISABLE_SPIN_DOWN   0x00000001

Definition at line 165 of file classpnp.h.

◆ CLASS_SPECIAL_DISABLE_SPIN_UP

#define CLASS_SPECIAL_DISABLE_SPIN_UP   0x00000002

Definition at line 166 of file classpnp.h.

◆ CLASS_SPECIAL_DISABLE_WRITE_CACHE

#define CLASS_SPECIAL_DISABLE_WRITE_CACHE   0x00000010

Definition at line 168 of file classpnp.h.

◆ CLASS_SPECIAL_DISABLE_WRITE_CACHE_NOT_SUPPORTED

#define CLASS_SPECIAL_DISABLE_WRITE_CACHE_NOT_SUPPORTED   0x00000040

Definition at line 171 of file classpnp.h.

◆ CLASS_SPECIAL_FUA_NOT_SUPPORTED

#define CLASS_SPECIAL_FUA_NOT_SUPPORTED   0x00000080

Definition at line 174 of file classpnp.h.

◆ CLASS_SPECIAL_MODIFY_CACHE_UNSUCCESSFUL

#define CLASS_SPECIAL_MODIFY_CACHE_UNSUCCESSFUL   0x00000040

Definition at line 173 of file classpnp.h.

◆ CLASS_SPECIAL_NO_QUEUE_LOCK

#define CLASS_SPECIAL_NO_QUEUE_LOCK   0x00000008

Definition at line 167 of file classpnp.h.

◆ CLASS_SPECIAL_RESERVED

#define CLASS_SPECIAL_RESERVED   (~CLASS_SPECIAL_VALID_MASK)

Definition at line 176 of file classpnp.h.

◆ CLASS_SPECIAL_VALID_MASK

#define CLASS_SPECIAL_VALID_MASK   0x000000FB

Definition at line 175 of file classpnp.h.

◆ CLASS_SRB_SCSI_REQUEST_BLOCK

#define CLASS_SRB_SCSI_REQUEST_BLOCK   0x1

Definition at line 572 of file classpnp.h.

◆ CLASS_SRB_STORAGE_REQUEST_BLOCK

#define CLASS_SRB_STORAGE_REQUEST_BLOCK   0x2

Definition at line 573 of file classpnp.h.

◆ CLASS_SRBEX_NO_SRBEX_DATA_BUFFER_SIZE

#define CLASS_SRBEX_NO_SRBEX_DATA_BUFFER_SIZE   (sizeof(STORAGE_REQUEST_BLOCK) + sizeof(STOR_ADDR_BTL8))

Definition at line 696 of file classpnp.h.

◆ CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE

#define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE   (sizeof(STORAGE_REQUEST_BLOCK) + sizeof(STOR_ADDR_BTL8) + sizeof(SRBEX_DATA_SCSI_CDB16))

Definition at line 695 of file classpnp.h.

◆ CLASS_TAG_AUTORUN_DISABLE

#define CLASS_TAG_AUTORUN_DISABLE   'ALcS'

Definition at line 77 of file classpnp.h.

◆ CLASS_TAG_DEVICE_CONTROL

#define CLASS_TAG_DEVICE_CONTROL   'OIcS'

Definition at line 85 of file classpnp.h.

◆ CLASS_TAG_FAILURE_PREDICT

#define CLASS_TAG_FAILURE_PREDICT   'fLcS'

Definition at line 84 of file classpnp.h.

◆ CLASS_TAG_FILE_OBJECT_EXTENSION

#define CLASS_TAG_FILE_OBJECT_EXTENSION   'FLcS'

Definition at line 78 of file classpnp.h.

◆ CLASS_TAG_LB_PROVISIONING

#define CLASS_TAG_LB_PROVISIONING   'PLcS'

Definition at line 89 of file classpnp.h.

◆ CLASS_TAG_LOCK_TRACKING

#define CLASS_TAG_LOCK_TRACKING   'TLcS'

Definition at line 88 of file classpnp.h.

◆ CLASS_TAG_MANAGE_DATASET

#define CLASS_TAG_MANAGE_DATASET   'MDcS'

Definition at line 90 of file classpnp.h.

◆ CLASS_TAG_MEDIA_CHANGE_DETECTION

#define CLASS_TAG_MEDIA_CHANGE_DETECTION   'MLcS'

Definition at line 79 of file classpnp.h.

◆ CLASS_TAG_MODE_DATA

#define CLASS_TAG_MODE_DATA   'oLcS'

Definition at line 86 of file classpnp.h.

◆ CLASS_TAG_MOUNT

#define CLASS_TAG_MOUNT   'mLcS'

Definition at line 80 of file classpnp.h.

◆ CLASS_TAG_MULTIPATH

#define CLASS_TAG_MULTIPATH   'mPcS'

Definition at line 87 of file classpnp.h.

◆ CLASS_TAG_POWER

#define CLASS_TAG_POWER   'WLcS'

Definition at line 82 of file classpnp.h.

◆ CLASS_TAG_RELEASE_QUEUE

#define CLASS_TAG_RELEASE_QUEUE   'qLcS'

Definition at line 81 of file classpnp.h.

◆ CLASS_TAG_WMI

#define CLASS_TAG_WMI   'wLcS'

Definition at line 83 of file classpnp.h.

◆ CLASS_WORKING_SET_MAXIMUM

#define CLASS_WORKING_SET_MAXIMUM   2048

Definition at line 161 of file classpnp.h.

◆ ClassAcquireRemoveLock

#define ClassAcquireRemoveLock (   devobj,
  tag 
)     ClassAcquireRemoveLockEx(devobj, tag, __FILE__, __LINE__)

Definition at line 100 of file classpnp.h.

◆ ClasspAllocateSrb

#define ClasspAllocateSrb (   ext)
Value:
ExAllocateFromNPagedLookasideList( \
&((ext)->CommonExtension.SrbLookasideList))
static const WCHAR *const ext[]
Definition: module.c:53

Definition at line 146 of file classpnp.h.

◆ ClasspFreeSrb

#define ClasspFreeSrb (   ext,
  srb 
)
Value:
ExFreeToNPagedLookasideList( \
&((ext)->CommonExtension.SrbLookasideList), \
(srb))

Definition at line 150 of file classpnp.h.

◆ CLEAR_FLAG

#define CLEAR_FLAG (   Flags,
  Bit 
)    ((Flags) &= ~(Bit))

Definition at line 158 of file classpnp.h.

◆ DEBUG_BUFFER_LENGTH

#define DEBUG_BUFFER_LENGTH   256

Definition at line 128 of file classpnp.h.

◆ DebugPrint

#define DebugPrint (   x)

Definition at line 125 of file classpnp.h.

◆ DEFAULT_FAILURE_PREDICTION_PERIOD

#define DEFAULT_FAILURE_PREDICTION_PERIOD   60 * 60 * 1

Definition at line 190 of file classpnp.h.

◆ DEV_NO_12BYTE_CDB

#define DEV_NO_12BYTE_CDB   0x00000008

Definition at line 181 of file classpnp.h.

◆ DEV_POWER_PROTECTED

#define DEV_POWER_PROTECTED   0x00000010

Definition at line 182 of file classpnp.h.

◆ DEV_SAFE_START_UNIT

#define DEV_SAFE_START_UNIT   0x00000004

Definition at line 180 of file classpnp.h.

◆ DEV_USE_16BYTE_CDB

#define DEV_USE_16BYTE_CDB   0x00000020

Definition at line 183 of file classpnp.h.

◆ DEV_USE_SCSI1

#define DEV_USE_SCSI1   0x00000002

Definition at line 179 of file classpnp.h.

◆ DEV_WRITE_CACHE

#define DEV_WRITE_CACHE   0x00000001

Definition at line 178 of file classpnp.h.

◆ DO_MCD

#define DO_MCD (   fdoExtension)
Value:
(((fdoExtension)->MediaChangeDetectionInfo != NULL) && \
((fdoExtension)->MediaChangeDetectionInfo->MediaChangeDetectionDisableCount == 0))
#define NULL
Definition: types.h:112

Definition at line 35 of file classpnp.h.

◆ FINALLY

#define FINALLY   __tryLabel:

Definition at line 116 of file classpnp.h.

◆ FREE_POOL

#define FREE_POOL (   _PoolPtr)
Value:
if (_PoolPtr != NULL) { \
ExFreePool(_PoolPtr); \
_PoolPtr = NULL; \
}

Definition at line 63 of file classpnp.h.

◆ GUID_CLASSPNP_QUERY_REGINFOEX

#define GUID_CLASSPNP_QUERY_REGINFOEX   {0x00e34b11, 0x2444, 0x4745, {0xa5, 0x3d, 0x62, 0x01, 0x00, 0xcd, 0x82, 0xf7}}

Definition at line 185 of file classpnp.h.

◆ GUID_CLASSPNP_SENSEINFO2

#define GUID_CLASSPNP_SENSEINFO2   {0x509a8c5f, 0x71d7, 0x48f6, {0x82, 0x1e, 0x17, 0x3c, 0x49, 0xbf, 0x2f, 0x18}}

Definition at line 186 of file classpnp.h.

◆ GUID_CLASSPNP_SRB_SUPPORT

#define GUID_CLASSPNP_SRB_SUPPORT   {0x0a483941, 0xbdfd, 0x4f7b, {0xbe, 0x95, 0xce, 0xe2, 0xa2, 0x16, 0x09, 0x0c}}

Definition at line 188 of file classpnp.h.

◆ GUID_CLASSPNP_WORKING_SET

#define GUID_CLASSPNP_WORKING_SET   {0x105701b0, 0x9e9b, 0x47cb, {0x97, 0x80, 0x81, 0x19, 0x8a, 0xf7, 0xb5, 0x24}}

Definition at line 187 of file classpnp.h.

◆ IS_CLEANUP_REQUEST

#define IS_CLEANUP_REQUEST (   majorFunction)
Value:
UCHAR majorFunction
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_CLEANUP

Definition at line 30 of file classpnp.h.

◆ IS_SCSIOP_READ

#define IS_SCSIOP_READ (   opCode)
Value:
((opCode == SCSIOP_READ6) || \
(opCode == SCSIOP_READ) || \
(opCode == SCSIOP_READ12) || \
(opCode == SCSIOP_READ16))
#define SCSIOP_READ6
Definition: cdrw_hw.h:874
#define SCSIOP_READ12
Definition: cdrw_hw.h:956
#define SCSIOP_READ
Definition: cdrw_hw.h:905
#define SCSIOP_READ16
Definition: scsi.h:914

Definition at line 39 of file classpnp.h.

◆ IS_SCSIOP_READWRITE

#define IS_SCSIOP_READWRITE (   opCode)    (IS_SCSIOP_READ(opCode) || IS_SCSIOP_WRITE(opCode))

Definition at line 51 of file classpnp.h.

◆ IS_SCSIOP_WRITE

#define IS_SCSIOP_WRITE (   opCode)
Value:
((opCode == SCSIOP_WRITE6) || \
(opCode == SCSIOP_WRITE) || \
(opCode == SCSIOP_WRITE12) || \
(opCode == SCSIOP_WRITE16))
#define SCSIOP_WRITE6
Definition: cdrw_hw.h:876
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
#define SCSIOP_WRITE12
Definition: cdrw_hw.h:957
#define SCSIOP_WRITE16
Definition: scsi.h:915

Definition at line 45 of file classpnp.h.

◆ LEAVE

#define LEAVE   goto __tryLabel;

Definition at line 115 of file classpnp.h.

◆ max

#define max (   a,
  b 
)    (((a) > (b)) ? (a) : (b))

Definition at line 16 of file classpnp.h.

◆ MAXIMUM_RETRIES

#define MAXIMUM_RETRIES   4

Definition at line 92 of file classpnp.h.

◆ MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS

#define MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS   (0x3b9aca00)

Definition at line 192 of file classpnp.h.

◆ MEDIA_CHANGE_DEFAULT_TIME

#define MEDIA_CHANGE_DEFAULT_TIME   1

Definition at line 132 of file classpnp.h.

◆ MEDIA_CHANGE_TIMEOUT_TIME

#define MEDIA_CHANGE_TIMEOUT_TIME   300

Definition at line 133 of file classpnp.h.

◆ min

#define min (   a,
  b 
)    (((a) < (b)) ? (a) : (b))

Definition at line 17 of file classpnp.h.

◆ NO_REMOVE

#define NO_REMOVE   0

Definition at line 96 of file classpnp.h.

◆ REMOVE_COMPLETE

#define REMOVE_COMPLETE   2

Definition at line 98 of file classpnp.h.

◆ REMOVE_PENDING

#define REMOVE_PENDING   1

Definition at line 97 of file classpnp.h.

◆ SET_FLAG

#define SET_FLAG (   Flags,
  Bit 
)    ((Flags) |= (Bit))

Definition at line 157 of file classpnp.h.

◆ SRB_CLASS_FLAGS_FREE_MDL

#define SRB_CLASS_FLAGS_FREE_MDL   0x80000000

Definition at line 22 of file classpnp.h.

◆ SRB_CLASS_FLAGS_LOW_PRIORITY

#define SRB_CLASS_FLAGS_LOW_PRIORITY   0x10000000

Definition at line 19 of file classpnp.h.

◆ SRB_CLASS_FLAGS_PAGING

#define SRB_CLASS_FLAGS_PAGING   0x40000000

Definition at line 21 of file classpnp.h.

◆ SRB_CLASS_FLAGS_PERSISTANT

#define SRB_CLASS_FLAGS_PERSISTANT   0x20000000

Definition at line 20 of file classpnp.h.

◆ START_UNIT_TIMEOUT

#define START_UNIT_TIMEOUT   (60 * 4)

Definition at line 130 of file classpnp.h.

◆ TEST_FLAG

#define TEST_FLAG (   Flags,
  Bit 
)    (((Flags) & (Bit)) != 0)

Definition at line 159 of file classpnp.h.

◆ TRY

#define TRY

Definition at line 114 of file classpnp.h.

Typedef Documentation

◆ CLASS_DEBUG_LEVEL

◆ CLASS_DEV_INFO

◆ CLASS_DRIVER_EXTENSION

◆ CLASS_FUNCTION_SUPPORT_INFO

◆ CLASS_INIT_DATA

Definition at line 276 of file classpnp.h.

◆ CLASS_INTERPRET_SENSE_INFO2

◆ CLASS_POWER_CONTEXT

◆ CLASS_POWER_OPTIONS

◆ CLASS_PRIVATE_COMMON_DATA

◆ CLASS_PRIVATE_FDO_DATA

◆ CLASS_PRIVATE_PDO_DATA

typedef struct _CLASS_PRIVATE_PDO_DATA CLASS_PRIVATE_PDO_DATA

Definition at line 282 of file classpnp.h.

◆ CLASS_QUERY_WMI_REGINFO_EX_LIST

◆ CLASS_READ_CAPACITY16_DATA

◆ CLASS_VPD_B0_DATA

◆ CLASS_VPD_B1_DATA

◆ CLASS_VPD_B2_DATA

◆ CLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS

◆ CLASS_WMI_INFO

◆ CLASS_WORKING_SET

◆ CLASSPNP_SCAN_FOR_SPECIAL_INFO

◆ COMMON_DEVICE_EXTENSION

◆ COMPLETION_CONTEXT

◆ DICTIONARY

◆ DICTIONARY_HEADER

Definition at line 291 of file classpnp.h.

◆ FILE_OBJECT_EXTENSION

◆ FUNCTIONAL_DEVICE_EXTENSION

◆ MEDIA_CHANGE_DETECTION_INFO

◆ MEDIA_CHANGE_DETECTION_STATE

◆ PCLASS_DEBUG_LEVEL

◆ PCLASS_DEV_INFO

◆ PCLASS_DRIVER_EXTENSION

◆ PCLASS_FUNCTION_SUPPORT_INFO

◆ PCLASS_INIT_DATA

Definition at line 276 of file classpnp.h.

◆ PCLASS_INTERPRET_SENSE_INFO2

◆ PCLASS_POWER_CONTEXT

◆ PCLASS_POWER_DEVICE

typedef NTSTATUS(NTAPI * PCLASS_POWER_DEVICE) (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)

Definition at line 320 of file classpnp.h.

◆ PCLASS_POWER_OPTIONS

◆ PCLASS_PRIVATE_COMMON_DATA

◆ PCLASS_PRIVATE_FDO_DATA

Definition at line 279 of file classpnp.h.

◆ PCLASS_PRIVATE_PDO_DATA

typedef struct _CLASS_PRIVATE_PDO_DATA * PCLASS_PRIVATE_PDO_DATA

Definition at line 282 of file classpnp.h.

◆ PCLASS_QUERY_WMI_REGINFO_EX_LIST

◆ PCLASS_READ_CAPACITY16_DATA

◆ PCLASS_VPD_B0_DATA

◆ PCLASS_VPD_B1_DATA

◆ PCLASS_VPD_B2_DATA

◆ PCLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS

◆ PCLASS_WMI_INFO

◆ PCLASS_WORKING_SET

◆ PCLASSPNP_SCAN_FOR_SPECIAL_INFO

◆ PCOMMON_DEVICE_EXTENSION

◆ PCOMPLETION_CONTEXT

◆ PDICTIONARY

◆ PDICTIONARY_HEADER

Definition at line 291 of file classpnp.h.

◆ PFAILURE_PREDICTION_METHOD

◆ PFILE_OBJECT_EXTENSION

◆ PFUNCTIONAL_DEVICE_EXTENSION

◆ PGUIDREGINFO

◆ PHYSICAL_DEVICE_EXTENSION

◆ PMEDIA_CHANGE_DETECTION_INFO

◆ PMEDIA_CHANGE_DETECTION_STATE

◆ PPHYSICAL_DEVICE_EXTENSION

◆ PSRB_HISTORY

◆ PSRB_HISTORY_ITEM

◆ SRB_HISTORY

◆ SRB_HISTORY_ITEM

Enumeration Type Documentation

◆ _CLASS_DEBUG_LEVEL

Enumerator
ClassDebugError 
ClassDebugWarning 
ClassDebugTrace 
ClassDebugInfo 
ClassDebugMediaLocks 
ClassDebugMCN 
ClassDebugDelayedRetry 
ClassDebugSenseInfo 
ClassDebugRemoveLock 
ClassDebugExternal4 
ClassDebugExternal3 
ClassDebugExternal2 
ClassDebugExternal1 

Definition at line 212 of file classpnp.h.

212 {
213 ClassDebugError = 0,
215 ClassDebugTrace = 2,
216 ClassDebugInfo = 3,
218 ClassDebugMCN = 9,
enum _CLASS_DEBUG_LEVEL CLASS_DEBUG_LEVEL
enum _CLASS_DEBUG_LEVEL * PCLASS_DEBUG_LEVEL
@ ClassDebugExternal4
Definition: classpnp.h:222
@ ClassDebugDelayedRetry
Definition: classpnp.h:219
@ ClassDebugMediaLocks
Definition: classpnp.h:217
@ ClassDebugWarning
Definition: classpnp.h:214
@ ClassDebugExternal3
Definition: classpnp.h:223
@ ClassDebugSenseInfo
Definition: classpnp.h:220
@ ClassDebugExternal2
Definition: classpnp.h:224
@ ClassDebugMCN
Definition: classpnp.h:218
@ ClassDebugTrace
Definition: classpnp.h:215
@ ClassDebugInfo
Definition: classpnp.h:216
@ ClassDebugError
Definition: classpnp.h:213
@ ClassDebugRemoveLock
Definition: classpnp.h:221
@ ClassDebugExternal1
Definition: classpnp.h:225

◆ _MEDIA_CHANGE_DETECTION_STATE

Enumerator
MediaUnknown 
MediaPresent 
MediaNotPresent 
MediaUnavailable 
MediaUnknown 
MediaPresent 
MediaNotPresent 
MediaUnavailable 

Definition at line 205 of file classpnp.h.

205 {
enum _MEDIA_CHANGE_DETECTION_STATE * PMEDIA_CHANGE_DETECTION_STATE
@ MediaUnknown
Definition: classpnp.h:206
@ MediaPresent
Definition: classpnp.h:207
@ MediaNotPresent
Definition: classpnp.h:208
@ MediaUnavailable
Definition: classpnp.h:209
enum _MEDIA_CHANGE_DETECTION_STATE MEDIA_CHANGE_DETECTION_STATE

◆ CLASS_FUNCTION_SUPPORT

Enumerator
SupportUnknown 
Supported 
NotSupported 

Definition at line 730 of file classpnp.h.

731{
732 SupportUnknown = 0,
733 Supported,
CLASS_FUNCTION_SUPPORT
Definition: classpnp.h:731
@ Supported
Definition: classpnp.h:733
@ SupportUnknown
Definition: classpnp.h:732
@ NotSupported
Definition: classpnp.h:734

◆ CLASS_POWER_DOWN_STATE

Enumerator
PowerDownDeviceInitial 
PowerDownDeviceLocked 
PowerDownDeviceStopped 
PowerDownDeviceOff 
PowerDownDeviceUnlocked 

Definition at line 240 of file classpnp.h.

240 {
CLASS_POWER_DOWN_STATE
Definition: classpnp.h:240
@ PowerDownDeviceUnlocked
Definition: classpnp.h:245
@ PowerDownDeviceStopped
Definition: classpnp.h:243
@ PowerDownDeviceOff
Definition: classpnp.h:244
@ PowerDownDeviceInitial
Definition: classpnp.h:241
@ PowerDownDeviceLocked
Definition: classpnp.h:242

◆ CLASS_POWER_DOWN_STATE2

Enumerator
PowerDownDeviceInitial2 
PowerDownDeviceLocked2 
PowerDownDeviceFlushed2 
PowerDownDeviceStopped2 
PowerDownDeviceOff2 
PowerDownDeviceUnlocked2 

Definition at line 248 of file classpnp.h.

248 {
CLASS_POWER_DOWN_STATE2
Definition: classpnp.h:248
@ PowerDownDeviceStopped2
Definition: classpnp.h:252
@ PowerDownDeviceOff2
Definition: classpnp.h:253
@ PowerDownDeviceLocked2
Definition: classpnp.h:250
@ PowerDownDeviceFlushed2
Definition: classpnp.h:251
@ PowerDownDeviceInitial2
Definition: classpnp.h:249
@ PowerDownDeviceUnlocked2
Definition: classpnp.h:254

◆ CLASS_POWER_DOWN_STATE3

Enumerator
PowerDownDeviceInitial3 
PowerDownDeviceLocked3 
PowerDownDeviceQuiesced3 
PowerDownDeviceFlushed3 
PowerDownDeviceStopped3 
PowerDownDeviceOff3 
PowerDownDeviceUnlocked3 

Definition at line 257 of file classpnp.h.

257 {
CLASS_POWER_DOWN_STATE3
Definition: classpnp.h:257
@ PowerDownDeviceUnlocked3
Definition: classpnp.h:264
@ PowerDownDeviceOff3
Definition: classpnp.h:263
@ PowerDownDeviceFlushed3
Definition: classpnp.h:261
@ PowerDownDeviceLocked3
Definition: classpnp.h:259
@ PowerDownDeviceInitial3
Definition: classpnp.h:258
@ PowerDownDeviceStopped3
Definition: classpnp.h:262
@ PowerDownDeviceQuiesced3
Definition: classpnp.h:260

◆ CLASS_POWER_UP_STATE

Enumerator
PowerUpDeviceInitial 
PowerUpDeviceLocked 
PowerUpDeviceOn 
PowerUpDeviceStarted 
PowerUpDeviceUnlocked 

Definition at line 267 of file classpnp.h.

267 {
CLASS_POWER_UP_STATE
Definition: classpnp.h:267
@ PowerUpDeviceOn
Definition: classpnp.h:270
@ PowerUpDeviceUnlocked
Definition: classpnp.h:272
@ PowerUpDeviceStarted
Definition: classpnp.h:271
@ PowerUpDeviceInitial
Definition: classpnp.h:268
@ PowerUpDeviceLocked
Definition: classpnp.h:269

◆ CLASSENABLEDISABLEFUNCTION

Enumerator
EventGeneration 
DataBlockCollection 

Definition at line 228 of file classpnp.h.

228 {
CLASSENABLEDISABLEFUNCTION
Definition: classpnp.h:228
@ DataBlockCollection
Definition: classpnp.h:230
@ EventGeneration
Definition: classpnp.h:229

◆ FAILURE_PREDICTION_METHOD

Enumerator
FailurePredictionNone 
FailurePredictionIoctl 
FailurePredictionSmart 
FailurePredictionSense 

Definition at line 233 of file classpnp.h.

233 {
enum FAILURE_PREDICTION_METHOD * PFAILURE_PREDICTION_METHOD
FAILURE_PREDICTION_METHOD
Definition: classpnp.h:233
@ FailurePredictionSense
Definition: classpnp.h:237
@ FailurePredictionSmart
Definition: classpnp.h:236
@ FailurePredictionNone
Definition: classpnp.h:234
@ FailurePredictionIoctl
Definition: classpnp.h:235

Function Documentation

◆ _Deref_out_range_()

◆ _In_reads_()

_In_ PIRP _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG _In_reads_ ( _Inexpressible_(max(InBufferSize, OutBufferSize))  )

◆ _In_reads_bytes_() [1/2]

_In_ PIRP _In_ ULONG _In_ ULONG _In_reads_bytes_ ( BufferSize  )

◆ _In_reads_bytes_() [2/2]

_In_ LPGUID _In_ ULONG _In_ ULONG _In_reads_bytes_ ( EventDataSize  )

◆ _In_reads_bytes_opt_() [1/2]

_In_ const GUID _In_ ULONG _In_reads_bytes_opt_ ( ExtraDataSize  )

◆ _In_reads_bytes_opt_() [2/2]

_In_ PCHAR _In_ ULONG _In_reads_bytes_opt_ ( InquiryDataLength  )

◆ _IRQL_requires_()

_IRQL_requires_ ( DISPATCH_LEVEL  )

Definition at line 1459 of file expool.c.

1465{
1466 SIZE_T OldSize = PoolBigPageTableSize;
1467 SIZE_T NewSize, NewSizeInBytes;
1468 PPOOL_TRACKER_BIG_PAGES NewTable;
1469 PPOOL_TRACKER_BIG_PAGES OldTable;
1470 ULONG i;
1471 ULONG PagesFreed;
1472 ULONG Hash;
1473 ULONG HashMask;
1474
1475 /* Must be holding ExpLargePoolTableLock */
1477
1478 /* Make sure we don't overflow */
1479 if (Shrink)
1480 {
1481 NewSize = OldSize / 2;
1482
1483 /* Make sure we don't shrink too much. */
1485
1487 ASSERT(NewSize <= OldSize);
1488
1489 /* If there is only one page left, then keep it around. Not a failure either. */
1490 if (NewSize == OldSize)
1491 {
1494 return TRUE;
1495 }
1496 }
1497 else
1498 {
1499 if (!NT_SUCCESS(RtlSIZETMult(2, OldSize, &NewSize)))
1500 {
1501 DPRINT1("Overflow expanding big page table. Size=%lu\n", OldSize);
1503 return FALSE;
1504 }
1505
1506 /* Make sure we don't stupidly waste pages */
1508 ASSERT(NewSize > OldSize);
1509 }
1510
1511 if (!NT_SUCCESS(RtlSIZETMult(sizeof(POOL_TRACKER_BIG_PAGES), NewSize, &NewSizeInBytes)))
1512 {
1513 DPRINT1("Overflow while calculating big page table size. Size=%lu\n", OldSize);
1515 return FALSE;
1516 }
1517
1518 NewTable = MiAllocatePoolPages(NonPagedPool, NewSizeInBytes);
1519 if (NewTable == NULL)
1520 {
1521 DPRINT("Could not allocate %lu bytes for new big page table\n", NewSizeInBytes);
1523 return FALSE;
1524 }
1525
1526 DPRINT("%s big pool tracker table to %lu entries\n", Shrink ? "Shrinking" : "Expanding", NewSize);
1527
1528 /* Initialize the new table */
1529 RtlZeroMemory(NewTable, NewSizeInBytes);
1530 for (i = 0; i < NewSize; i++)
1531 {
1532 NewTable[i].Va = (PVOID)POOL_BIG_TABLE_ENTRY_FREE;
1533 }
1534
1535 /* Copy over all items */
1536 OldTable = PoolBigPageTable;
1537 HashMask = NewSize - 1;
1538 for (i = 0; i < OldSize; i++)
1539 {
1540 /* Skip over empty items */
1541 if ((ULONG_PTR)OldTable[i].Va & POOL_BIG_TABLE_ENTRY_FREE)
1542 {
1543 continue;
1544 }
1545
1546 /* Recalculate the hash due to the new table size */
1547 Hash = ExpComputePartialHashForAddress(OldTable[i].Va) % HashMask;
1548
1549 /* Find the location in the new table */
1550 while (!((ULONG_PTR)NewTable[Hash].Va & POOL_BIG_TABLE_ENTRY_FREE))
1551 {
1552 if (++Hash == NewSize)
1553 Hash = 0;
1554 }
1555
1556 /* We must have space */
1558
1559 /* Finally, copy the item */
1560 NewTable[Hash] = OldTable[i];
1561 }
1562
1563 /* Activate the new table */
1564 PoolBigPageTable = NewTable;
1567
1568 /* Release the lock, we're done changing global state */
1570
1571 /* Free the old table and update our tracker */
1572 PagesFreed = MiFreePoolPages(OldTable);
1573 ExpRemovePoolTracker('looP', PagesFreed << PAGE_SHIFT, 0);
1574 ExpInsertPoolTracker('looP', ALIGN_UP_BY(NewSizeInBytes, PAGE_SIZE), 0);
1575
1576 return TRUE;
1577}
#define ALIGN_DOWN_BY(size, align)
#define ALIGN_UP_BY(size, align)
#define DPRINT1
Definition: precomp.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static int Hash(const char *)
Definition: reader.c:2257
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define NonPagedPool
Definition: env_spec_w32.h:307
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
ULONG ExpPoolBigEntriesInUse
Definition: expool.c:55
VOID NTAPI ExpRemovePoolTracker(IN ULONG Key, IN SIZE_T NumberOfBytes, IN POOL_TYPE PoolType)
Definition: expool.c:760
SIZE_T PoolBigPageTableSize
Definition: expool.c:47
FORCEINLINE ULONG ExpComputePartialHashForAddress(IN PVOID BaseAddress)
Definition: expool.c:457
PPOOL_TRACKER_BIG_PAGES PoolBigPageTable
Definition: expool.c:50
#define POOL_BIG_TABLE_ENTRY_FREE
Definition: expool.c:23
KSPIN_LOCK ExpLargePoolTableLock
Definition: expool.c:54
VOID NTAPI ExpInsertPoolTracker(IN ULONG Key, IN SIZE_T NumberOfBytes, IN POOL_TYPE PoolType)
Definition: expool.c:851
SIZE_T PoolBigPageTableHash
Definition: expool.c:47
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ASSERT(a)
Definition: mode.c:44
PVOID NTAPI MiAllocatePoolPages(IN POOL_TYPE PoolType, IN SIZE_T SizeInBytes)
Definition: pool.c:422
ULONG NTAPI MiFreePoolPages(IN PVOID StartingAddress)
Definition: pool.c:918
#define DPRINT
Definition: sndvol32.h:71
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

◆ _IRQL_requires_max_() [1/2]

_IRQL_requires_max_ ( DISPATCH_LEVEL  )

Definition at line 347 of file hardware.c.

1709{
1710 SendKey();
1712}
static VOID SendKey(VOID)
Definition: hardware.c:332
static VOID Wake(_In_ UCHAR Csn)
Definition: hardware.c:149
_In_ PISAPNP_LOGICAL_DEVICE LogicalDevice
Definition: isapnp.h:399

◆ _IRQL_requires_max_() [2/2]

_IRQL_requires_max_ ( PASSIVE_LEVEL  )

Queries information details about a security descriptor.

Computes the quota size of a security descriptor.

Assigns a security descriptor for a new object.

An extended function that assigns a security descriptor for a new object.

Frees a security descriptor.

An extended function that sets new information data to a security descriptor.

Modifies some information data about a security descriptor.

Parameters
[in]SecurityInformationSecurity information details to be queried from a security descriptor.
[out]SecurityDescriptorThe returned security descriptor with security information data.
[in,out]LengthThe returned length of a security descriptor.
[in,out]ObjectsSecurityDescriptorThe returned object security descriptor.
Returns
Returns STATUS_SUCCESS if the operations have been completed successfully and that the specific information about the security descriptor has been queried. STATUS_BUFFER_TOO_SMALL is returned if the buffer size is too small to contain the queried info about the security descriptor.
Parameters
[in]ObjectIf specified, the function will use this arbitrary object that points to an object security descriptor.
[in]SecurityInformationSecurity information details to be set.
[in]SecurityDescriptorA security descriptor where its info is to be changed.
[in,out]ObjectsSecurityDescriptorThe returned pointer to security descriptor objects.
[in]PoolTypePool type for the new security descriptor to allocate.
[in]GenericMappingThe generic mapping of access rights masks.
Returns
See SeSetSecurityDescriptorInfoEx.
Parameters
[in]ObjectIf specified, the function will use this arbitrary object that points to an object security descriptor.
[in]SecurityInformationSecurity information details to be set.
[in]SecurityDescriptorA security descriptor where its info is to be changed.
[in,out]ObjectsSecurityDescriptorThe returned pointer to security descriptor objects.
[in]AutoInheritFlagsFlags bitmask inheritation, influencing how the security descriptor can be inherited and if it can be in the first place.
[in]PoolTypePool type for the new security descriptor to allocate.
[in]GenericMappingThe generic mapping of access rights masks.
Returns
Returns STATUS_SUCCESS if the operations have been completed without problems and that new info has been set to the security descriptor. STATUS_NO_SECURITY_ON_OBJECT is returned if the object does not have a security descriptor. STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation for the new security descriptor with new info set has failed.
Parameters
[in]SecurityDescriptorA security descriptor to be freed from memory.
Returns
Returns STATUS_SUCCESS.
Parameters
[in]_ParentDescriptorA security descriptor of the parent object that is being created.
[in]_ExplicitDescriptorAn explicit security descriptor that is applied to a new object.
[out]NewDescriptorThe new allocated security descriptor.
[in]ObjectTypeThe type of the new object.
[in]IsDirectoryObjectSet this to TRUE if the newly created object is a directory object, otherwise set this to FALSE.
[in]AutoInheritFlagsAutomatic inheritance flags that influence how access control entries within ACLs from security descriptors are inherited.
[in]SubjectContextSecurity subject context of the new object.
[in]GenericMappingGeneric mapping of access mask rights.
[in]PoolTypeThis parameter is unused.
Returns
Returns STATUS_SUCCESS if the operations have been completed successfully and that the security descriptor has been assigned to the new object. STATUS_NO_TOKEN is returned if the caller hasn't supplied a valid argument to a security subject context. STATUS_INVALID_OWNER is returned if the caller hasn't supplied a parent descriptor that belongs to the main user (owner). STATUS_INVALID_PRIMARY_GROUP is returned by the same reason as with the previous NTSTATUS code. The two NTSTATUS codes are returned if the calling thread stated that the owner and/or group is defaulted to the parent descriptor (SEF_DEFAULT_OWNER_FROM_PARENT and/or SEF_DEFAULT_GROUP_FROM_PARENT respectively). STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation for the descriptor buffer has failed. A failure NTSTATUS is returned otherwise.
Parameters
[in]ParentDescriptorA security descriptor of the parent object that is being created.
[in]ExplicitDescriptorAn explicit security descriptor that is applied to a new object.
[out]NewDescriptorThe new allocated security descriptor.
[in]IsDirectoryObjectSet this to TRUE if the newly created object is a directory object, otherwise set this to FALSE.
[in]SubjectContextSecurity subject context of the new object.
[in]GenericMappingGeneric mapping of access mask rights.
[in]PoolTypeThis parameter is unused.
Returns
See SeAssignSecurityEx.
Parameters
[in]SecurityDescriptorA security descriptor.
[out]QuotaInfoSizeThe returned quota size of the given security descriptor to the caller. The function may return 0 to this parameter if the descriptor doesn't have a group or a discretionary access control list (DACL) even.
Returns
Returns STATUS_SUCCESS if the quota size of a security descriptor has been computed successfully. STATUS_UNKNOWN_REVISION is returned if the security descriptor has an invalid revision.

Definition at line 923 of file Messaging.c.

75{
76 PFLT_SERVER_PORT_OBJECT PortObject;
78
79 /* The caller must allow at least one connection */
80 if (MaxConnections == 0)
81 {
83 }
84
85 /* The request must be for a kernel handle */
86 if (!(ObjectAttributes->Attributes & OBJ_KERNEL_HANDLE))
87 {
89 }
90
91 /*
92 * Get rundown protection on the target to stop the owner
93 * from unloading whilst this port object is open. It gets
94 * removed in the FltpServerPortClose callback
95 */
97 if (!NT_SUCCESS(Status))
98 {
99 return Status;
100 }
101
102 /* Create the server port object for this filter */
107 NULL,
109 0,
110 0,
111 (PVOID *)&PortObject);
112 if (NT_SUCCESS(Status))
113 {
114 /* Zero out the struct */
115 RtlZeroMemory(PortObject, sizeof(FLT_SERVER_PORT_OBJECT));
116
117 /* Increment the ref count on the target filter */
119
120 /* Setup the filter port object */
121 PortObject->Filter = Filter;
125 PortObject->Cookie = ServerPortCookie;
126 PortObject->MaxConnections = MaxConnections;
127
128 /* Insert the object */
129 Status = ObInsertObject(PortObject,
130 NULL,
132 0,
133 NULL,
135 if (NT_SUCCESS(Status))
136 {
137 /* Lock the connection list */
139
140 /* Add the new port object to the connection list and increment the count */
143
144 /* Unlock the connection list*/
146 }
147 }
148
149 if (!NT_SUCCESS(Status))
150 {
151 /* Allow the filter to be cleaned up */
153 }
154
155 return Status;
156}
static const INTERNET_PORT ServerPort
Definition: CWebService.cpp:11
POBJECT_TYPE ServerPortObjectType
Definition: Messaging.c:24
VOID FLTAPI FltObjectDereference(_Inout_ PVOID Object)
Definition: Object.c:53
NTSTATUS FLTAPI FltObjectReference(_Inout_ PVOID Object)
Definition: Object.c:41
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
_Must_inspect_result_ _Outptr_ PFLT_PORT _In_ POBJECT_ATTRIBUTES _In_opt_ PVOID _In_ PFLT_CONNECT_NOTIFY _In_ PFLT_DISCONNECT_NOTIFY _In_opt_ PFLT_MESSAGE_NOTIFY MessageNotifyCallback
Definition: fltkernel.h:1877
_Must_inspect_result_ _Outptr_ PFLT_PORT _In_ POBJECT_ATTRIBUTES _In_opt_ PVOID _In_ PFLT_CONNECT_NOTIFY ConnectNotifyCallback
Definition: fltkernel.h:1875
_Must_inspect_result_ _Outptr_ PFLT_PORT _In_ POBJECT_ATTRIBUTES _In_opt_ PVOID ServerPortCookie
Definition: fltkernel.h:1874
_Must_inspect_result_ _Outptr_ PFLT_PORT _In_ POBJECT_ATTRIBUTES _In_opt_ PVOID _In_ PFLT_CONNECT_NOTIFY _In_ PFLT_DISCONNECT_NOTIFY DisconnectNotifyCallback
Definition: fltkernel.h:1876
ULONG FltpObjectPointerReference(_In_ PFLT_OBJECT Object)
Definition: Object.c:322
Status
Definition: gdiplustypes.h:25
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
static LONG MaxConnections
#define KernelMode
Definition: asm.h:34
#define FILE_READ_DATA
Definition: nt_native.h:628
#define STANDARD_RIGHTS_ALL
Definition: nt_native.h:69
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2935
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1039
FLT_MUTEX_LIST_HEAD ConnectionList
Definition: fltmgrint.h:121
LIST_ENTRY mList
Definition: fltmgrint.h:56
FAST_MUTEX mLock
Definition: fltmgrint.h:55
PFLT_DISCONNECT_NOTIFY DisconnectNotify
Definition: fltmgrint.h:192
PFLT_MESSAGE_NOTIFY MessageNotify
Definition: fltmgrint.h:193
PFLT_CONNECT_NOTIFY ConnectNotify
Definition: fltmgrint.h:191
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

◆ _Out_writes_bytes_()

_In_ PIRP _In_ ULONG _In_ ULONG _Out_writes_bytes_ ( BufferAvail  )

◆ C_ASSERT()

C_ASSERT ( (MAXULONG - sizeof(SRB_HISTORY))/30000 >=sizeof(SRB_HISTORY_ITEM )

◆ ClassAcquireRemoveLockEx()

SCSIPORT_API ULONG NTAPI ClassAcquireRemoveLockEx ( _In_ PDEVICE_OBJECT  DeviceObject,
PVOID  Tag,
_In_ PCSTR  File,
_In_ ULONG  Line 
)

◆ ClassAsynchronousCompletion()

SCSIPORT_API NTSTATUS NTAPI ClassAsynchronousCompletion ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  Event 
)

Definition at line 3246 of file class.c.

3251{
3254 ULONG srbFunction;
3255 ULONG srbFlags;
3256
3257 if (context == NULL) {
3259 }
3260
3261 if (DeviceObject == NULL) {
3262
3263 DeviceObject = context->DeviceObject;
3264 }
3265
3266 srb = &context->Srb.Srb;
3267
3269 srbFunction = ((PSTORAGE_REQUEST_BLOCK)srb)->SrbFunction;
3270 srbFlags = ((PSTORAGE_REQUEST_BLOCK)srb)->SrbFlags;
3271 } else {
3272 srbFunction = srb->Function;
3273 srbFlags = srb->SrbFlags;
3274 }
3275
3276 //
3277 // If this is an execute srb, then check the return status and make sure.
3278 // the queue is not frozen.
3279 //
3280
3281 if (srbFunction == SRB_FUNCTION_EXECUTE_SCSI) {
3282
3283 //
3284 // Check for a frozen queue.
3285 //
3286
3288
3289 //
3290 // Unfreeze the queue getting the device object from the context.
3291 //
3292
3293 ClassReleaseQueue(context->DeviceObject);
3294 }
3295 }
3296
3297 { // free port-allocated sense buffer if we can detect
3298
3299 if (((PCOMMON_DEVICE_EXTENSION)(DeviceObject->DeviceExtension))->IsFdo) {
3300
3301 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
3302 if (PORT_ALLOCATED_SENSE(fdoExtension, srb)) {
3303 FREE_PORT_ALLOCATED_SENSE_BUFFER(fdoExtension, srb);
3304 }
3305
3306 } else {
3307
3309
3310 }
3311 }
3312
3313
3314 //
3315 // Free the context and the Irp.
3316 //
3317
3318 if (Irp->MdlAddress != NULL) {
3319 MmUnlockPages(Irp->MdlAddress);
3320 IoFreeMdl(Irp->MdlAddress);
3321
3322 Irp->MdlAddress = NULL;
3323 }
3324
3326
3328
3329 IoFreeIrp(Irp);
3330
3331 //
3332 // Indicate the I/O system should stop processing the Irp completion.
3333 //
3334
3336
3337} // end ClassAsynchronousCompletion()
FORCEINLINE BOOLEAN PORT_ALLOCATED_SENSE(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: cdrom.h:826
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
FORCEINLINE VOID FREE_PORT_ALLOCATED_SENSE_BUFFER(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: cdrom.h:839
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI ClassReleaseQueue(_In_ PDEVICE_OBJECT Fdo)
Definition: class.c:11589
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
#define SRB_FLAGS_FREE_SENSE_BUFFER
Definition: srb.h:406
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:386
#define IoFreeMdl
Definition: fxmdl.h:89
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define SRB_FUNCTION_STORAGE_REQUEST_BLOCK
Definition: srb.h:108
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:661
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
UCHAR Function
Definition: srb.h:250
ULONG SrbFlags
Definition: srb.h:260
UCHAR SrbStatus
Definition: srb.h:251
Definition: http.c:7252
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define NT_ASSERT
Definition: rtlfuncs.h:3310

Referenced by ClassSendStartUnit(), ResetBus(), and ScsiFlopProcessError().

◆ ClassBuildRequest()

SCSIPORT_API NTSTATUS NTAPI ClassBuildRequest ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)

Definition at line 505 of file obsolete.c.

509{
510 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
511
513
514 // This function is obsolete, but still called by CDROM.SYS .
515 // TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassBuildRequest is OBSOLETE !"));
516
517 //
518 // Allocate an Srb.
519 //
520
521 srb = ClasspAllocateSrb(fdoExtension);
522
523 if (srb == NULL) {
525 }
526
527 ClasspBuildRequestEx(fdoExtension, Irp, srb);
528 return STATUS_SUCCESS;
529
530} // end ClassBuildRequest()
#define ClasspAllocateSrb(ext)
Definition: classpnp.h:146
VOID ClasspBuildRequestEx(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PIRP Irp, _In_ __drv_aliasesMem PSCSI_REQUEST_BLOCK Srb)
Definition: obsolete.c:537
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461

◆ ClassCheckMediaState()

SCSIPORT_API VOID NTAPI ClassCheckMediaState ( _In_ PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension)

Definition at line 1752 of file autorun.c.

1755{
1756 PMEDIA_CHANGE_DETECTION_INFO info = FdoExtension->MediaChangeDetectionInfo;
1757 LONG countDown;
1758
1759 if(info == NULL) {
1760 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_MCN,
1761 "ClassCheckMediaState: detection not enabled\n"));
1762 return;
1763 }
1764
1765 //
1766 // Media change support is active and the IRP is waiting. Decrement the
1767 // timer. There is no MP protection on the timer counter. This code
1768 // is the only code that will manipulate the timer counter and only one
1769 // instance of it should be running at any given time.
1770 //
1771
1772 countDown = InterlockedDecrement(&(info->MediaChangeCountDown));
1773
1774 //
1775 // Try to acquire the media change event. If we can't do it immediately
1776 // then bail out and assume the caller will try again later.
1777 //
1779 info,
1780 countDown);
1781
1782 return;
1783} // end ClassCheckMediaState()
#define InterlockedDecrement
Definition: armddk.h:52
VOID ClasspSendMediaStateIrp(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMEDIA_CHANGE_DETECTION_INFO Info, IN ULONG CountDown)
Definition: autorun.c:1559
@ FdoExtension
Definition: precomp.h:48
long LONG
Definition: pedump.c:60
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29

Referenced by _Function_class_(), and ClasspStorageEventNotification().

◆ ClassCheckVerifyComplete()

SCSIPORT_API NTSTATUS NTAPI ClassCheckVerifyComplete ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  Context 
)

◆ ClassCompleteRequest()

SCSIPORT_API VOID NTAPI ClassCompleteRequest ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp,
_In_ CCHAR  PriorityBoost 
)

Definition at line 401 of file lock.c.

406{
407 #if DBG
408 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
409
410 PRTL_GENERIC_TABLE removeTrackingList = NULL;
411 REMOVE_TRACKING_BLOCK searchDataBlock;
412 PREMOVE_TRACKING_BLOCK foundTrackingBlock;
413
414 KIRQL oldIrql;
415
416 KeAcquireSpinLock(&commonExtension->RemoveTrackingSpinlock, &oldIrql);
417
418 removeTrackingList = commonExtension->RemoveTrackingList;
419
420 if (removeTrackingList != NULL)
421 {
422 searchDataBlock.Tag = Irp;
423
424 foundTrackingBlock = RtlLookupElementGenericTable(removeTrackingList, &searchDataBlock);
425
426 if(foundTrackingBlock != NULL) {
427
428 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_LOCK, ">>>>>ClassCompleteRequest: "
429 "Irp %p completed while still holding the remove lock\n", Irp));
430 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_LOCK, ">>>>>ClassCompleteRequest: "
431 "Lock acquired in file %s on line %d\n",
432 foundTrackingBlock->File, foundTrackingBlock->Line));
434 }
435 }
436
437 KeReleaseSpinLock(&commonExtension->RemoveTrackingSpinlock, oldIrql);
438 #endif
439
440
442
444 return;
445} // end ClassCompleteRequest()
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define IoCompleteRequest
Definition: irp.c:1240
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
KSPIN_LOCK RemoveTrackingSpinlock
Definition: classpnp.h:603
_In_ WDFREQUEST _In_ NTSTATUS _In_ CCHAR PriorityBoost
Definition: wdfrequest.h:1016
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlLookupElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ PVOID Buffer)

Referenced by _IRQL_requires_max_(), _Success_(), ClassCheckVerifyComplete(), ClassCreateClose(), ClassDeviceControl(), ClassDeviceControlDispatch(), ClassDeviceGetLBProvisioningResources(), ClassDeviceHwFirmwareActivateProcess(), ClassDeviceHwFirmwareDownloadProcess(), ClassDeviceHwFirmwareGetInfoProcess(), ClassDispatchPnp(), ClassDispatchPower(), ClassInternalIoControl(), ClassIoCompleteAssociated(), ClassMinimalPowerHandler(), ClasspAccessAlignmentProperty(), ClasspCompleteOffloadRequest(), ClasspDeviceGetLBAStatus(), ClasspDeviceLBProvisioningProperty(), ClasspDeviceMediaTypeProperty(), ClasspDeviceSeekPenaltyProperty(), ClasspDeviceTrimProcess(), ClasspDeviceTrimProperty(), ClasspDuidQueryProperty(), ClasspMcnControl(), ClasspPersistentReserve(), ClasspPowerDownCompletion(), ClasspPowerHandler(), ClasspPowerUpCompletion(), ClasspPriorityHint(), ClasspStartIo(), ClasspStorageEventNotification(), ClasspWriteCacheProperty(), ClassReadWrite(), ClassShutdownFlush(), ClassSystemControl(), ClassWmiCompleteRequest(), DiskDeviceControl(), DiskFlushComplete(), DiskIoctlVerifyThread(), DiskShutdownFlush(), ScsiFlopDeviceControl(), and TransferPktComplete().

◆ ClassDebugPrint()

SCSIPORT_API VOID ClassDebugPrint ( _In_ CLASS_DEBUG_LEVEL  DebugPrintLevel,
_In_z_ PCCHAR  DebugMessage,
  ... 
)

Definition at line 563 of file debug.c.

564 {
565 UNREFERENCED_PARAMETER(DebugPrintLevel);
566 UNREFERENCED_PARAMETER(DebugMessage);
567 }

◆ ClassDeviceControl()

SCSIPORT_API NTSTATUS NTAPI ClassDeviceControl ( _In_ PDEVICE_OBJECT  DeviceObject,
_Inout_ PIRP  Irp 
)

Definition at line 7317 of file class.c.

7321{
7322 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
7323
7325 PIO_STACK_LOCATION nextStack = NULL;
7326
7327 ULONG controlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
7328
7330 PCDB cdb = NULL;
7331
7333 ULONG modifiedIoControlCode = 0;
7334 GUID activityId = {0};
7335
7336
7337 //
7338 // If this is a pass through I/O control, set the minor function code
7339 // and device address and pass it to the port driver.
7340 //
7341
7342 if ( (controlCode == IOCTL_SCSI_PASS_THROUGH) ||
7343 (controlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT) ||
7344 (controlCode == IOCTL_SCSI_PASS_THROUGH_EX) ||
7345 (controlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT_EX) ) {
7346
7347
7348
7349 //
7350 // Validiate the user buffer for SCSI pass through.
7351 // For pass through EX: as the handler will validate the size anyway,
7352 // do not apply the similar check and leave the work to the handler.
7353 //
7354 if ( (controlCode == IOCTL_SCSI_PASS_THROUGH) ||
7355 (controlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT) ) {
7356
7357 #if BUILD_WOW64_ENABLED && defined(_WIN64)
7358
7359 if (IoIs32bitProcess(Irp)) {
7360
7361 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH32)){
7362
7363 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
7364
7367
7369 goto SetStatusAndReturn;
7370 }
7371 }
7372 else
7373
7374 #endif
7375
7376 {
7377 if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
7378 sizeof(SCSI_PASS_THROUGH)) {
7379
7380 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
7381
7384
7386 goto SetStatusAndReturn;
7387 }
7388 }
7389 }
7390
7391
7393
7394 nextStack = IoGetNextIrpStackLocation(Irp);
7395 nextStack->MinorFunction = 1;
7396
7398
7399 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
7400 goto SetStatusAndReturn;
7401
7402 }
7403
7404 Irp->IoStatus.Information = 0;
7405
7406
7407 switch (controlCode) {
7408
7410
7411 PMOUNTDEV_UNIQUE_ID uniqueId;
7412
7413 if (!commonExtension->MountedDeviceInterfaceName.Buffer) {
7415 break;
7416 }
7417
7418 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7419 sizeof(MOUNTDEV_UNIQUE_ID)) {
7420
7422 Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
7423 break;
7424 }
7425
7426 uniqueId = Irp->AssociatedIrp.SystemBuffer;
7427 RtlZeroMemory(uniqueId, sizeof(MOUNTDEV_UNIQUE_ID));
7428 uniqueId->UniqueIdLength =
7429 commonExtension->MountedDeviceInterfaceName.Length;
7430
7431 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7432 sizeof(USHORT) + uniqueId->UniqueIdLength) {
7433
7435 Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
7436 break;
7437 }
7438
7439 RtlCopyMemory(uniqueId->UniqueId,
7440 commonExtension->MountedDeviceInterfaceName.Buffer,
7441 uniqueId->UniqueIdLength);
7442
7444 Irp->IoStatus.Information = sizeof(USHORT) +
7445 uniqueId->UniqueIdLength;
7446 break;
7447 }
7448
7450
7452
7453 NT_ASSERT(commonExtension->DeviceName.Buffer);
7454
7455 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7456 sizeof(MOUNTDEV_NAME)) {
7457
7459 Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
7460 break;
7461 }
7462
7463 name = Irp->AssociatedIrp.SystemBuffer;
7465 name->NameLength = commonExtension->DeviceName.Length;
7466
7467 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7468 sizeof(USHORT) + name->NameLength) {
7469
7471 Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
7472 break;
7473 }
7474
7475 RtlCopyMemory(name->Name, commonExtension->DeviceName.Buffer,
7476 name->NameLength);
7477
7479 Irp->IoStatus.Information = sizeof(USHORT) + name->NameLength;
7480 break;
7481 }
7482
7484
7485 PMOUNTDEV_SUGGESTED_LINK_NAME suggestedName;
7486 WCHAR driveLetterNameBuffer[10] = {0};
7487 RTL_QUERY_REGISTRY_TABLE queryTable[2] = {0};
7488 PWSTR valueName;
7489 UNICODE_STRING driveLetterName;
7490
7491 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7493
7495 Irp->IoStatus.Information = sizeof(MOUNTDEV_SUGGESTED_LINK_NAME);
7496 break;
7497 }
7498
7499 valueName = ExAllocatePoolWithTag(
7500 PagedPool,
7501 commonExtension->DeviceName.Length + sizeof(WCHAR),
7502 '8CcS');
7503
7504 if (!valueName) {
7506 break;
7507 }
7508
7509 RtlCopyMemory(valueName, commonExtension->DeviceName.Buffer,
7510 commonExtension->DeviceName.Length);
7511 valueName[commonExtension->DeviceName.Length/sizeof(WCHAR)] = 0;
7512
7513 driveLetterName.Buffer = driveLetterNameBuffer;
7514 driveLetterName.MaximumLength = sizeof(driveLetterNameBuffer);
7515 driveLetterName.Length = 0;
7516
7517 queryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED |
7520 queryTable[0].Name = valueName;
7521 queryTable[0].EntryContext = &driveLetterName;
7523
7525 L"\\Registry\\Machine\\System\\DISK",
7526 queryTable, NULL, NULL);
7527
7528 if (!NT_SUCCESS(status)) {
7529 FREE_POOL(valueName);
7530 break;
7531 }
7532
7533 if (driveLetterName.Length == 4 &&
7534 driveLetterName.Buffer[0] == '%' &&
7535 driveLetterName.Buffer[1] == ':') {
7536
7537 driveLetterName.Buffer[0] = 0xFF;
7538
7539 } else if (driveLetterName.Length != 4 ||
7540 driveLetterName.Buffer[0] < FirstDriveLetter ||
7541 driveLetterName.Buffer[0] > LastDriveLetter ||
7542 driveLetterName.Buffer[1] != ':') {
7543
7545 FREE_POOL(valueName);
7546 break;
7547 }
7548
7549 suggestedName = Irp->AssociatedIrp.SystemBuffer;
7550 RtlZeroMemory(suggestedName, sizeof(MOUNTDEV_SUGGESTED_LINK_NAME));
7551 suggestedName->UseOnlyIfThereAreNoOtherLinks = TRUE;
7552 suggestedName->NameLength = 28;
7553
7554 Irp->IoStatus.Information =
7556
7557 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7558 Irp->IoStatus.Information) {
7559
7560 Irp->IoStatus.Information =
7563 FREE_POOL(valueName);
7564 break;
7565 }
7566
7568 L"\\Registry\\Machine\\System\\DISK",
7569 valueName);
7570
7571 FREE_POOL(valueName);
7572
7573 RtlCopyMemory(suggestedName->Name, L"\\DosDevices\\", 24);
7574 suggestedName->Name[12] = driveLetterName.Buffer[0];
7575 suggestedName->Name[13] = ':';
7576
7577 //
7578 // NT_SUCCESS(status) based on RtlQueryRegistryValues
7579 //
7581
7582 break;
7583 }
7584
7585 default:
7587 break;
7588 }
7589
7590 if (status != STATUS_PENDING) {
7592 Irp->IoStatus.Status = status;
7593
7594
7596 return status;
7597 }
7598
7599 if (commonExtension->IsFdo){
7600
7601 PULONG_PTR function;
7602 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = (PFUNCTIONAL_DEVICE_EXTENSION)commonExtension;
7603 size_t sizeNeeded;
7604
7605 //
7606 // Allocate a SCSI SRB for handling various IOCTLs.
7607 // NOTE - there is a case where an IOCTL is sent to classpnp before AdapterDescriptor
7608 // is initialized. In this case, default to legacy SRB.
7609 //
7610 if ((fdoExtension->AdapterDescriptor != NULL) &&
7611 (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK)) {
7613 } else {
7614 sizeNeeded = sizeof(SCSI_REQUEST_BLOCK);
7615 }
7616
7617 srb = ExAllocatePoolWithTag(NonPagedPoolNx,
7618 sizeNeeded +
7619 (sizeof(ULONG_PTR) * 2),
7620 '9CcS');
7621
7622 if (srb == NULL) {
7623
7624 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
7628 goto SetStatusAndReturn;
7629 }
7630
7631 if ((fdoExtension->AdapterDescriptor != NULL) &&
7632 (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK)) {
7636 1,
7638 if (NT_SUCCESS(status)) {
7640 function = (PULONG_PTR)((PCHAR)srb + sizeNeeded);
7641 } else {
7642 //
7643 // Should not occur.
7644 //
7646 goto SetStatusAndReturn;
7647 }
7648 } else {
7649 RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
7650 srb->Length = sizeof(SCSI_REQUEST_BLOCK);
7651 srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
7652 function = (PULONG_PTR) ((PSCSI_REQUEST_BLOCK) (srb + 1));
7653 }
7654
7655 //
7656 // Save the function code and the device object in the memory after
7657 // the SRB.
7658 //
7659
7660 *function = (ULONG_PTR) DeviceObject;
7661 function++;
7662 *function = (ULONG_PTR) controlCode;
7663
7664 } else {
7665 srb = NULL;
7666 }
7667
7668 //
7669 // Change the device type to storage for the switch statement, but only
7670 // if from a legacy device type
7671 //
7672
7673 if (((controlCode & 0xffff0000) == (IOCTL_DISK_BASE << 16)) ||
7674 ((controlCode & 0xffff0000) == (IOCTL_TAPE_BASE << 16)) ||
7675 ((controlCode & 0xffff0000) == (IOCTL_CDROM_BASE << 16))
7676 ) {
7677
7678 modifiedIoControlCode = (controlCode & ~0xffff0000);
7679 modifiedIoControlCode |= (IOCTL_STORAGE_BASE << 16);
7680
7681 } else {
7682
7683 modifiedIoControlCode = controlCode;
7684
7685 }
7686
7687 TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_GENERAL, "> ioctl %xh (%s)", modifiedIoControlCode, DBGGETIOCTLSTR(modifiedIoControlCode)));
7688
7689
7690 switch (modifiedIoControlCode) {
7691
7693
7694 FREE_POOL(srb);
7695
7696 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7697 sizeof(STORAGE_HOTPLUG_INFO)) {
7698
7699 //
7700 // Indicate unsuccessful status and no data transferred.
7701 //
7702
7703 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
7704 Irp->IoStatus.Information = sizeof(STORAGE_HOTPLUG_INFO);
7705
7709
7710 } else if (!commonExtension->IsFdo) {
7711
7712
7713 //
7714 // Just forward this down and return
7715 //
7716
7718
7720 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
7721
7722 } else {
7723
7724 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
7726
7727 fdoExtension = (PFUNCTIONAL_DEVICE_EXTENSION)commonExtension;
7728 info = Irp->AssociatedIrp.SystemBuffer;
7729
7730 *info = fdoExtension->PrivateFdoData->HotplugInfo;
7731 Irp->IoStatus.Status = STATUS_SUCCESS;
7732 Irp->IoStatus.Information = sizeof(STORAGE_HOTPLUG_INFO);
7736 }
7737 break;
7738 }
7739
7741
7742 FREE_POOL(srb);
7743
7744 if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
7745 sizeof(STORAGE_HOTPLUG_INFO)) {
7746
7747 //
7748 // Indicate unsuccessful status and no data transferred.
7749 //
7750
7751 Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH;
7752
7756 goto SetStatusAndReturn;
7757
7758 }
7759
7760 if (!commonExtension->IsFdo) {
7761
7762
7763 //
7764 // Just forward this down and return
7765 //
7766
7768
7770 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
7771
7772 } else {
7773
7774 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = (PFUNCTIONAL_DEVICE_EXTENSION)commonExtension;
7775 PSTORAGE_HOTPLUG_INFO info = Irp->AssociatedIrp.SystemBuffer;
7776
7778
7779 if (info->Size != fdoExtension->PrivateFdoData->HotplugInfo.Size)
7780 {
7782 }
7783
7784 if (info->MediaRemovable != fdoExtension->PrivateFdoData->HotplugInfo.MediaRemovable)
7785 {
7787 }
7788
7789 if (info->MediaHotplug != fdoExtension->PrivateFdoData->HotplugInfo.MediaHotplug)
7790 {
7792 }
7793
7794 if (NT_SUCCESS(status))
7795 {
7796 if (info->WriteCacheEnableOverride != fdoExtension->PrivateFdoData->HotplugInfo.WriteCacheEnableOverride)
7797 {
7798 fdoExtension->PrivateFdoData->HotplugInfo.WriteCacheEnableOverride = info->WriteCacheEnableOverride;
7799
7800 //
7801 // Store the user-defined override in the registry
7802 //
7803
7804 ClassSetDeviceParameter(fdoExtension,
7807 info->WriteCacheEnableOverride);
7808 }
7809
7810 fdoExtension->PrivateFdoData->HotplugInfo.DeviceHotplug = info->DeviceHotplug;
7811
7812 //
7813 // Store the user-defined override in the registry
7814 //
7815
7816 ClassSetDeviceParameter(fdoExtension,
7820 }
7821
7822 Irp->IoStatus.Status = status;
7823
7826 }
7827
7828 break;
7829 }
7830
7833
7834 PIRP irp2 = NULL;
7835 PIO_STACK_LOCATION newStack;
7836
7837 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = NULL;
7838
7839 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DeviceIoControl: Check verify\n"));
7840
7841 //
7842 // If a buffer for a media change count was provided, make sure it's
7843 // big enough to hold the result
7844 //
7845
7846 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength) {
7847
7848 //
7849 // If the buffer is too small to hold the media change count
7850 // then return an error to the caller
7851 //
7852
7853 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
7854 sizeof(ULONG)) {
7855
7856 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL, "DeviceIoControl: media count "
7857 "buffer too small\n"));
7858
7859 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
7860 Irp->IoStatus.Information = sizeof(ULONG);
7861
7862 FREE_POOL(srb);
7863
7866
7868 goto SetStatusAndReturn;
7869 }
7870 }
7871
7872 if (!commonExtension->IsFdo) {
7873
7874
7875 //
7876 // If this is a PDO then we should just forward the request down
7877 //
7878 NT_ASSERT(!srb);
7879
7881
7883
7884 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
7885
7886 goto SetStatusAndReturn;
7887
7888 } else {
7889
7890 fdoExtension = DeviceObject->DeviceExtension;
7891
7892 }
7893
7894 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength) {
7895
7896 //
7897 // The caller has provided a valid buffer. Allocate an additional
7898 // irp and stick the CheckVerify completion routine on it. We will
7899 // then send this down to the port driver instead of the irp the
7900 // caller sent in
7901 //
7902
7903 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DeviceIoControl: Check verify wants "
7904 "media count\n"));
7905
7906 //
7907 // Allocate a new irp to send the TestUnitReady to the port driver
7908 //
7909
7910 irp2 = IoAllocateIrp((CCHAR) (DeviceObject->StackSize + 3), FALSE);
7911
7912 if (irp2 == NULL) {
7913 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
7914 Irp->IoStatus.Information = 0;
7915 FREE_POOL(srb);
7919 goto SetStatusAndReturn;
7920
7921 break;
7922 }
7923
7924 //
7925 // Make sure to acquire the lock for the new irp.
7926 //
7927
7929
7930 irp2->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
7932
7933 //
7934 // Set the top stack location and shove the master Irp into the
7935 // top location
7936 //
7937
7938 newStack = IoGetCurrentIrpStackLocation(irp2);
7939 newStack->Parameters.Others.Argument1 = Irp;
7940 newStack->DeviceObject = DeviceObject;
7941
7942 //
7943 // Stick the check verify completion routine onto the stack
7944 // and prepare the irp for the port driver
7945 //
7946
7949 NULL,
7950 TRUE,
7951 TRUE,
7952 TRUE);
7953
7955 newStack = IoGetCurrentIrpStackLocation(irp2);
7956 newStack->DeviceObject = DeviceObject;
7957 newStack->MajorFunction = irpStack->MajorFunction;
7958 newStack->MinorFunction = irpStack->MinorFunction;
7959 newStack->Flags = irpStack->Flags;
7960
7961
7962 //
7963 // Mark the master irp as pending - whether the lower level
7964 // driver completes it immediately or not this should allow it
7965 // to go all the way back up.
7966 //
7967
7969
7970 Irp = irp2;
7971
7972 }
7973
7974 //
7975 // Test Unit Ready
7976 //
7977
7978 SrbSetCdbLength(srb, 6);
7979 cdb = SrbGetCdb(srb);
7980 cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
7981
7982 //
7983 // Set timeout value.
7984 //
7985
7986 SrbSetTimeOutValue(srb, fdoExtension->TimeOutValue);
7987
7988 //
7989 // If this was a CV2 then mark the request as low-priority so we don't
7990 // spin up the drive just to satisfy it.
7991 //
7992
7993 if (controlCode == IOCTL_STORAGE_CHECK_VERIFY2) {
7995 }
7996
7997 //
7998 // Since this routine will always hand the request to the
7999 // port driver if there isn't a data transfer to be done
8000 // we don't have to worry about completing the request here
8001 // on an error
8002 //
8003
8004 //
8005 // This routine uses a completion routine so we don't want to release
8006 // the remove lock until then.
8007 //
8008
8010 srb,
8011 Irp,
8012 NULL,
8013 0,
8014 FALSE);
8015
8016 break;
8017 }
8018
8021
8022 PPREVENT_MEDIA_REMOVAL mediaRemoval = Irp->AssociatedIrp.SystemBuffer;
8023
8024 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoControl: ejection control\n"));
8025
8026 FREE_POOL(srb);
8027
8028 if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
8029 sizeof(PREVENT_MEDIA_REMOVAL)) {
8030
8031 //
8032 // Indicate unsuccessful status and no data transferred.
8033 //
8034
8035 Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH;
8036
8040 goto SetStatusAndReturn;
8041 }
8042
8043 if (!commonExtension->IsFdo) {
8044
8045
8046 //
8047 // Just forward this down and return
8048 //
8049
8051
8053 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8054 }
8055 else {
8056
8057 // i don't believe this assertion is valid. this is a request
8058 // from user-mode, so they could request this for any device
8059 // they want? also, we handle it properly.
8060 // NT_ASSERT(TEST_FLAG(DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA));
8063 Irp,
8064 ((modifiedIoControlCode ==
8067 mediaRemoval->PreventMediaRemoval);
8068
8069 Irp->IoStatus.Status = status;
8072 }
8073
8074 break;
8075 }
8076
8078
8079 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskIoControl: MCN control\n"));
8080
8081 if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
8082 sizeof(PREVENT_MEDIA_REMOVAL)) {
8083
8084 //
8085 // Indicate unsuccessful status and no data transferred.
8086 //
8087
8088 Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH;
8089 Irp->IoStatus.Information = 0;
8090
8091 FREE_POOL(srb);
8092
8096 goto SetStatusAndReturn;
8097 }
8098
8099 if (!commonExtension->IsFdo) {
8100
8101
8102 //
8103 // Just forward this down and return
8104 //
8105
8106 FREE_POOL(srb);
8107
8109
8111 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8112
8113 } else {
8114
8115 //
8116 // Call to the FDO - handle the ejection control.
8117 //
8118
8119 status = ClasspMcnControl(DeviceObject->DeviceExtension,
8120 Irp,
8121 srb);
8122 }
8123 goto SetStatusAndReturn;
8124 }
8125
8127 case IOCTL_STORAGE_RELEASE: {
8128
8129 //
8130 // Reserve logical unit.
8131 //
8132
8133 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = NULL;
8134
8135 if (!commonExtension->IsFdo) {
8136
8137
8139
8141 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8142 goto SetStatusAndReturn;
8143
8144 } else {
8145 fdoExtension = DeviceObject->DeviceExtension;
8146 }
8147
8148 if (TEST_FLAG(fdoExtension->PrivateFdoData->HackFlags, FDO_HACK_NO_RESERVE6))
8149 {
8150 SrbSetCdbLength(srb, 10);
8151 cdb = SrbGetCdb(srb);
8152 cdb->CDB10.OperationCode = (modifiedIoControlCode == IOCTL_STORAGE_RESERVE) ? SCSIOP_RESERVE_UNIT10 : SCSIOP_RELEASE_UNIT10;
8153 }
8154 else
8155 {
8156 SrbSetCdbLength(srb, 6);
8157 cdb = SrbGetCdb(srb);
8158 cdb->CDB6GENERIC.OperationCode = (modifiedIoControlCode == IOCTL_STORAGE_RESERVE) ? SCSIOP_RESERVE_UNIT : SCSIOP_RELEASE_UNIT;
8159 }
8160
8161 //
8162 // Set timeout value.
8163 //
8164
8165 SrbSetTimeOutValue(srb, fdoExtension->TimeOutValue);
8166
8167 //
8168 // Send reserves as tagged requests.
8169 //
8170
8171 if ( IOCTL_STORAGE_RESERVE == modifiedIoControlCode ) {
8174 }
8175
8177 srb,
8178 Irp,
8179 NULL,
8180 0,
8181 FALSE);
8182
8183 break;
8184 }
8185
8188
8189 if (!commonExtension->IsFdo) {
8190
8192
8194 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8195 goto SetStatusAndReturn;
8196 }
8197
8198 //
8199 // Process Persistent Reserve
8200 //
8201
8203
8204 break;
8205
8206 }
8207
8211
8212 //
8213 // Eject media.
8214 //
8215
8216 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = NULL;
8217
8218 if (!commonExtension->IsFdo) {
8219
8220
8222
8224
8225 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8226 goto SetStatusAndReturn;
8227 } else {
8228 fdoExtension = DeviceObject->DeviceExtension;
8229 }
8230
8231 if (commonExtension->PagingPathCount != 0) {
8232
8233 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL, "ClassDeviceControl: call to eject paging device - "
8234 "failure\n"));
8235
8237 Irp->IoStatus.Status = status;
8238
8239 Irp->IoStatus.Information = 0;
8240
8241 FREE_POOL(srb);
8242
8245 goto SetStatusAndReturn;
8246 }
8247
8248 //
8249 // Synchronize with ejection control and ejection cleanup code as
8250 // well as other eject/load requests.
8251 //
8252
8256 KernelMode,
8257 FALSE,
8258 NULL);
8259
8260 if (fdoExtension->ProtectedLockCount != 0) {
8261
8262 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL, "ClassDeviceControl: call to eject protected locked "
8263 "device - failure\n"));
8264
8266 Irp->IoStatus.Status = status;
8267 Irp->IoStatus.Information = 0;
8268
8269 FREE_POOL(srb);
8270
8273
8276 FALSE);
8278
8279 goto SetStatusAndReturn;
8280 }
8281
8282 SrbSetCdbLength(srb, 6);
8283 cdb = SrbGetCdb(srb);
8284
8285 cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
8286 cdb->START_STOP.LoadEject = 1;
8287
8288 if (modifiedIoControlCode == IOCTL_STORAGE_EJECT_MEDIA) {
8289 cdb->START_STOP.Start = 0;
8290 } else {
8291 cdb->START_STOP.Start = 1;
8292 }
8293
8294 //
8295 // Set timeout value.
8296 //
8297
8298 SrbSetTimeOutValue(srb, fdoExtension->TimeOutValue);
8300 srb,
8301 Irp,
8302 NULL,
8303 0,
8304 FALSE);
8305
8308
8309 break;
8310 }
8311
8313
8314 FREE_POOL(srb);
8315
8316 if (commonExtension->IsFdo) {
8317
8319 ((PFUNCTIONAL_DEVICE_EXTENSION) commonExtension)->LowerPdo,
8320 BusRelations);
8321
8323 Irp->IoStatus.Status = status;
8324
8327 }
8328 else {
8329
8330
8332
8334 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8335 }
8336 break;
8337 }
8338
8340
8341 FREE_POOL(srb);
8342
8343 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >=
8344 sizeof(STORAGE_DEVICE_NUMBER)) {
8345
8346 PSTORAGE_DEVICE_NUMBER deviceNumber =
8347 Irp->AssociatedIrp.SystemBuffer;
8348 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension =
8349 commonExtension->PartitionZeroExtension;
8350
8351 deviceNumber->DeviceType = fdoExtension->CommonExtension.DeviceObject->DeviceType;
8352 deviceNumber->DeviceNumber = fdoExtension->DeviceNumber;
8353 deviceNumber->PartitionNumber = commonExtension->PartitionNumber;
8354
8356 Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_NUMBER);
8357
8358 } else {
8360 Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_NUMBER);
8361 }
8362
8363 Irp->IoStatus.Status = status;
8366
8367 break;
8368 }
8369
8370
8372
8373 FREE_POOL(srb);
8374
8375 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
8376 sizeof(STORAGE_READ_CAPACITY)) {
8377
8378 //
8379 // Indicate unsuccessful status and no data transferred.
8380 //
8381
8382 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
8383 Irp->IoStatus.Information = sizeof(STORAGE_READ_CAPACITY);
8384
8388 break;
8389 }
8390
8391 if (!commonExtension->IsFdo) {
8392
8393
8394 //
8395 // Just forward this down and return
8396 //
8397
8399
8401 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8402 }
8403 else {
8404
8405 PFUNCTIONAL_DEVICE_EXTENSION fdoExt = DeviceObject->DeviceExtension;
8406 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
8407 PSTORAGE_READ_CAPACITY readCapacity = Irp->AssociatedIrp.SystemBuffer;
8408 LARGE_INTEGER diskLength;
8409
8411 if (NT_SUCCESS(status) && fdoData->IsCachedDriveCapDataValid) {
8412
8413 readCapacity->Version = sizeof(STORAGE_READ_CAPACITY);
8414 readCapacity->Size = sizeof(STORAGE_READ_CAPACITY);
8415
8416 REVERSE_BYTES(&readCapacity->BlockLength,
8418 REVERSE_BYTES_QUAD(&readCapacity->NumberOfBlocks,
8420 readCapacity->NumberOfBlocks.QuadPart++;
8421
8422 readCapacity->DiskLength = fdoExt->CommonExtension.PartitionLength;
8423
8424 //
8425 // Make sure the lengths are equal.
8426 // Remove this after testing.
8427 //
8428 diskLength.QuadPart = readCapacity->NumberOfBlocks.QuadPart *
8429 readCapacity->BlockLength;
8430
8431 Irp->IoStatus.Status = STATUS_SUCCESS;
8432 Irp->IoStatus.Information = sizeof(STORAGE_READ_CAPACITY);
8433
8434 } else {
8435 //
8436 // Read capacity request failed.
8437 //
8438 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_IOCTL, "ClassDeviceControl: ClassReadDriveCapacity failed: 0x%X IsCachedDriveCapDataValid: %d\n",
8440 Irp->IoStatus.Status = status;
8441 Irp->IoStatus.Information = 0;
8442 }
8445 }
8446
8447 break;
8448 }
8449
8451
8452 PSTORAGE_PROPERTY_QUERY query = Irp->AssociatedIrp.SystemBuffer;
8453
8454 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(STORAGE_PROPERTY_QUERY)) {
8455
8457 Irp->IoStatus.Status = status;
8460 FREE_POOL(srb);
8461 break;
8462 }
8463
8464 if (!commonExtension->IsFdo) {
8465
8466
8468
8470 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8471 FREE_POOL(srb);
8472 break;
8473 }
8474
8475 //
8476 // Determine PropertyId type and either call appropriate routine
8477 // or pass request to lower drivers.
8478 //
8479
8480 switch ( query->PropertyId ) {
8481
8483
8485 break;
8486 }
8487
8489
8491 break;
8492 }
8493
8494 // these propertyId has been implemented in some port driver and filter drivers.
8495 // to keep the backwards compatibility, classpnp will send the request down if it's supported by lower layer.
8496 // otherwise, classpnp sends SCSI command and then interprets the result.
8498
8500 break;
8501 }
8502
8504
8506 break;
8507 }
8508
8510
8512 break;
8513 }
8514
8516
8518 break;
8519 }
8520
8522
8523 status = ClasspDeviceCopyOffloadProperty(DeviceObject, Irp, srb);
8524 break;
8525 }
8526
8528
8530 break;
8531 }
8532
8533 default: {
8534
8535 //
8536 // Copy the Irp stack parameters to the next stack location.
8537 //
8538
8540
8542 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8543 break;
8544 }
8545 } // end switch
8546
8547 FREE_POOL(srb);
8548 break;
8549 }
8550
8552
8553 FREE_POOL(srb);
8554
8555 if (!commonExtension->IsFdo) {
8556
8557
8559
8561 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8562 break;
8563 }
8564
8565 //
8566 // Process priority hit request
8567 //
8568
8570 break;
8571 }
8572
8574
8575 PDEVICE_MANAGE_DATA_SET_ATTRIBUTES dsmAttributes = Irp->AssociatedIrp.SystemBuffer;
8576
8577 if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES)) {
8578
8580 Irp->IoStatus.Status = status;
8583 FREE_POOL(srb);
8584 break;
8585 }
8586
8587 if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
8588 (sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES) + dsmAttributes->ParameterBlockLength + dsmAttributes->DataSetRangesLength)) {
8589
8591 Irp->IoStatus.Status = status;
8594 FREE_POOL(srb);
8595 break;
8596 }
8597
8598 if (!commonExtension->IsFdo) {
8599
8600
8602
8604 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8605 FREE_POOL(srb);
8606 break;
8607 }
8608
8609 switch(dsmAttributes->Action) {
8610
8611 // only process Trim action in class layer if possible.
8612 case DeviceDsmAction_Trim: {
8613 status = ClasspDeviceTrimProcess(DeviceObject, Irp, &activityId, srb);
8614 break;
8615 }
8616
8618 status = ClassDeviceProcessOffloadRead(DeviceObject, Irp, srb);
8619 break;
8620 }
8621
8623 status = ClassDeviceProcessOffloadWrite(DeviceObject, Irp, srb);
8624 break;
8625 }
8626
8629 break;
8630 }
8631
8632
8633 default: {
8634
8635
8636 //
8637 // Copy the Irp stack parameters to the next stack location.
8638 //
8639
8641
8643 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8644 break;
8645 }
8646 } // end switch
8647
8648 FREE_POOL(srb);
8649 break;
8650 }
8651
8653
8654 if (commonExtension->IsFdo) {
8655
8657
8658 } else {
8659
8661
8663 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8664 }
8665
8666 FREE_POOL(srb);
8667
8668 break;
8669 }
8670
8672
8673 FREE_POOL(srb);
8674
8676 break;
8677 }
8678
8679#if (NTDDI_VERSION >= NTDDI_WINTRHESHOLD)
8681 FREE_POOL(srb);
8682
8684 break;
8685 }
8686
8688 if (!commonExtension->IsFdo) {
8689
8691
8693 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8694 goto SetStatusAndReturn;
8695 }
8696
8698 break;
8699 }
8700
8702 if (!commonExtension->IsFdo) {
8703
8705
8707 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8708 goto SetStatusAndReturn;
8709 }
8710
8712 break;
8713 }
8714#endif
8715
8716
8717 default: {
8718
8719 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_IOCTL, "IoDeviceControl: Unsupported device IOCTL %x for %p\n",
8720 controlCode, DeviceObject));
8721
8722
8723 //
8724 // Pass the device control to the next driver.
8725 //
8726
8727 FREE_POOL(srb);
8728
8729 //
8730 // Copy the Irp stack parameters to the next stack location.
8731 //
8732
8734
8736 status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
8737 break;
8738 }
8739
8740 } // end switch( ...
8741
8742SetStatusAndReturn:
8743
8744 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "< ioctl %xh (%s): status %xh.", modifiedIoControlCode, DBGGETIOCTLSTR(modifiedIoControlCode), status));
8745
8746 return status;
8747} // end ClassDeviceControl()
#define VOID
Definition: acefi.h:82
#define SRB_CLASS_FLAGS_LOW_PRIORITY
Definition: cdrom.h:162
#define FDO_HACK_NO_RESERVE6
Definition: cdromp.h:135
#define CLASSP_REG_WRITE_CACHE_VALUE_NAME
Definition: cdromp.h:124
@ SimpleMediaLock
Definition: cdromp.h:289
@ SecureMediaLock
Definition: cdromp.h:290
#define CLASSP_REG_REMOVAL_POLICY_VALUE_NAME
Definition: cdromp.h:126
#define CLASSP_REG_SUBKEY_NAME
Definition: cdromp.h:120
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
#define SCSIOP_RELEASE_UNIT
Definition: cdrw_hw.h:893
#define SCSIOP_RESERVE_UNIT
Definition: cdrw_hw.h:892
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
NTSTATUS InitializeStorageRequestBlock(_Inout_bytecount_(ByteSize) PSTORAGE_REQUEST_BLOCK Srb, _In_ USHORT AddressType, _In_ ULONG ByteSize, _In_ ULONG NumSrbExData,...)
Definition: srblib.c:206
NTSTATUS ClasspDeviceLBProvisioningProperty(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:2894
NTSTATUS ClasspWriteCacheProperty(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:1199
NTSTATUS ClasspDeviceTrimProcess(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PGUID ActivityId, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:3476
_IRQL_requires_same_ NTSTATUS ClasspStorageEventNotification(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: utils.c:7826
NTSTATUS ClassDeviceHwFirmwareDownloadProcess(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:8541
NTSTATUS ClasspDeviceGetLBAStatus(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:3861
NTSTATUS ClasspPersistentReserve(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:6211
NTSTATUS ClasspDuidQueryProperty(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: utils.c:997
NTSTATUS ClasspAccessAlignmentProperty(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:1700
NTSTATUS ClassDeviceHwFirmwareGetInfoProcess(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: utils.c:8366
NTSTATUS ClasspPriorityHint(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: utils.c:6480
NTSTATUS ClasspDeviceSeekPenaltyProperty(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:2172
NTSTATUS ClasspDeviceTrimProperty(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:2730
NTSTATUS ClasspEjectionControl(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN MEDIA_LOCK_TYPE LockType, IN BOOLEAN Lock)
Definition: create.c:474
NTSTATUS ClassDeviceGetLBProvisioningResources(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:5087
NTSTATUS ClassDeviceHwFirmwareActivateProcess(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:8902
NTSTATUS ClasspDeviceMediaTypeProperty(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _Inout_ PSCSI_REQUEST_BLOCK Srb)
Definition: utils.c:1917
NTSTATUS ClasspMcnControl(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PIRP Irp, IN PSCSI_REQUEST_BLOCK Srb)
Definition: autorun.c:3276
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:100
struct _FUNCTIONAL_DEVICE_EXTENSION * PFUNCTIONAL_DEVICE_EXTENSION
#define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE
Definition: classpnp.h:695
SCSIPORT_API NTSTATUS NTAPI ClassSendSrbAsynchronous(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PSCSI_REQUEST_BLOCK Srb, _In_ PIRP Irp, _In_reads_bytes_opt_(BufferLength) __drv_aliasesMem PVOID BufferAddress, _In_ ULONG BufferLength, _In_ BOOLEAN WriteToDevice)
IO_COMPLETION_ROUTINE ClassCheckVerifyComplete
Definition: class.c:84
#define LastDriveLetter
Definition: class.c:93
_Must_inspect_result_ NTSTATUS NTAPI ClassReadDriveCapacity(_In_ PDEVICE_OBJECT Fdo)
Definition: class.c:2742
#define FirstDriveLetter
Definition: class.c:92
#define DBGGETIOCTLSTR(_ioctl)
Definition: debug.h:25
VOID NTAPI ClassCompleteRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ CCHAR PriorityBoost)
Definition: lock.c:401
#define ULONG_PTR
Definition: config.h:101
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:423
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:395
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define PagedPool
Definition: env_spec_w32.h:308
#define IOCTL_STORAGE_CHECK_VERIFY2
Definition: ntddk_ex.h:212
#define IOCTL_STORAGE_LOAD_MEDIA2
Definition: ntddk_ex.h:210
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
IoMarkIrpPending(Irp)
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define REG_SZ
Definition: layer.c:22
struct _MOUNTDEV_NAME MOUNTDEV_NAME
struct _MOUNTDEV_UNIQUE_ID MOUNTDEV_UNIQUE_ID
struct _STORAGE_HOTPLUG_INFO STORAGE_HOTPLUG_INFO
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
#define IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
Definition: imports.h:99
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
#define IOCTL_STORAGE_GET_HOTPLUG_INFO
Definition: imports.h:238
struct _MOUNTDEV_SUGGESTED_LINK_NAME MOUNTDEV_SUGGESTED_LINK_NAME
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define REG_NONE
Definition: nt_native.h:1492
#define IOCTL_DISK_BASE
Definition: ntdddisk.h:44
#define IOCTL_STORAGE_QUERY_PROPERTY
Definition: ntddstor.h:178
#define IOCTL_STORAGE_RELEASE
Definition: ntddstor.h:119
#define DeviceDsmAction_OffloadRead
Definition: ntddstor.h:278
STORAGE_READ_CAPACITY
Definition: ntddstor.h:861
#define IOCTL_STORAGE_EVENT_NOTIFICATION
Definition: ntddstor.h:226
#define DeviceDsmAction_Allocation
Definition: ntddstor.h:280
struct _STORAGE_DEVICE_NUMBER STORAGE_DEVICE_NUMBER
#define IOCTL_STORAGE_SET_HOTPLUG_INFO
Definition: ntddstor.h:157
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
#define IOCTL_STORAGE_FIRMWARE_ACTIVATE
Definition: ntddstor.h:211
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:98
#define IOCTL_STORAGE_READ_CAPACITY
Definition: ntddstor.h:175
#define IOCTL_STORAGE_FIRMWARE_DOWNLOAD
Definition: ntddstor.h:208
#define DeviceDsmAction_OffloadWrite
Definition: ntddstor.h:279
#define IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES
Definition: ntddstor.h:181
#define IOCTL_STORAGE_PERSISTENT_RESERVE_IN
Definition: ntddstor.h:169
#define IOCTL_STORAGE_PERSISTENT_RESERVE_OUT
Definition: ntddstor.h:172
#define IOCTL_STORAGE_LOAD_MEDIA
Definition: ntddstor.h:110
#define IOCTL_STORAGE_RESERVE
Definition: ntddstor.h:116
@ StorageDeviceUniqueIdProperty
Definition: ntddstor.h:515
@ StorageDeviceMediumProductType
Definition: ntddstor.h:527
@ StorageDeviceSeekPenaltyProperty
Definition: ntddstor.h:519
@ StorageDeviceLBProvisioningProperty
Definition: ntddstor.h:523
@ StorageDeviceWriteCacheProperty
Definition: ntddstor.h:516
@ StorageDeviceTrimProperty
Definition: ntddstor.h:520
@ StorageDeviceCopyOffloadProperty
Definition: ntddstor.h:525
@ StorageAccessAlignmentProperty
Definition: ntddstor.h:518
#define IOCTL_STORAGE_FIRMWARE_GET_INFO
Definition: ntddstor.h:205
#define IOCTL_STORAGE_GET_LB_PROVISIONING_MAP_RESOURCES
Definition: ntddstor.h:184
#define IOCTL_STORAGE_FIND_NEW_DEVICES
Definition: ntddstor.h:122
#define IOCTL_STORAGE_BASE
Definition: ntddstor.h:96
#define IOCTL_STORAGE_MCN_CONTROL
Definition: ntddstor.h:128
#define IOCTL_STORAGE_CHECK_PRIORITY_HINT_SUPPORT
Definition: ntddstor.h:196
#define DeviceDsmAction_Trim
Definition: ntddstor.h:276
#define IOCTL_STORAGE_EJECT_MEDIA
Definition: ntddstor.h:107
#define IOCTL_STORAGE_EJECTION_CONTROL
Definition: ntddstor.h:125
#define IOCTL_STORAGE_MEDIA_REMOVAL
Definition: ntddstor.h:104
* PSTORAGE_READ_CAPACITY
Definition: ntddstor.h:861
#define IOCTL_TAPE_BASE
Definition: ntddtape.h:35
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:475
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:477
#define STATUS_FILES_OPEN
Definition: ntstatus.h:499
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:1772
#define IOCTL_SCSI_PASS_THROUGH
Definition: scsi_port.h:47
#define IOCTL_SCSI_PASS_THROUGH_DIRECT
Definition: scsi_port.h:51
#define SCSIOP_RELEASE_UNIT10
Definition: scsi.h:322
#define SCSIOP_RESERVE_UNIT10
Definition: scsi.h:320
#define REVERSE_BYTES_QUAD(Destination, Source)
Definition: scsi.h:3452
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:3465
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:664
#define STORAGE_ADDRESS_TYPE_BTL8
Definition: srb.h:666
@ SrbExDataTypeScsiCdb16
Definition: srb.h:459
#define IOCTL_SCSI_PASS_THROUGH_DIRECT_EX
Definition: ntddscsi.h:38
#define IOCTL_SCSI_PASS_THROUGH_EX
Definition: ntddscsi.h:37
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
FORCEINLINE VOID SrbSetSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:964
FORCEINLINE VOID SrbSetRequestAttribute(_In_ PVOID Srb, _In_ UCHAR RequestAttribute)
Definition: srbhelper.h:1131
FORCEINLINE VOID SrbSetCdbLength(_In_ PVOID Srb, _In_ UCHAR CdbLength)
Definition: srbhelper.h:1093
FORCEINLINE VOID SrbSetTimeOutValue(_In_ PVOID Srb, _In_ ULONG TimeOutValue)
Definition: srbhelper.h:821
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
BOOLEAN IsCachedDriveCapDataValid
Definition: classp.h:803
READ_CAPACITY_DATA_EX LastKnownDriveCapacityData
Definition: classp.h:802
PDEVICE_OBJECT DeviceObject
Definition: pci.h:46
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:598
UNICODE_STRING DeviceName
Definition: classpnp.h:615
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
UNICODE_STRING MountedDeviceInterfaceName
Definition: classpnp.h:628
LARGE_INTEGER PartitionLength
Definition: classpnp.h:618
DEVICE_DATA_MANAGEMENT_SET_ACTION Action
Definition: ntddstor.h:773
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:873
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
USHORT UniqueIdLength
Definition: imports.h:138
UCHAR UniqueId[1]
Definition: imports.h:139
BOOLEAN PreventMediaRemoval
Definition: ntddstor.h:343
LARGE_INTEGER LogicalBlockAddress
Definition: scsi.h:2749
DEVICE_TYPE DeviceType
Definition: ntddstor.h:324
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: name.c:39
Definition: ps.c:97
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
char CCHAR
Definition: typedefs.h:51
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
Definition: cdrw_hw.h:28
struct _CDB::_CDB10 CDB10
struct _CDB::_CDB6GENERIC CDB6GENERIC
struct _CDB::_START_STOP START_STOP
LONGLONG QuadPart
Definition: typedefs.h:114
#define SrbGetCdb(srb)
Definition: usbstor.h:18
#define IOCTL_CDROM_BASE
Definition: vcdcli.c:21
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2680
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
@ BusRelations
Definition: iotypes.h:2152
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ RemovalPolicyExpectSurpriseRemoval
Definition: iotypes.h:842
@ RemovalPolicyExpectOrderlyRemoval
Definition: iotypes.h:841
@ UserRequest
Definition: ketypes.h:421
#define RTL_QUERY_REGISTRY_TYPECHECK
#define RTL_QUERY_REGISTRY_TYPECHECK_SHIFT
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ ClassFindModePage()

SCSIPORT_API PVOID NTAPI ClassFindModePage ( _In_reads_bytes_(Length) PCHAR  ModeSenseBuffer,
_In_ ULONG  Length,
_In_ UCHAR  PageMode,
_In_ BOOLEAN  Use6Byte 
)

Definition at line 6798 of file class.c.

6804{
6805 PUCHAR limit;
6806 ULONG parameterHeaderLength;
6807 PVOID result = NULL;
6808
6809 limit = (PUCHAR)ModeSenseBuffer + Length;
6810 parameterHeaderLength = (Use6Byte) ? sizeof(MODE_PARAMETER_HEADER) : sizeof(MODE_PARAMETER_HEADER10);
6811
6812 if (Length >= parameterHeaderLength) {
6813
6814 PMODE_PARAMETER_HEADER10 modeParam10;
6815 ULONG blockDescriptorLength;
6816
6817 /*
6818 * Skip the mode select header and block descriptors.
6819 */
6820 if (Use6Byte){
6821 blockDescriptorLength = ((PMODE_PARAMETER_HEADER) ModeSenseBuffer)->BlockDescriptorLength;
6822 }
6823 else {
6824 modeParam10 = (PMODE_PARAMETER_HEADER10) ModeSenseBuffer;
6825 blockDescriptorLength = modeParam10->BlockDescriptorLength[1];
6826 }
6827
6828 ModeSenseBuffer += parameterHeaderLength + blockDescriptorLength;
6829
6830 //
6831 // ModeSenseBuffer now points at pages. Walk the pages looking for the
6832 // requested page until the limit is reached.
6833 //
6834
6835 while (ModeSenseBuffer +
6837
6838 if (((PMODE_DISCONNECT_PAGE) ModeSenseBuffer)->PageCode == PageMode) {
6839
6840 /*
6841 * found the mode page. make sure it's safe to touch it all
6842 * before returning the pointer to caller
6843 */
6844
6845 if (ModeSenseBuffer + ((PMODE_DISCONNECT_PAGE)ModeSenseBuffer)->PageLength > (PCHAR)limit) {
6846 /*
6847 * Return NULL since the page is not safe to access in full
6848 */
6849 result = NULL;
6850 }
6851 else {
6852 result = ModeSenseBuffer;
6853 }
6854 break;
6855 }
6856
6857 //
6858 // Advance to the next page which is 4-byte-aligned offset after this page.
6859 //
6860 ModeSenseBuffer +=
6861 ((PMODE_DISCONNECT_PAGE) ModeSenseBuffer)->PageLength +
6863
6864 }
6865 }
6866
6867 return result;
6868} // end ClassFindModePage()
_In_ size_t _In_ UCHAR _In_ BOOLEAN Use6Byte
Definition: cdrom.h:1328
_In_ size_t _In_ UCHAR PageMode
Definition: cdrom.h:1326
_In_ ULONG _In_ UCHAR PageCode
Definition: cdrom.h:1317
struct _MODE_PARAMETER_HEADER10 MODE_PARAMETER_HEADER10
struct _MODE_PARAMETER_HEADER10 * PMODE_PARAMETER_HEADER10
struct _MODE_PARAMETER_HEADER * PMODE_PARAMETER_HEADER
GLint limit
Definition: glext.h:10326
GLuint64EXT * result
Definition: glext.h:11304
#define PCHAR
Definition: match.c:90
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:672
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
struct _MODE_DISCONNECT_PAGE * PMODE_DISCONNECT_PAGE
UCHAR BlockDescriptorLength[2]
Definition: cdrw_hw.h:2516
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by ClasspWriteCacheProperty(), ClasspZeroQERR(), DetermineDriveType(), DiskGetCacheInformation(), DiskGetInfoExceptionInformation(), DiskGetModePage(), DiskInfoExceptionComplete(), DiskSetCacheInformation(), and FormatMedia().

◆ ClassForwardIrpSynchronous()

SCSIPORT_API NTSTATUS NTAPI ClassForwardIrpSynchronous ( _In_ PCOMMON_DEVICE_EXTENSION  CommonExtension,
_In_ PIRP  Irp 
)

Definition at line 11343 of file class.c.

11347{
11349 return ClassSendIrpSynchronous(CommonExtension->LowerDeviceObject, Irp);
11350} // end ClassForwardIrpSynchronous()
NTSTATUS NTAPI ClassSendIrpSynchronous(_In_ PDEVICE_OBJECT TargetDeviceObject, _In_ PIRP Irp)
Definition: class.c:11373

Referenced by ClassDispatchPnp(), ClasspAccessAlignmentProperty(), ClasspDeviceSeekPenaltyProperty(), ClasspDeviceTrimProcess(), ClasspDeviceTrimProperty(), and ClasspPriorityHint().

◆ ClassGetVpb()

SCSIPORT_API PVPB NTAPI ClassGetVpb ( _In_ PDEVICE_OBJECT  DeviceObject)

Definition at line 11473 of file class.c.

11476{
11477#ifdef _MSC_VER
11478#pragma prefast(suppress:28175)
11479#endif
11480 return DeviceObject->Vpb;
11481} // end ClassGetVpb()

Referenced by ClassInterpretSenseInfo(), ClassMinimalPowerHandler(), and ClasspInterpretGesnData().

◆ ClassInternalIoControl()

SCSIPORT_API NTSTATUS NTAPI ClassInternalIoControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

◆ ClassInterpretSenseInfo()

SCSIPORT_API BOOLEAN NTAPI ClassInterpretSenseInfo ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PSCSI_REQUEST_BLOCK  Srb,
_In_ UCHAR  MajorFunctionCode,
_In_ ULONG  IoDeviceCode,
_In_ ULONG  RetryCount,
_Out_ NTSTATUS Status,
_Out_opt_ _Deref_out_range_(0, 100) ULONG RetryInterval 
)

Definition at line 4452 of file class.c.

4461{
4462 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
4463 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
4465 PVOID senseBuffer = SrbGetSenseInfoBuffer(Srb);
4466 BOOLEAN retry = TRUE;
4467 BOOLEAN logError = FALSE;
4468 BOOLEAN unhandledError = FALSE;
4469 BOOLEAN incrementErrorCount = FALSE;
4470
4471 //
4472 // NOTE: This flag must be used only for read/write requests that
4473 // fail with a unexpected retryable error.
4474 //
4475 BOOLEAN logRetryableError = TRUE;
4476
4477 //
4478 // Indicates if we should log this error in our internal log.
4479 //
4480 BOOLEAN logErrorInternal = TRUE;
4481
4482 ULONGLONG badSector = 0;
4483 ULONG uniqueId = 0;
4484
4485 NTSTATUS logStatus;
4486
4487 ULONGLONG readSector;
4488 ULONG index;
4489
4490 ULONG retryInterval = 0;
4491 KIRQL oldIrql;
4492 PCDB cdb = SrbGetCdb(Srb);
4493 UCHAR cdbOpcode = 0;
4494 ULONG cdbLength = SrbGetCdbLength(Srb);
4495
4496#if DBG
4497 BOOLEAN isReservationConflict = FALSE;
4498#endif
4499
4500 if (cdb) {
4501 cdbOpcode = cdb->CDB6GENERIC.OperationCode;
4502 }
4503
4505 logStatus = -1;
4506
4508
4509 //
4510 // Log anything remotely incorrect about paging i/o
4511 //
4512
4513 logError = TRUE;
4514 uniqueId = 301;
4515 logStatus = IO_WARNING_PAGING_FAILURE;
4516 }
4517
4518 //
4519 // Check that request sense buffer is valid.
4520 //
4521
4522 NT_ASSERT(fdoExtension->CommonExtension.IsFdo);
4523
4524
4525 //
4526 // must handle the SRB_STATUS_INTERNAL_ERROR case first,
4527 // as it has all the flags set.
4528 //
4529
4531
4532 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
4533 "ClassInterpretSenseInfo: Internal Error code is %x\n",
4535
4536 retry = FALSE;
4538
4540
4541 //
4542 // Need to reserve STATUS_DEVICE_BUSY to convey reservation conflict
4543 // for read/write requests as there are upper level components that
4544 // have built-in assumptions that STATUS_DEVICE_BUSY implies reservation
4545 // conflict.
4546 //
4548 retry = FALSE;
4549 logError = FALSE;
4550#if DBG
4551 isReservationConflict = TRUE;
4552#endif
4553
4554 } else {
4555
4557
4558 if ((Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID) && senseBuffer) {
4559
4560 UCHAR errorCode = 0;
4561 UCHAR senseKey = 0;
4562 UCHAR addlSenseCode = 0;
4563 UCHAR addlSenseCodeQual = 0;
4564 BOOLEAN isIncorrectLengthValid = FALSE;
4565 BOOLEAN incorrectLength = FALSE;
4566 BOOLEAN isInformationValid = FALSE;
4568
4569
4570 validSense = ScsiGetSenseKeyAndCodes(senseBuffer,
4573 &senseKey,
4574 &addlSenseCode,
4575 &addlSenseCodeQual);
4576
4577 if (!validSense && !IsSenseDataFormatValueValid(senseBuffer)) {
4578
4580
4581 validSense = ScsiGetFixedSenseKeyAndCodes(senseBuffer,
4583 &senseKey,
4584 &addlSenseCode,
4585 &addlSenseCodeQual);
4586 }
4587
4588 if (!validSense) {
4589 goto __ClassInterpretSenseInfo_ProcessingInvalidSenseBuffer;
4590 }
4591
4592 errorCode = ScsiGetSenseErrorCode(senseBuffer);
4593
4594 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: Error code is %x\n", errorCode));
4595 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: Sense key is %x\n", senseKey));
4596 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: Additional sense code is %x\n", addlSenseCode));
4597 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: Additional sense code qualifier is %x\n", addlSenseCodeQual));
4598
4599 if (IsDescriptorSenseDataFormat(senseBuffer)) {
4600
4601 //
4602 // Sense data in Descriptor format
4603 //
4604
4605 PVOID startBuffer = NULL;
4606 UCHAR startBufferLength = 0;
4607
4608
4609 if (ScsiGetSenseDescriptor(senseBuffer,
4611 &startBuffer,
4612 &startBufferLength)) {
4613 UCHAR outType;
4615 UCHAR outBufferLength = 0;
4616 BOOLEAN foundBlockCommandType = FALSE;
4617 BOOLEAN foundInformationType = FALSE;
4619
4622
4623 while ((!foundBlockCommandType || !foundInformationType) &&
4624 ScsiGetNextSenseDescriptorByType(startBuffer,
4625 startBufferLength,
4626 typeList,
4627 ARRAYSIZE(typeList),
4628 &outType,
4629 &outBuffer,
4630 &outBufferLength)) {
4631
4633
4634 if (outBufferLength < descriptorLength) {
4635
4636 // Descriptor data is truncated.
4637 // Complete searching descriptors. Exit the loop now.
4638 break;
4639 }
4640
4642
4643 //
4644 // Block Command type
4645 //
4646
4647 if (!foundBlockCommandType) {
4648
4649 foundBlockCommandType = TRUE;
4650
4651 if (ScsiValidateBlockCommandSenseDescriptor(outBuffer, outBufferLength)) {
4652 incorrectLength = ((PSCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND)outBuffer)->IncorrectLength;
4653 isIncorrectLengthValid = TRUE;
4654 }
4655 } else {
4656
4657 //
4658 // A Block Command descriptor is already found earlier.
4659 //
4660 // T10 SPC specification only allows one descriptor for Block Command Descriptor type.
4661 // Assert here to catch devices that violate this rule. Ignore this descriptor.
4662 //
4664 }
4665
4666 } else if (outType == SCSI_SENSE_DESCRIPTOR_TYPE_INFORMATION) {
4667
4668 //
4669 // Information type
4670 //
4671
4672 if (!foundInformationType) {
4673
4674 foundInformationType = TRUE;
4675
4676 if (ScsiValidateInformationSenseDescriptor(outBuffer, outBufferLength)) {
4678 isInformationValid = TRUE;
4679 }
4680 } else {
4681
4682 //
4683 // A Information descriptor is already found earlier.
4684 //
4685 // T10 SPC specification only allows one descriptor for Information Descriptor type.
4686 // Assert here to catch devices that violate this rule. Ignore this descriptor.
4687 //
4689 }
4690
4691 } else {
4692
4693 //
4694 // ScsiGetNextDescriptorByType should only return a type that is specified by us.
4695 //
4697 break;
4698 }
4699
4700 //
4701 // Advance to start address of next descriptor
4702 //
4703 startBuffer = (PUCHAR)outBuffer + descriptorLength;
4704 startBufferLength = outBufferLength - descriptorLength;
4705 }
4706 }
4707 } else {
4708
4709 //
4710 // Sense data in Fixed format
4711 //
4712
4713 incorrectLength = ((PFIXED_SENSE_DATA)(senseBuffer))->IncorrectLength;
4715 isInformationValid = TRUE;
4716 isIncorrectLengthValid = TRUE;
4717 }
4718
4719
4720 switch (senseKey) {
4721
4722 case SCSI_SENSE_NO_SENSE: {
4723
4724 //
4725 // Check other indicators.
4726 //
4727
4728 if (isIncorrectLengthValid && incorrectLength) {
4729
4730 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4731 "Incorrect length detected.\n"));
4733 retry = FALSE;
4734
4735 } else {
4736
4737 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4738 "No specific sense key\n"));
4740 retry = TRUE;
4741 }
4742
4743 break;
4744 } // end SCSI_SENSE_NO_SENSE
4745
4747
4748 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4749 "Recovered error\n"));
4751 retry = FALSE;
4752 logError = TRUE;
4753 uniqueId = 258;
4754
4755 switch(addlSenseCode) {
4758 logStatus = IO_ERR_SEEK_ERROR;
4759 break;
4760 }
4761
4764 logStatus = IO_RECOVERED_VIA_ECC;
4765 break;
4766 }
4767
4769
4770 UCHAR wmiEventData[sizeof(ULONG)+sizeof(UCHAR)] = {0};
4771
4772 *((PULONG)wmiEventData) = sizeof(UCHAR);
4773 wmiEventData[sizeof(ULONG)] = addlSenseCodeQual;
4774
4775 //
4776 // Don't log another eventlog if we have already logged once
4777 // NOTE: this should have been interlocked, but the structure
4778 // was publicly defined to use a BOOLEAN (char). Since
4779 // media only reports these errors once per X minutes,
4780 // the potential race condition is nearly non-existant.
4781 // the worst case is duplicate log entries, so ignore.
4782 //
4783
4784 logError = FALSE;
4785 if (fdoExtension->FailurePredicted == 0) {
4786 logError = TRUE;
4787 }
4788 fdoExtension->FailureReason = addlSenseCodeQual;
4789 logStatus = IO_WRN_FAILURE_PREDICTED;
4790
4791 ClassNotifyFailurePredicted(fdoExtension,
4792 (PUCHAR)wmiEventData,
4793 sizeof(wmiEventData),
4794 FALSE, // do not log error
4795 4, // unique error value
4798 SrbGetLun(Srb));
4799
4800 fdoExtension->FailurePredicted = TRUE;
4801 break;
4802 }
4803
4804 default: {
4805 logStatus = IO_ERR_CONTROLLER_ERROR;
4806 break;
4807 }
4808
4809 } // end switch(addlSenseCode)
4810
4811 if (isIncorrectLengthValid && incorrectLength) {
4812
4813 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4814 "Incorrect length detected.\n"));
4816 }
4817
4818
4819 break;
4820 } // end SCSI_SENSE_RECOVERED_ERROR
4821
4822 case SCSI_SENSE_NOT_READY: {
4823
4824 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4825 "Device not ready\n"));
4827
4828 switch (addlSenseCode) {
4829
4831
4832 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4833 "Lun not ready\n"));
4834
4835 retryInterval = NOT_READY_RETRY_INTERVAL;
4836
4837 switch (addlSenseCodeQual) {
4838
4840 DEVICE_EVENT_BECOMING_READY notReady = {0};
4841
4842 logRetryableError = FALSE;
4843 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4844 "In process of becoming ready\n"));
4845
4846 notReady.Version = 1;
4847 notReady.Reason = 1;
4848 notReady.Estimated100msToReady = retryInterval * 10;
4849 ClassSendNotification(fdoExtension,
4850 &GUID_IO_DEVICE_BECOMING_READY,
4852 &notReady);
4853 break;
4854 }
4855
4857 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4858 "Manual intervention required\n"));
4860 retry = FALSE;
4861 break;
4862 }
4863
4865 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4866 "Format in progress\n"));
4867 retry = FALSE;
4868 break;
4869 }
4870
4872 DEVICE_EVENT_BECOMING_READY notReady = {0};
4873
4874 logRetryableError = FALSE;
4875 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4876 "Operation In Progress\n"));
4877
4878 notReady.Version = 1;
4879 notReady.Reason = 2;
4880 notReady.Estimated100msToReady = retryInterval * 10;
4881 ClassSendNotification(fdoExtension,
4882 &GUID_IO_DEVICE_BECOMING_READY,
4884 &notReady);
4885
4886 break;
4887 }
4888
4890 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4891 "Long write in progress\n"));
4892 //
4893 // This has been seen as a transcient failure on some cdrom
4894 // drives. The cdrom class driver is going to override this
4895 // setting but has no way of dropping the retry interval
4896 //
4897 retry = FALSE;
4898 retryInterval = 1;
4899 break;
4900 }
4901
4903 logRetryableError = FALSE;
4904 TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4905 "The device (%p) is busy allocating space.\n",
4906 Fdo));
4907
4908 //
4909 // This indicates that a thinly-provisioned device has hit
4910 // a temporary resource exhaustion and is busy allocating
4911 // more space. We need to retry the request as the device
4912 // will eventually be able to service it.
4913 //
4915 retry = TRUE;
4916
4917 break;
4918 }
4919
4921
4922 if (!TEST_FLAG(fdoExtension->ScanForSpecialFlags,
4924
4925 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL,
4926 "ClassInterpretSenseInfo: "
4927 "not ready, cause unknown\n"));
4928 /*
4929 Many non-WHQL certified drives (mostly CD-RW) return
4930 this when they have no media instead of the obvious
4931 choice of:
4932
4933 SCSI_SENSE_NOT_READY/SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
4934
4935 These drives should not pass WHQL certification due
4936 to this discrepency.
4937
4938 */
4939 retry = FALSE;
4940 break;
4941
4942 } else {
4943
4944 //
4945 // Treat this as init command required and fall through.
4946 //
4947 }
4948 }
4949
4951 default: {
4952 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4953 "Initializing command required\n"));
4954 retryInterval = 0; // go back to default
4955 logRetryableError = FALSE;
4956
4957 //
4958 // This sense code/additional sense code
4959 // combination may indicate that the device
4960 // needs to be started. Send an start unit if this
4961 // is a disk device.
4962 //
4963 if (TEST_FLAG(fdoExtension->DeviceFlags, DEV_SAFE_START_UNIT) &&
4965
4967 }
4968 break;
4969 }
4970
4971 } // end switch (addlSenseCodeQual)
4972 break;
4973 }
4974
4976 TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4977 "No Media in device.\n"));
4979 retry = FALSE;
4980
4981 //
4982 // signal MCN that there isn't any media in the device
4983 //
4984 if (!TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
4985 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
4986 "No Media in a non-removable device %p\n",
4987 Fdo));
4988 }
4989
4990 if (addlSenseCodeQual == 0xCC){
4991 /*
4992 * The IMAPI filter returns this ASCQ value when it is burning CD-R media.
4993 * We want to indicate that the media is not present to most applications;
4994 * but RSM has to know that the media is still in the drive (i.e. the drive is not free).
4995 */
4996 ClassSetMediaChangeState(fdoExtension, MediaUnavailable, FALSE);
4997 }
4998 else {
4999 ClassSetMediaChangeState(fdoExtension, MediaNotPresent, FALSE);
5000 }
5001
5002 break;
5003 }
5004 } // end switch (addlSenseCode)
5005
5006 break;
5007 } // end SCSI_SENSE_NOT_READY
5008
5010 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5011 "Medium Error (bad block)\n"));
5013
5014 retry = FALSE;
5015 logError = TRUE;
5016 uniqueId = 256;
5017 logStatus = IO_ERR_BAD_BLOCK;
5018
5019 //
5020 // Check if this error is due to unknown format
5021 //
5022 if (addlSenseCode == SCSI_ADSENSE_INVALID_MEDIA) {
5023
5024 switch (addlSenseCodeQual) {
5025
5027
5029
5030 //
5031 // Log error only if this is a paging request
5032 //
5034 logError = FALSE;
5035 }
5036 break;
5037 }
5038
5040
5042 logError = FALSE;
5043 break;
5044
5045 }
5046 default: {
5047 break;
5048 }
5049 } // end switch addlSenseCodeQual
5050
5051 } // end SCSI_ADSENSE_INVALID_MEDIA
5052
5053 break;
5054
5055 } // end SCSI_SENSE_MEDIUM_ERROR
5056
5058 BOOLEAN logHardwareError = TRUE;
5059
5060 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5061 "Hardware error\n"));
5062
5063 if (fdoData->LegacyErrorHandling == FALSE) {
5064 //
5065 // Hardware errors indicate something has seriously gone
5066 // wrong with the device and retries are very unlikely to
5067 // succeed so fail this request back immediately.
5068 //
5069 retry = FALSE;
5071 logError = FALSE;
5072
5073 } else {
5074 //
5075 // Revert to legacy behavior. That is, retry everything by default.
5076 //
5077 retry = TRUE;
5079 logError = TRUE;
5080 uniqueId = 257;
5081 logStatus = IO_ERR_CONTROLLER_ERROR;
5082 logHardwareError = FALSE;
5083
5084 //
5085 // This indicates the possibility of a dropped FC packet.
5086 //
5087 if ((addlSenseCode == SCSI_ADSENSE_LOGICAL_UNIT_ERROR && addlSenseCodeQual == SCSI_SENSEQ_TIMEOUT_ON_LOGICAL_UNIT) ||
5088 (addlSenseCode == SCSI_ADSENSE_DATA_TRANSFER_ERROR && addlSenseCodeQual == SCSI_SENSEQ_INITIATOR_RESPONSE_TIMEOUT)) {
5089 //
5090 // Fail requests that report this error back to the application.
5091 //
5092 retry = FALSE;
5093
5094 //
5095 // Log a more descriptive error and avoid a second
5096 // error message (IO_ERR_CONTROLLER_ERROR) being logged.
5097 //
5098 logHardwareError = TRUE;
5099 logError = FALSE;
5100 }
5101 }
5102
5103 //
5104 // If CRC error was returned, retry after a slight delay.
5105 //
5106 if (addlSenseCode == SCSI_ADSENSE_LUN_COMMUNICATION &&
5107 addlSenseCodeQual == SCSI_SESNEQ_COMM_CRC_ERROR) {
5108 retry = TRUE;
5109 retryInterval = 1;
5110 logHardwareError = FALSE;
5111 logError = FALSE;
5112 }
5113
5114 //
5115 // Hardware errors warrant a more descriptive error.
5116 // Specifically, we need to ensure this disk is easily
5117 // identifiable.
5118 //
5119 if (logHardwareError) {
5120 UCHAR senseInfoBufferLength = SrbGetSenseInfoBufferLength(Srb);
5121 UCHAR senseBufferSize = 0;
5122
5123 if (ScsiGetTotalSenseByteCountIndicated(senseBuffer,
5124 senseInfoBufferLength,
5125 &senseBufferSize)) {
5126
5127 senseBufferSize = min(senseBufferSize, senseInfoBufferLength);
5128
5129 } else {
5130 //
5131 // it's smaller than required to read the total number of
5132 // valid bytes, so just use the SenseInfoBufferLength field.
5133 //
5134 senseBufferSize = senseInfoBufferLength;
5135 }
5136
5138 senseBufferSize,
5139 senseBuffer,
5143 cdbLength,
5144 cdb,
5145 NULL);
5146 }
5147
5148 break;
5149 } // end SCSI_SENSE_HARDWARE_ERROR
5150
5152
5153 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5154 "Illegal SCSI request\n"));
5156 retry = FALSE;
5157
5158 switch (addlSenseCode) {
5159
5160 case SCSI_ADSENSE_NO_SENSE: {
5161
5162 switch (addlSenseCodeQual) {
5163
5164 //
5165 // 1. Duplicate List Identifier
5166 //
5168
5169 //
5170 // XCOPY, READ BUFFER and CHANGE ALIASES return this sense combination under
5171 // certain conditions. Since these commands aren't sent down natively by the
5172 // Windows OS, return the default error for them and only handle this sense
5173 // combination for offload data transfer commands.
5174 //
5176
5177 TracePrint((TRACE_LEVEL_ERROR,
5178 TRACE_FLAG_IOCTL,
5179 "ClassInterpretSenseInfo (%p): Duplicate List Identifier (command %x, parameter field offset 0x%016llx)\n",
5180 Fdo,
5181 cdbOpcode,
5182 information));
5183
5184 NT_ASSERTMSG("Duplicate list identifier specified", FALSE);
5185
5186 //
5187 // The host should ensure that it uses unique list id for each TokenOperation request.
5188 //
5190 }
5191 break;
5192 }
5193 }
5194 break;
5195 }
5196
5198
5199 switch (addlSenseCodeQual) {
5200
5201 //
5202 // 1. Source/Destination pairing can't communicate with each other or the copy manager.
5203 //
5205
5206 TracePrint((TRACE_LEVEL_ERROR,
5207 TRACE_FLAG_IOCTL,
5208 "ClassInterpretSenseInfo (%p): Source-Destination LUNs can't communicate (command %x)\n",
5209 Fdo,
5210 cdbOpcode));
5211
5213 break;
5214 }
5215 }
5216 break;
5217 }
5218
5220
5221 switch (addlSenseCodeQual) {
5222
5223 //
5224 // 1. Sum of logical block fields in all block device range descriptors is greater than number
5225 // of logical blocks in the ROD minus block offset into ROD
5226 //
5228
5229 TracePrint((TRACE_LEVEL_ERROR,
5230 TRACE_FLAG_IOCTL,
5231 "ClassInterpretSenseInfo (%p): Host specified a transfer length greater than what is represented by the token (considering the offset) [command %x]\n",
5232 Fdo,
5233 cdbOpcode));
5234
5235 NT_ASSERTMSG("Host specified blocks to write beyond what is represented by the token", FALSE);
5236
5238 break;
5239 }
5240 }
5241 break;
5242 }
5243
5244 //
5245 // 1. Parameter data truncation (e.g. last descriptor was not fully specified)
5246 //
5248
5249 TracePrint((TRACE_LEVEL_ERROR,
5250 TRACE_FLAG_IOCTL,
5251 "ClassInterpretSenseInfo (%p): Target truncated the block device range descriptors in the parameter list (command %x)\n",
5252 Fdo,
5253 cdbOpcode));
5254
5255 NT_ASSERTMSG("Parameter data truncation", FALSE);
5256
5258 break;
5259 }
5260
5262 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5263 "Illegal command\n"));
5264 break;
5265 }
5266
5268
5269 LARGE_INTEGER logicalBlockAddr;
5270 LARGE_INTEGER lastLBA;
5271 ULONG numTransferBlocks = 0;
5272
5273 logicalBlockAddr.QuadPart = 0;
5274
5275 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: Illegal block address\n"));
5276
5278
5279 if (Fdo->DeviceType == FILE_DEVICE_DISK) {
5280
5281 if (IS_SCSIOP_READWRITE(cdbOpcode) && cdb) {
5282
5283 if (TEST_FLAG(fdoExtension->DeviceFlags, DEV_USE_16BYTE_CDB)) {
5284 REVERSE_BYTES_QUAD(&logicalBlockAddr, &cdb->CDB16.LogicalBlock);
5285 REVERSE_BYTES(&numTransferBlocks, &cdb->CDB16.TransferLength);
5286 } else {
5287 REVERSE_BYTES(&logicalBlockAddr.LowPart, &cdb->CDB10.LogicalBlockByte0);
5288 REVERSE_BYTES_SHORT((PUSHORT)&numTransferBlocks, &cdb->CDB10.TransferBlocksMsb);
5289 }
5290
5292
5293 if ((logicalBlockAddr.QuadPart > lastLBA.QuadPart) ||
5294 ((logicalBlockAddr.QuadPart + numTransferBlocks - 1) > lastLBA.QuadPart)) {
5295
5296 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5297 "Request beyond boundary. Last LBA: 0x%I64X Read LBA: 0x%I64X Length: 0x%X\n",
5298 (__int64) lastLBA.QuadPart, (__int64) logicalBlockAddr.QuadPart, numTransferBlocks));
5299 } else {
5300 //
5301 // Should only retry these if the request was
5302 // truly within our expected size.
5303 //
5304 // Fujitsu IDE drives have been observed to
5305 // return this error transiently for a legal LBA;
5306 // manual retry in the debugger then works, so
5307 // there is a good chance that a programmed retry
5308 // will also work.
5309 //
5310
5311 retry = TRUE;
5312 retryInterval = 5;
5313 }
5314 } else if (ClasspIsOffloadDataTransferCommand(cdb)) {
5315
5316 //
5317 // 1. Number of logical blocks of block device range descriptor exceeds capacity of the medium
5318 //
5319 TracePrint((TRACE_LEVEL_ERROR,
5320 TRACE_FLAG_IOCTL,
5321 "ClassInterpretSenseInfo (%p): LBA out of range (command %x, parameter field offset 0x%016llx)\n",
5322 Fdo,
5323 cdbOpcode,
5324 information));
5325
5326 NT_ASSERTMSG("Number of blocks specified exceeds LUN capacity", FALSE);
5327 }
5328 }
5329 break;
5330 }
5331
5332 //
5333 // 1. Generic error - cause not reportable
5334 // 2. Insufficient resources to create ROD
5335 // 3. Insufficient resources to create Token
5336 // 4. Max number of tokens exceeded
5337 // 5. Remote Token creation not supported
5338 // 6. Token expired
5339 // 7. Token unknown
5340 // 8. Unsupported Token type
5341 // 9. Token corrupt
5342 // 10. Token revoked
5343 // 11. Token cancelled
5344 // 12. Remote Token usage not supported
5345 //
5347
5348 TracePrint((TRACE_LEVEL_ERROR,
5349 TRACE_FLAG_IOCTL,
5350 "ClassInterpretSenseInfo (%p): Invalid/Expired/Modified token specified (command %x, parameter field offset 0x%016llx)\n",
5351 Fdo,
5352 cdbOpcode,
5353 information));
5354
5356 break;
5357 }
5358
5361
5362 //
5363 // 1. Mismatched I_T nexus and list identifier
5364 //
5365 TracePrint((TRACE_LEVEL_ERROR,
5366 TRACE_FLAG_IOCTL,
5367 "ClassInterpretSenseInfo (%p): Incorrect I_T nexus likely used (command %x)\n",
5368 Fdo,
5369 cdbOpcode));
5370
5371 //
5372 // The host should ensure that it sends TokenOperation and ReceiveTokenInformation for the same
5373 // list Id using the same I_T nexus.
5374 //
5376
5377 } else {
5378
5379 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5380 "Invalid CDB\n"));
5381
5382 //
5383 // Note: the retry interval is not typically used.
5384 // it is set here only because a ClassErrorHandler
5385 // cannot set the retryInterval, and the error may
5386 // require a few commands to be sent to clear whatever
5387 // caused this condition (i.e. disk clears the write
5388 // cache, requiring at least two commands)
5389 //
5390 // hopefully, this shortcoming can be changed for
5391 // blackcomb.
5392 //
5393
5394 retryInterval = 3;
5395 }
5396 break;
5397 }
5398
5400 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5401 "Invalid LUN\n"));
5403 break;
5404 }
5405
5407
5408 switch (addlSenseCodeQual) {
5409
5410 //
5411 // 1. Alignment violation (e.g. copy manager is unable to copy because destination offset is NOT aligned to LUN's granularity/alignment)
5412 //
5414
5415 TracePrint((TRACE_LEVEL_ERROR,
5416 TRACE_FLAG_IOCTL,
5417 "ClassInterpretSenseInfo (%p): Alignment violation for command %x.\n",
5418 Fdo,
5419 cdbOpcode));
5420
5421 NT_ASSERTMSG("Specified offset is not aligned to LUN's granularity", FALSE);
5422
5424 break;
5425 }
5426
5427 //
5428 // 1. Number of block device range descriptors is greater than maximum range descriptors
5429 //
5431
5432 TracePrint((TRACE_LEVEL_ERROR,
5433 TRACE_FLAG_IOCTL,
5434 "ClassInterpretSenseInfo (%p): Too many descriptors in parameter list for command %x (parameter field offset 0x%016llx)\n",
5435 Fdo,
5436 cdbOpcode,
5437 information));
5438
5439 NT_ASSERTMSG("Too many descriptors specified", FALSE);
5440
5442 break;
5443 }
5444
5445 default: {
5446
5448
5449 //
5450 // 1. (Various) Invalid parameter length
5451 // 2. Requested inactivity timeout is greater than maximum inactivity timeout
5452 // 3. Same LBA is included in more than one block device range descriptor (overlapping LBAs)
5453 // 4. Total number of logical blocks of all block range descriptors is greater than the maximum transfer size
5454 // 5. Total number of logical blocks of all block range descriptors is greater than maximum token transfer size
5455 // (e.g. WriteUsingToken descriptors specify a cumulative total block count that exceeds the PopulateToken that created the token)
5456 // 6. Block offset into ROD specified an offset that is greater than or equal to the number of logical blocks in the ROD
5457 // 7. Number of logical blocks in a block device range descriptor is greater than maximum transfer length in blocks
5458 //
5459 TracePrint((TRACE_LEVEL_ERROR,
5460 TRACE_FLAG_IOCTL,
5461 "ClassInterpretSenseInfo (%p): Illegal field in parameter list for command %x (parameter field offset 0x%016llx) [AddSense %x, AddSenseQ %x]\n",
5462 Fdo,
5463 cdbOpcode,
5465 addlSenseCode,
5466 addlSenseCodeQual));
5467
5468 NT_ASSERTMSG("Invalid field in parameter list", FALSE);
5469
5471 }
5472
5473 break;
5474 }
5475 }
5476 break;
5477 }
5478
5480 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5481 "Copy protection failure\n"));
5482
5484
5485 switch (addlSenseCodeQual) {
5487 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
5488 "ClassInterpretSenseInfo: "
5489 "Authentication failure\n"));
5491 break;
5493 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
5494 "ClassInterpretSenseInfo: "
5495 "Key not present\n"));
5497 break;
5499 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
5500 "ClassInterpretSenseInfo: "
5501 "Key not established\n"));
5503 break;
5505 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
5506 "ClassInterpretSenseInfo: "
5507 "Read of scrambled sector w/o "
5508 "authentication\n"));
5510 break;
5512 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
5513 "ClassInterpretSenseInfo: "
5514 "Media region does not logical unit "
5515 "region\n"));
5517 break;
5519 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
5520 "ClassInterpretSenseInfo: "
5521 "Region set error -- region may "
5522 "be permanent\n"));
5524 break;
5525 } // end switch of ASCQ for COPY_PROTECTION_FAILURE
5526
5527 break;
5528 }
5529
5531 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5532 "Music area\n"));
5533 break;
5534 }
5535
5537 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5538 "Data area\n"));
5539 break;
5540 }
5541
5543 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5544 "Volume overflow\n"));
5545 break;
5546 }
5547
5548 } // end switch (addlSenseCode)
5549
5550 break;
5551 } // end SCSI_SENSE_ILLEGAL_REQUEST
5552
5554
5555 ULONG count;
5556
5557 //
5558 // A media change may have occured so increment the change
5559 // count for the physical device
5560 //
5561
5562 count = InterlockedIncrement((volatile LONG *)&fdoExtension->MediaChangeCount);
5563 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_MCN, "ClassInterpretSenseInfo: "
5564 "Media change count for device %d incremented to %#lx\n",
5565 fdoExtension->DeviceNumber, count));
5566
5567
5568 switch (addlSenseCode) {
5570 logRetryableError = FALSE;
5571 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_MCN, "ClassInterpretSenseInfo: "
5572 "Media changed\n"));
5573
5574 if (!TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
5575 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_MCN, "ClassInterpretSenseInfo: "
5576 "Media Changed on non-removable device %p\n",
5577 Fdo));
5578 }
5579 ClassSetMediaChangeState(fdoExtension, MediaPresent, FALSE);
5580 break;
5581 }
5582
5584 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5585 "Bus reset\n"));
5586 break;
5587 }
5588
5590 logRetryableError = FALSE;
5591 if (addlSenseCodeQual == SCSI_SENSEQ_CAPACITY_DATA_CHANGED) {
5592 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5593 "Device capacity changed (e.g. thinly provisioned LUN). Retry the request.\n"));
5594
5596
5597 //
5598 // Retry with 1 second delay as ClassQueueCapacityChangedEventWorker may trigger a couple of commands sent to disk.
5599 //
5600 retryInterval = 1;
5601 retry = TRUE;
5602 }
5603 break;
5604 }
5605
5607
5608 switch (addlSenseCodeQual) {
5609
5611
5612 logRetryableError = FALSE;
5613 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5614 "Device (%p) has hit a soft threshold.\n",
5615 Fdo));
5616
5617 //
5618 // This indicates that a resource provisioned or thinly
5619 // provisioned device has hit a soft threshold. Queue a
5620 // worker thread to log a system event and then retry the
5621 // original request.
5622 //
5624 break;
5625 }
5626 default: {
5627 retry = FALSE;
5628 break;
5629 }
5630
5631 } // end switch (addlSenseCodeQual)
5632 break;
5633 }
5634
5636
5637 if (addlSenseCodeQual == SCSI_SENSEQ_MICROCODE_CHANGED) {
5638 //
5639 // Device firmware has been changed. Retry the request.
5640 //
5641 logRetryableError = TRUE;
5642 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5643 "Device firmware has been changed.\n"));
5644
5645 retryInterval = 1;
5646 retry = TRUE;
5647 } else {
5648 //
5649 // Device information has changed, we need to rescan the
5650 // bus for changed information such as the capacity.
5651 //
5652 logRetryableError = FALSE;
5653 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5654 "Device information changed. Invalidate the bus\n"));
5655
5656 if (addlSenseCodeQual == SCSI_SENSEQ_INQUIRY_DATA_CHANGED) {
5657
5659 }
5660
5661 if (addlSenseCodeQual == SCSI_SENSEQ_INQUIRY_DATA_CHANGED ||
5662 addlSenseCodeQual == SCSI_SENSEQ_OPERATING_DEFINITION_CHANGED) {
5663
5664 //
5665 // Since either the LB provisioning type changed, or the block/slab size
5666 // changed, next time anyone trying to query the FunctionSupportInfo, we
5667 // will requery the device.
5668 //
5669 InterlockedIncrement((volatile LONG *)&fdoExtension->FunctionSupportInfo->ChangeRequestCount);
5670 }
5671
5673 retryInterval = 5;
5674 }
5675 break;
5676 }
5677
5679 switch (addlSenseCodeQual) {
5680
5682 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5683 "Ejection request received!\n"));
5684 ClassSendEjectionNotification(fdoExtension);
5685 break;
5686 }
5687
5689 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5690 "Operator selected write permit?! "
5691 "(unsupported!)\n"));
5692 break;
5693 }
5694
5696 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5697 "Operator selected write protect?! "
5698 "(unsupported!)\n"));
5699 break;
5700 }
5701 }
5702 }
5703
5705
5706 UCHAR wmiEventData[sizeof(ULONG)+sizeof(UCHAR)] = {0};
5707
5708 *((PULONG)wmiEventData) = sizeof(UCHAR);
5709 wmiEventData[sizeof(ULONG)] = addlSenseCodeQual;
5710
5711 //
5712 // Don't log another eventlog if we have already logged once
5713 // NOTE: this should have been interlocked, but the structure
5714 // was publicly defined to use a BOOLEAN (char). Since
5715 // media only reports these errors once per X minutes,
5716 // the potential race condition is nearly non-existant.
5717 // the worst case is duplicate log entries, so ignore.
5718 //
5719
5720 logError = FALSE;
5721 if (fdoExtension->FailurePredicted == 0) {
5722 logError = TRUE;
5723 }
5724 fdoExtension->FailureReason = addlSenseCodeQual;
5725 logStatus = IO_WRN_FAILURE_PREDICTED;
5726
5727 ClassNotifyFailurePredicted(fdoExtension,
5728 (PUCHAR)wmiEventData,
5729 sizeof(wmiEventData),
5730 FALSE, // do not log error
5731 4, // unique error value
5734 SrbGetLun(Srb));
5735
5736 fdoExtension->FailurePredicted = TRUE;
5737
5738 //
5739 // Since this is a Unit Attention we need to make
5740 // sure we retry this request.
5741 //
5742 retry = TRUE;
5743
5744 break;
5745 }
5746
5747 default: {
5748 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5749 "Unit attention\n"));
5750 break;
5751 }
5752
5753 } // end switch (addlSenseCode)
5754
5755 if (TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA))
5756 {
5757
5758 if ((ClassGetVpb(Fdo) != NULL) && (ClassGetVpb(Fdo)->Flags & VPB_MOUNTED))
5759 {
5760 //
5761 // Set bit to indicate that media may have changed
5762 // and volume needs verification.
5763 //
5764
5765 SET_FLAG(Fdo->Flags, DO_VERIFY_VOLUME);
5766
5768 retry = FALSE;
5769 }
5770 else {
5772 }
5773 }
5774 else
5775 {
5777 }
5778
5779 break;
5780
5781 } // end SCSI_SENSE_UNIT_ATTENTION
5782
5784
5785 retry = FALSE;
5786
5787 if (addlSenseCode == SCSI_ADSENSE_WRITE_PROTECT)
5788 {
5789 switch (addlSenseCodeQual) {
5790
5792
5793 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5794 "Device's (%p) resources are exhausted.\n",
5795 Fdo));
5796
5798
5799 //
5800 // This indicates that a thinly-provisioned device has
5801 // hit a permanent resource exhaustion. We need to
5802 // return this status code so that patmgr can take the
5803 // disk offline.
5804 //
5806 break;
5807 }
5808 default:
5809 {
5810 break;
5811 }
5812
5813 } // end switch addlSenseCodeQual
5814 }
5815 else
5816 {
5817 if (IS_SCSIOP_WRITE(cdbOpcode)) {
5818 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5819 "Media write protected\n"));
5821 } else {
5822 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5823 "Access denied\n"));
5825 }
5826 }
5827 break;
5828 } // end SCSI_SENSE_DATA_PROTECT
5829
5831 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5832 "Media blank check\n"));
5833 retry = FALSE;
5835 break;
5836 } // end SCSI_SENSE_BLANK_CHECK
5837
5839
5840 switch (addlSenseCode) {
5841
5843
5844 switch (addlSenseCodeQual) {
5845
5846 //
5847 // 1. Target truncated the data transfer.
5848 //
5850
5851 TracePrint((TRACE_LEVEL_WARNING,
5852 TRACE_FLAG_IOCTL,
5853 "ClassInterpretSenseInfo (%p): Data transfer was truncated (command %x)\n",
5854 Fdo,
5855 cdbOpcode));
5856
5858 retry = FALSE;
5859 break;
5860 }
5861 }
5862 break;
5863 }
5864 }
5865 break;
5866 }
5867
5870
5871 switch (addlSenseCode) {
5872
5874
5875 switch (addlSenseCodeQual) {
5876
5877 //
5878 // 1. Target truncated the data transfer.
5879 //
5881
5882 TracePrint((TRACE_LEVEL_WARNING,
5883 TRACE_FLAG_IOCTL,
5884 "ClassInterpretSenseInfo (%p): Target has truncated the data transfer (command %x)\n",
5885 Fdo,
5886 cdbOpcode));
5887
5889 retry = FALSE;
5890 break;
5891 }
5892 }
5893 break;
5894 }
5895
5897
5898 switch (addlSenseCodeQual) {
5899
5900 //
5901 // 1. Copy manager wasn't able to finish the operation because of insuffient resources
5902 // (e.g. microsnapshot failure on read, no space on write, etc.)
5903 //
5905
5906 TracePrint((TRACE_LEVEL_ERROR,
5907 TRACE_FLAG_IOCTL,
5908 "ClassInterpretSenseInfo (%p): Target has insufficient resources (command %x)\n",
5909 Fdo,
5910 cdb->CDB6GENERIC.OperationCode));
5911
5913 retry = FALSE;
5914 break;
5915 }
5916 }
5917 break;
5918 }
5919 }
5920 } else {
5921 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5922 "Command aborted\n"));
5924 retryInterval = 1;
5925 }
5926 break;
5927 } // end SCSI_SENSE_ABORTED_COMMAND
5928
5929 default: {
5930 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5931 "Unrecognized sense code\n"));
5933 break;
5934 }
5935
5936 } // end switch (senseKey)
5937
5938
5939
5940 //
5941 // Try to determine bad sector information from sense data
5942 //
5943
5944 if (((IS_SCSIOP_READWRITE(cdbOpcode)) ||
5945 (cdbOpcode == SCSIOP_VERIFY) ||
5946 (cdbOpcode == SCSIOP_VERIFY16)) && cdb) {
5947
5948 if (isInformationValid)
5949 {
5950 readSector = 0;
5951 badSector = information;
5952
5953 if (cdbOpcode == SCSIOP_READ16 || cdbOpcode == SCSIOP_WRITE16 || cdbOpcode == SCSIOP_VERIFY16) {
5954 REVERSE_BYTES_QUAD(&readSector, &(cdb->AsByte[2]));
5955 } else {
5956 REVERSE_BYTES(&readSector, &(cdb->AsByte[2]));
5957 }
5958
5959 if (cdbOpcode == SCSIOP_READ || cdbOpcode == SCSIOP_WRITE || cdbOpcode == SCSIOP_VERIFY) {
5960 REVERSE_BYTES_SHORT(&index, &(cdb->CDB10.TransferBlocksMsb));
5961 } else if (cdbOpcode == SCSIOP_READ6 || cdbOpcode == SCSIOP_WRITE6) {
5962 index = cdb->CDB6READWRITE.TransferBlocks;
5963 } else if(cdbOpcode == SCSIOP_READ12 || cdbOpcode == SCSIOP_WRITE12) {
5964 REVERSE_BYTES(&index, &(cdb->CDB12.TransferLength));
5965 } else {
5966 REVERSE_BYTES(&index, &(cdb->CDB16.TransferLength));
5967 }
5968
5969 //
5970 // Make sure the bad sector is within the read sectors.
5971 //
5972
5973 if (!(badSector >= readSector && badSector < readSector + index)) {
5974 badSector = readSector;
5975 }
5976 }
5977 }
5978 }
5979
5980__ClassInterpretSenseInfo_ProcessingInvalidSenseBuffer:
5981
5982 if (!validSense) {
5983
5984 //
5985 // Request sense buffer not valid. No sense information
5986 // to pinpoint the error. Return general request fail.
5987 //
5988
5989 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassInterpretSenseInfo: "
5990 "Request sense info not valid. SrbStatus %2x\n",
5992 retry = TRUE;
5993
5994
5995 switch (SRB_STATUS(Srb->SrbStatus)) {
5996 case SRB_STATUS_ABORTED: {
5997
5998 //
5999 // Update the error count for the device.
6000 //
6001
6002 incrementErrorCount = TRUE;
6004 retryInterval = 1;
6005 retry = TRUE;
6006 break;
6007 }
6008
6009 case SRB_STATUS_ERROR: {
6010
6013
6014 //
6015 // This is some strange return code. Update the error
6016 // count for the device.
6017 //
6018
6019 incrementErrorCount = TRUE;
6020
6021 } else if (SrbGetScsiStatus(Srb) == SCSISTAT_BUSY) {
6022
6024 logRetryableError = FALSE;
6025 }
6026
6027 break;
6028 }
6029
6032 retry = FALSE;
6033 break;
6034 }
6035
6038 case SRB_STATUS_NO_HBA:
6042 retry = FALSE;
6043 break;
6044 }
6045
6047 logError = TRUE;
6048 logStatus = IO_ERR_NOT_READY;
6049 uniqueId = 260;
6051 retry = FALSE;
6052 break;
6053 }
6054
6055 case SRB_STATUS_TIMEOUT:
6057
6058 //
6059 // Update the error count for the device.
6060 //
6061 incrementErrorCount = TRUE;
6063 break;
6064 }
6065
6068
6069 //
6070 // Update the error count for the device
6071 // and fall through to below
6072 //
6073 incrementErrorCount = TRUE;
6074
6075 case SRB_STATUS_BUS_RESET: {
6076
6078 logRetryableError = FALSE;
6079 break;
6080 }
6081
6083
6085 retry = FALSE;
6086
6087 //
6088 // For some commands, we allocate a buffer that may be
6089 // larger than necessary. In these cases, the SRB may be
6090 // returned with SRB_STATUS_DATA_OVERRUN to indicate a
6091 // buffer *underrun*. However, the command was still
6092 // successful so we ensure STATUS_SUCCESS is returned.
6093 // We will also prevent these errors from causing noise in
6094 // the error logs.
6095 //
6096 if ((cdbOpcode == SCSIOP_MODE_SENSE && SrbGetDataTransferLength(Srb) <= cdb->MODE_SENSE.AllocationLength) ||
6097 (cdbOpcode == SCSIOP_INQUIRY && SrbGetDataTransferLength(Srb) <= cdb->CDB6INQUIRY.AllocationLength)) {
6099 logErrorInternal = FALSE;
6100 logError = FALSE;
6101 } else if (cdbOpcode == SCSIOP_MODE_SENSE10) {
6102 USHORT allocationLength;
6103 REVERSE_BYTES_SHORT(&(cdb->MODE_SENSE10.AllocationLength), &allocationLength);
6104 if (SrbGetDataTransferLength(Srb) <= allocationLength) {
6106 logErrorInternal = FALSE;
6107 logError = FALSE;
6108 }
6109 } else if (ClasspIsReceiveTokenInformation(cdb)) {
6110 ULONG allocationLength;
6111 REVERSE_BYTES(&(cdb->RECEIVE_TOKEN_INFORMATION.AllocationLength), &allocationLength);
6112 if (SrbGetDataTransferLength(Srb) <= allocationLength) {
6114 logErrorInternal = FALSE;
6115 logError = FALSE;
6116 }
6117 }
6118
6119 break;
6120 }
6121
6123
6124 //
6125 // Update the error count for the device.
6126 //
6127
6128 incrementErrorCount = TRUE;
6130
6131 //
6132 // If there was phase sequence error then limit the number of
6133 // retries.
6134 //
6135
6136 if (RetryCount > 1 ) {
6137 retry = FALSE;
6138 }
6139
6140 break;
6141 }
6142
6144
6145 //
6146 // If the status needs verification bit is set. Then set
6147 // the status to need verification and no retry; otherwise,
6148 // just retry the request.
6149 //
6150
6151 if (TEST_FLAG(Fdo->Flags, DO_VERIFY_VOLUME)) {
6152
6154 retry = FALSE;
6155
6156 } else {
6158 logRetryableError = FALSE;
6159 }
6160
6161 break;
6162 }
6163
6164
6165 default: {
6166 logError = TRUE;
6167 logStatus = IO_ERR_CONTROLLER_ERROR;
6168 uniqueId = 259;
6170 unhandledError = TRUE;
6171 logRetryableError = FALSE;
6172 break;
6173 }
6174 }
6175
6176
6177 //
6178 // NTRAID #183546 - if we support GESN subtype NOT_READY events, and
6179 // we know from a previous poll when the device will be ready (ETA)
6180 // we should delay the retry more appropriately than just guessing.
6181 //
6182 /*
6183 if (fdoExtension->MediaChangeDetectionInfo &&
6184 fdoExtension->MediaChangeDetectionInfo->Gesn.Supported &&
6185 TEST_FLAG(fdoExtension->MediaChangeDetectionInfo->Gesn.EventMask,
6186 NOTIFICATION_DEVICE_BUSY_CLASS_MASK)
6187 ) {
6188 // check if Gesn.ReadyTime if greater than current tick count
6189 // if so, delay that long (from 1 to 30 seconds max?)
6190 // else, leave the guess of time alone.
6191 }
6192 */
6193
6194 }
6195
6196 }
6197
6198 if (incrementErrorCount) {
6199
6200 //
6201 // if any error count occurred, delay the retry of this io by
6202 // at least one second, if caller supports it.
6203 //
6204
6205 if (retryInterval == 0) {
6206 retryInterval = 1;
6207 }
6208 ClasspPerfIncrementErrorCount(fdoExtension);
6209 }
6210
6211 //
6212 // If there is a class specific error handler call it.
6213 //
6214
6215 if (fdoExtension->CommonExtension.DevInfo->ClassError != NULL) {
6216
6217 SCSI_REQUEST_BLOCK tempSrb = {0};
6219
6220 //
6221 // If class driver does not support extended SRB and this is
6222 // an extended SRB, convert to legacy SRB and pass to class
6223 // driver.
6224 //
6226 ((fdoExtension->CommonExtension.DriverExtension->SrbSupport &
6229 srbPtr = &tempSrb;
6230 }
6231
6232 fdoExtension->CommonExtension.DevInfo->ClassError(Fdo,
6233 srbPtr,
6234 Status,
6235 &retry);
6236 }
6237
6238 //
6239 // If the caller wants to know the suggested retry interval tell them.
6240 //
6241
6242 if (ARGUMENT_PRESENT(RetryInterval)) {
6243 *RetryInterval = retryInterval;
6244 }
6245
6246 //
6247 // The RESERVE(6) / RELEASE(6) commands are optional. So
6248 // if they aren't supported, try the 10-byte equivalents
6249 //
6250
6251 cdb = SrbGetCdb(Srb);
6252 if (cdb) {
6253 cdbOpcode = cdb->CDB6GENERIC.OperationCode;
6254 }
6255
6256 if ((cdbOpcode == SCSIOP_RESERVE_UNIT ||
6257 cdbOpcode == SCSIOP_RELEASE_UNIT) && cdb)
6258 {
6260 {
6261 SrbSetCdbLength(Srb, 10);
6262 cdb->CDB10.OperationCode = (cdb->CDB6GENERIC.OperationCode == SCSIOP_RESERVE_UNIT) ? SCSIOP_RESERVE_UNIT10 : SCSIOP_RELEASE_UNIT10;
6263
6264 SET_FLAG(fdoExtension->PrivateFdoData->HackFlags, FDO_HACK_NO_RESERVE6);
6265 retry = TRUE;
6266 }
6267 }
6268
6269#if DBG
6270
6271 //
6272 // Ensure that for read/write requests, only return STATUS_DEVICE_BUSY if
6273 // reservation conflict.
6274 //
6275 if (IS_SCSIOP_READWRITE(cdbOpcode) && (*Status == STATUS_DEVICE_BUSY)) {
6276 NT_ASSERT(isReservationConflict == TRUE);
6277 }
6278
6279#endif
6280
6281 /*
6282 * LOG the error:
6283 * If logErrorInternal is set, log the error in our internal log.
6284 * If logError is set, also log the error in the system log.
6285 */
6286 if (logErrorInternal || logError) {
6287 ULONG totalSize;
6288 ULONG senseBufferSize = 0;
6289 IO_ERROR_LOG_PACKET staticErrLogEntry = {0};
6290 CLASS_ERROR_LOG_DATA staticErrLogData = {0};
6291 SENSE_DATA convertedSenseBuffer = {0};
6292 UCHAR convertedSenseBufferLength = 0;
6293 BOOLEAN senseDataConverted = FALSE;
6294
6295 //
6296 // Logic below assumes that IO_ERROR_LOG_PACKET + CLASS_ERROR_LOG_DATA
6297 // is less than ERROR_LOG_MAXIMUM_SIZE which is not true for extended SRB.
6298 // Given that classpnp currently does not use >16 byte CDB, we'll convert
6299 // an extended SRB to SCSI_REQUEST_BLOCK instead of changing this code.
6300 // More changes will need to be made when classpnp starts using >16 byte
6301 // CDBs.
6302 //
6303
6304 //
6305 // Calculate the total size of the error log entry.
6306 // add to totalSize in the order that they are used.
6307 // the advantage to calculating all the sizes here is
6308 // that we don't have to do a bunch of extraneous checks
6309 // later on in this code path.
6310 //
6311 totalSize = sizeof(IO_ERROR_LOG_PACKET) // required
6312 + sizeof(CLASS_ERROR_LOG_DATA);// struct for ease
6313
6314 //
6315 // also save any available extra sense data, up to the maximum errlog
6316 // packet size . WMI should be used for real-time analysis.
6317 // the event log should only be used for post-mortem debugging.
6318 //
6319 if ((TEST_FLAG(Srb->SrbStatus, SRB_STATUS_AUTOSENSE_VALID)) && senseBuffer) {
6320
6321 UCHAR validSenseBytes = 0;
6322 UCHAR senseInfoBufferLength = 0;
6323
6324 senseInfoBufferLength = SrbGetSenseInfoBufferLength(Srb);
6325
6326 //
6327 // If sense data is in Descriptor format, convert it to Fixed format
6328 // for the private log.
6329 //
6330
6331 if (IsDescriptorSenseDataFormat(senseBuffer)) {
6332
6333 convertedSenseBufferLength = sizeof(convertedSenseBuffer);
6334
6335 senseDataConverted = ScsiConvertToFixedSenseFormat(senseBuffer,
6336 senseInfoBufferLength,
6337 (PVOID)&convertedSenseBuffer,
6338 convertedSenseBufferLength);
6339 }
6340
6341 //
6342 // For System Log, copy the maximum amount of available sense data
6343 //
6344
6345 if (ScsiGetTotalSenseByteCountIndicated(senseBuffer,
6346 senseInfoBufferLength,
6347 &validSenseBytes)) {
6348
6349 //
6350 // If it is able to determine number of valid bytes,
6351 // copy the maximum amount of available
6352 // sense data that can be saved into the the errlog.
6353 //
6354
6355 //
6356 // set to save the most sense buffer possible
6357 //
6358
6359 senseBufferSize = max(validSenseBytes, sizeof(staticErrLogData.SenseData));
6360 senseBufferSize = min(senseBufferSize, senseInfoBufferLength);
6361
6362 } else {
6363 //
6364 // it's smaller than required to read the total number of
6365 // valid bytes, so just use the SenseInfoBufferLength field.
6366 //
6367 senseBufferSize = senseInfoBufferLength;
6368 }
6369
6370 /*
6371 * Bump totalSize by the number of extra senseBuffer bytes
6372 * (beyond the default sense buffer within CLASS_ERROR_LOG_DATA).
6373 * Make sure to never allocate more than ERROR_LOG_MAXIMUM_SIZE.
6374 */
6375 if (senseBufferSize > sizeof(staticErrLogData.SenseData)){
6376 totalSize += senseBufferSize-sizeof(staticErrLogData.SenseData);
6377 if (totalSize > ERROR_LOG_MAXIMUM_SIZE){
6378 senseBufferSize -= totalSize-ERROR_LOG_MAXIMUM_SIZE;
6379 totalSize = ERROR_LOG_MAXIMUM_SIZE;
6380 }
6381 }
6382 }
6383
6384 //
6385 // If we've used up all of our retry attempts, set the final status to
6386 // reflect the appropriate result.
6387 //
6388 // ISSUE: the test below should also check RetryCount to determine if we will actually retry,
6389 // but there is no easy test because we'd have to consider the original retry count
6390 // for the op; besides, InterpretTransferPacketError sometimes ignores the retry
6391 // decision returned by this function. So just ErrorRetried to be true in the majority case.
6392 //
6393 if (retry){
6394 staticErrLogEntry.FinalStatus = STATUS_SUCCESS;
6395 staticErrLogData.ErrorRetried = TRUE;
6396 } else {
6397 staticErrLogEntry.FinalStatus = *Status;
6398 }
6399
6400 //
6401 // Don't log generic IO_WARNING_PAGING_FAILURE message if either the
6402 // I/O is retried, or it completed successfully.
6403 //
6404 if (logStatus == IO_WARNING_PAGING_FAILURE &&
6405 (retry || NT_SUCCESS(*Status)) ) {
6406 logError = FALSE;
6407 }
6408
6410 staticErrLogData.ErrorPaging = TRUE;
6411 }
6412 if (unhandledError) {
6413 staticErrLogData.ErrorUnhandled = TRUE;
6414 }
6415
6416 //
6417 // Calculate the device offset if there is a geometry.
6418 //
6419 staticErrLogEntry.DeviceOffset.QuadPart = (LONGLONG)badSector;
6420 staticErrLogEntry.DeviceOffset.QuadPart *= (LONGLONG)fdoExtension->DiskGeometry.BytesPerSector;
6421 if (logStatus == -1){
6422 staticErrLogEntry.ErrorCode = STATUS_IO_DEVICE_ERROR;
6423 } else {
6424 staticErrLogEntry.ErrorCode = logStatus;
6425 }
6426
6427 /*
6428 * The dump data follows the IO_ERROR_LOG_PACKET
6429 */
6430 staticErrLogEntry.DumpDataSize = (USHORT)totalSize - sizeof(IO_ERROR_LOG_PACKET);
6431
6432 staticErrLogEntry.SequenceNumber = 0;
6433 staticErrLogEntry.MajorFunctionCode = MajorFunctionCode;
6434 staticErrLogEntry.IoControlCode = IoDeviceCode;
6435 staticErrLogEntry.RetryCount = (UCHAR) RetryCount;
6436 staticErrLogEntry.UniqueErrorValue = uniqueId;
6437
6438 KeQueryTickCount(&staticErrLogData.TickCount);
6439 staticErrLogData.PortNumber = (ULONG)-1;
6440
6441 /*
6442 * Save the entire contents of the SRB.
6443 */
6446 } else {
6447 staticErrLogData.Srb = *(PSCSI_REQUEST_BLOCK)Srb;
6448 }
6449
6450 /*
6451 * For our private log, save just the default length of the SENSE_DATA.
6452 */
6453
6454 if ((senseBufferSize != 0) && senseBuffer) {
6455
6456 //
6457 // If sense buffer is in Fixed format, put it in the private log
6458 //
6459 // If sense buffer is in Descriptor format, put it in the private log if conversion to Fixed format
6460 // succeeded. Otherwise, do not put it in the private log.
6461 //
6462 // If sense buffer is in unknown format, the device or the driver probably does not populate
6463 // the first byte of sense data, we probably still want to log error in this case assuming
6464 // it's fixed format, so that its sense key, its additional sense code, and its additional sense code
6465 // qualifier would be shown in the debugger extension output. By doing so, it minimizes any potential
6466 // negative impacts to our ability to diagnose issue.
6467 //
6468 if (IsDescriptorSenseDataFormat(senseBuffer)) {
6469 if (senseDataConverted) {
6470 RtlCopyMemory(&staticErrLogData.SenseData, &convertedSenseBuffer, min(convertedSenseBufferLength, sizeof(staticErrLogData.SenseData)));
6471 }
6472 } else {
6473 RtlCopyMemory(&staticErrLogData.SenseData, senseBuffer, min(senseBufferSize, sizeof(staticErrLogData.SenseData)));
6474 }
6475 }
6476
6477 /*
6478 * Save the error log in our context.
6479 * We only save the default sense buffer length.
6480 */
6481 if (logErrorInternal) {
6482 KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
6483 fdoData->ErrorLogs[fdoData->ErrorLogNextIndex] = staticErrLogData;
6484 fdoData->ErrorLogNextIndex++;
6486 KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);
6487 }
6488
6489 /*
6490 * Log an event if an IO is being retried for reasons that may indicate
6491 * a transient/permanent problem with the I_T_L nexus. But log the event
6492 * only once per retried IO.
6493 */
6494 if (!IS_SCSIOP_READWRITE(cdbOpcode) ||
6495 !retry ||
6496 (RetryCount != 0)) {
6497
6498 logRetryableError = FALSE;
6499 }
6500
6501 if (logRetryableError) {
6502
6503 logError = TRUE;
6504 }
6505
6506 /*
6507 * If logError is set, also save this log in the system's error log.
6508 * But make sure we don't log TUR failures over and over
6509 * (e.g. if an external drive was switched off and we're still sending TUR's to it every second).
6510 */
6511
6512 if (logError)
6513 {
6514 //
6515 // We do not want to log certain system events repetitively
6516 //
6517
6518 cdb = SrbGetCdb(Srb);
6519 if (cdb) {
6520 switch (cdb->CDB10.OperationCode)
6521 {
6523 {
6524 if (fdoData->LoggedTURFailureSinceLastIO)
6525 {
6526 logError = FALSE;
6527 }
6528 else
6529 {
6531 }
6532
6533 break;
6534 }
6535
6537 {
6538 if (fdoData->LoggedSYNCFailure)
6539 {
6540 logError = FALSE;
6541 }
6542 else
6543 {
6544 fdoData->LoggedSYNCFailure = TRUE;
6545 }
6546
6547 break;
6548 }
6549 }
6550 }
6551 }
6552
6553 if (logError){
6554
6555 if (logRetryableError) {
6556
6557 NT_ASSERT(IS_SCSIOP_READWRITE(cdbOpcode));
6558
6559 //
6560 // A large Disk TimeOutValue (like 60 seconds) results in giving a command a
6561 // large window to complete in. However, if the target returns a retryable error
6562 // just prior to the command timing out, and if multiple retries kick in, it may
6563 // take a significantly long time for the request to complete back to the
6564 // application, leading to a user perception of a hung system. So log an event
6565 // for retried IO so that an admin can help explain the reason for this behavior.
6566 //
6568 senseBufferSize,
6569 senseBuffer,
6573 cdbLength,
6574 cdb,
6575 NULL);
6576
6577 } else {
6578
6579 PIO_ERROR_LOG_PACKET errorLogEntry;
6580 PCLASS_ERROR_LOG_DATA errlogData;
6581
6582 errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(Fdo, (UCHAR)totalSize);
6583 if (errorLogEntry){
6584 errlogData = (PCLASS_ERROR_LOG_DATA)errorLogEntry->DumpData;
6585
6586 *errorLogEntry = staticErrLogEntry;
6587 *errlogData = staticErrLogData;
6588
6589 /*
6590 * For the system log, copy as much of the sense buffer as possible.
6591 */
6592 if ((senseBufferSize != 0) && senseBuffer) {
6593 RtlCopyMemory(&errlogData->SenseData, senseBuffer, senseBufferSize);
6594 }
6595
6596 /*
6597 * Write the error log packet to the system error logging thread.
6598 * It will be freed by the kernel.
6599 */
6600 IoWriteErrorLogEntry(errorLogEntry);
6601 }
6602 }
6603 }
6604 }
6605
6606 return retry;
6607
6608} // end ClassInterpretSenseInfo()
unsigned char BOOLEAN
#define InterlockedIncrement
Definition: armddk.h:53
#define index(s, c)
Definition: various.h:29
#define __int64
Definition: basetyps.h:16
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
#define DEV_SAFE_START_UNIT
Definition: cdrom.h:139
#define IS_SCSIOP_READWRITE(opCode)
Definition: cdrom.h:803
#define IS_SCSIOP_WRITE(opCode)
Definition: cdrom.h:797
#define SRB_CLASS_FLAGS_PAGING
Definition: cdrom.h:165
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
#define NUM_ERROR_LOG_ENTRIES
Definition: cdromp.h:323
@ MediaPresent
Definition: cdromp.h:82
@ MediaNotPresent
Definition: cdromp.h:83
@ MediaUnavailable
Definition: cdromp.h:84
#define SCSI_ADSENSE_ILLEGAL_BLOCK
Definition: cdrw_hw.h:1264
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define SCSIOP_MODE_SENSE10
Definition: cdrw_hw.h:946
#define SCSI_SENSEQ_INVALID_RELEASE_OF_PERSISTENT_RESERVATION
Definition: cdrw_hw.h:1362
#define SCSI_SENSEQ_MANUAL_INTERVENTION_REQUIRED
Definition: cdrw_hw.h:1315
#define SCSI_SENSE_NO_SENSE
Definition: cdrw_hw.h:1187
#define SCSI_SENSEQ_CLEANING_CARTRIDGE_INSTALLED
Definition: cdrw_hw.h:1324
#define SCSI_SENSEQ_OPERATION_IN_PROGRESS
Definition: cdrw_hw.h:1317
#define SCSISTAT_RESERVATION_CONFLICT
Definition: cdrw_hw.h:1084
#define SCSI_SENSEQ_AUTHENTICATION_FAILURE
Definition: cdrw_hw.h:1390
#define SCSIOP_INQUIRY
Definition: cdrw_hw.h:888
#define SCSISTAT_GOOD
Definition: cdrw_hw.h:1078
#define SCSI_ADSENSE_SEEK_ERROR
Definition: cdrw_hw.h:1232
#define SCSISTAT_BUSY
Definition: cdrw_hw.h:1081
#define SCSI_ADSENSE_REC_DATA_NOECC
Definition: cdrw_hw.h:1211
#define SCSI_SENSE_COPY_ABORTED
Definition: cdrw_hw.h:1197
#define SCSI_ADSENSE_INVALID_LUN
Definition: cdrw_hw.h:1266
#define SCSI_SENSE_DATA_PROTECT
Definition: cdrw_hw.h:1194
#define SCSI_ADSENSE_INVALID_CDB
Definition: cdrw_hw.h:1265
#define SCSI_ADSENSE_WRITE_PROTECT
Definition: cdrw_hw.h:1268
#define SCSI_ADSENSE_MUSIC_AREA
Definition: cdrw_hw.h:1282
#define SCSI_ADSENSE_TRACK_ERROR
Definition: cdrw_hw.h:1231
#define SCSI_SENSEQ_KEY_NOT_ESTABLISHED
Definition: cdrw_hw.h:1392
#define SCSI_SENSE_MEDIUM_ERROR
Definition: cdrw_hw.h:1190
#define SCSI_SENSEQ_READ_OF_SCRAMBLED_SECTOR_WITHOUT_AUTHENTICATION
Definition: cdrw_hw.h:1393
#define SCSI_ADSENSE_ILLEGAL_COMMAND
Definition: cdrw_hw.h:1263
#define SCSI_SENSEQ_UNKNOWN_FORMAT
Definition: cdrw_hw.h:1322
#define SCSI_SENSEQ_MEDIA_CODE_MISMATCHED_TO_LOGICAL_UNIT
Definition: cdrw_hw.h:1394
#define SCSI_SENSEQ_CAUSE_NOT_REPORTABLE
Definition: cdrw_hw.h:1312
#define SCSIOP_VERIFY
Definition: cdrw_hw.h:912
#define SCSI_SENSEQ_KEY_NOT_PRESENT
Definition: cdrw_hw.h:1391
#define SCSI_ADSENSE_REC_DATA_ECC
Definition: cdrw_hw.h:1212
#define NOT_READY_RETRY_INTERVAL
Definition: cdrw_hw.h:1094
#define SCSI_SENSEQ_BECOMING_READY
Definition: cdrw_hw.h:1313
#define SCSI_ADSENSE_INVALID_MEDIA
Definition: cdrw_hw.h:1220
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
#define SCSI_SENSEQ_LOGICAL_UNIT_RESET_COUNT_ERROR
Definition: cdrw_hw.h:1395
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
#define SCSI_ADSENSE_NO_SENSE
Definition: cdrw_hw.h:1207
#define SCSI_SENSE_UNIT_ATTENTION
Definition: cdrw_hw.h:1193
#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
Definition: cdrw_hw.h:1221
#define SCSI_SENSEQ_INIT_COMMAND_REQUIRED
Definition: cdrw_hw.h:1314
#define SCSI_ADSENSE_DATA_AREA
Definition: cdrw_hw.h:1283
#define SCSI_ADSENSE_MEDIUM_CHANGED
Definition: cdrw_hw.h:1288
#define SCSI_SENSE_BLANK_CHECK
Definition: cdrw_hw.h:1195
#define SCSI_SENSE_HARDWARE_ERROR
Definition: cdrw_hw.h:1191
#define SCSI_ADSENSE_VOLUME_OVERFLOW
Definition: cdrw_hw.h:1284
#define SCSI_SENSE_RECOVERED_ERROR
Definition: cdrw_hw.h:1188
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
#define SCSI_SENSE_ABORTED_COMMAND
Definition: cdrw_hw.h:1198
#define SCSI_ADSENSE_BUS_RESET
Definition: cdrw_hw.h:1289
#define SCSI_SENSEQ_FORMAT_IN_PROGRESS
Definition: cdrw_hw.h:1316
#define SCSIOP_SYNCHRONIZE_CACHE
Definition: cdrw_hw.h:918
#define SCSI_SENSEQ_LONG_WRITE_IN_PROGRESS
Definition: cdrw_hw.h:1318
VOID ClassQueueResourceExhaustionEventWorker(_In_ PDEVICE_OBJECT DeviceObject)
Definition: utils.c:5528
VOID ClassQueueCapacityChangedEventWorker(_In_ PDEVICE_OBJECT DeviceObject)
Definition: utils.c:5637
VOID ClasspQueueLogIOEventWithContextWorker(_In_ PDEVICE_OBJECT DeviceObject, _In_ ULONG SenseBufferSize, _In_ PVOID SenseData, _In_ UCHAR SrbStatus, _In_ UCHAR ScsiStatus, _In_ ULONG ErrorCode, _In_ ULONG CdbLength, _In_opt_ PCDB Cdb, _In_opt_ PTRANSFER_PACKET Pkt)
Definition: utils.c:6010
FORCEINLINE BOOLEAN ClasspIsOffloadDataTransferCommand(_In_ PCDB Cdb)
Definition: classp.h:2087
FORCEINLINE BOOLEAN ClasspIsReceiveTokenInformation(_In_ PCDB Cdb)
Definition: classp.h:2066
VOID ClassQueueThresholdEventWorker(_In_ PDEVICE_OBJECT DeviceObject)
Definition: utils.c:5471
VOID ClassQueueProvisioningTypeChangedEventWorker(_In_ PDEVICE_OBJECT DeviceObject)
Definition: utils.c:5726
struct _CLASS_ERROR_LOG_DATA * PCLASS_ERROR_LOG_DATA
VOID ClasspPerfIncrementErrorCount(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: utils.c:432
VOID ClasspConvertToScsiRequestBlock(_Out_ PSCSI_REQUEST_BLOCK Srb, _In_ PSTORAGE_REQUEST_BLOCK SrbEx)
Definition: utils.c:6559
VOID ClassSendEjectionNotification(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: autorun.c:155
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR MajorFunctionCode
Definition: classpnp.h:484
#define DEV_USE_16BYTE_CDB
Definition: classpnp.h:183
#define CLASS_SRB_STORAGE_REQUEST_BLOCK
Definition: classpnp.h:573
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR _In_ ULONG IoDeviceCode
Definition: classpnp.h:485
static PDB_INFORMATION information
Definition: db.cpp:178
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
PVPB NTAPI ClassGetVpb(_In_ PDEVICE_OBJECT DeviceObject)
Definition: class.c:11473
VOID NTAPI ClassSendStartUnit(_In_ PDEVICE_OBJECT Fdo)
Definition: class.c:3071
#define SCSIOP_VERIFY16
Definition: scsi.h:916
#define SRB_STATUS_INVALID_LUN
Definition: srb.h:362
#define SRB_STATUS_REQUEST_FLUSHED
Definition: srb.h:361
#define SRB_STATUS_PHASE_SEQUENCE_FAILURE
Definition: srb.h:359
#define SRB_STATUS_NO_HBA
Definition: srb.h:356
#define SRB_STATUS_BUS_RESET
Definition: srb.h:353
#define SRB_STATUS_INVALID_TARGET_ID
Definition: srb.h:363
#define SRB_STATUS_UNEXPECTED_BUS_FREE
Definition: srb.h:358
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:357
#define SRB_STATUS_ABORTED
Definition: srb.h:342
#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
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
#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_INTERNAL_ERROR
Definition: srb.h:373
#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 SRB_STATUS_INVALID_REQUEST
Definition: srb.h:346
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint index
Definition: glext.h:6031
if(dx< 0)
Definition: linetemp.h:194
#define min(a, b)
Definition: monoChain.cc:55
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define ARGUMENT_PRESENT(ArgumentPointer)
#define IO_ERR_NOT_READY
Definition: ntiologc.h:42
#define IO_ERR_SEEK_ERROR
Definition: ntiologc.h:33
#define IO_WRN_FAILURE_PREDICTED
Definition: ntiologc.h:78
#define IO_WARNING_PAGING_FAILURE
Definition: ntiologc.h:77
#define IO_ERR_CONTROLLER_ERROR
Definition: ntiologc.h:38
#define IO_WARNING_IO_OPERATION_RETRIED
Definition: ntiologc.h:114
#define IO_ERROR_IO_HARDWARE_ERROR
Definition: ntiologc.h:115
#define IO_RECOVERED_VIA_ECC
Definition: ntiologc.h:60
#define IO_ERR_BAD_BLOCK
Definition: ntiologc.h:34
VOID NTAPI IoWriteErrorLogEntry(IN PVOID ElEntry)
Definition: error.c:628
PVOID NTAPI IoAllocateErrorLogEntry(IN PVOID IoObject, IN UCHAR EntrySize)
Definition: error.c:528
#define STATUS_CLEANER_CARTRIDGE_INSTALLED
Definition: ntstatus.h:218
#define STATUS_CSS_AUTHENTICATION_FAILURE
Definition: ntstatus.h:882
#define STATUS_COPY_PROTECTION_FAILURE
Definition: ntstatus.h:881
#define STATUS_DISK_RESOURCES_EXHAUSTED
Definition: ntstatus.h:983
#define STATUS_CSS_REGION_MISMATCH
Definition: ntstatus.h:886
#define STATUS_INVALID_INITIATOR_TARGET_PATH
Definition: ntstatus.h:1005
#define STATUS_CSS_KEY_NOT_ESTABLISHED
Definition: ntstatus.h:884
#define STATUS_CSS_SCRAMBLED_SECTOR
Definition: ntstatus.h:885
#define STATUS_TOO_MANY_SEGMENT_DESCRIPTORS
Definition: ntstatus.h:1001
#define STATUS_CSS_KEY_NOT_PRESENT
Definition: ntstatus.h:883
#define STATUS_INVALID_OFFSET_ALIGNMENT
Definition: ntstatus.h:1002
#define STATUS_INVALID_TOKEN
Definition: ntstatus.h:987
#define STATUS_DEVICE_UNREACHABLE
Definition: ntstatus.h:986
#define STATUS_OPERATION_IN_PROGRESS
Definition: ntstatus.h:1004
#define STATUS_DEVICE_HARDWARE_ERROR
Definition: ntstatus.h:1017
#define STATUS_INVALID_FIELD_IN_PARAMETER_LIST
Definition: ntstatus.h:1003
#define STATUS_CSS_RESETS_EXHAUSTED
Definition: ntstatus.h:887
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
#define CLASS_SPECIAL_CAUSE_NOT_REPORTABLE_HACK
Definition: scsi_port.h:175
#define SCSI_ADSENSE_INVALID_FIELD_PARAMETER_LIST
Definition: scsi.h:672
#define ScsiGetSenseDescriptorLength(DescriptorBuffer)
Definition: scsi.h:3678
#define SCSI_ADSENSE_COPY_PROTECTION_FAILURE
Definition: scsi.h:694
#define SCSI_ADSENSE_INVALID_TOKEN
Definition: scsi.h:669
#define SCSI_ADSENSE_FAILURE_PREDICTION_THRESHOLD_EXCEEDED
Definition: scsi.h:692
#define SCSI_SENSEQ_TOO_MANY_SEGMENT_DESCRIPTORS
Definition: scsi.h:799
#define SCSI_ADSENSE_LB_PROVISIONING
Definition: scsi.h:680
#define SCSI_SENSEQ_OPERATION_IS_IN_PROGRESS
Definition: scsi.h:712
#define SCSI_SENSEQ_OPERATING_DEFINITION_CHANGED
Definition: scsi.h:842
#define SCSI_SENSEQ_INSUFFICIENT_RESOURCES
Definition: scsi.h:874
#define SCSI_SENSE_DESCRIPTOR_TYPE_INFORMATION
Definition: scsi.h:630
#define SCSI_SENSEQ_INITIATOR_RESPONSE_TIMEOUT
Definition: scsi.h:867
#define SCSI_SENSEQ_INQUIRY_DATA_CHANGED
Definition: scsi.h:843
#define SCSI_SENSEQ_SPACE_ALLOC_IN_PROGRESS
Definition: scsi.h:731
#define SCSI_ADSENSE_RESOURCE_FAILURE
Definition: scsi.h:690
#define SCSI_SESNEQ_COMM_CRC_ERROR
Definition: scsi.h:738
#define SCSI_SENSEQ_SOFT_THRESHOLD_REACHED
Definition: scsi.h:828
#define SCSI_ADSENSE_LUN_COMMUNICATION
Definition: scsi.h:653
#define SCSI_SENSEQ_TIMEOUT_ON_LOGICAL_UNIT
Definition: scsi.h:834
#define IsSenseDataFormatValueValid(SenseInfoBuffer)
Definition: scsi.h:3697
UCHAR descriptorLength
Definition: scsi.h:4078
#define SCSI_SENSE_DESCRIPTOR_TYPE_BLOCK_COMMAND
Definition: scsi.h:635
#define SCSI_SENSEQ_WRITE_PROTECT_DISABLE
Definition: scsi.h:881
#define REVERSE_BYTES_SHORT(Destination, Source)
Definition: scsi.h:3474
#define SCSI_SENSEQ_MICROCODE_CHANGED
Definition: scsi.h:841
#define SCSI_ADSENSE_PARAMETERS_CHANGED
Definition: scsi.h:676
#define SCSI_SENSEQ_UNREACHABLE_TARGET
Definition: scsi.h:739
UCHAR senseKey
Definition: scsi.h:4019
#define SCSI_SENSEQ_MEDIUM_REMOVAL
Definition: scsi.h:879
struct _SENSE_DATA * PFIXED_SENSE_DATA
Definition: scsi.h:2723
#define ScsiGetSenseErrorCode(SenseInfoBuffer)
Definition: scsi.h:3676
#define SCSI_SENSEQ_CAPACITY_DATA_CHANGED
Definition: scsi.h:807
#define SCSI_ADSENSE_OPERATOR_REQUEST
Definition: scsi.h:691
#define SCSI_ADSENSE_COPY_TARGET_DEVICE_ERROR
Definition: scsi.h:657
#define SCSI_ADSENSE_OPERATING_CONDITIONS_CHANGED
Definition: scsi.h:684
#define SCSI_ADSENSE_DATA_TRANSFER_ERROR
Definition: scsi.h:688
#define SCSI_SENSEQ_DATA_UNDERRUN
Definition: scsi.h:761
PFIXED_SENSE_DATA outBuffer
Definition: scsi.h:4022
struct _SCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND * PSCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND
#define SCSI_ADSENSE_PARAMETER_LIST_LENGTH
Definition: scsi.h:664
#define SCSI_ADSENSE_LOGICAL_UNIT_ERROR
Definition: scsi.h:683
#define SCSI_SENSEQ_WRITE_PROTECT_ENABLE
Definition: scsi.h:880
#define SCSI_SENSEQ_SPACE_ALLOC_FAILED_WRITE_PROTECT
Definition: scsi.h:803
#define SCSI_SENSE_OPTIONS_NONE
Definition: scsi.h:3838
BOOLEAN validSense
Definition: scsi.h:4018
#define IsDescriptorSenseDataFormat(SenseInfoBuffer)
Definition: scsi.h:3685
struct SRB_ALIGN _STORAGE_REQUEST_BLOCK_HEADER * PSTORAGE_REQUEST_BLOCK_HEADER
#define KeQueryTickCount(CurrentCount)
Definition: ke.h:43
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
FORCEINLINE UCHAR SrbGetCdbLength(_In_ PVOID Srb)
Definition: srbhelper.h:1074
FORCEINLINE UCHAR SrbGetTargetId(_In_ PVOID Srb)
Definition: srbhelper.h:1184
FORCEINLINE UCHAR SrbGetLun(_In_ PVOID Srb)
Definition: srbhelper.h:1217
FORCEINLINE UCHAR SrbGetPathId(_In_ PVOID Srb)
Definition: srbhelper.h:1151
FORCEINLINE UCHAR SrbGetScsiStatus(_In_ PVOID Srb)
Definition: srbhelper.h:1037
FORCEINLINE ULONG SrbGetSrbFlags(_In_ PVOID Srb)
Definition: srbhelper.h:927
FORCEINLINE PVOID SrbGetSenseInfoBuffer(_In_ PVOID Srb)
Definition: srbhelper.h:619
FORCEINLINE ULONG SrbGetSystemStatus(_In_ PVOID Srb)
Definition: srbhelper.h:1000
FORCEINLINE UCHAR SrbGetSenseInfoBufferLength(_In_ PVOID Srb)
Definition: srbhelper.h:638
FORCEINLINE ULONG SrbGetDataTransferLength(_In_ PVOID Srb)
Definition: srbhelper.h:765
PCLASS_ERROR ClassError
Definition: classpnp.h:522
SENSE_DATA SenseData
Definition: classp.h:479
LARGE_INTEGER TickCount
Definition: classp.h:461
SCSI_REQUEST_BLOCK Srb
Definition: classp.h:471
BOOLEAN LegacyErrorHandling
Definition: classp.h:971
BOOLEAN LoggedSYNCFailure
Definition: classp.h:754
KSPIN_LOCK SpinLock
Definition: classp.h:795
BOOLEAN LoggedTURFailureSinceLastIO
Definition: classp.h:753
CLASS_ERROR_LOG_DATA ErrorLogs[NUM_ERROR_LOG_ENTRIES]
Definition: classp.h:821
PCLASS_DRIVER_EXTENSION DriverExtension
Definition: classpnp.h:600
PCLASS_DEV_INFO DevInfo
Definition: classpnp.h:620
ULONG BytesPerSector
Definition: ntdddisk.h:409
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:888
PDEVICE_OBJECT LowerPdo
Definition: classpnp.h:875
LARGE_INTEGER DeviceOffset
Definition: iotypes.h:2012
NTSTATUS ErrorCode
Definition: iotypes.h:2007
NTSTATUS FinalStatus
Definition: iotypes.h:2009
#define max(a, b)
Definition: svc.c:63
uint32_t * PULONG
Definition: typedefs.h:59
int64_t LONGLONG
Definition: typedefs.h:68
uint16_t * PUSHORT
Definition: typedefs.h:56
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define STATUS_RETRY
Definition: udferr_usr.h:182
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_UNRECOGNIZED_MEDIA
Definition: udferr_usr.h:142
#define STATUS_INVALID_BLOCK_LENGTH
Definition: udferr_usr.h:175
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define STATUS_NONEXISTENT_SECTOR
Definition: udferr_usr.h:143
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
#define STATUS_NO_DATA_DETECTED
Definition: udferr_usr.h:131
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
UCHAR AsByte[16]
Definition: scsi.h:1988
struct _CDB::_MODE_SENSE10 MODE_SENSE10
struct _CDB::_CDB12 CDB12
struct _CDB::_CDB6INQUIRY CDB6INQUIRY
struct _CDB::_MODE_SENSE MODE_SENSE
struct _CDB::_RECEIVE_TOKEN_INFORMATION RECEIVE_TOKEN_INFORMATION
struct _CDB::_CDB16 CDB16
struct _CDB::_CDB6READWRITE CDB6READWRITE
ULONG LowPart
Definition: typedefs.h:106
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ERROR_LOG_MAXIMUM_SIZE
Definition: iotypes.h:2042
#define VPB_MOUNTED
Definition: iotypes.h:1807
struct _IO_ERROR_LOG_PACKET * PIO_ERROR_LOG_PACKET
struct _IO_ERROR_LOG_PACKET IO_ERROR_LOG_PACKET
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3311
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by ClasspReceivePopulateTokenInformationTransferPacketDone(), ClasspReceiveWriteUsingTokenInformationTransferPacketDone(), DiskInfoExceptionComplete(), InterpretSenseInfoWithoutHistory(), and InterpretTransferPacketError().

◆ ClassIoComplete()

SCSIPORT_API NTSTATUS NTAPI ClassIoComplete ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  Context 
)

◆ ClassIoCompleteAssociated()

SCSIPORT_API NTSTATUS NTAPI ClassIoCompleteAssociated ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  Context 
)

◆ ClassModeSense()

SCSIPORT_API ULONG NTAPI ClassModeSense ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_reads_bytes_(Length) PCHAR  ModeSenseBuffer,
_In_ ULONG  Length,
_In_ UCHAR  PageMode 
)

Definition at line 6637 of file class.c.

6643{
6644 PAGED_CODE();
6645
6646 return ClasspModeSense(Fdo,
6647 ModeSenseBuffer,
6648 Length,
6649 PageMode,
6651}
#define PAGED_CODE()
#define MODE_SENSE_CURRENT_VALUES
Definition: cdrw_hw.h:859
ULONG ClasspModeSense(_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode, _In_ UCHAR PageControl)
Definition: class.c:6681

Referenced by ClasspWriteCacheProperty(), ClasspZeroQERR(), DetermineDriveType(), DiskGetCacheInformation(), DiskGetInfoExceptionInformation(), DiskSetCacheInformation(), FormatMedia(), and ScsiFlopDeviceControl().

◆ ClassReadDriveCapacity()

_Must_inspect_result_ SCSIPORT_API NTSTATUS NTAPI ClassReadDriveCapacity ( _In_ PDEVICE_OBJECT  DeviceObject)

Definition at line 2742 of file class.c.

2743{
2744 PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
2745 PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
2746 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
2747 READ_CAPACITY_DATA_EX PTRALIGN readCapacityData = {0};
2748 PTRANSFER_PACKET pkt;
2750 PMDL driveCapMdl = NULL;
2751 KEVENT event;
2752 IRP pseudoIrp = {0};
2753 ULONG readCapacityDataSize;
2754 BOOLEAN use16ByteCdb;
2755 BOOLEAN match = TRUE;
2756
2757 use16ByteCdb = TEST_FLAG(fdoExt->DeviceFlags, DEV_USE_16BYTE_CDB);
2758
2760
2761 if (use16ByteCdb) {
2762 readCapacityDataSize = sizeof(READ_CAPACITY_DATA_EX);
2763 } else {
2764 readCapacityDataSize = sizeof(READ_CAPACITY_DATA);
2765 }
2766
2767 if (driveCapMdl != NULL) {
2768 FreeDeviceInputMdl(driveCapMdl);
2769 driveCapMdl = NULL;
2770 }
2771
2772 //
2773 // Allocate the MDL based on the Read Capacity command.
2774 //
2775 driveCapMdl = BuildDeviceInputMdl(&readCapacityData, readCapacityDataSize);
2776 if (driveCapMdl == NULL) {
2778 goto SafeExit;
2779 }
2780
2782 if (pkt == NULL) {
2784 goto SafeExit;
2785 }
2786
2787 //
2788 // Our engine needs an "original irp" to write the status back to
2789 // and to count down packets (one in this case).
2790 // Just use a pretend irp for this.
2791 //
2792
2793 pseudoIrp.Tail.Overlay.DriverContext[0] = LongToPtr(1);
2794 pseudoIrp.IoStatus.Status = STATUS_SUCCESS;
2795 pseudoIrp.IoStatus.Information = 0;
2796 pseudoIrp.MdlAddress = driveCapMdl;
2797
2798 //
2799 // Set this up as a SYNCHRONOUS transfer, submit it,
2800 // and wait for the packet to complete. The result
2801 // status will be written to the original irp.
2802 //
2803
2806 &readCapacityData,
2807 readCapacityDataSize,
2808 &event,
2809 &pseudoIrp,
2810 use16ByteCdb);
2813
2814 status = pseudoIrp.IoStatus.Status;
2815
2816 //
2817 // If we got an UNDERRUN, retry exactly once.
2818 // (The transfer_packet engine didn't retry because the result
2819 // status was success).
2820 //
2821
2822 if (NT_SUCCESS(status) &&
2823 (pseudoIrp.IoStatus.Information < readCapacityDataSize)) {
2824
2825 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_INIT, "ClassReadDriveCapacity: read len (%xh) < %xh, retrying ...",
2826 (ULONG)pseudoIrp.IoStatus.Information, readCapacityDataSize));
2827
2829 if (pkt) {
2830 pseudoIrp.Tail.Overlay.DriverContext[0] = LongToPtr(1);
2831 pseudoIrp.IoStatus.Status = STATUS_SUCCESS;
2832 pseudoIrp.IoStatus.Information = 0;
2835 &readCapacityData,
2836 readCapacityDataSize,
2837 &event,
2838 &pseudoIrp,
2839 use16ByteCdb);
2842 status = pseudoIrp.IoStatus.Status;
2843 if (pseudoIrp.IoStatus.Information < readCapacityDataSize){
2845 }
2846 } else {
2848 }
2849 }
2850
2851 if (NT_SUCCESS(status)) {
2852 //
2853 // The request succeeded. Check for 8 byte LBA support.
2854 //
2855
2856 if (use16ByteCdb == FALSE) {
2857
2858 PREAD_CAPACITY_DATA readCapacity;
2859
2860 //
2861 // Check whether the device supports 8 byte LBA. If the device supports
2862 // it then retry the request using 16 byte CDB.
2863 //
2864
2865 readCapacity = (PREAD_CAPACITY_DATA) &readCapacityData;
2866
2867 if (readCapacity->LogicalBlockAddress == 0xFFFFFFFF) {
2868 //
2869 // Device returned max size for last LBA. Need to send
2870 // 16 byte request to get the size.
2871 //
2872 use16ByteCdb = TRUE;
2873 goto RetryRequest;
2874
2875 } else {
2876 //
2877 // Convert the 4 byte LBA (READ_CAPACITY_DATA) to 8 byte LBA (READ_CAPACITY_DATA_EX)
2878 // format for ease of use. This is the only format stored in the device extension.
2879 //
2880
2881 RtlMoveMemory((PUCHAR)(&readCapacityData) + sizeof(ULONG), readCapacity, sizeof(READ_CAPACITY_DATA));
2882 RtlZeroMemory((PUCHAR)(&readCapacityData), sizeof(ULONG));
2883
2884 }
2885 } else {
2886 //
2887 // Device completed 16 byte command successfully, it supports 8-byte LBA.
2888 //
2889
2891 }
2892
2893 //
2894 // Read out and store the drive information.
2895 //
2896
2897 InterpretCapacityData(Fdo, &readCapacityData);
2898
2899 //
2900 // Before caching the new drive capacity, compare it with the
2901 // cached capacity for any change.
2902 //
2903
2904 if (fdoData->IsCachedDriveCapDataValid == TRUE) {
2905
2907 &readCapacityData, sizeof(READ_CAPACITY_DATA_EX));
2908 }
2909
2910 //
2911 // Store the readCapacityData in private FDO data.
2912 // This is so that runtime memory failures don't cause disk.sys to put
2913 // the paging disk in an error state. Also this is used in
2914 // IOCTL_STORAGE_READ_CAPACITY.
2915 //
2916 fdoData->LastKnownDriveCapacityData = readCapacityData;
2918
2919 if (match == FALSE) {
2920 if (commonExtension->CurrentState != IRP_MN_START_DEVICE)
2921 {
2922 //
2923 // This can happen if a disk reports Parameters Changed / Capacity Data Changed sense data.
2924 // NT_ASSERT(!"Drive capacity has changed while the device wasn't started!");
2925 //
2926 } else {
2927 //
2928 // state of (commonExtension->CurrentState == IRP_MN_START_DEVICE) indicates that the device has been started.
2929 // UpdateDiskPropertiesWorkItemActive is used as a flag to ensure we only have one work item updating the disk
2930 // properties at a time.
2931 //
2932 if (InterlockedCompareExchange((volatile LONG *)&fdoData->UpdateDiskPropertiesWorkItemActive, 1, 0) == 0)
2933 {
2934 PIO_WORKITEM workItem;
2935
2936 workItem = IoAllocateWorkItem(Fdo);
2937
2938 if (workItem) {
2939 //
2940 // The disk capacity has changed, send notification to the disk driver.
2941 // Start a work item to notify the disk class driver asynchronously.
2942 //
2944 } else {
2946 }
2947 }
2948 }
2949 }
2950
2951 } else {
2952 //
2953 // The request failed.
2954 //
2955
2956 //
2957 // ISSUE - 2000/02/04 - henrygab - non-512-byte sector sizes and failed geometry update
2958 // what happens when the disk's sector size is bigger than
2959 // 512 bytes and we hit this code path? this is untested.
2960 //
2961 // If the read capacity fails, set the geometry to reasonable parameter
2962 // so things don't fail at unexpected places. Zero the geometry
2963 // except for the bytes per sector and sector shift.
2964 //
2965
2966 //
2967 // This request can sometimes fail legitimately
2968 // (e.g. when a SCSI device is attached but turned off)
2969 // so this is not necessarily a device/driver bug.
2970 //
2971
2972 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_INIT, "ClassReadDriveCapacity on Fdo %p failed with status %ul.", Fdo, status));
2973
2974 //
2975 // Write in a default disk geometry which we HOPE is right (??).
2976 //
2977
2978 RtlZeroMemory(&fdoExt->DiskGeometry, sizeof(DISK_GEOMETRY));
2979 fdoExt->DiskGeometry.BytesPerSector = 512;
2980 fdoExt->SectorShift = 9;
2982
2983 //
2984 // Is this removable or fixed media
2985 //
2986
2987 if (TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)){
2989 } else {
2991 }
2992 }
2993
2994SafeExit:
2995
2996
2997 //
2998 // In case DEV_USE_16BYTE_CDB flag is not set, classpnp translates R/W request into READ/WRITE 10 SCSI command.
2999 // These SCSI commands have 2 bytes in "Transfer Blocks" field.
3000 // Make sure this max length (0xFFFF * sector size) is respected during request split.
3001 //
3002 if (!TEST_FLAG(fdoExt->DeviceFlags, DEV_USE_16BYTE_CDB)) {
3003 ULONG cdb10MaxBlocks = ((ULONG)USHORT_MAX) << fdoExt->SectorShift;
3004
3005 fdoData->HwMaxXferLen = min(cdb10MaxBlocks, fdoData->HwMaxXferLen);
3006 }
3007
3008 if (driveCapMdl != NULL) {
3009 FreeDeviceInputMdl(driveCapMdl);
3010 }
3011
3012 //
3013 // If the request failed for some reason then invalidate the cached
3014 // capacity data for removable devices. So that we won't return
3015 // wrong capacity in IOCTL_STORAGE_READ_CAPACITY
3016 //
3017
3018 if (!NT_SUCCESS(status) && (fdoExt->DiskGeometry.MediaType == RemovableMedia)) {
3020 }
3021
3022 //
3023 // Don't let memory failures (either here or in the port driver) in the ReadDriveCapacity call
3024 // put the paging disk in an error state such that paging fails.
3025 // Return the last known drive capacity (which may possibly be slightly out of date, even on
3026 // fixed media, e.g. for storage cabinets that can grow a logical disk).
3027 //
3029 (fdoData->IsCachedDriveCapDataValid) &&
3030 (fdoExt->DiskGeometry.MediaType == FixedMedia)) {
3031 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_INIT, "ClassReadDriveCapacity: defaulting to cached DriveCapacity data"));
3034 }
3035
3036 return status;
3037}
#define InterlockedExchange
Definition: armddk.h:54
#define LongToPtr(l)
Definition: basetsd.h:91
#define PTRALIGN
Definition: cdromp.h:44
struct _READ_CAPACITY_DATA * PREAD_CAPACITY_DATA
struct _READ_CAPACITY_DATA READ_CAPACITY_DATA
VOID FreeDeviceInputMdl(PMDL Mdl)
Definition: utils.c:622
VOID RetryRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp, PSCSI_REQUEST_BLOCK Srb, BOOLEAN Associated, LONGLONG TimeDelta100ns)
Definition: obsolete.c:359
PTRANSFER_PACKET DequeueFreeTransferPacket(PDEVICE_OBJECT Fdo, BOOLEAN AllocIfNeeded)
Definition: xferpkt.c:656
VOID SetupDriveCapacityTransferPacket(TRANSFER_PACKET *Pkt, PVOID ReadCapacityBuffer, ULONG ReadCapacityBufferLen, PKEVENT SyncEventPtr, PIRP OriginalIrp, BOOLEAN Use16ByteCdb)
Definition: xferpkt.c:1480
NTSTATUS SubmitTransferPacket(PTRANSFER_PACKET Pkt)
Definition: xferpkt.c:850
PMDL BuildDeviceInputMdl(PVOID Buffer, ULONG BufferLen)
Definition: utils.c:609
IO_WORKITEM_ROUTINE ClasspUpdateDiskProperties
Definition: classp.h:1714
VOID InterpretCapacityData(PDEVICE_OBJECT Fdo, PREAD_CAPACITY_DATA_EX ReadCapacityData)
Definition: class.c:2640
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
struct _cl_event * event
Definition: glext.h:7739
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define USHORT_MAX
Definition: intsafe.h:147
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
#define RtlEqualMemory(a, b, c)
Definition: kdvm.h:18
@ RemovableMedia
Definition: ntdddisk.h:387
@ FixedMedia
Definition: ntdddisk.h:388
@ SynchronizationEvent
#define BOOLEAN
Definition: pedump.c:73
struct _READ_CAPACITY_DATA_EX READ_CAPACITY_DATA_EX
ULONG UpdateDiskPropertiesWorkItemActive
Definition: classp.h:704
MEDIA_TYPE MediaType
Definition: ntdddisk.h:406
IO_STATUS_BLOCK IoStatus
ULONG LogicalBlockAddress
Definition: cdrw_hw.h:1471
Definition: match.c:28
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
@ DelayedWorkQueue
Definition: extypes.h:190
#define IRP_MN_START_DEVICE
@ Executive
Definition: ketypes.h:415

Referenced by ClassDeviceControl(), ClasspDeviceGetLBAStatusWorker(), ClasspDeviceLBProvisioningProperty(), ClasspDeviceTrimProcess(), DetermineMediaType(), DiskInitFdo(), and USBFlopGetMediaTypes().

◆ ClassReleaseChildLock()

SCSIPORT_API VOID NTAPI ClassReleaseChildLock ( _In_ PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension)

Definition at line 12019 of file class.c.

12022{
12023 NT_ASSERT(FdoExtension->ChildLockOwner == KeGetCurrentThread());
12024 NT_ASSERT(FdoExtension->ChildLockAcquisitionCount != 0);
12025
12026 FdoExtension->ChildLockAcquisitionCount -= 1;
12027
12028 if(FdoExtension->ChildLockAcquisitionCount == 0) {
12029 FdoExtension->ChildLockOwner = NULL;
12031 }
12032
12033 return;
12034} // end ClassReleaseChildLock(
#define KeGetCurrentThread
Definition: hal.h:55

Referenced by ClassAddChild(), ClassRemoveChild(), and ClassRetrieveDeviceRelations().

◆ ClassReleaseQueue()

SCSIPORT_API VOID NTAPI ClassReleaseQueue ( _In_ PDEVICE_OBJECT  DeviceObject)

Definition at line 11589 of file class.c.

11592{
11594 return;
11595} // end ClassReleaseQueue()
VOID ClasspReleaseQueue(IN PDEVICE_OBJECT Fdo, IN PIRP ReleaseQueueIrp OPTIONAL)
Definition: class.c:11743

Referenced by ClassAsynchronousCompletion(), ClassIoComplete(), ClassIoCompleteAssociated(), DiskInfoExceptionComplete(), and TransferPktComplete().

◆ ClassReleaseRemoveLock()

SCSIPORT_API VOID NTAPI ClassReleaseRemoveLock ( _In_ PDEVICE_OBJECT  DeviceObject,
PIRP  Tag 
)

◆ ClassResetMediaChangeTimer()

SCSIPORT_API VOID NTAPI ClassResetMediaChangeTimer ( _In_ PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension)

Definition at line 1804 of file autorun.c.

1807{
1808 PMEDIA_CHANGE_DETECTION_INFO info = FdoExtension->MediaChangeDetectionInfo;
1809
1810 if(info != NULL) {
1811 InterlockedExchange(&(info->MediaChangeCountDown),
1813 }
1814 return;
1815} // end ClassResetMediaChangeTimer()
#define MEDIA_CHANGE_DEFAULT_TIME
Definition: classpnp.h:132

Referenced by ClasspMediaChangeDetectionCompletion().

◆ ClassSendDeviceIoControlSynchronous()

VOID NTAPI ClassSendDeviceIoControlSynchronous ( _In_ ULONG  IoControlCode,
_In_ PDEVICE_OBJECT  TargetDeviceObject,
_Inout_updates_opt_(_Inexpressible_(max(InputBufferLength, OutputBufferLength))) PVOID  Buffer,
_In_ ULONG  InputBufferLength,
_In_ ULONG  OutputBufferLength,
_In_ BOOLEAN  InternalDeviceIoControl,
_Out_ PIO_STATUS_BLOCK  IoStatus 
)

Definition at line 11065 of file class.c.

11074{
11075 PIRP irp;
11077 ULONG method;
11078
11079 PAGED_CODE();
11080
11081 irp = NULL;
11082 method = IoControlCode & 3;
11083
11084 #if DBG // Begin Argument Checking (nop in fre version)
11085
11087
11088 if ((InputBufferLength != 0) || (OutputBufferLength != 0)) {
11090 }
11091 else {
11093 }
11094 #endif
11095
11096 //
11097 // Begin by allocating the IRP for this request. Do not charge quota to
11098 // the current process for this IRP.
11099 //
11100
11102 if (!irp) {
11103 IoStatus->Information = 0;
11105 return;
11106 }
11107
11108 //
11109 // Get a pointer to the stack location of the first driver which will be
11110 // invoked. This is where the function codes and the parameters are set.
11111 //
11112
11114
11115 //
11116 // Set the major function code based on the type of device I/O control
11117 // function the caller has specified.
11118 //
11119
11121 irpSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
11122 } else {
11123 irpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
11124 }
11125
11126 //
11127 // Copy the caller's parameters to the service-specific portion of the
11128 // IRP for those parameters that are the same for all four methods.
11129 //
11130
11131 irpSp->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferLength;
11132 irpSp->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
11133 irpSp->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
11134
11135 //
11136 // Get the method bits from the I/O control code to determine how the
11137 // buffers are to be passed to the driver.
11138 //
11139
11140 switch (method)
11141 {
11142 //
11143 // case 0
11144 //
11145 case METHOD_BUFFERED:
11146 {
11147 if ((InputBufferLength != 0) || (OutputBufferLength != 0))
11148 {
11149 irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
11152 if (irp->AssociatedIrp.SystemBuffer == NULL)
11153 {
11154 IoFreeIrp(irp);
11155
11156 IoStatus->Information = 0;
11158 return;
11159 }
11160
11161 if (InputBufferLength != 0)
11162 {
11163 RtlCopyMemory(irp->AssociatedIrp.SystemBuffer, Buffer, InputBufferLength);
11164 }
11165 }
11166
11167 irp->UserBuffer = Buffer;
11168
11169 break;
11170 }
11171
11172 //
11173 // case 1, case 2
11174 //
11175 case METHOD_IN_DIRECT:
11176 case METHOD_OUT_DIRECT:
11177 {
11178 if (InputBufferLength != 0)
11179 {
11180 irp->AssociatedIrp.SystemBuffer = Buffer;
11181 }
11182
11183 if (OutputBufferLength != 0)
11184 {
11185 irp->MdlAddress = IoAllocateMdl(Buffer,
11187 FALSE,
11188 FALSE,
11189 (PIRP) NULL);
11190 if (irp->MdlAddress == NULL)
11191 {
11192 IoFreeIrp(irp);
11193
11194 IoStatus->Information = 0;
11196 return;
11197 }
11198
11199 _SEH2_TRY
11200 {
11201 MmProbeAndLockPages(irp->MdlAddress,
11202 KernelMode,
11204 }
11205#ifdef _MSC_VER
11206 #pragma warning(suppress: 6320) // We want to handle any exception that MmProbeAndLockPages might throw
11207#endif
11209 {
11210 IoFreeMdl(irp->MdlAddress);
11211 IoFreeIrp(irp);
11212
11213 IoStatus->Information = 0;
11214 IoStatus->Status = _SEH2_GetExceptionCode();
11215 _SEH2_YIELD(return);
11216 } _SEH2_END;
11217 }
11218
11219 break;
11220 }
11221
11222 //
11223 // case 3
11224 //
11225 case METHOD_NEITHER:
11226 {
11227 NT_ASSERT(!"ClassSendDeviceIoControlSynchronous does not support METHOD_NEITHER Ioctls");
11228
11229 IoFreeIrp(irp);
11230
11231 IoStatus->Information = 0;
11233 return;
11234 }
11235 }
11236
11237 irp->Tail.Overlay.Thread = PsGetCurrentThread();
11238
11239 //
11240 // send the irp synchronously
11241 //
11242
11244
11245 //
11246 // copy the iostatus block for the caller
11247 //
11248
11249 *IoStatus = irp->IoStatus;
11250
11251 //
11252 // free any allocated resources
11253 //
11254
11255 switch (method) {
11256 case METHOD_BUFFERED: {
11257
11258 NT_ASSERT(irp->UserBuffer == Buffer);
11259
11260 //
11261 // first copy the buffered result, if any
11262 // Note that there are no security implications in
11263 // not checking for success since only drivers can
11264 // call into this routine anyways...
11265 //
11266
11267 if (OutputBufferLength != 0) {
11268#ifdef _MSC_VER
11269 #pragma warning(suppress: 6386) // Buffer's size is max(InputBufferLength, OutputBufferLength)
11270#endif
11271 RtlCopyMemory(Buffer, // irp->UserBuffer
11272 irp->AssociatedIrp.SystemBuffer,
11274 );
11275 }
11276
11277 //
11278 // then free the memory allocated to buffer the io
11279 //
11280
11281 if ((InputBufferLength !=0) || (OutputBufferLength != 0)) {
11282 FREE_POOL(irp->AssociatedIrp.SystemBuffer);
11283 }
11284 break;
11285 }
11286
11287 case METHOD_IN_DIRECT:
11288 case METHOD_OUT_DIRECT: {
11289
11290 //
11291 // we alloc a mdl if there is an output buffer specified
11292 // free it here after unlocking the pages
11293 //
11294
11295 if (OutputBufferLength != 0) {
11296 NT_ASSERT(irp->MdlAddress != NULL);
11297 MmUnlockPages(irp->MdlAddress);
11298 IoFreeMdl(irp->MdlAddress);
11299 irp->MdlAddress = (PMDL) NULL;
11300 }
11301 break;
11302 }
11303
11304 case METHOD_NEITHER: {
11305 NT_ASSERT(!"Code is out of date");
11306 break;
11307 }
11308 }
11309
11310 //
11311 // we always have allocated an irp. free it here.
11312 //
11313
11314 IoFreeIrp(irp);
11315 irp = (PIRP) NULL;
11316
11317 //
11318 // return the io status block's status to the caller
11319 //
11320
11321 return;
11322} // end ClassSendDeviceIoControlSynchronous()
struct _IRP * PIRP
Definition: bufpool.h:45
#define CLASS_TAG_DEVICE_CONTROL
Definition: classpnp.h:85
method
Definition: dragdrop.c:54
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1674
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define IoAllocateMdl
Definition: fxmdl.h:88
FxIrp * irp
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define METHOD_NEITHER
Definition: nt_native.h:597
#define METHOD_OUT_DIRECT
Definition: nt_native.h:596
#define METHOD_BUFFERED
Definition: nt_native.h:594
#define METHOD_IN_DIRECT
Definition: nt_native.h:595
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
PVOID PMDL
Definition: usb.h:39
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID _In_ ULONG _In_ BOOLEAN InternalDeviceIoControl
Definition: iofuncs.h:720
irpSp
Definition: iofuncs.h:2719
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
@ IoReadAccess
Definition: ketypes.h:863
@ IoWriteAccess
Definition: ketypes.h:864

Referenced by ClasspGetHwFirmwareInfo(), ClasspSendEnableIdlePowerIoctl(), and DiskIoctlSmartGetVersion().

◆ ClassSendIrpSynchronous()

SCSIPORT_API NTSTATUS NTAPI ClassSendIrpSynchronous ( _In_ PDEVICE_OBJECT  TargetDeviceObject,
_In_ PIRP  Irp 
)

Definition at line 11373 of file class.c.

11377{
11378 KEVENT event;
11380
11383 NT_ASSERT(Irp != NULL);
11384 NT_ASSERT(Irp->StackCount >= TargetDeviceObject->StackSize);
11385
11386 //
11387 // ISSUE-2000/02/20-henrygab What if APCs are disabled?
11388 // May need to enter critical section before IoCallDriver()
11389 // until the event is hit?
11390 //
11391
11394 TRUE, TRUE, TRUE);
11395
11398 if (status == STATUS_PENDING) {
11399
11400 #if DBG
11402
11403 timeout.QuadPart = (LONGLONG)(-1 * 10 * 1000 * (LONGLONG)1000 *
11404 ClasspnpGlobals.SecondsToWaitForIrps);
11405
11406 do {
11408 Executive,
11409 KernelMode,
11410 FALSE,
11411 &timeout);
11412
11413
11414 if (status == STATUS_TIMEOUT) {
11415
11416 //
11417 // This DebugPrint should almost always be investigated by the
11418 // party who sent the irp and/or the current owner of the irp.
11419 // Synchronous Irps should not take this long (currently 30
11420 // seconds) without good reason. This points to a potentially
11421 // serious problem in the underlying device stack.
11422 //
11423
11424 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassSendIrpSynchronous: (%p) irp %p did not "
11425 "complete within %x seconds\n",
11427 ClasspnpGlobals.SecondsToWaitForIrps
11428 ));
11429
11430 if (ClasspnpGlobals.BreakOnLostIrps != 0) {
11431 NT_ASSERT(!" - Irp failed to complete within 30 seconds - ");
11432 }
11433 }
11434
11435
11436 } while (status==STATUS_TIMEOUT);
11437 #else
11439 Executive,
11440 KernelMode,
11441 FALSE,
11442 NULL);
11443 #endif
11444
11445 status = Irp->IoStatus.Status;
11446 }
11447
11448 return status;
11449} // end ClassSendIrpSynchronous()
IO_COMPLETION_ROUTINE ClassSignalCompletion
Definition: classpnp.h:1330
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
Definition: dhcpd.h:245

Referenced by ClassForwardIrpSynchronous(), and ClassSendDeviceIoControlSynchronous().

◆ ClassSendSrbAsynchronous()

◆ ClassSendSrbSynchronous()

SCSIPORT_API NTSTATUS NTAPI ClassSendSrbSynchronous ( _In_ PDEVICE_OBJECT  DeviceObject,
_Inout_ PSCSI_REQUEST_BLOCK  Srb,
_In_reads_bytes_opt_(BufferLength) PVOID  BufferAddress,
_In_ ULONG  BufferLength,
_In_ BOOLEAN  WriteToDevice 
)

Definition at line 4042 of file class.c.

4049{
4050
4051 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
4052 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
4053 IO_STATUS_BLOCK ioStatus = {0};
4054 PIRP irp;
4055 PIO_STACK_LOCATION irpStack;
4056 KEVENT event;
4058 ULONG senseInfoBufferLength = SENSE_BUFFER_SIZE_EX;
4059 ULONG retryCount = MAXIMUM_RETRIES;
4061 BOOLEAN retry;
4063
4064 //
4065 // NOTE: This code is only pagable because we are not freezing
4066 // the queue. Allowing the queue to be frozen from a pagable
4067 // routine could leave the queue frozen as we try to page in
4068 // the code to unfreeze the queue. The result would be a nice
4069 // case of deadlock. Therefore, since we are unfreezing the
4070 // queue regardless of the result, just set the NO_FREEZE_QUEUE
4071 // flag in the SRB.
4072 //
4073
4075 NT_ASSERT(fdoExtension->CommonExtension.IsFdo);
4076
4078 //
4079 // Write length to SRB.
4080 //
4081
4082 Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
4083
4084 //
4085 // Set SCSI bus address.
4086 //
4087
4089 }
4090
4091 //
4092 // The Srb->Function should have been set corresponding to SrbType.
4093 //
4094
4097
4098
4099 //
4100 // Sense buffer is in aligned nonpaged pool.
4101 //
4102
4103#if defined(_ARM_) || defined(_ARM64_)
4104
4105 //
4106 // ARM has specific alignment requirements, although this will not have a functional impact on x86 or amd64
4107 // based platforms. We are taking the conservative approach here.
4108 //
4109 senseInfoBufferLength = ALIGN_UP_BY(senseInfoBufferLength,KeGetRecommendedSharedDataAlignment());
4110
4111#endif
4112
4113 senseInfoBuffer = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
4114 senseInfoBufferLength,
4115 '7CcS');
4116
4117 if (senseInfoBuffer == NULL) {
4118
4119 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassSendSrbSynchronous: Can't allocate request sense "
4120 "buffer\n"));
4122 }
4123
4124
4125 //
4126 // Enable auto request sense.
4127 //
4130
4132
4133
4134 //
4135 // Start retries here.
4136 //
4137
4138retry:
4139
4140 //
4141 // use fdoextension's flags by default.
4142 // do not move out of loop, as the flag may change due to errors
4143 // sending this command.
4144 //
4145
4146 SrbAssignSrbFlags(Srb, fdoExtension->SrbFlags);
4147
4148 if (BufferAddress != NULL) {
4149 if (WriteToDevice) {
4151 } else {
4153 }
4154 }
4155
4156
4157 //
4158 // Initialize the QueueAction field.
4159 //
4160
4162
4163 //
4164 // Disable synchronous transfer for these requests.
4165 //
4167
4168 //
4169 // Set the event object to the unsignaled state.
4170 // It will be used to signal request completion.
4171 //
4172
4174
4175 //
4176 // Build device I/O control request with METHOD_NEITHER data transfer.
4177 // We'll queue a completion routine to cleanup the MDL's and such ourself.
4178 //
4179
4181 (CCHAR) (fdoExtension->CommonExtension.LowerDeviceObject->StackSize + 1),
4182 FALSE);
4183
4184 if (irp == NULL) {
4188 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassSendSrbSynchronous: Can't allocate Irp\n"));
4190 }
4191
4192 //
4193 // Get next stack location.
4194 //
4195
4196 irpStack = IoGetNextIrpStackLocation(irp);
4197
4198 //
4199 // Set up SRB for execute scsi request. Save SRB address in next stack
4200 // for the port driver.
4201 //
4202
4203 irpStack->MajorFunction = IRP_MJ_SCSI;
4204 irpStack->Parameters.Scsi.Srb = (PSCSI_REQUEST_BLOCK)Srb;
4205
4208 Srb,
4209 TRUE,
4210 TRUE,
4211 TRUE);
4212
4213 irp->UserIosb = &ioStatus;
4214 irp->UserEvent = &event;
4215
4216 if (BufferAddress) {
4217 //
4218 // Build an MDL for the data buffer and stick it into the irp. The
4219 // completion routine will unlock the pages and free the MDL.
4220 //
4221
4222 irp->MdlAddress = IoAllocateMdl( BufferAddress,
4224 FALSE,
4225 FALSE,
4226 irp );
4227 if (irp->MdlAddress == NULL) {
4231 IoFreeIrp( irp );
4232 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassSendSrbSynchronous: Can't allocate MDL\n"));
4234 }
4235
4236 _SEH2_TRY {
4237
4238 //
4239 // the io manager unlocks these pages upon completion
4240 //
4241
4242 MmProbeAndLockPages( irp->MdlAddress,
4243 KernelMode,
4245 IoWriteAccess));
4246
4247#ifdef _MSC_VER
4248 #pragma warning(suppress: 6320) // We want to handle any exception that MmProbeAndLockPages might throw
4249#endif
4252
4256 IoFreeMdl(irp->MdlAddress);
4257 IoFreeIrp(irp);
4258
4259 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassSendSrbSynchronous: Exception %lx "
4260 "locking buffer\n", status));
4261 _SEH2_YIELD(return status);
4262 } _SEH2_END;
4263 }
4264
4265 //
4266 // Set the transfer length.
4267 //
4268
4270
4271 //
4272 // Zero out status.
4273 //
4274
4276 Srb->SrbStatus = 0;
4278
4279 //
4280 // Set up IRP Address.
4281 //
4282
4284
4285 //
4286 // Call the port driver with the request and wait for it to complete.
4287 //
4288
4290
4291 if (status == STATUS_PENDING) {
4293 status = ioStatus.Status;
4294 }
4295
4296// NT_ASSERT(SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_PENDING);
4299
4300 //
4301 // Clear the IRP address in SRB as IRP has been freed at this time
4302 // and don't want to leave any references that may be accessed.
4303 //
4304
4306
4307 //
4308 // Check that request completed without error.
4309 //
4310
4312
4313 LONGLONG retryInterval;
4314
4315 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "ClassSendSrbSynchronous - srb %ph failed (op=%s srbstat=%s(%xh), irpstat=%xh, sense=%s/%s/%s)", Srb,
4321
4322 //
4323 // assert that the queue is not frozen
4324 //
4325
4327
4328 //
4329 // Update status and determine if request should be retried.
4330 //
4331
4333 NULL, // no valid irp exists
4336 0,
4337 MAXIMUM_RETRIES - retryCount,
4338 &status,
4339 &retryInterval);
4340
4341 if (retry) {
4342
4345
4347
4348 validSense = ScsiGetSenseKeyAndCodes(senseInfoBuffer,
4351 NULL,
4353 NULL);
4354 }
4355
4358
4359 LARGE_INTEGER delay;
4360
4361 //
4362 // Delay for at least 2 seconds.
4363 //
4364
4365 if (retryInterval < 2*1000*1000*10) {
4366 retryInterval = 2*1000*1000*10;
4367 }
4368
4369 delay.QuadPart = -retryInterval;
4370
4371 //
4372 // Stall for a while to let the device become ready
4373 //
4374
4376
4377 }
4378
4379
4380 //
4381 // If retries are not exhausted then retry this operation.
4382 //
4383
4384 if (retryCount--) {
4385
4386 if (PORT_ALLOCATED_SENSE_EX(fdoExtension, Srb)) {
4388 }
4389
4390 goto retry;
4391 }
4392 }
4393
4394
4395 } else {
4398 }
4399
4400 //
4401 // required even though we allocated our own, since the port driver may
4402 // have allocated one also
4403 //
4404
4405 if (PORT_ALLOCATED_SENSE_EX(fdoExtension, Srb)) {
4407 }
4408
4412
4413 return status;
4414}
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID BufferAddress
Definition: cdrom.h:990
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG _In_ BOOLEAN WriteToDevice
Definition: cdrom.h:992
FORCEINLINE BOOLEAN PORT_ALLOCATED_SENSE_EX(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb)
Definition: classp.h:2547
FORCEINLINE VOID FREE_PORT_ALLOCATED_SENSE_BUFFER_EX(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb)
Definition: classp.h:2560
IO_COMPLETION_ROUTINE ClasspSendSynchronousCompletion
Definition: classp.h:1410
BOOLEAN InterpretSenseInfoWithoutHistory(_In_ PDEVICE_OBJECT Fdo, _In_opt_ PIRP OriginalRequest, _In_ PSCSI_REQUEST_BLOCK Srb, UCHAR MajorFunctionCode, ULONG IoDeviceCode, ULONG PreviousRetryCount, _Out_ NTSTATUS *Status, _Out_opt_ _Deref_out_range_(0, MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS) LONGLONG *RetryIn100nsUnits)
Definition: class.c:12844
#define DBGGETSCSIOPSTR(_pSrb)
Definition: debug.h:26
#define DBGGETADSENSECODESTR(_pSrb)
Definition: debug.h:29
#define DBGGETADSENSEQUALIFIERSTR(_pSrb)
Definition: debug.h:30
#define DBGGETSRBSTATUSSTR(_pSrb)
Definition: debug.h:27
#define DBGGETSENSECODESTR(_pSrb)
Definition: debug.h:28
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:401
#define SRB_FLAGS_DATA_IN
Definition: srb.h:400
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:397
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:404
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
@ NotificationEvent
ULONG NTAPI KeGetRecommendedSharedDataAlignment(VOID)
Definition: cpu.c:675
UCHAR additionalSenseCode
Definition: scsi.h:4020
#define SCSI_SENSE_OPTIONS_FIXED_FORMAT_IF_UNKNOWN_FORMAT_INDICATED
Definition: scsi.h:3839
PFIXED_SENSE_DATA senseInfoBuffer
Definition: scsi.h:3710
#define SENSE_BUFFER_SIZE_EX
Definition: scsi.h:596
#define SRB_TYPE_SCSI_REQUEST_BLOCK
Definition: srb.h:663
FORCEINLINE VOID SrbAssignSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:946
FORCEINLINE VOID SrbSetDataTransferLength(_In_ PVOID Srb, _In_ ULONG DataTransferLength)
Definition: srbhelper.h:784
FORCEINLINE VOID SrbSetNextSrb(_In_ PVOID Srb, _In_opt_ PVOID NextSrb)
Definition: srbhelper.h:909
FORCEINLINE VOID SrbSetOriginalRequest(_In_ PVOID Srb, _In_opt_ PVOID OriginalRequest)
Definition: srbhelper.h:710
FORCEINLINE VOID SrbSetScsiStatus(_In_ PVOID Srb, _In_ UCHAR ScsiStatus)
Definition: srbhelper.h:1056
FORCEINLINE VOID SrbSetSenseInfoBufferLength(_In_ PVOID Srb, _In_ UCHAR SenseInfoBufferLength)
Definition: srbhelper.h:675
FORCEINLINE VOID SrbSetSenseInfoBuffer(_In_ PVOID Srb, _In_opt_ PVOID SenseInfoBuffer)
Definition: srbhelper.h:657
FORCEINLINE VOID SrbSetDataBuffer(_In_ PVOID Srb, _In_opt_ __drv_aliasesMem PVOID DataBuffer)
Definition: srbhelper.h:747
USHORT Length
Definition: srb.h:249
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
#define IRP_MJ_SCSI

Referenced by ClassGetLBProvisioningLogPage(), ClasspCleanupProtectedLocks(), ClasspDeviceGetBlockDeviceCharacteristicsVPDPage(), ClasspDeviceGetBlockLimitsVPDPage(), ClasspDeviceGetLBProvisioningVPDPage(), ClasspEjectionControl(), ClasspGetBlockDeviceTokenLimitsInfo(), ClasspGetInquiryVpdSupportInfo(), ClasspWriteCacheProperty(), ClassReadCapacity16(), DetermineMediaType(), DeviceProcessDsmTrimRequest(), DiskFlushDispatch(), DiskIoctlGetMediaTypesEx(), DiskIoctlIsWritable(), DiskIoctlReassignBlocks(), DiskIoctlReassignBlocksEx(), DiskIoctlVerifyThread(), DiskModeSelect(), DiskShutdownFlush(), FormatMedia(), GetLBAStatus(), USBFlopFormatTracks(), and USBFlopGetMediaTypes().

◆ ClassSendStartUnit()

VOID NTAPI ClassSendStartUnit ( _In_ PDEVICE_OBJECT  DeviceObject)

Definition at line 3071 of file class.c.

3074{
3075 PIO_STACK_LOCATION irpStack;
3076 PIRP irp;
3077 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
3080 PCDB cdb;
3083
3084 //
3085 // Allocate Srb from nonpaged pool.
3086 //
3087
3088 context = ExAllocatePoolWithTag(NonPagedPoolNx,
3089 sizeof(COMPLETION_CONTEXT),
3090 '6CcS');
3091
3092 if (context == NULL) {
3093
3094 //
3095 // ISSUE-2000/02/03-peterwie
3096 // This code path was inheritted from the NT 4.0 class2.sys driver.
3097 // It needs to be changed to survive low-memory conditions.
3098 //
3099
3100 KeBugCheck(SCSI_DISK_DRIVER_INTERNAL);
3101 }
3102
3103 //
3104 // Save the device object in the context for use by the completion
3105 // routine.
3106 //
3107
3108 context->DeviceObject = Fdo;
3109
3110 srb = &context->Srb.Srb;
3111 if (fdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
3112 srbEx = &context->Srb.SrbEx;
3115 sizeof(context->Srb.SrbExBuffer),
3116 1,
3118 if (!NT_SUCCESS(status)) {
3121 return;
3122 }
3123
3124 srbEx->SrbFunction = SRB_FUNCTION_EXECUTE_SCSI;
3125
3126 } else {
3127
3128 //
3129 // Zero out srb.
3130 //
3131
3132 RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
3133
3134 //
3135 // Write length to SRB.
3136 //
3137
3138 srb->Length = sizeof(SCSI_REQUEST_BLOCK);
3139
3141 }
3142
3143 //
3144 // Set timeout value large enough for drive to spin up.
3145 //
3146
3148
3149 //
3150 // Set the transfer length.
3151 //
3152
3157
3158 //
3159 // Build the start unit CDB.
3160 //
3161
3162 SrbSetCdbLength(srb, 6);
3163 cdb = SrbGetCdb(srb);
3164
3165 cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
3166 cdb->START_STOP.Start = 1;
3167 cdb->START_STOP.Immediate = 0;
3168 cdb->START_STOP.LogicalUnitNumber = srb->Lun;
3169
3170 //
3171 // Build the asynchronous request to be sent to the port driver.
3172 // Since this routine is called from a DPC the IRP should always be
3173 // available.
3174 //
3175
3176 irp = IoAllocateIrp(Fdo->StackSize, FALSE);
3177
3178 if (irp == NULL) {
3179
3180 //
3181 // ISSUE-2000/02/03-peterwie
3182 // This code path was inheritted from the NT 4.0 class2.sys driver.
3183 // It needs to be changed to survive low-memory conditions.
3184 //
3185
3186 KeBugCheck(SCSI_DISK_DRIVER_INTERNAL);
3187
3188 }
3189
3191
3194 context,
3195 TRUE,
3196 TRUE,
3197 TRUE);
3198
3199 irpStack = IoGetNextIrpStackLocation(irp);
3200 irpStack->MajorFunction = IRP_MJ_SCSI;
3202
3203 //
3204 // Store the SRB address in next stack for port driver.
3205 //
3206
3207 irpStack->Parameters.Scsi.Srb = srb;
3208
3209 //
3210 // Call the port driver with the IRP.
3211 //
3212
3214
3215 return;
3216
3217} // end StartUnit()
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
#define START_UNIT_TIMEOUT
Definition: cdrom.h:132
NTSTATUS NTAPI ClassAsynchronousCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: class.c:3246
#define SRB_FLAGS_NO_DATA_TRANSFER
Definition: srb.h:402
#define SRB_FLAGS_DISABLE_AUTOSENSE
Definition: srb.h:399
IO_COMPLETION_ROUTINE * PIO_COMPLETION_ROUTINE
Definition: iotypes.h:2835

Referenced by ClassInterpretSenseInfo().

◆ ClassSpinDownPowerHandler()

SCSIPORT_API NTSTATUS NTAPI ClassSpinDownPowerHandler ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)

◆ ClassSplitRequest()

SCSIPORT_API VOID NTAPI ClassSplitRequest ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp,
_In_ ULONG  MaximumBytes 
)

Definition at line 61 of file obsolete.c.

62{
63 PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
64 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
65
66 if (MaximumBytes > fdoData->HwMaxXferLen) {
67 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_RW, "ClassSplitRequest - driver requesting split to size that "
68 "hardware is unable to handle!\n"));
69 }
70
71 if (MaximumBytes < fdoData->HwMaxXferLen){
72 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_RW, "ClassSplitRequest - driver requesting smaller HwMaxXferLen "
73 "than required"));
74 fdoData->HwMaxXferLen = MAX(MaximumBytes, PAGE_SIZE);
75 }
76
78}
#define MAX(x, y)
Definition: rdesktop.h:175
NTSTATUS ServiceTransferRequest(PDEVICE_OBJECT Fdo, PIRP Irp, BOOLEAN PostToDpc)
Definition: class.c:3341

◆ ClassStopUnitPowerHandler()

NTSTATUS NTAPI ClassStopUnitPowerHandler ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)

Definition at line 2048 of file power.c.

2052{
2053 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
2054
2055 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_POWER, "ClassStopUnitPowerHandler - Devobj %p using outdated call\n"
2056 "Drivers should set the following flags in ScanForSpecialFlags "
2057 " in the FDO extension:\n"
2058 "\tCLASS_SPECIAL_DISABLE_SPIN_UP\n"
2059 "\tCLASS_SPECIAL_NO_QUEUE_LOCK\n"
2060 "This will provide equivalent functionality if the power "
2061 "routine is then set to ClassSpinDownPowerHandler\n\n",
2062 DeviceObject));
2063
2064 fdoExtension = (PFUNCTIONAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
2065
2066 SET_FLAG(fdoExtension->ScanForSpecialFlags,
2068 SET_FLAG(fdoExtension->ScanForSpecialFlags,
2070
2072} // end ClassStopUnitPowerHandler()
SCSIPORT_API NTSTATUS NTAPI ClassSpinDownPowerHandler(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
#define CLASS_SPECIAL_NO_QUEUE_LOCK
Definition: classpnp.h:167
#define CLASS_SPECIAL_DISABLE_SPIN_UP
Definition: classpnp.h:166

◆ ClassWmiCompleteRequest()

SCSIPORT_API NTSTATUS NTAPI ClassWmiCompleteRequest ( _In_ PDEVICE_OBJECT  DeviceObject,
_Inout_ PIRP  Irp,
_In_ NTSTATUS  Status,
_In_ ULONG  BufferUsed,
_In_ CCHAR  PriorityBoost 
)

Definition at line 1009 of file classwmi.c.

1016{
1018 PUCHAR buffer;
1019 ULONG retSize;
1020 UCHAR minorFunction;
1021
1022 minorFunction = irpStack->MinorFunction;
1023 buffer = (PUCHAR)irpStack->Parameters.WMI.Buffer;
1024
1025 switch(minorFunction)
1026 {
1028 {
1029 PWNODE_ALL_DATA wnode;
1030 PWNODE_TOO_SMALL wnodeTooSmall;
1031 ULONG bufferNeeded;
1032
1033 wnode = (PWNODE_ALL_DATA)buffer;
1034
1035 bufferNeeded = sizeof(WNODE_ALL_DATA) + BufferUsed;
1036
1037 if (NT_SUCCESS(Status))
1038 {
1039 retSize = bufferNeeded;
1040 wnode->WnodeHeader.BufferSize = bufferNeeded;
1041 KeQuerySystemTime(&wnode->WnodeHeader.TimeStamp);
1044 wnode->InstanceCount = 1;
1045
1046 } else if (Status == STATUS_BUFFER_TOO_SMALL) {
1047 wnodeTooSmall = (PWNODE_TOO_SMALL)wnode;
1048
1049 wnodeTooSmall->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL);
1050 wnodeTooSmall->WnodeHeader.Flags = WNODE_FLAG_TOO_SMALL;
1051 wnodeTooSmall->SizeNeeded = sizeof(WNODE_ALL_DATA) + BufferUsed;
1052 retSize = sizeof(WNODE_TOO_SMALL);
1054 } else {
1055 retSize = 0;
1056 }
1057 break;
1058 }
1059
1061 {
1063 PWNODE_TOO_SMALL wnodeTooSmall;
1064 ULONG bufferNeeded;
1065
1067
1068 bufferNeeded = wnode->DataBlockOffset + BufferUsed;
1069
1070 if (NT_SUCCESS(Status))
1071 {
1072 retSize = bufferNeeded;
1073 wnode->WnodeHeader.BufferSize = bufferNeeded;
1074 KeQuerySystemTime(&wnode->WnodeHeader.TimeStamp);
1075 wnode->SizeDataBlock = BufferUsed;
1076
1077 } else if (Status == STATUS_BUFFER_TOO_SMALL) {
1078 wnodeTooSmall = (PWNODE_TOO_SMALL)wnode;
1079
1080 wnodeTooSmall->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL);
1081 wnodeTooSmall->WnodeHeader.Flags = WNODE_FLAG_TOO_SMALL;
1082 wnodeTooSmall->SizeNeeded = bufferNeeded;
1083 retSize = sizeof(WNODE_TOO_SMALL);
1085 } else {
1086 retSize = 0;
1087 }
1088 break;
1089 }
1090
1092 {
1093 PWNODE_METHOD_ITEM wnode;
1094 PWNODE_TOO_SMALL wnodeTooSmall;
1095 ULONG bufferNeeded;
1096
1097 wnode = (PWNODE_METHOD_ITEM)buffer;
1098
1099 bufferNeeded = wnode->DataBlockOffset + BufferUsed;
1100
1101 if (NT_SUCCESS(Status))
1102 {
1103 retSize = bufferNeeded;
1104 wnode->WnodeHeader.BufferSize = bufferNeeded;
1105 KeQuerySystemTime(&wnode->WnodeHeader.TimeStamp);
1106 wnode->SizeDataBlock = BufferUsed;
1107
1108 } else if (Status == STATUS_BUFFER_TOO_SMALL) {
1109 wnodeTooSmall = (PWNODE_TOO_SMALL)wnode;
1110
1111 wnodeTooSmall->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL);
1112 wnodeTooSmall->WnodeHeader.Flags = WNODE_FLAG_TOO_SMALL;
1113 wnodeTooSmall->SizeNeeded = bufferNeeded;
1114 retSize = sizeof(WNODE_TOO_SMALL);
1116 } else {
1117 retSize = 0;
1118 }
1119 break;
1120 }
1121
1122 default:
1123 {
1124 //
1125 // All other requests don't return any data
1126 retSize = 0;
1127 break;
1128 }
1129
1130 }
1131
1132 Irp->IoStatus.Status = Status;
1133 Irp->IoStatus.Information = retSize;
1136 return(Status);
1137} // end ClassWmiCompleteRequest()
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
GLuint buffer
Definition: glext.h:5915
ULONG InstanceCount
Definition: wmistr.h:114
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:112
ULONG FixedInstanceSize
Definition: wmistr.h:118
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:136
ULONG DataBlockOffset
Definition: wmistr.h:140
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:58
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:52
ULONG SizeNeeded
Definition: wmistr.h:53
_In_ ULONG _Out_ PULONG BufferUsed
Definition: wdfwmi.h:92
struct tagWNODE_METHOD_ITEM * PWNODE_METHOD_ITEM
#define WNODE_FLAG_TOO_SMALL
Definition: wmistr.h:33
#define WNODE_FLAG_FIXED_INSTANCE_SIZE
Definition: wmistr.h:32
struct tagWNODE_ALL_DATA WNODE_ALL_DATA
struct tagWNODE_ALL_DATA * PWNODE_ALL_DATA
struct tagWNODE_SINGLE_INSTANCE * PWNODE_SINGLE_INSTANCE
struct tagWNODE_TOO_SMALL * PWNODE_TOO_SMALL
struct tagWNODE_TOO_SMALL WNODE_TOO_SMALL
#define IRP_MN_EXECUTE_METHOD
#define IRP_MN_QUERY_ALL_DATA
#define IRP_MN_QUERY_SINGLE_INSTANCE

Referenced by ClassQueryInternalDataBlock(), ClassSystemControl(), DiskFdoExecuteWmiMethod(), DiskFdoQueryWmiDataBlock(), DiskFdoSetWmiDataBlock(), DiskFdoSetWmiDataItem(), and DiskWmiFunctionControl().

◆ CountOfSetBitsUChar()

static ULONG CountOfSetBitsUChar ( UCHAR  _X)
inlinestatic

Definition at line 194 of file classpnp.h.

195{ ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
#define _X(x)
Definition: CPath.cpp:42

◆ CountOfSetBitsULong()

static ULONG CountOfSetBitsULong ( ULONG  _X)
inlinestatic

Definition at line 196 of file classpnp.h.

197{ ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }

◆ CountOfSetBitsULong32()

static ULONG CountOfSetBitsULong32 ( ULONG32  _X)
inlinestatic

Definition at line 198 of file classpnp.h.

199{ ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }

◆ CountOfSetBitsULong64()

static ULONG CountOfSetBitsULong64 ( ULONG64  _X)
inlinestatic

Definition at line 200 of file classpnp.h.

201{ ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }

◆ CountOfSetBitsUlongPtr()

static ULONG CountOfSetBitsUlongPtr ( ULONG_PTR  _X)
inlinestatic

Definition at line 202 of file classpnp.h.

203{ ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }

◆ DeviceObject()

◆ FREE_PORT_ALLOCATED_SENSE_BUFFER()

static __inline VOID FREE_PORT_ALLOCATED_SENSE_BUFFER ( _In_ PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
_In_ PSCSI_REQUEST_BLOCK  Srb 
)
static

Definition at line 1475 of file classpnp.h.

1478{
1481 ASSERT(Srb->SenseInfoBuffer != FdoExtension->SenseData);
1482
1484 Srb->SenseInfoBuffer = FdoExtension->SenseData;
1487 return;
1488}
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: classpnp.h:310
#define CLEAR_FLAG(Flags, Bit)
Definition: classpnp.h:158
#define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE
Definition: srb.h:413
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
UCHAR SenseInfoBufferLength
Definition: srb.h:259
PVOID SenseInfoBuffer
Definition: srb.h:264

◆ GET_FDO_EXTENSON_SENSE_DATA_LENGTH()

FORCEINLINE UCHAR GET_FDO_EXTENSON_SENSE_DATA_LENGTH ( _In_ PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension)

Definition at line 1437 of file classpnp.h.

1439{
1440 UCHAR SenseDataLength = 0;
1441
1442 if (FdoExtension->SenseData != NULL)
1443 {
1444#if (NTDDI_VERSION >= NTDDI_WIN8)
1445 if (FdoExtension->SenseDataLength > 0)
1446 {
1447 SenseDataLength = FdoExtension->SenseDataLength;
1448 }
1449 else
1450 {
1451 // For backward compatibility with Windows 7 and earlier
1452 SenseDataLength = SENSE_BUFFER_SIZE;
1453 }
1454#else
1455 SenseDataLength = SENSE_BUFFER_SIZE;
1456#endif
1457 }
1458
1459 return SenseDataLength;
1460}

Referenced by _Success_(), ClasspBuildRequestEx(), ClasspPowerDownCompletion(), ClasspPowerUpCompletion(), and FREE_PORT_ALLOCATED_SENSE_BUFFER_EX().

◆ PORT_ALLOCATED_SENSE()

static __inline BOOLEAN PORT_ALLOCATED_SENSE ( _In_ PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
_In_ PSCSI_REQUEST_BLOCK  Srb 
)
static

Definition at line 1464 of file classpnp.h.

Variable Documentation

◆ AcquireChildLock

_In_ BOOLEAN AcquireChildLock

Definition at line 1182 of file classpnp.h.

◆ AllowDriveToSleep

_In_ BOOLEAN AllowDriveToSleep

Definition at line 1275 of file classpnp.h.

Referenced by ClasspInitializePolling().

◆ Argument2

◆ BufferAvail

◆ BufferSize

Definition at line 429 of file classpnp.h.

◆ Capabilities

_In_ PDEVICE_CAPABILITIES Capabilities

Definition at line 392 of file classpnp.h.

◆ ClassSignalCompletion

IO_COMPLETION_ROUTINE ClassSignalCompletion

Definition at line 1330 of file classpnp.h.

Referenced by ClasspCreateClose(), ClasspInitializeGesn(), and ClassSendIrpSynchronous().

◆ Data

Definition at line 972 of file classpnp.h.

◆ DataItemId

Definition at line 438 of file classpnp.h.

◆ Descriptor

◆ DeviceList

Definition at line 1501 of file classpnp.h.

◆ DeviceName

Definition at line 1229 of file classpnp.h.

◆ DeviceNumber

◆ Enable

◆ EventDataSize

Definition at line 1252 of file classpnp.h.

◆ EventPrefix

_In_ PUCHAR EventPrefix

Definition at line 1267 of file classpnp.h.

◆ ExtraDataSize

_In_ const GUID _In_ ULONG ExtraDataSize

Definition at line 1430 of file classpnp.h.

Referenced by _IRQL_requires_max_(), and DeviceSendNotification().

◆ FailurePredictionMethod

_In_ FAILURE_PREDICTION_METHOD FailurePredictionMethod

Definition at line 1301 of file classpnp.h.

◆ FileObject

Definition at line 1422 of file classpnp.h.

◆ Function

_In_ CLASSPNP_SCAN_FOR_SPECIAL_INFO _In_ PCLASS_SCAN_FOR_SPECIAL_HANDLER Function

Definition at line 459 of file classpnp.h.

◆ Guid

Definition at line 971 of file classpnp.h.

◆ GuidIndex

◆ IdString

Definition at line 375 of file classpnp.h.

Referenced by ClassGetPdoId().

◆ IdType

◆ InBufferSize

Definition at line 449 of file classpnp.h.

◆ InitializationData

_In_ PVOID _In_ PCLASS_INIT_DATA InitializationData

Definition at line 722 of file classpnp.h.

Referenced by _IRQL_requires_max_(), and DriverEntry().

◆ InquiryDataLength

_In_ PCHAR _In_ ULONG _In_ ULONG InquiryDataLength

Definition at line 1232 of file classpnp.h.

◆ InstanceIndex

◆ IoDeviceCode

◆ Irp

Definition at line 350 of file classpnp.h.

◆ IsFdo

◆ LogError

_In_ ULONG _In_ BOOLEAN LogError

Definition at line 1311 of file classpnp.h.

◆ LowerDeviceObject

◆ Lun

◆ MajorFunctionCode

◆ MethodId

Definition at line 448 of file classpnp.h.

◆ MofResourceName

◆ Name

Definition at line 404 of file classpnp.h.

◆ NumberElements

_In_ ULONG NumberElements

Definition at line 1137 of file classpnp.h.

◆ ObjectNameBuffer

_In_z_ PCCHAR ObjectNameBuffer

Definition at line 982 of file classpnp.h.

Referenced by WmipCaptureGuidObjectAttributes().

◆ OriginalRequest

_In_opt_ PIRP OriginalRequest

Definition at line 482 of file classpnp.h.

◆ OutBufferSize

◆ ParameterName

_In_opt_ PWSTR _In_ PWSTR ParameterName

Definition at line 1403 of file classpnp.h.

◆ ParameterValue

_In_opt_ PWSTR _In_ PWSTR _In_ ULONG ParameterValue

Definition at line 1404 of file classpnp.h.

◆ PathId

◆ Pdo

Definition at line 318 of file classpnp.h.

◆ PollingPeriod

Definition at line 1302 of file classpnp.h.

◆ PreviousRetryCount

Definition at line 486 of file classpnp.h.

Referenced by InterpretSenseInfoWithoutHistory().

◆ PropertyId

Definition at line 1159 of file classpnp.h.

◆ RegFlags

◆ Release

_In_ BOOLEAN Release

Definition at line 1122 of file classpnp.h.

◆ RemoveType

_In_ UCHAR RemoveType

Definition at line 1343 of file classpnp.h.

◆ RequestHistory

◆ Retry

◆ Srb

Definition at line 310 of file classpnp.h.

◆ State

Definition at line 1373 of file classpnp.h.

◆ Status

◆ SubkeyName

_In_opt_ PWSTR SubkeyName

Definition at line 1402 of file classpnp.h.

◆ TargetId

◆ Type

Definition at line 334 of file classpnp.h.

◆ UniqueErrorValue

_In_ ULONG _In_ BOOLEAN _In_ ULONG UniqueErrorValue

Definition at line 1312 of file classpnp.h.

Referenced by TiWriteErrorLog().

◆ Wait