From 3da77f91732177cfffe927d6be086416f1d9c67d Mon Sep 17 00:00:00 2001 From: Victor Perevertkin Date: Fri, 28 Aug 2020 05:16:59 +0300 Subject: [PATCH] [DDK] Import definitions required by newer storage class drivers CORE-17129 --- sdk/include/ddk/classpnp.h | 324 ++++++-- sdk/include/ddk/scsi.h | 1467 ++++++++++++++++++++++++++++++++++-- sdk/include/ddk/scsiwmi.h | 6 +- sdk/include/ddk/srb.h | 381 ++++++++-- 4 files changed, 1981 insertions(+), 197 deletions(-) diff --git a/sdk/include/ddk/classpnp.h b/sdk/include/ddk/classpnp.h index 4d2c6b100e7..e8fda74498f 100644 --- a/sdk/include/ddk/classpnp.h +++ b/sdk/include/ddk/classpnp.h @@ -85,6 +85,9 @@ #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 @@ -182,6 +185,7 @@ #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 @@ -250,6 +254,16 @@ typedef enum { PowerDownDeviceUnlocked2 } CLASS_POWER_DOWN_STATE2; +typedef enum { + PowerDownDeviceInitial3 = 0, + PowerDownDeviceLocked3, + PowerDownDeviceQuiesced3, + PowerDownDeviceFlushed3, + PowerDownDeviceStopped3, + PowerDownDeviceOff3, + PowerDownDeviceUnlocked3 +} CLASS_POWER_DOWN_STATE3; + typedef enum { PowerUpDeviceInitial, PowerUpDeviceLocked, @@ -273,6 +287,9 @@ typedef struct _CLASS_PRIVATE_COMMON_DATA CLASS_PRIVATE_COMMON_DATA, *PCLASS_PRI struct _MEDIA_CHANGE_DETECTION_INFO; typedef struct _MEDIA_CHANGE_DETECTION_INFO MEDIA_CHANGE_DETECTION_INFO, *PMEDIA_CHANGE_DETECTION_INFO; +struct _DICTIONARY_HEADER; +typedef struct _DICTIONARY_HEADER DICTIONARY_HEADER, *PDICTIONARY_HEADER; + typedef struct _DICTIONARY { ULONGLONG Signature; struct _DICTIONARY_HEADER* List; @@ -551,6 +568,10 @@ typedef struct _CLASS_INTERPRET_SENSE_INFO2 { C_ASSERT((MAXULONG - sizeof(SRB_HISTORY)) / 30000 >= sizeof(SRB_HISTORY_ITEM)); +// for SrbSupport +#define CLASS_SRB_SCSI_REQUEST_BLOCK 0x1 +#define CLASS_SRB_STORAGE_REQUEST_BLOCK 0x2 + typedef struct _CLASS_DRIVER_EXTENSION { UNICODE_STRING RegistryPath; CLASS_INIT_DATA InitData; @@ -566,6 +587,9 @@ typedef struct _CLASS_DRIVER_EXTENSION { PCLASS_INTERPRET_SENSE_INFO2 InterpretSenseInfo; PCLASS_WORKING_SET WorkingSet; #endif +#if (NTDDI_VERSION >= NTDDI_WIN8) + ULONG SrbSupport; +#endif } CLASS_DRIVER_EXTENSION, *PCLASS_DRIVER_EXTENSION; typedef struct _COMMON_DEVICE_EXTENSION { @@ -651,6 +675,7 @@ typedef struct _CLASS_POWER_CONTEXT { union { CLASS_POWER_DOWN_STATE PowerDown; CLASS_POWER_DOWN_STATE2 PowerDown2; + CLASS_POWER_DOWN_STATE3 PowerDown3; CLASS_POWER_UP_STATE PowerUp; } PowerChangeState; CLASS_POWER_OPTIONS Options; @@ -665,14 +690,30 @@ typedef struct _CLASS_POWER_CONTEXT { SCSI_REQUEST_BLOCK Srb; } CLASS_POWER_CONTEXT, *PCLASS_POWER_CONTEXT; +#if (NTDDI_VERSION >= NTDDI_WIN8) + +#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)) + +#endif + typedef struct _COMPLETION_CONTEXT { PDEVICE_OBJECT DeviceObject; +#if (NTDDI_VERSION >= NTDDI_WIN8) + union + { + SCSI_REQUEST_BLOCK Srb; + STORAGE_REQUEST_BLOCK SrbEx; + UCHAR SrbExBuffer[CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE]; + } Srb; +#else SCSI_REQUEST_BLOCK Srb; +#endif } COMPLETION_CONTEXT, *PCOMPLETION_CONTEXT; _IRQL_requires_max_(PASSIVE_LEVEL) _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API ULONG NTAPI ClassInitialize( @@ -686,6 +727,143 @@ typedef struct _CLASS_QUERY_WMI_REGINFO_EX_LIST { __callback PCLASS_QUERY_WMI_REGINFO_EX ClassPdoQueryWmiRegInfoEx; } CLASS_QUERY_WMI_REGINFO_EX_LIST, *PCLASS_QUERY_WMI_REGINFO_EX_LIST; +typedef enum +{ + SupportUnknown = 0, + Supported, + NotSupported +} CLASS_FUNCTION_SUPPORT; + +typedef struct _CLASS_VPD_B1_DATA +{ + NTSTATUS CommandStatus; + USHORT MediumRotationRate; + UCHAR NominalFormFactor; + UCHAR Zoned; + ULONG MediumProductType; + ULONG DepopulationTime; +} CLASS_VPD_B1_DATA, *PCLASS_VPD_B1_DATA; + +typedef struct _CLASS_VPD_B0_DATA +{ + NTSTATUS CommandStatus; + ULONG MaxUnmapLbaCount; + ULONG MaxUnmapBlockDescrCount; + ULONG OptimalUnmapGranularity; + ULONG UnmapGranularityAlignment; + BOOLEAN UGAVALID; + UCHAR Reserved0; + USHORT OptimalTransferLengthGranularity; + ULONG MaximumTransferLength; + ULONG OptimalTransferLength; +} CLASS_VPD_B0_DATA, *PCLASS_VPD_B0_DATA; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4214) +#endif +typedef struct _CLASS_VPD_B2_DATA +{ + NTSTATUS CommandStatus; + UCHAR ThresholdExponent; + UCHAR DP:1; + UCHAR ANC_SUP:1; + UCHAR Reserved0:2; + UCHAR LBPRZ:1; + UCHAR LBPWS10:1; + UCHAR LBPWS:1; + UCHAR LBPU:1; + UCHAR ProvisioningType:3; + UCHAR Reserved1:5; + ULONG SoftThresholdEventPending; +} CLASS_VPD_B2_DATA, *PCLASS_VPD_B2_DATA; +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +typedef struct _CLASS_READ_CAPACITY16_DATA +{ + NTSTATUS CommandStatus; + ULONG BytesPerLogicalSector; + ULONG BytesPerPhysicalSector; + ULONG BytesOffsetForSectorAlignment; + BOOLEAN LBProvisioningEnabled; + BOOLEAN LBProvisioningReadZeros; + UCHAR Reserved0[2]; + ULONG Reserved1; +} CLASS_READ_CAPACITY16_DATA, *PCLASS_READ_CAPACITY16_DATA; + +typedef struct _CLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS +{ + NTSTATUS CommandStatus; + USHORT MaximumRangeDescriptors; + UCHAR Restricted; + UCHAR Reserved; + ULONG MaximumInactivityTimer; + ULONG DefaultInactivityTimer; + ULONGLONG MaximumTokenTransferSize; + ULONGLONG OptimalTransferCount; +} CLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS, *PCLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4214) +#endif +typedef struct _CLASS_FUNCTION_SUPPORT_INFO +{ + KSPIN_LOCK SyncLock; + ULONG GenerationCount; + volatile ULONG ChangeRequestCount; + struct + { + ULONG BlockLimits:1; + ULONG BlockDeviceCharacteristics:1; + ULONG LBProvisioning:1; + ULONG BlockDeviceRODLimits:1; + ULONG ZonedBlockDeviceCharacteristics:1; + ULONG Reserved:22; + ULONG DeviceType:5; + } ValidInquiryPages; + struct + { + CLASS_FUNCTION_SUPPORT SeekPenaltyProperty; + CLASS_FUNCTION_SUPPORT AccessAlignmentProperty; + CLASS_FUNCTION_SUPPORT TrimProperty; + CLASS_FUNCTION_SUPPORT TrimProcess; + } LowerLayerSupport; + BOOLEAN RegAccessAlignmentQueryNotSupported; + BOOLEAN AsynchronousNotificationSupported; +#if (NTDDI_VERSION >= NTDDI_WIN10_RS2) + BOOLEAN UseModeSense10; + UCHAR Reserved; +#else + UCHAR Reserved[2]; +#endif + CLASS_VPD_B0_DATA BlockLimitsData; + CLASS_VPD_B1_DATA DeviceCharacteristicsData; + CLASS_VPD_B2_DATA LBProvisioningData; + CLASS_READ_CAPACITY16_DATA ReadCapacity16Data; + CLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS BlockDeviceRODLimitsData; + struct + { + ULONG D3ColdSupported:1; + ULONG DeviceWakeable:1; + ULONG IdlePowerEnabled:1; + ULONG D3IdleTimeoutOverridden:1; + ULONG NoVerifyDuringIdlePower:1; + ULONG Reserved2:27; + ULONG D3IdleTimeout; + } IdlePower; + +#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) + CLASS_FUNCTION_SUPPORT HwFirmwareGetInfoSupport; + PSTORAGE_HW_FIRMWARE_INFO HwFirmwareInfo; +#endif +} CLASS_FUNCTION_SUPPORT_INFO, *PCLASS_FUNCTION_SUPPORT_INFO; +#ifdef _MSC_VER +#pragma warning(pop) +#endif + typedef struct _FUNCTIONAL_DEVICE_EXTENSION { _ANONYMOUS_UNION union { _ANONYMOUS_STRUCT struct { @@ -701,6 +879,12 @@ typedef struct _FUNCTIONAL_DEVICE_EXTENSION { ULONG DMByteSkew; ULONG DMSkew; BOOLEAN DMActive; +#if (NTDDI_VERSION >= NTDDI_WIN8) + UCHAR SenseDataLength; +#else + UCHAR Reserved; +#endif + UCHAR Reserved0[2]; DISK_GEOMETRY DiskGeometry; PSENSE_DATA SenseData; ULONG TimeOutValue; @@ -755,22 +939,31 @@ typedef struct _FUNCTIONAL_DEVICE_EXTENSION { ULONG SavedSrbFlags; ULONG SavedErrorCount; ULONG_PTR Reserved1; -#endif +#endif /* (SPVER(NTDDI_VERSION) < 2) */ #else /* (NTDDI_VERSION <= NTDDI_WIN2K) */ PCLASS_PRIVATE_FDO_DATA PrivateFdoData; +#if (NTDDI_VERSION >= NTDDI_WIN8) + PCLASS_FUNCTION_SUPPORT_INFO FunctionSupportInfo; + PSTORAGE_MINIPORT_DESCRIPTOR MiniportDescriptor; +#else ULONG_PTR Reserved2; ULONG_PTR Reserved3; - ULONG_PTR Reserved4; +#endif +#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) + PADDITIONAL_FDO_DATA AdditionalFdoData; +#else + ULONG_PTR Reserved4; +#endif #endif /* (NTDDI_VERSION <= NTDDI_WIN2K) */ } FUNCTIONAL_DEVICE_EXTENSION, *PFUNCTIONAL_DEVICE_EXTENSION; _IRQL_requires_max_(PASSIVE_LEVEL) _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API ULONG NTAPI ClassInitializeEx( @@ -781,7 +974,7 @@ ClassInitializeEx( _IRQL_requires_max_(PASSIVE_LEVEL) _Must_inspect_result_ _Post_satisfies_(return <= 0) -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassCreateDeviceObject( @@ -793,19 +986,19 @@ ClassCreateDeviceObject( PDEVICE_OBJECT *DeviceObject); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassReadDriveCapacity( _In_ PDEVICE_OBJECT DeviceObject); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassReleaseQueue( _In_ PDEVICE_OBJECT DeviceObject); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassSplitRequest( @@ -813,14 +1006,14 @@ ClassSplitRequest( _In_ PIRP Irp, _In_ ULONG MaximumBytes); -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassDeviceControl( _In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp); -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassIoComplete( @@ -828,7 +1021,7 @@ ClassIoComplete( PIRP Irp, PVOID Context); -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassIoCompleteAssociated( @@ -836,7 +1029,7 @@ ClassIoCompleteAssociated( PIRP Irp, PVOID Context); -SCSIPORTAPI +SCSIPORT_API BOOLEAN NTAPI ClassInterpretSenseInfo( @@ -860,21 +1053,21 @@ ClassSendDeviceIoControlSynchronous( _In_ BOOLEAN InternalDeviceIoControl, _Out_ PIO_STATUS_BLOCK IoStatus); -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassSendIrpSynchronous( _In_ PDEVICE_OBJECT TargetDeviceObject, _In_ PIRP Irp); -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassForwardIrpSynchronous( _In_ PCOMMON_DEVICE_EXTENSION CommonExtension, _In_ PIRP Irp); -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassSendSrbSynchronous( @@ -884,7 +1077,7 @@ ClassSendSrbSynchronous( _In_ ULONG BufferLength, _In_ BOOLEAN WriteToDevice); -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassSendSrbAsynchronous( @@ -895,14 +1088,14 @@ ClassSendSrbAsynchronous( _In_ ULONG BufferLength, _In_ BOOLEAN WriteToDevice); -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassBuildRequest( _In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp); -SCSIPORTAPI +SCSIPORT_API ULONG NTAPI ClassModeSense( @@ -911,7 +1104,7 @@ ClassModeSense( _In_ ULONG Length, _In_ UCHAR PageMode); -SCSIPORTAPI +SCSIPORT_API PVOID NTAPI ClassFindModePage( @@ -921,14 +1114,14 @@ ClassFindModePage( _In_ BOOLEAN Use6Byte); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassClaimDevice( _In_ PDEVICE_OBJECT LowerDeviceObject, _In_ BOOLEAN Release); -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassInternalIoControl( @@ -936,7 +1129,7 @@ ClassInternalIoControl( PIRP Irp); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassInitializeSrbLookasideList( @@ -944,51 +1137,51 @@ ClassInitializeSrbLookasideList( _In_ ULONG NumberElements); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassDeleteSrbLookasideList( _Inout_ PCOMMON_DEVICE_EXTENSION CommonExtension); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API ULONG NTAPI ClassQueryTimeOutRegistryValue( _In_ PDEVICE_OBJECT DeviceObject); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassGetDescriptor( _In_ PDEVICE_OBJECT DeviceObject, _In_ PSTORAGE_PROPERTY_ID PropertyId, - _Outptr_ PSTORAGE_DESCRIPTOR_HEADER *Descriptor); + _Outptr_ PVOID *Descriptor); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassInvalidateBusRelations( _In_ PDEVICE_OBJECT Fdo); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassMarkChildrenMissing( _In_ PFUNCTIONAL_DEVICE_EXTENSION Fdo); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API BOOLEAN NTAPI ClassMarkChildMissing( _In_ PPHYSICAL_DEVICE_EXTENSION PdoExtension, _In_ BOOLEAN AcquireChildLock); -SCSIPORTAPI +SCSIPORT_API VOID ClassDebugPrint( _In_ CLASS_DEBUG_LEVEL DebugPrintLevel, @@ -997,13 +1190,13 @@ ClassDebugPrint( __drv_aliasesMem _IRQL_requires_max_(DISPATCH_LEVEL) -SCSIPORTAPI +SCSIPORT_API PCLASS_DRIVER_EXTENSION NTAPI ClassGetDriverExtension( _In_ PDRIVER_OBJECT DriverObject); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassCompleteRequest( @@ -1011,14 +1204,14 @@ ClassCompleteRequest( _In_ PIRP Irp, _In_ CCHAR PriorityBoost); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassReleaseRemoveLock( _In_ PDEVICE_OBJECT DeviceObject, PIRP Tag); -SCSIPORTAPI +SCSIPORT_API ULONG NTAPI ClassAcquireRemoveLockEx( @@ -1028,7 +1221,7 @@ ClassAcquireRemoveLockEx( _In_ ULONG Line); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassUpdateInformationInRegistry( @@ -1038,7 +1231,7 @@ ClassUpdateInformationInRegistry( _In_reads_bytes_opt_(InquiryDataLength) PINQUIRYDATA InquiryData, _In_ ULONG InquiryDataLength); -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassWmiCompleteRequest( @@ -1049,7 +1242,7 @@ ClassWmiCompleteRequest( _In_ CCHAR PriorityBoost); _IRQL_requires_max_(DISPATCH_LEVEL) -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassWmiFireEvent( @@ -1059,14 +1252,14 @@ ClassWmiFireEvent( _In_ ULONG EventDataSize, _In_reads_bytes_(EventDataSize) PVOID EventData); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassResetMediaChangeTimer( _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassInitializeMediaChangeDetection( @@ -1074,20 +1267,20 @@ ClassInitializeMediaChangeDetection( _In_ PUCHAR EventPrefix); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassInitializeTestUnitPolling( _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ BOOLEAN AllowDriveToSleep); -SCSIPORTAPI +SCSIPORT_API PVPB NTAPI ClassGetVpb( _In_ PDEVICE_OBJECT DeviceObject); -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassSpinDownPowerHandler( @@ -1122,13 +1315,13 @@ ClassNotifyFailurePredicted( _In_ UCHAR Lun); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassAcquireChildLock( _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassReleaseChildLock( @@ -1142,14 +1335,14 @@ ClassSendStartUnit( _In_ PDEVICE_OBJECT DeviceObject); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassRemoveDevice( _In_ PDEVICE_OBJECT DeviceObject, _In_ UCHAR RemoveType); -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassAsynchronousCompletion( @@ -1157,13 +1350,13 @@ ClassAsynchronousCompletion( PIRP Irp, PVOID Event); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassCheckMediaState( _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension); -SCSIPORTAPI +SCSIPORT_API NTSTATUS NTAPI ClassCheckVerifyComplete( @@ -1172,7 +1365,7 @@ ClassCheckVerifyComplete( PVOID Context); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassSetMediaChangeState( @@ -1181,21 +1374,21 @@ ClassSetMediaChangeState( _In_ BOOLEAN Wait); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassEnableMediaChangeDetection( _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassDisableMediaChangeDetection( _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension); _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ClassCleanupMediaChangeDetection( @@ -1239,6 +1432,33 @@ ClassSendNotification( #endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ +__inline +UCHAR +GET_FDO_EXTENSON_SENSE_DATA_LENGTH ( + _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension) +{ + UCHAR SenseDataLength = 0; + + if (FdoExtension->SenseData != NULL) + { +#if (NTDDI_VERSION >= NTDDI_WIN8) + if (FdoExtension->SenseDataLength > 0) + { + SenseDataLength = FdoExtension->SenseDataLength; + } + else + { + // For backward compatibility with Windows 7 and earlier + SenseDataLength = SENSE_BUFFER_SIZE; + } +#else + SenseDataLength = SENSE_BUFFER_SIZE; +#endif + } + + return SenseDataLength; +} + static __inline BOOLEAN PORT_ALLOCATED_SENSE( diff --git a/sdk/include/ddk/scsi.h b/sdk/include/ddk/scsi.h index 59c7c5361b9..42027d5b84d 100644 --- a/sdk/include/ddk/scsi.h +++ b/sdk/include/ddk/scsi.h @@ -292,6 +292,7 @@ extern "C" { #define SCSIOP_CHANGE_DEFINITION 0x40 #define SCSIOP_WRITE_SAME 0x41 #define SCSIOP_READ_SUB_CHANNEL 0x42 +#define SCSIOP_UNMAP 0x42 #define SCSIOP_READ_TOC 0x43 #define SCSIOP_READ_HEADER 0x44 #define SCSIOP_REPORT_DENSITY_SUPPORT 0x44 @@ -299,6 +300,7 @@ extern "C" { #define SCSIOP_GET_CONFIGURATION 0x46 #define SCSIOP_PLAY_AUDIO_MSF 0x47 #define SCSIOP_PLAY_TRACK_INDEX 0x48 +#define SCSIOP_SANITIZE 0x48 #define SCSIOP_PLAY_TRACK_RELATIVE 0x49 #define SCSIOP_GET_EVENT_STATUS 0x4A #define SCSIOP_PAUSE_RESUME 0x4B @@ -326,10 +328,50 @@ extern "C" { #define SCSIOP_PERSISTENT_RESERVE_IN 0x5E #define SCSIOP_PERSISTENT_RESERVE_OUT 0x5F +#define SCSIOP_OPERATION32 0x7F + +#define SCSIOP_XDWRITE_EXTENDED16 0x80 +#define SCSIOP_WRITE_FILEMARKS16 0x80 +#define SCSIOP_REBUILD16 0x81 +#define SCSIOP_READ_REVERSE16 0x81 +#define SCSIOP_REGENERATE16 0x82 +#define SCSIOP_EXTENDED_COPY 0x83 +#define SCSIOP_POPULATE_TOKEN 0x83 +#define SCSIOP_WRITE_USING_TOKEN 0x83 +#define SCSIOP_RECEIVE_COPY_RESULTS 0x84 +#define SCSIOP_RECEIVE_ROD_TOKEN_INFORMATION 0x84 +#define SCSIOP_ATA_PASSTHROUGH16 0x85 +#define SCSIOP_ACCESS_CONTROL_IN 0x86 +#define SCSIOP_ACCESS_CONTROL_OUT 0x87 +#define SCSIOP_READ16 0x88 +#define SCSIOP_COMPARE_AND_WRITE 0x89 +#define SCSIOP_WRITE16 0x8A +#define SCSIOP_READ_ATTRIBUTES 0x8C +#define SCSIOP_WRITE_ATTRIBUTES 0x8D +#define SCSIOP_WRITE_VERIFY16 0x8E +#define SCSIOP_VERIFY16 0x8F +#define SCSIOP_PREFETCH16 0x90 +#define SCSIOP_SYNCHRONIZE_CACHE16 0x91 +#define SCSIOP_SPACE16 0x91 +#define SCSIOP_LOCK_UNLOCK_CACHE16 0x92 +#define SCSIOP_LOCATE16 0x92 +#define SCSIOP_WRITE_SAME16 0x93 +#define SCSIOP_ERASE16 0x93 +#define SCSIOP_ZBC_OUT 0x94 +#define SCSIOP_ZBC_IN 0x95 +#define SCSIOP_READ_DATA_BUFF16 0x9B +#define SCSIOP_READ_CAPACITY16 0x9E +#define SCSIOP_GET_LBA_STATUS 0x9E +#define SCSIOP_GET_PHYSICAL_ELEMENT_STATUS 0x9E +#define SCSIOP_REMOVE_ELEMENT_AND_TRUNCATE 0x9E +#define SCSIOP_SERVICE_ACTION_IN16 0x9E +#define SCSIOP_SERVICE_ACTION_OUT16 0x9F + #define SCSIOP_REPORT_LUNS 0xA0 #define SCSIOP_BLANK 0xA1 #define SCSIOP_ATA_PASSTHROUGH12 0xA1 #define SCSIOP_SEND_EVENT 0xA2 +#define SCSIOP_SECURITY_PROTOCOL_IN 0xA2 #define SCSIOP_SEND_KEY 0xA3 #define SCSIOP_MAINTENANCE_IN 0xA3 #define SCSIOP_REPORT_KEY 0xA4 @@ -355,6 +397,7 @@ extern "C" { #define SCSIOP_SET_LIMITS12 0xB3 #define SCSIOP_READ_ELEMENT_STATUS_ATTACHED 0xB4 #define SCSIOP_REQUEST_VOL_ELEMENT 0xB5 +#define SCSIOP_SECURITY_PROTOCOL_OUT 0xB5 #define SCSIOP_SEND_VOLUME_TAG 0xB6 #define SCSIOP_SET_STREAMING 0xB6 #define SCSIOP_READ_DEFECT_DATA 0xB7 @@ -374,32 +417,71 @@ extern "C" { #define SCSIOP_VOLUME_SET_OUT 0xBF #define SCSIOP_INIT_ELEMENT_RANGE 0xE7 -#define SCSIOP_XDWRITE_EXTENDED16 0x80 -#define SCSIOP_WRITE_FILEMARKS16 0x80 -#define SCSIOP_REBUILD16 0x81 -#define SCSIOP_READ_REVERSE16 0x81 -#define SCSIOP_REGENERATE16 0x82 -#define SCSIOP_EXTENDED_COPY 0x83 -#define SCSIOP_RECEIVE_COPY_RESULTS 0x84 -#define SCSIOP_ATA_PASSTHROUGH16 0x85 -#define SCSIOP_ACCESS_CONTROL_IN 0x86 -#define SCSIOP_ACCESS_CONTROL_OUT 0x87 -#define SCSIOP_READ16 0x88 -#define SCSIOP_WRITE16 0x8A -#define SCSIOP_READ_ATTRIBUTES 0x8C -#define SCSIOP_WRITE_ATTRIBUTES 0x8D -#define SCSIOP_WRITE_VERIFY16 0x8E -#define SCSIOP_VERIFY16 0x8F -#define SCSIOP_PREFETCH16 0x90 -#define SCSIOP_SYNCHRONIZE_CACHE16 0x91 -#define SCSIOP_SPACE16 0x91 -#define SCSIOP_LOCK_UNLOCK_CACHE16 0x92 -#define SCSIOP_LOCATE16 0x92 -#define SCSIOP_WRITE_SAME16 0x93 -#define SCSIOP_ERASE16 0x93 -#define SCSIOP_READ_CAPACITY16 0x9E -#define SCSIOP_SERVICE_ACTION_IN16 0x9E -#define SCSIOP_SERVICE_ACTION_OUT16 0x9F +// SCSI operation parameters + +// SCSIOP_SANITIZE (0x48) + +#define SERVICE_ACTION_OVERWRITE 0x01 +#define SERVICE_ACTION_BLOCK_ERASE 0x02 +#define SERVICE_ACTION_CRYPTO_ERASE 0x03 +#define SERVICE_ACTION_EXIT_FAILURE 0x1f + +// SCSIOP_OPERATION32 (0x7F) + +#define SERVICE_ACTION_XDWRITE 0x0004 +#define SERVICE_ACTION_XPWRITE 0x0006 +#define SERVICE_ACTION_XDWRITEREAD 0x0007 +#define SERVICE_ACTION_WRITE 0x000B +#define SERVICE_ACTION_WRITE_VERIFY 0x000C +#define SERVICE_ACTION_WRITE_SAME 0x000D +#define SERVICE_ACTION_ORWRITE 0x000E + +// SCSIOP_POPULATE_TOKEN, SCSIOP_WRITE_USING_TOKEN (0x83) + +#define SERVICE_ACTION_POPULATE_TOKEN 0x10 +#define SERVICE_ACTION_WRITE_USING_TOKEN 0x11 + +// SCSIOP_RECEIVE_ROD_TOKEN_INFORMATION (0x84) + +#define SERVICE_ACTION_RECEIVE_TOKEN_INFORMATION 0x07 + +// SCSIOP_ZBC_OUT (0x94) + +#define SERVICE_ACTION_CLOSE_ZONE 0x01 +#define SERVICE_ACTION_FINISH_ZONE 0x02 +#define SERVICE_ACTION_OPEN_ZONE 0x03 +#define SERVICE_ACTION_RESET_WRITE_POINTER 0x04 + +// SCSIOP_ZBC_IN (0x95) + +#define SERVICE_ACTION_REPORT_ZONES 0x00 + +#define REPORT_ZONES_OPTION_LIST_ALL_ZONES 0x00 +#define REPORT_ZONES_OPTION_LIST_EMPTY_ZONES 0x01 +#define REPORT_ZONES_OPTION_LIST_IMPLICITLY_OPENED_ZONES 0x02 +#define REPORT_ZONES_OPTION_LIST_EXPLICITLY_OPENED_ZONES 0x03 +#define REPORT_ZONES_OPTION_LIST_CLOSED_ZONES 0x04 +#define REPORT_ZONES_OPTION_LIST_FULL_ZONES 0x05 +#define REPORT_ZONES_OPTION_LIST_READ_ONLY_ZONES 0x06 +#define REPORT_ZONES_OPTION_LIST_OFFLINE_ZONES 0x07 +#define REPORT_ZONES_OPTION_LIST_RWP_ZONES 0x10 +#define REPORT_ZONES_OPTION_LIST_NON_SEQUENTIAL_WRITE_RESOURCES_ACTIVE_ZONES 0x11 +#define REPORT_ZONES_OPTION_LIST_NOT_WRITE_POINTER_ZONES 0x3F + +// SCSIOP_SERVICE_ACTION_IN16 (0x9E) + +#define SERVICE_ACTION_READ_CAPACITY16 0x10 +#define SERVICE_ACTION_GET_LBA_STATUS 0x12 +#define SERVICE_ACTION_GET_PHYSICAL_ELEMENT_STATUS 0x17 +#define SERVICE_ACTION_REMOVE_ELEMENT_AND_TRUNCATE 0x18 + +// SCSIOP_MAINTENANCE_IN (0xA3) + +#define SERVICE_ACTION_REPORT_TIMESTAMP 0x0F + +// SCSIOP_MAINTENANCE_OUT (0xA4) + +#define SERVICE_ACTION_SET_TIMESTAMP 0x0F #define CDB_RETURN_ON_COMPLETION 0 #define CDB_RETURN_IMMEDIATE 1 @@ -490,18 +572,6 @@ extern "C" { #define SCSISTAT_COMMAND_TERMINATED 0x22 #define SCSISTAT_QUEUE_FULL 0x28 -#define VPD_MAX_BUFFER_SIZE 0xff - -#define VPD_SUPPORTED_PAGES 0x00 -#define VPD_SERIAL_NUMBER 0x80 -#define VPD_DEVICE_IDENTIFIERS 0x83 -#define VPD_MEDIA_SERIAL_NUMBER 0x84 -#define VPD_SOFTWARE_INTERFACE_IDENTIFIERS 0x84 -#define VPD_NETWORK_MANAGEMENT_ADDRESSES 0x85 -#define VPD_EXTENDED_INQUIRY_DATA 0x86 -#define VPD_MODE_PAGE_POLICY 0x87 -#define VPD_SCSI_PORTS 0x88 - #define RESERVATION_ACTION_READ_KEYS 0x00 #define RESERVATION_ACTION_READ_RESERVATIONS 0x01 @@ -521,11 +591,13 @@ extern "C" { #define RESERVATION_TYPE_WRITE_EXCLUSIVE_REGISTRANTS 0x05 #define RESERVATION_TYPE_EXCLUSIVE_REGISTRANTS 0x06 -#define SENSE_BUFFER_SIZE 18 +#define SENSE_BUFFER_SIZE sizeof(SENSE_DATA) +#define SENSE_BUFFER_SIZE_EX sizeof(SENSE_DATA_EX) #define MAX_SENSE_BUFFER_SIZE 255 #define MAX_ADDITIONAL_SENSE_BYTES (MAX_SENSE_BUFFER_SIZE - SENSE_BUFFER_SIZE) +#define MAX_ADDITIONAL_SENSE_BYTES_EX (MAX_SENSE_BUFFER_SIZE - SENSE_BUFFER_SIZE_EX) /* Sense codes */ #define SCSI_SENSE_NO_SENSE 0x00 @@ -545,6 +617,28 @@ extern "C" { #define SCSI_SENSE_MISCOMPARE 0x0E #define SCSI_SENSE_RESERVED 0x0F +// Sense Error Codes + +#define SCSI_SENSE_ERRORCODE_FIXED_CURRENT 0x70 +#define SCSI_SENSE_ERRORCODE_FIXED_DEFERRED 0x71 +#define SCSI_SENSE_ERRORCODE_DESCRIPTOR_CURRENT 0x72 +#define SCSI_SENSE_ERRORCODE_DESCRIPTOR_DEFERRED 0x73 + +// Sense Descriptor Types + +#define SCSI_SENSE_DESCRIPTOR_TYPE_INFORMATION 0x00 +#define SCSI_SENSE_DESCRIPTOR_TYPE_COMMAND_SPECIFIC 0x01 +#define SCSI_SENSE_DESCRIPTOR_TYPE_SENSE_KEY_SPECIFIC 0x02 +#define SCSI_SENSE_DESCRIPTOR_TYPE_FIELD_REPLACEABLE_UNIT 0x03 +#define SCSI_SENSE_DESCRIPTOR_TYPE_STREAM_COMMAND 0x04 +#define SCSI_SENSE_DESCRIPTOR_TYPE_BLOCK_COMMAND 0x05 +#define SCSI_SENSE_DESCRIPTOR_TYPE_OSD_OBJECT_IDENTIFICATION 0x06 +#define SCSI_SENSE_DESCRIPTOR_TYPE_OSD_RESPONSE_INTEGRITY_CHECK 0x07 +#define SCSI_SENSE_DESCRIPTOR_TYPE_OSD_ATTRIBUTE_IDENTIFICATION 0x08 +#define SCSI_SENSE_DESCRIPTOR_TYPE_ATA_STATUS_RETURN 0x09 +#define SCSI_SENSE_DESCRIPTOR_TYPE_PROGRESS_INDICATION 0x0A +#define SCSI_SENSE_DESCRIPTOR_TYPE_USER_DATA_SEGMENT_REFERRAL 0x0B + /* Additional tape bit */ #define SCSI_ILLEGAL_LENGTH 0x20 #define SCSI_EOM 0x40 @@ -553,16 +647,25 @@ extern "C" { /* Additional Sense codes */ #define SCSI_ADSENSE_NO_SENSE 0x00 #define SCSI_ADSENSE_NO_SEEK_COMPLETE 0x02 +#define SCSI_ADSENSE_WRITE 0x03 #define SCSI_ADSENSE_LUN_NOT_READY 0x04 #define SCSI_ADSENSE_LUN_COMMUNICATION 0x08 +#define SCSI_ADSENSE_SERVO_ERROR 0x09 +#define SCSI_ADSENSE_WARNING 0x0B #define SCSI_ADSENSE_WRITE_ERROR 0x0C +#define SCSI_ADSENSE_COPY_TARGET_DEVICE_ERROR 0x0D +#define SCSI_ADSENSE_UNRECOVERED_ERROR 0x11 #define SCSI_ADSENSE_TRACK_ERROR 0x14 #define SCSI_ADSENSE_SEEK_ERROR 0x15 #define SCSI_ADSENSE_REC_DATA_NOECC 0x17 #define SCSI_ADSENSE_REC_DATA_ECC 0x18 +#define SCSI_ADSENSE_DEFECT_LIST_ERROR 0x19 #define SCSI_ADSENSE_PARAMETER_LIST_LENGTH 0x1A +#define SCSI_ADSENSE_MISCOMPARE_DURING_VERIFY_OPERATION 0x1D #define SCSI_ADSENSE_ILLEGAL_COMMAND 0x20 +#define SCSI_ADSENSE_ACCESS_DENIED 0x20 #define SCSI_ADSENSE_ILLEGAL_BLOCK 0x21 +#define SCSI_ADSENSE_INVALID_TOKEN 0x23 #define SCSI_ADSENSE_INVALID_CDB 0x24 #define SCSI_ADSENSE_INVALID_LUN 0x25 #define SCSI_ADSENSE_INVALID_FIELD_PARAMETER_LIST 0x26 @@ -572,9 +675,18 @@ extern "C" { #define SCSI_ADSENSE_PARAMETERS_CHANGED 0x2A #define SCSI_ADSENSE_INSUFFICIENT_TIME_FOR_OPERATION 0x2E #define SCSI_ADSENSE_INVALID_MEDIA 0x30 +#define SCSI_ADSENSE_DEFECT_LIST 0x32 +#define SCSI_ADSENSE_LB_PROVISIONING 0x38 #define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE 0x3a #define SCSI_ADSENSE_POSITION_ERROR 0x3b +#define SCSI_ADSENSE_LOGICAL_UNIT_ERROR 0x3e #define SCSI_ADSENSE_OPERATING_CONDITIONS_CHANGED 0x3f +#define SCSI_ADSENSE_DATA_PATH_FAILURE 0x41 +#define SCSI_ADSENSE_POWER_ON_SELF_TEST_FAILURE 0x42 +#define SCSI_ADSENSE_INTERNAL_TARGET_FAILURE 0x44 +#define SCSI_ADSENSE_DATA_TRANSFER_ERROR 0x4b +#define SCSI_ADSENSE_LUN_FAILED_SELF_CONFIGURATION 0x4c +#define SCSI_ADSENSE_RESOURCE_FAILURE 0x55 #define SCSI_ADSENSE_OPERATOR_REQUEST 0x5a #define SCSI_ADSENSE_FAILURE_PREDICTION_THRESHOLD_EXCEEDED 0x5d #define SCSI_ADSENSE_ILLEGAL_MODE_FOR_THIS_TRACK 0x64 @@ -588,17 +700,36 @@ extern "C" { #define SCSI_ADWRITE_PROTECT SCSI_ADSENSE_WRITE_PROTECT #define SCSI_FAILURE_PREDICTION_THRESHOLD_EXCEEDED SCSI_ADSENSE_FAILURE_PREDICTION_THRESHOLD_EXCEEDED -#define SCSI_SENSEQ_CAUSE_NOT_REPORTABLE 0x00 -#define SCSI_SENSEQ_BECOMING_READY 0x01 -#define SCSI_SENSEQ_INIT_COMMAND_REQUIRED 0x02 -#define SCSI_SENSEQ_MANUAL_INTERVENTION_REQUIRED 0x03 -#define SCSI_SENSEQ_FORMAT_IN_PROGRESS 0x04 -#define SCSI_SENSEQ_REBUILD_IN_PROGRESS 0x05 -#define SCSI_SENSEQ_RECALCULATION_IN_PROGRESS 0x06 -#define SCSI_SENSEQ_OPERATION_IN_PROGRESS 0x07 -#define SCSI_SENSEQ_LONG_WRITE_IN_PROGRESS 0x08 -#define SCSI_SENSEQ_LOSS_OF_STREAMING 0x09 -#define SCSI_SENSEQ_PADDING_BLOCKS_ADDED 0x0A +// ADSENSE additional qualifiers + +// SCSI_ADSENSE_NO_SENSE (0x00) + +#define SCSI_SENSEQ_FILEMARK_DETECTED 0x01 +#define SCSI_SENSEQ_END_OF_MEDIA_DETECTED 0x02 +#define SCSI_SENSEQ_SETMARK_DETECTED 0x03 +#define SCSI_SENSEQ_BEGINNING_OF_MEDIA_DETECTED 0x04 +#define SCSI_SENSEQ_OPERATION_IS_IN_PROGRESS 0x16 + +// SCSI_ADSENSE_WRITE (0x03) + +#define SCSI_SENSEQ_PERIPHERAL_DEVICE_WRITE_FAULT 0x00 +#define SCSI_SENSEQ_NO_WRITE_CURRENT 0x01 +#define SCSI_SENSEQ_EXCESSIVE_WRITE_ERRORS 0x02 + +// SCSI_ADSENSE_LUN_NOT_READY (0x04) + +#define SCSI_SENSEQ_CAUSE_NOT_REPORTABLE 0x00 +#define SCSI_SENSEQ_BECOMING_READY 0x01 +#define SCSI_SENSEQ_INIT_COMMAND_REQUIRED 0x02 +#define SCSI_SENSEQ_MANUAL_INTERVENTION_REQUIRED 0x03 +#define SCSI_SENSEQ_FORMAT_IN_PROGRESS 0x04 +#define SCSI_SENSEQ_REBUILD_IN_PROGRESS 0x05 +#define SCSI_SENSEQ_RECALCULATION_IN_PROGRESS 0x06 +#define SCSI_SENSEQ_OPERATION_IN_PROGRESS 0x07 +#define SCSI_SENSEQ_LONG_WRITE_IN_PROGRESS 0x08 +#define SCSI_SENSEQ_SPACE_ALLOC_IN_PROGRESS 0x14 + +// SCSI_ADSENSE_LUN_COMMUNICATION (0x08) #define SCSI_SENSEQ_COMM_FAILURE 0x00 #define SCSI_SENSEQ_COMM_TIMEOUT 0x01 @@ -606,21 +737,105 @@ extern "C" { #define SCSI_SESNEQ_COMM_CRC_ERROR 0x03 #define SCSI_SENSEQ_UNREACHABLE_TARGET 0x04 -#define SCSI_SENSEQ_FILEMARK_DETECTED 0x01 -#define SCSI_SENSEQ_END_OF_MEDIA_DETECTED 0x02 -#define SCSI_SENSEQ_SETMARK_DETECTED 0x03 -#define SCSI_SENSEQ_BEGINNING_OF_MEDIA_DETECTED 0x04 +// SCSI_ADSENSE_SERVO_ERROR (0x09) -#define SCSI_SENSEQ_ILLEGAL_ELEMENT_ADDR 0x01 +#define SCSI_SENSEQ_TRACK_FOLLOWING_ERROR 0x00 +#define SCSI_SENSEQ_TRACKING_SERVO_FAILURE 0x01 +#define SCSI_SENSEQ_FOCUS_SERVO_FAILURE 0x02 +#define SCSI_SENSEQ_SPINDLE_SERVO_FAILURE 0x03 +#define SCSI_SENSEQ_HEAD_SELECT_FAULT 0x04 -#define SCSI_SENSEQ_DESTINATION_FULL 0x0d -#define SCSI_SENSEQ_SOURCE_EMPTY 0x0e +// SCSI_ADSENSE_WARNING (0x0B) + +#define SCSI_SENSEQ_POWER_LOSS_EXPECTED 0x08 + +// SCSI_ADSENSE_WRITE_ERROR (0x0C) + +#define SCSI_SENSEQ_LOSS_OF_STREAMING 0x09 +#define SCSI_SENSEQ_PADDING_BLOCKS_ADDED 0x0A + +// SCSI_ADSENSE_COPY_TARGET_DEVICE_ERROR (0x0D) + +#define SCSI_SENSEQ_NOT_REACHABLE 0x02 +#define SCSI_SENSEQ_DATA_UNDERRUN 0x04 + +// SCSI_ADSENSE_UNRECOVERED_ERROR (0x11) + +#define SCSI_SENSEQ_UNRECOVERED_READ_ERROR 0x00 + +// SCSI_ADSENSE_SEEK_ERROR (0x15) + +#define SCSI_SENSEQ_RANDOM_POSITIONING_ERROR 0x00 +#define SCSI_SENSEQ_MECHANICAL_POSITIONING_ERROR 0x01 +#define SCSI_SENSEQ_POSITIONING_ERROR_DETECTED_BY_READ_OF_MEDIUM 0x02 + +// SCSI_ADSENSE_DEFECT_LIST_ERROR (0x19) + +#define SCSI_SENSEQ_DEFECT_LIST_ERROR 0x00 +#define SCSI_SENSEQ_DEFECT_LIST_NOT_AVAILABLE 0x01 +#define SCSI_SENSEQ_DEFECT_LIST_ERROR_IN_PRIMARY_LIST 0x02 +#define SCSI_SENSEQ_DEFECT_LIST_ERROR_IN_GROWN_LIST 0x03 + +// SCSI_ADSENSE_ACCESS_DENIED (0x20) + +#define SCSI_SENSEQ_NO_ACCESS_RIGHTS 0x02 + +// SCSI_ADSENSE_ILLEGAL_BLOCK (0x21) + +#define SCSI_SENSEQ_LOGICAL_ADDRESS_OUT_OF_RANGE 0x00 +#define SCSI_SENSEQ_ILLEGAL_ELEMENT_ADDR 0x01 +#define SCSI_SENSEQ_INVALID_WRITE_ADDRESS 0x02 +#define SCSI_SENSEQ_INVALID_WRITE_CROSSING_LAYER_JUMP 0x03 +#define SCSI_SENSEQ_UNALIGNED_WRITE 0x04 +#define SCSI_SENSEQ_WRITE_BOUNDARY_VIOLATION 0x05 +#define SCSI_SENSEQ_READ_INVALID_DATA 0x06 +#define SCSI_SENSEQ_READ_BOUNDARY_VIOLATION 0x07 +#define SCSI_SENSEQ_MISALIGNED_WRITE 0x08 + +// SCSI_ADSENSE_INVALID_FIELD_PARAMETER_LIST (0x26) + +#define SCSI_SENSEQ_INVALID_RELEASE_OF_PERSISTENT_RESERVATION 0x04 +#define SCSI_SENSEQ_TOO_MANY_SEGMENT_DESCRIPTORS 0x08 + +// SCSI_ADSENSE_WRITE_PROTECT (0x27) + +#define SCSI_SENSEQ_SPACE_ALLOC_FAILED_WRITE_PROTECT 0x07 + +// SCSI_ADSENSE_PARAMETERS_CHANGED (0x2A) + +#define SCSI_SENSEQ_CAPACITY_DATA_CHANGED 0x09 + +// SCSI_ADSENSE_POSITION_ERROR (0x3b) + +#define SCSI_SENSEQ_DESTINATION_FULL 0x0d +#define SCSI_SENSEQ_SOURCE_EMPTY 0x0e + +// SCSI_ADSENSE_INVALID_MEDIA (0x30) #define SCSI_SENSEQ_INCOMPATIBLE_MEDIA_INSTALLED 0x00 #define SCSI_SENSEQ_UNKNOWN_FORMAT 0x01 #define SCSI_SENSEQ_INCOMPATIBLE_FORMAT 0x02 #define SCSI_SENSEQ_CLEANING_CARTRIDGE_INSTALLED 0x03 +// SCSI_ADSENSE_DEFECT_LIST (0x32) + +#define SCSI_SENSEQ_NO_DEFECT_SPARE_LOCATION_AVAILABLE 0x00 +#define SCSI_SENSEQ_DEFECT_LIST_UPDATE_FAILURE 0x01 + +// SCSI_ADSENSE_LB_PROVISIONING (0x38) + +#define SCSI_SENSEQ_SOFT_THRESHOLD_REACHED 0x07 + +// SCSI_ADSENSE_LOGICAL_UNIT_ERROR (0x3e) + +#define SCSI_SENSEQ_LOGICAL_UNIT_HAS_NOT_SELF_CONFIGURED_YET 0x00 +#define SCSI_SENSEQ_LOGICAL_UNIT_FAILURE 0x01 +#define SCSI_SENSEQ_TIMEOUT_ON_LOGICAL_UNIT 0x02 +#define SCSI_SENSEQ_LOGICAL_UNIT_FAILED_SELF_TEST 0x03 +#define SCSI_SENSEQ_LOGICAL_UNIT_FAILED_TO_UPDATE_SELF_TEST_LOG 0x04 + +// SCSI_ADSENSE_OPERATING_CONDITIONS_CHANGED (0x3f) + #define SCSI_SENSEQ_TARGET_OPERATING_CONDITIONS_CHANGED 0x00 #define SCSI_SENSEQ_MICROCODE_CHANGED 0x01 #define SCSI_SENSEQ_OPERATING_DEFINITION_CHANGED 0x02 @@ -640,10 +855,55 @@ extern "C" { #define SCSI_SENSEQ_MEDIUM_LOADABLE 0x10 #define SCSI_SENSEQ_MEDIUM_AUXILIARY_MEMORY_ACCESSIBLE 0x11 -#define SCSI_SENSEQ_STATE_CHANGE_INPUT 0x00 -#define SCSI_SENSEQ_MEDIUM_REMOVAL 0x01 -#define SCSI_SENSEQ_WRITE_PROTECT_ENABLE 0x02 -#define SCSI_SENSEQ_WRITE_PROTECT_DISABLE 0x03 +// SCSI_ADSENSE_INTERNAL_TARGET_FAILURE (0x44) + +#define SCSI_SENSEQ_INTERNAL_TARGET_FAILURE 0x00 +#define SCSI_SENSEQ_PRESISTENT_RESERVATION_INFORMATION_LOST 0x01 +#define SCSI_SENSEQ_ATA_DEVICE_FAILED_SET_FEATURES 0x71 + +// SCSI_ADSENSE_DATA_TRANSFER_ERROR (0x4b) + +#define SCSI_SENSEQ_INITIATOR_RESPONSE_TIMEOUT 0x06 + +// SCSI_ADSENSE_RESOURCE_FAILURE (0x55) + +#define SCSI_SENSEQ_SYSTEM_RESOURCE_FAILURE 0x00 +#define SCSI_SENSEQ_SYSTEM_BUFFER_FULL 0x01 +#define SCSI_SENSEQ_INSUFFICIENT_RESERVATION_RESOURCES 0x02 +#define SCSI_SENSEQ_INSUFFICIENT_RESOURCES 0x03 + +// SCSI_ADSENSE_OPERATOR_REQUEST (0x5a) + +#define SCSI_SENSEQ_STATE_CHANGE_INPUT 0x00 +#define SCSI_SENSEQ_MEDIUM_REMOVAL 0x01 +#define SCSI_SENSEQ_WRITE_PROTECT_ENABLE 0x02 +#define SCSI_SENSEQ_WRITE_PROTECT_DISABLE 0x03 + +// SCSI_ADSENSE_FAILURE_PREDICTION_THRESHOLD_EXCEEDED (0x5d) + +#define SCSI_SENSEQ_FAILURE_PREDICTION_THRESHOLD_EXCEEDED 0x00 +#define SCSI_SENSEQ_MEDIA_FAILURE_PREDICTION_THRESHOLD_EXCEEDED 0x01 +#define SCSI_SENSEQ_LUN_FAILURE_PREDICTION_THRESHOLD_EXCEEDED 0x02 +#define SCSI_SENSEQ_SPARE_AREA_EXHAUSTION_PREDICTION_THRESHOLD_EXCEEDED 0x03 +#define SCSI_SENSEQ_GENERAL_HARD_DRIVE_FAILURE 0x10 +#define SCSI_SENSEQ_DRIVE_ERROR_RATE_TOO_HIGH 0x11 +#define SCSI_SENSEQ_DATA_ERROR_RATE_TOO_HIGH 0x12 +#define SCSI_SENSEQ_SEEK_ERROR_RATE_TOO_HIGH 0x13 +#define SCSI_SENSEQ_TOO_MANY_BLOCK_REASSIGNS 0x14 +#define SCSI_SENSEQ_ACCESS_TIMES_TOO_HIGH 0x15 +#define SCSI_SENSEQ_START_UNIT_TIMES_TOO_HIGH 0x16 +#define SCSI_SENSEQ_CHANNEL_PARAMETRICS 0x17 +#define SCSI_SENSEQ_CONTROLLER_DETECTED 0x18 +#define SCSI_SENSEQ_THROUGHPUT_PERFORMANCE 0x19 +#define SCSI_SENSEQ_SEEK_TIME_PERFORMANCE 0x1A +#define SCSI_SENSEQ_SPIN_UP_RETRY_COUNT 0x1B +#define SCSI_SENSEQ_DRIVE_CALIBRATION_RETRY_COUNT 0x1C +#define SCSI_SENSEQ_DATA_CHANNEL_DATA_ERROR_RATE_TOO_HIGH 0x32 +#define SCSI_SENSEQ_SERVO_DATA_ERROR_RATE_TOO_HIGH 0x42 +#define SCSI_SENSEQ_SERVER_SEEK_ERROR_RATE_TOO_HIGH 0x43 +#define SCSI_SENSEQ_FAILURE_PREDICTION_THRESHOLD_EXCEEDED_FALSE 0xFF + +// SCSI_ADSENSE_COPY_PROTECTION_FAILURE (0x6f) #define SCSI_SENSEQ_AUTHENTICATION_FAILURE 0x00 #define SCSI_SENSEQ_KEY_NOT_PRESENT 0x01 @@ -652,12 +912,14 @@ extern "C" { #define SCSI_SENSEQ_MEDIA_CODE_MISMATCHED_TO_LOGICAL_UNIT 0x04 #define SCSI_SENSEQ_LOGICAL_UNIT_RESET_COUNT_ERROR 0x05 -#define SCSI_SENSEQ_POWER_CALIBRATION_AREA_ALMOST_FULL 0x01 -#define SCSI_SENSEQ_POWER_CALIBRATION_AREA_FULL 0x02 -#define SCSI_SENSEQ_POWER_CALIBRATION_AREA_ERROR 0x03 -#define SCSI_SENSEQ_PMA_RMA_UPDATE_FAILURE 0x04 -#define SCSI_SENSEQ_PMA_RMA_IS_FULL 0x05 -#define SCSI_SENSEQ_PMA_RMA_ALMOST_FULL 0x06 +// SCSI_ADSENSE_POWER_CALIBRATION_ERROR (0x73) + +#define SCSI_SENSEQ_POWER_CALIBRATION_AREA_ALMOST_FULL 0x01 +#define SCSI_SENSEQ_POWER_CALIBRATION_AREA_FULL 0x02 +#define SCSI_SENSEQ_POWER_CALIBRATION_AREA_ERROR 0x03 +#define SCSI_SENSEQ_PMA_RMA_UPDATE_FAILURE 0x04 +#define SCSI_SENSEQ_PMA_RMA_IS_FULL 0x05 +#define SCSI_SENSEQ_PMA_RMA_ALMOST_FULL 0x06 #define FILE_DEVICE_SCSI 0x0000001b @@ -1103,6 +1365,32 @@ typedef union _CDB { UCHAR TransferBlockByte1; UCHAR Control; } NEC_READ_CDDA, *PNEC_READ_CDDA; +#if (NTDDI_VERSION >= NTDDI_WIN8) + struct _MODE_SENSE { + UCHAR OperationCode; + UCHAR Reserved1:3; + UCHAR Dbd:1; + UCHAR Reserved2:4; + UCHAR PageCode:6; + UCHAR Pc:2; + UCHAR SubPageCode; + UCHAR AllocationLength; + UCHAR Control; + } MODE_SENSE; + struct _MODE_SENSE10 { + UCHAR OperationCode; + UCHAR Reserved1:3; + UCHAR Dbd:1; + UCHAR LongLBAAccepted:1; + UCHAR Reserved2:3; + UCHAR PageCode:6; + UCHAR Pc:2; + UCHAR SubPageCode; + UCHAR Reserved3[3]; + UCHAR AllocationLength[2]; + UCHAR Control; + } MODE_SENSE10; +#else struct _MODE_SENSE { UCHAR OperationCode; UCHAR Reserved1:3; @@ -1127,6 +1415,7 @@ typedef union _CDB { UCHAR AllocationLength[2]; UCHAR Control; } MODE_SENSE10, *PMODE_SENSE10; +#endif struct _MODE_SELECT { UCHAR OperationCode; UCHAR SPBit:1; @@ -1649,11 +1938,51 @@ typedef union _CDB { UCHAR ServiceAction:5; UCHAR Reserved1:3; UCHAR LogicalBlock[8]; - UCHAR BlockCount[4]; + UCHAR AllocationLength[4]; UCHAR PMI:1; UCHAR Reserved2:7; UCHAR Control; } READ_CAPACITY16; + struct _TOKEN_OPERATION { + UCHAR OperationCode; + UCHAR ServiceAction:5; + UCHAR Reserved1:3; + UCHAR Reserved2[4]; + UCHAR ListIdentifier[4]; + UCHAR ParameterListLength[4]; + UCHAR GroupNumber:5; + UCHAR Reserved3:3; + UCHAR Control; + } TOKEN_OPERATION; + struct _RECEIVE_TOKEN_INFORMATION { + UCHAR OperationCode; + UCHAR ServiceAction:5; + UCHAR Reserved1:3; + UCHAR ListIdentifier[4]; + UCHAR Reserved2[4]; + UCHAR AllocationLength[4]; + UCHAR Reserved3; + UCHAR Control; + } RECEIVE_TOKEN_INFORMATION; + struct _UNMAP { + UCHAR OperationCode; + UCHAR Anchor:1; + UCHAR Reserved1:7; + UCHAR Reserved2[4]; + UCHAR GroupNumber:5; + UCHAR Reserved3:3; + UCHAR AllocationLength[2]; + UCHAR Control; + } UNMAP; + struct _GET_LBA_STATUS { + UCHAR OperationCode; + UCHAR ServiceAction:5; + UCHAR Reserved1:3; + UCHAR StartingLBA[8]; + UCHAR AllocationLength[4]; + UCHAR Reserved2; + UCHAR Control; + } GET_LBA_STATUS; ULONG AsUlong[4]; UCHAR AsByte[16]; } CDB, *PCDB; @@ -2069,6 +2398,25 @@ typedef struct _INQUIRYDATA { #endif /* _INQUIRYDATA_DEFINED */ +#define VPD_MAX_BUFFER_SIZE 0xff + +#define VPD_SUPPORTED_PAGES 0x00 +#define VPD_SERIAL_NUMBER 0x80 +#define VPD_DEVICE_IDENTIFIERS 0x83 +#define VPD_MEDIA_SERIAL_NUMBER 0x84 +#define VPD_SOFTWARE_INTERFACE_IDENTIFIERS 0x84 +#define VPD_NETWORK_MANAGEMENT_ADDRESSES 0x85 +#define VPD_EXTENDED_INQUIRY_DATA 0x86 +#define VPD_MODE_PAGE_POLICY 0x87 +#define VPD_SCSI_PORTS 0x88 +#define VPD_ATA_INFORMATION 0x89 + +#define VPD_THIRD_PARTY_COPY 0x8F +#define VPD_BLOCK_LIMITS 0xB0 +#define VPD_BLOCK_DEVICE_CHARACTERISTICS 0xB1 +#define VPD_LOGICAL_BLOCK_PROVISIONING 0xB2 +#define VPD_ZONED_BLOCK_DEVICE_CHARACTERISTICS 0xB6 + typedef struct _VPD_MEDIA_SERIAL_NUMBER_PAGE { UCHAR DeviceType:5; UCHAR DeviceTypeQualifier:3; @@ -2134,6 +2482,147 @@ typedef struct _VPD_IDENTIFICATION_PAGE { UCHAR Descriptors[0]; } VPD_IDENTIFICATION_PAGE, *PVPD_IDENTIFICATION_PAGE; +typedef struct _VPD_ATA_INFORMATION_PAGE { + UCHAR DeviceType:5; + UCHAR DeviceTypeQualifier:3; + UCHAR PageCode; + UCHAR PageLength[2]; + UCHAR Reserved0[4]; + UCHAR VendorId[8]; + UCHAR ProductId[16]; + UCHAR ProductRevisionLevel[4]; + UCHAR DeviceSignature[20]; + UCHAR CommandCode; + UCHAR Reserved1[3]; + UCHAR IdentifyDeviceData[512]; +} VPD_ATA_INFORMATION_PAGE, *PVPD_ATA_INFORMATION_PAGE; + +#if (NTDDI_VERSION >= NTDDI_WIN8) +typedef struct _VPD_THIRD_PARTY_COPY_PAGE { + UCHAR DeviceType:5; + UCHAR DeviceTypeQualifier:3; + UCHAR PageCode; + UCHAR PageLength[2]; +#if !defined(__midl) + UCHAR ThirdPartyCopyDescriptors[ANYSIZE_ARRAY]; +#endif +} VPD_THIRD_PARTY_COPY_PAGE, *PVPD_THIRD_PARTY_COPY_PAGE; + +typedef struct _WINDOWS_BLOCK_DEVICE_TOKEN_LIMITS_DESCRIPTOR { + UCHAR DescriptorType[2]; + UCHAR DescriptorLength[2]; + UCHAR VendorSpecific[6]; + UCHAR MaximumRangeDescriptors[2]; + UCHAR MaximumInactivityTimer[4]; + UCHAR DefaultInactivityTimer[4]; + UCHAR MaximumTokenTransferSize[8]; + UCHAR OptimalTransferCount[8]; +} WINDOWS_BLOCK_DEVICE_TOKEN_LIMITS_DESCRIPTOR, *PWINDOWS_BLOCK_DEVICE_TOKEN_LIMITS_DESCRIPTOR; + +#define BLOCK_DEVICE_TOKEN_LIMITS_DESCRIPTOR_TYPE_WINDOWS 0x00 + +#endif /* (NTDDI_VERSION >= NTDDI_WIN8) */ + +typedef struct _VPD_BLOCK_LIMITS_PAGE { + UCHAR DeviceType:5; + UCHAR DeviceTypeQualifier:3; + UCHAR PageCode; + UCHAR PageLength[2]; + union { + struct { + UCHAR Reserved0; + UCHAR MaximumCompareAndWriteLength; + UCHAR OptimalTransferLengthGranularity[2]; + UCHAR MaximumTransferLength[4]; + UCHAR OptimalTransferLength[4]; + UCHAR MaxPrefetchXDReadXDWriteTransferLength[4]; + UCHAR MaximumUnmapLBACount[4]; + UCHAR MaximumUnmapBlockDescriptorCount[4]; + UCHAR OptimalUnmapGranularity[4]; + union { + struct { + UCHAR UnmapGranularityAlignmentByte3:7; + UCHAR UGAValid:1; + UCHAR UnmapGranularityAlignmentByte2; + UCHAR UnmapGranularityAlignmentByte1; + UCHAR UnmapGranularityAlignmentByte0; + }; + UCHAR UnmapGranularityAlignment[4]; + }; + UCHAR Reserved1[28]; + }; +#if !defined(__midl) + UCHAR Descriptors[0]; +#endif + }; +} VPD_BLOCK_LIMITS_PAGE, *PVPD_BLOCK_LIMITS_PAGE; + +#define ZONED_CAPABILITIES_NOT_REPORTED 0x0 +#define ZONED_CAPABILITIES_HOST_AWARE 0x1 +#define ZONED_CAPABILITIES_DEVICE_MANAGED 0x2 + +typedef struct _VPD_BLOCK_DEVICE_CHARACTERISTICS_PAGE { + UCHAR DeviceType:5; + UCHAR DeviceTypeQualifier:3; + UCHAR PageCode; + UCHAR Reserved0; + UCHAR PageLength; + UCHAR MediumRotationRateMsb; + UCHAR MediumRotationRateLsb; + UCHAR MediumProductType; + UCHAR NominalFormFactor:4; + UCHAR WACEREQ:2; + UCHAR WABEREQ:2; + UCHAR VBULS:1; + UCHAR FUAB:1; + UCHAR BOCS:1; + UCHAR Reserved1:1; + UCHAR ZONED:2; + UCHAR Reserved2:2; + UCHAR Reserved3[3]; + UCHAR DepopulationTime[4]; + UCHAR Reserved4[48]; +} VPD_BLOCK_DEVICE_CHARACTERISTICS_PAGE, *PVPD_BLOCK_DEVICE_CHARACTERISTICS_PAGE; + +#define PROVISIONING_TYPE_UNKNOWN 0x0 +#define PROVISIONING_TYPE_RESOURCE 0x1 +#define PROVISIONING_TYPE_THIN 0x2 + +typedef struct _VPD_LOGICAL_BLOCK_PROVISIONING_PAGE { + UCHAR DeviceType:5; + UCHAR DeviceTypeQualifier:3; + UCHAR PageCode; + UCHAR PageLength[2]; + UCHAR ThresholdExponent; + UCHAR DP:1; + UCHAR ANC_SUP:1; + UCHAR LBPRZ:1; + UCHAR Reserved0:2; + UCHAR LBPWS10:1; + UCHAR LBPWS:1; + UCHAR LBPU:1; + UCHAR ProvisioningType:3; + UCHAR Reserved1:5; + UCHAR Reserved2; +#if !defined(__midl) + UCHAR ProvisioningGroupDescr[0]; +#endif +} VPD_LOGICAL_BLOCK_PROVISIONING_PAGE, *PVPD_LOGICAL_BLOCK_PROVISIONING_PAGE; + +typedef struct _VPD_ZONED_BLOCK_DEVICE_CHARACTERISTICS_PAGE { + UCHAR DeviceType:5; + UCHAR DeviceTypeQualifier:3; + UCHAR PageCode; + UCHAR PageLength[2]; + UCHAR URSWRZ:1; + UCHAR Reserved1:7; + UCHAR Reserved2[3]; + UCHAR OptimalNumberOfOpenSequentialWritePreferredZone[4]; + UCHAR OptimalNumberOfNonSequentiallyWrittenSequentialWritePreferredZone[4]; + UCHAR MaxNumberOfOpenSequentialWriteRequiredZone[4]; + UCHAR Reserved3[44]; +} VPD_ZONED_BLOCK_DEVICE_CHARACTERISTICS_PAGE, *PVPD_ZONED_BLOCK_DEVICE_CHARACTERISTICS_PAGE; + typedef struct _VPD_SUPPORTED_PAGES_PAGE { UCHAR DeviceType:5; UCHAR DeviceTypeQualifier:3; @@ -2192,6 +2681,63 @@ typedef struct _SENSE_DATA { UCHAR SenseKeySpecific[3]; } SENSE_DATA, *PSENSE_DATA; +typedef struct _SCSI_SENSE_DESCRIPTOR_HEADER { + UCHAR DescriptorType; + UCHAR AdditionalLength; +} SCSI_SENSE_DESCRIPTOR_HEADER, *PSCSI_SENSE_DESCRIPTOR_HEADER; + +typedef struct _SCSI_SENSE_DESCRIPTOR_INFORMATION { + SCSI_SENSE_DESCRIPTOR_HEADER Header; + UCHAR Valid:1; + UCHAR Reserved1:7; + UCHAR Reserved2; + UCHAR Information[8]; +} SCSI_SENSE_DESCRIPTOR_INFORMATION, *PSCSI_SENSE_DESCRIPTOR_INFORMATION; + +typedef struct _SCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND { + SCSI_SENSE_DESCRIPTOR_HEADER Header; + UCHAR Reserved1; + UCHAR Reserved2:5; + UCHAR IncorrectLength:1; + UCHAR Reserved3:2; +} SCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND, *PSCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND; + +typedef struct _SCSI_SENSE_DESCRIPTOR_ATA_STATUS_RETURN { + SCSI_SENSE_DESCRIPTOR_HEADER Header; + UCHAR Extend:1; + UCHAR Reserved1:7; + UCHAR Error; + UCHAR SectorCount15_8; + UCHAR SectorCount7_0; + UCHAR LbaLow15_8; + UCHAR LbaLow7_0; + UCHAR LbaMid15_8; + UCHAR LbaMid7_0; + UCHAR LbaHigh15_8; + UCHAR LbaHigh7_0; + UCHAR Device; + UCHAR Status; +} SCSI_SENSE_DESCRIPTOR_ATA_STATUS_RETURN, *PSCSI_SENSE_DESCRIPTOR_ATA_STATUS_RETURN; + +typedef struct _SENSE_DATA FIXED_SENSE_DATA, *PFIXED_SENSE_DATA; + +typedef struct _DESCRIPTOR_SENSE_DATA { + UCHAR ErrorCode:7; + UCHAR Reserved1:1; + UCHAR SenseKey:4; + UCHAR Reserved2:4; + UCHAR AdditionalSenseCode; + UCHAR AdditionalSenseCodeQualifier; + UCHAR Reserved3[3]; + UCHAR AdditionalSenseLength; + UCHAR DescriptorBuffer[ANYSIZE_ARRAY]; +} DESCRIPTOR_SENSE_DATA, *PDESCRIPTOR_SENSE_DATA; + +typedef union _SENSE_DATA_EX { + FIXED_SENSE_DATA FixedData; + DESCRIPTOR_SENSE_DATA DescriptorData; +} SENSE_DATA_EX, *PSENSE_DATA_EX; + /* Read Capacity Data. Returned in Big Endian format */ typedef struct _READ_CAPACITY_DATA { ULONG LogicalBlockAddress; @@ -2203,6 +2749,43 @@ typedef struct _READ_CAPACITY_DATA_EX { ULONG BytesPerBlock; } READ_CAPACITY_DATA_EX, *PREAD_CAPACITY_DATA_EX; +#define RC_BASIS_LAST_LBA_NOT_SEQUENTIAL_WRITE_REQUIRED_ZONES 0x0 +#define RC_BASIS_LAST_LBA_ON_LOGICAL_UNIT 0x1 + +typedef struct _READ_CAPACITY16_DATA { + LARGE_INTEGER LogicalBlockAddress; + ULONG BytesPerBlock; + UCHAR ProtectionEnable:1; + UCHAR ProtectionType:3; + UCHAR RcBasis:2; + UCHAR Reserved:2; + UCHAR LogicalPerPhysicalExponent:4; + UCHAR ProtectionInfoExponent:4; + UCHAR LowestAlignedBlock_MSB:6; + UCHAR LBPRZ:1; + UCHAR LBPME:1; + UCHAR LowestAlignedBlock_LSB; + UCHAR Reserved3[16]; +} READ_CAPACITY16_DATA, *PREAD_CAPACITY16_DATA; + +typedef struct _LBA_STATUS_DESCRIPTOR { + ULONGLONG StartingLBA; + ULONG LogicalBlockCount; + UCHAR ProvisioningStatus:4; + UCHAR Reserved1:4; + UCHAR Reserved2[3]; +} LBA_STATUS_DESCRIPTOR, *PLBA_STATUS_DESCRIPTOR; + +typedef struct _LBA_STATUS_LIST_HEADER { + ULONG ParameterLength; + ULONG Reserved; + LBA_STATUS_DESCRIPTOR Descriptors[0]; +} LBA_STATUS_LIST_HEADER, *PLBA_STATUS_LIST_HEADER; + +#define LBA_STATUS_MAPPED 0x0 +#define LBA_STATUS_DEALLOCATED 0x1 +#define LBA_STATUS_ANCHORED 0x2 + /* Read Block Limits Data. Returned in Big Endian format */ typedef struct _READ_BLOCK_LIMITS { UCHAR Reserved; @@ -2655,6 +3238,180 @@ typedef struct _TAPE_POSITION_DATA { UCHAR NumberOfBytes[4]; } TAPE_POSITION_DATA, *PTAPE_POSITION_DATA; +#include +typedef struct _UNMAP_BLOCK_DESCRIPTOR { + UCHAR StartingLba[8]; + UCHAR LbaCount[4]; + UCHAR Reserved[4]; +} UNMAP_BLOCK_DESCRIPTOR, *PUNMAP_BLOCK_DESCRIPTOR; + +typedef struct _UNMAP_LIST_HEADER { + UCHAR DataLength[2]; + UCHAR BlockDescrDataLength[2]; + UCHAR Reserved[4]; +#if !defined(__midl) + UNMAP_BLOCK_DESCRIPTOR Descriptors[0]; +#endif +} UNMAP_LIST_HEADER, *PUNMAP_LIST_HEADER; +#include + +#define LOG_PAGE_CODE_SUPPORTED_LOG_PAGES 0x00 +#define LOG_PAGE_CODE_WRITE_ERROR_COUNTERS 0x02 +#define LOG_PAGE_CODE_READ_ERROR_COUNTERS 0x03 +#define LOG_PAGE_CODE_LOGICAL_BLOCK_PROVISIONING 0x0C +#define LOG_PAGE_CODE_TEMPERATURE 0x0D +#define LOG_PAGE_CODE_STARTSTOP_CYCLE_COUNTERS 0x0E +#define LOG_PAGE_CODE_SELFTEST_RESULTS 0x10 +#define LOG_PAGE_CODE_SOLID_STATE_MEDIA 0x11 +#define LOG_PAGE_CODE_BACKGROUND_SCAN_RESULTS 0x15 +#define LOG_PAGE_CODE_INFORMATIONAL_EXCEPTIONS 0x2F + + +#include +typedef struct _LOG_PARAMETER_HEADER { + UCHAR ParameterCode[2]; + union { + UCHAR ControlByte; + struct { + UCHAR FormatAndLinking:2; + UCHAR TMC:2; + UCHAR ETC:1; + UCHAR TSD:1; + UCHAR Obsolete:1; + UCHAR DU:1; + }; + }; + UCHAR ParameterLength; +} LOG_PARAMETER_HEADER, *PLOG_PARAMETER_HEADER; + +typedef struct _LOG_PARAMETER { + LOG_PARAMETER_HEADER Header; + union { +#if !defined(__midl) + UCHAR AsByte[0]; +#endif + struct _THRESHOLD_RESOURCE_COUNT { + UCHAR ResourceCount[4]; + UCHAR Scope : 2; + UCHAR Reserved1 : 6; + UCHAR Reserved2[3]; + } THRESHOLD_RESOURCE_COUNT; + struct _TEMPERATURE { + UCHAR Reserved; + UCHAR Temperature; + } TEMPERATURE; + struct _DATE_OF_MANUFACTURE { + UCHAR Year[4]; + UCHAR Week[2]; + } DATE_OF_MANUFACTURE; + struct _SELF_TEST_RESULTS { + UCHAR SelfTestResults : 4; + UCHAR Reserved1 : 1; + UCHAR SelfTestCode : 3; + UCHAR SelfTestNumber; + UCHAR PowerOnHours[2]; + UCHAR AddressOfFirstFailure[8]; + UCHAR SenseKey : 4; + UCHAR Reserved2 : 4; + UCHAR AdditionalSenseCode; + UCHAR AdditionalSenseCodeQualifier; + UCHAR VendorSpecific; + } SELF_TEST_RESULTS; + + struct _SOLID_STATE_MEDIA { + UCHAR Reserved[3]; + UCHAR PercentageUsed; + } SOLID_STATE_MEDIA; + + struct _BACKGROUND_SCAN_STATUS { + UCHAR PowerOnMinutes[4]; + UCHAR Reserved; + UCHAR ScanStatus; + UCHAR ScansPerformed[2]; + UCHAR ScanProgress[2]; + UCHAR MediumScansPerformed[2]; + } BACKGROUND_SCAN_STATUS; + + struct _INFORMATIONAL_EXCEPTIONS { + UCHAR ASC; + UCHAR ASCQ; + UCHAR MostRecentTemperature; + UCHAR VendorSpecific[ANYSIZE_ARRAY]; + } INFORMATIONAL_EXCEPTIONS; + }; +} LOG_PARAMETER, *PLOG_PARAMETER; + +typedef struct _LOG_PAGE { + UCHAR PageCode:6; + UCHAR SPF:1; + UCHAR DS:1; + UCHAR SubPageCode; + UCHAR PageLength[2]; +#if !defined(__midl) + LOG_PARAMETER Parameters[0]; +#endif + +} LOG_PAGE, *PLOG_PAGE; + +#include + +#define LOG_PAGE_LBP_PARAMETER_CODE_AVAILABLE 0x1 +#define LOG_PAGE_LBP_PARAMETER_CODE_USED 0x2 + +#define LOG_PAGE_LBP_RESOURCE_SCOPE_NOT_REPORTED 0x0 +#define LOG_PAGE_LBP_RESOURCE_SCOPE_DEDICATED_TO_LUN 0x1 +#define LOG_PAGE_LBP_RESOURCE_SCOPE_NOT_DEDICATED_TO_LUN 0x2 + +typedef struct _LOG_PARAMETER_THRESHOLD_RESOURCE_COUNT { + LOG_PARAMETER_HEADER Header; + UCHAR ResourceCount[4]; + UCHAR Scope:2; + UCHAR Reserved0:6; + UCHAR Reserved1[3]; +} LOG_PARAMETER_THRESHOLD_RESOURCE_COUNT, *PLOG_PARAMETER_THRESHOLD_RESOURCE_COUNT; + +typedef struct _LOG_PAGE_LOGICAL_BLOCK_PROVISIONING { + UCHAR PageCode:6; + UCHAR SPF:1; + UCHAR DS:1; + UCHAR SubPageCode; + UCHAR PageLength[2]; +#if !defined(__midl) + LOG_PARAMETER_HEADER Parameters[0]; +#endif +} LOG_PAGE_LOGICAL_BLOCK_PROVISIONING, *PLOG_PAGE_LOGICAL_BLOCK_PROVISIONING; + +typedef struct _MODE_CONTROL_PAGE { + UCHAR PageCode:6; + UCHAR Reserved1:1; + UCHAR PageSavable:1; + UCHAR PageLength; + UCHAR RLEC:1; + UCHAR GLTSD:1; + UCHAR D_SENSE:1; + UCHAR DPICZ:1; + UCHAR TMF_ONLY:1; + UCHAR TST:3; + UCHAR Obsolete1:1; + UCHAR QERR:2; + UCHAR NUAR:1; + UCHAR QueueAlgorithmModifier:4; + UCHAR Obsolete2:3; + UCHAR SWP:1; + UCHAR UA_INTLCK_CTRL:2; + UCHAR RAC:1; + UCHAR VS:1; + UCHAR AutoloadMode:3; + UCHAR Reserved2:1; + UCHAR RWWP:1; + UCHAR ATMPE:1; + UCHAR TAS:1; + UCHAR ATO:1; + UCHAR Obsolete3[2]; + UCHAR BusyTimeoutPeriod[2]; + UCHAR ExtendeSelfTestCompletionTime[2]; +} MODE_CONTROL_PAGE, *PMODE_CONTROL_PAGE; + /* This structure is used to convert little endian ULONGs to SCSI CDB big endians values. */ typedef union _EIGHT_BYTE { @@ -2750,6 +3507,37 @@ typedef union _TWO_BYTE { (Bit) = _val; \ } +#if defined(_WIN64) +#define STOR_ADDRESS_ALIGN DECLSPEC_ALIGN(8) +#else +#define STOR_ADDRESS_ALIGN +#endif + +typedef struct STOR_ADDRESS_ALIGN _STOR_ADDRESS { + USHORT Type; + USHORT Port; + ULONG AddressLength; + _Field_size_bytes_(AddressLength) UCHAR AddressData[ANYSIZE_ARRAY]; +} STOR_ADDRESS, *PSTOR_ADDRESS; + +#define STOR_ADDRESS_TYPE_UNKNOWN 0x0 +#define STOR_ADDRESS_TYPE_BTL8 0x1 +#define STOR_ADDRESS_TYPE_MAX 0xffff + +#define STOR_ADDR_BTL8_ADDRESS_LENGTH 4 + +typedef struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 { + _Field_range_(STOR_ADDRESS_TYPE_BTL8, STOR_ADDRESS_TYPE_BTL8) + USHORT Type; + USHORT Port; + _Field_range_(STOR_ADDR_BTL8_ADDRESS_LENGTH, STOR_ADDR_BTL8_ADDRESS_LENGTH) + ULONG AddressLength; + UCHAR Path; + UCHAR Target; + UCHAR Lun; + UCHAR Reserved; +} STOR_ADDR_BTL8, *PSTOR_ADDR_BTL8; + /* FIXME : This structure doesn't exist in the official header */ typedef struct _MODE_CDROM_WRITE_PARAMETERS_PAGE { UCHAR PageLength; @@ -2789,6 +3577,549 @@ typedef struct _MODE_CDROM_WRITE_PARAMETERS_PAGE { UCHAR SubHeaderData[4]; } MODE_CDROM_WRITE_PARAMETERS_PAGE, *PMODE_CDROM_WRITE_PARAMETERS_PAGE; +#if (NTDDI_VERSION >= NTDDI_WIN8) +#include + +#define BLOCK_DEVICE_TOKEN_SIZE 512 + +typedef struct { + UCHAR LogicalBlockAddress[8]; + UCHAR TransferLength[4]; + UCHAR Reserved[4]; +} BLOCK_DEVICE_RANGE_DESCRIPTOR, *PBLOCK_DEVICE_RANGE_DESCRIPTOR; + +typedef struct { + UCHAR PopulateTokenDataLength[2]; + UCHAR Immediate:1; + UCHAR Reserved1:7; + UCHAR Reserved2; + UCHAR InactivityTimeout[4]; + UCHAR Reserved3[6]; + UCHAR BlockDeviceRangeDescriptorListLength[2]; +#if !defined(__midl) + UCHAR BlockDeviceRangeDescriptor[ANYSIZE_ARRAY]; +#endif +} POPULATE_TOKEN_HEADER, *PPOPULATE_TOKEN_HEADER; + +typedef struct { + UCHAR WriteUsingTokenDataLength[2]; + UCHAR Immediate:1; + UCHAR Reserved1:7; + UCHAR Reserved2[5]; + UCHAR BlockOffsetIntoToken[8]; + UCHAR Token[BLOCK_DEVICE_TOKEN_SIZE]; + UCHAR Reserved3[6]; + UCHAR BlockDeviceRangeDescriptorListLength[2]; +#if !defined(__midl) + UCHAR BlockDeviceRangeDescriptor[ANYSIZE_ARRAY]; +#endif +} WRITE_USING_TOKEN_HEADER, *PWRITE_USING_TOKEN_HEADER; + +typedef struct { + UCHAR AvailableData[4]; + UCHAR ResponseToServiceAction:5; + UCHAR Reserved1:3; + UCHAR OperationStatus:7; + UCHAR Reserved2:1; + UCHAR OperationCounter[2]; + UCHAR EstimatedStatusUpdateDelay[4]; + UCHAR CompletionStatus; + UCHAR SenseDataFieldLength; + UCHAR SenseDataLength; + UCHAR TransferCountUnits; + UCHAR TransferCount[8]; + UCHAR SegmentsProcessed[2]; + UCHAR Reserved3[6]; +#if !defined(__midl) + UCHAR SenseData[ANYSIZE_ARRAY]; +#endif +} RECEIVE_TOKEN_INFORMATION_HEADER, *PRECEIVE_TOKEN_INFORMATION_HEADER; + +typedef struct { + UCHAR TokenDescriptorsLength[4]; +#if !defined(__midl) + UCHAR TokenDescriptor[ANYSIZE_ARRAY]; +#endif +} RECEIVE_TOKEN_INFORMATION_RESPONSE_HEADER, *PRECEIVE_TOKEN_INFORMATION_RESPONSE_HEADER; + +typedef struct { + UCHAR TokenIdentifier[2]; + UCHAR Token[BLOCK_DEVICE_TOKEN_SIZE]; +} BLOCK_DEVICE_TOKEN_DESCRIPTOR, *PBLOCK_DEVICE_TOKEN_DESCRIPTOR; + +typedef enum _OPERATION_STATUS { + OPERATION_COMPLETED_WITH_SUCCESS = 0x01, + OPERATION_COMPLETED_WITH_ERROR = 0x02, + OPERATION_COMPLETED_WITH_RESIDUAL_DATA = 0x03, + OPERATION_IN_PROGRESS_IN_FOREGROUND = 0x11, + OPERATION_IN_PROGRESS_IN_BACKGROUND = 0x12, + OPERATION_TERMINATED = 0x60 +} OPERATION_STATUS, *POPERATION_STATUS; + +typedef enum _TRANSFER_COUNT_UNITS { + TRANSFER_COUNT_UNITS_BYTES = 0, + TRANSFER_COUNT_UNITS_KIBIBYTES = 1, + TRANSFER_COUNT_UNITS_MEBIBYTES = 2, + TRANSFER_COUNT_UNITS_GIBIBYTES = 3, + TRANSFER_COUNT_UNITS_TEBIBYTES = 4, + TRANSFER_COUNT_UNITS_PEBIBYTES = 5, + TRANSFER_COUNT_UNITS_EXBIBYTES = 6, + TRANSFER_COUNT_UNITS_NUMBER_BLOCKS = 0xF1 +} TRANSFER_COUNT_UNITS, *PTRANSFER_COUNT_UNITS; + +#include +#endif /* (NTDDI_VERSION >= NTDDI_WIN8) */ + +// SCSI utility functions + +#define ScsiGetSenseErrorCode(SenseInfoBuffer) (((PUCHAR)(SenseInfoBuffer))[0] & 0x7f) + +#define ScsiGetSenseDescriptorLength(DescriptorBuffer) \ + (sizeof(SCSI_SENSE_DESCRIPTOR_HEADER) + ((PSCSI_SENSE_DESCRIPTOR_HEADER)(DescriptorBuffer))->AdditionalLength) + +#define IsFixedSenseDataFormat(SenseInfoBuffer) \ + ((ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_FIXED_CURRENT || \ + (ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_FIXED_DEFERRED) + +#define IsDescriptorSenseDataFormat(SenseInfoBuffer) \ + ((ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_DESCRIPTOR_CURRENT || \ + (ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_DESCRIPTOR_DEFERRED) + +#define IsSenseDataCurrentError(SenseInfoBuffer) \ + ((ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_FIXED_CURRENT || \ + (ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_DESCRIPTOR_CURRENT) + +#define IsSenseDataDeferredError(SenseInfoBuffer) \ + ((ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_FIXED_DEFERRED || \ + (ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_DESCRIPTOR_DEFERRED) + +#define IsSenseDataFormatValueValid(SenseInfoBuffer) \ + (IsFixedSenseDataFormat(SenseInfoBuffer) || IsDescriptorSenseDataFormat(SenseInfoBuffer)) + +_Success_(return != FALSE) +FORCEINLINE +BOOLEAN +ScsiGetTotalSenseByteCountIndicated( + _In_reads_bytes_(SenseInfoBufferLength) PVOID SenseInfoBuffer, + _In_ UCHAR SenseInfoBufferLength, + _Out_ UCHAR *TotalByteCountIndicated) +{ + BOOLEAN succeed = FALSE; + UCHAR byteCount = 0; + PFIXED_SENSE_DATA senseInfoBuffer = NULL; + + if (SenseInfoBuffer == NULL || SenseInfoBufferLength == 0 || TotalByteCountIndicated == NULL) + { + + return FALSE; + } + + senseInfoBuffer = (PFIXED_SENSE_DATA)SenseInfoBuffer; + + if (RTL_CONTAINS_FIELD(senseInfoBuffer, SenseInfoBufferLength, AdditionalSenseLength)) + { + + if (senseInfoBuffer->AdditionalSenseLength <= + (MAX_SENSE_BUFFER_SIZE - RTL_SIZEOF_THROUGH_FIELD(FIXED_SENSE_DATA, AdditionalSenseLength))) + { + + byteCount = senseInfoBuffer->AdditionalSenseLength + + RTL_SIZEOF_THROUGH_FIELD(FIXED_SENSE_DATA, AdditionalSenseLength); + + *TotalByteCountIndicated = byteCount; + + succeed = TRUE; + } + } + + return succeed; +} + +_Success_(return != FALSE) +FORCEINLINE +BOOLEAN +ScsiGetFixedSenseKeyAndCodes( + _In_reads_bytes_(SenseInfoBufferLength) PVOID SenseInfoBuffer, + _In_ UCHAR SenseInfoBufferLength, + _Out_opt_ PUCHAR SenseKey, + _Out_opt_ PUCHAR AdditionalSenseCode, + _Out_opt_ PUCHAR AdditionalSenseCodeQualifier) +{ + PFIXED_SENSE_DATA fixedSenseData = (PFIXED_SENSE_DATA)SenseInfoBuffer; + BOOLEAN succeed = FALSE; + ULONG dataLength = 0; + + if (SenseInfoBuffer == NULL || SenseInfoBufferLength == 0) + { + return FALSE; + } + + if (RTL_CONTAINS_FIELD(fixedSenseData, SenseInfoBufferLength, AdditionalSenseLength)) + { + + dataLength = fixedSenseData->AdditionalSenseLength + + RTL_SIZEOF_THROUGH_FIELD(FIXED_SENSE_DATA, AdditionalSenseLength); + + if (dataLength > SenseInfoBufferLength) + { + dataLength = SenseInfoBufferLength; + } + + if (SenseKey != NULL) + { + *SenseKey = fixedSenseData->SenseKey; + } + + if (AdditionalSenseCode != NULL) + { + *AdditionalSenseCode = RTL_CONTAINS_FIELD(fixedSenseData, dataLength, AdditionalSenseCode) + ? fixedSenseData->AdditionalSenseCode + : 0; + } + + if (AdditionalSenseCodeQualifier != NULL) + { + *AdditionalSenseCodeQualifier = + RTL_CONTAINS_FIELD(fixedSenseData, dataLength, AdditionalSenseCodeQualifier) + ? fixedSenseData->AdditionalSenseCodeQualifier + : 0; + } + + succeed = TRUE; + } + + return succeed; +} + +_Success_(return != FALSE) +FORCEINLINE +BOOLEAN +ScsiGetDescriptorSenseKeyAndCodes( + _In_reads_bytes_(SenseInfoBufferLength) PVOID SenseInfoBuffer, + _In_ UCHAR SenseInfoBufferLength, + _Out_opt_ PUCHAR SenseKey, + _Out_opt_ PUCHAR AdditionalSenseCode, + _Out_opt_ PUCHAR AdditionalSenseCodeQualifier) +{ + PDESCRIPTOR_SENSE_DATA descriptorSenseData = (PDESCRIPTOR_SENSE_DATA)SenseInfoBuffer; + BOOLEAN succeed = FALSE; + + if (SenseInfoBuffer == NULL || SenseInfoBufferLength == 0) + { + return FALSE; + } + if (RTL_CONTAINS_FIELD(descriptorSenseData, SenseInfoBufferLength, AdditionalSenseLength)) + { + + if (SenseKey) + { + *SenseKey = descriptorSenseData->SenseKey; + } + + if (AdditionalSenseCode != NULL) + { + *AdditionalSenseCode = descriptorSenseData->AdditionalSenseCode; + } + + if (AdditionalSenseCodeQualifier != NULL) + { + *AdditionalSenseCodeQualifier = descriptorSenseData->AdditionalSenseCodeQualifier; + } + + succeed = TRUE; + } + + return succeed; +} + +typedef ULONG SCSI_SENSE_OPTIONS; + +#define SCSI_SENSE_OPTIONS_NONE ((SCSI_SENSE_OPTIONS)0x00000000) +#define SCSI_SENSE_OPTIONS_FIXED_FORMAT_IF_UNKNOWN_FORMAT_INDICATED ((SCSI_SENSE_OPTIONS)0x00000001) + +_Success_(return != FALSE) +FORCEINLINE +BOOLEAN +ScsiGetSenseKeyAndCodes( + _In_reads_bytes_(SenseInfoBufferLength) PVOID SenseInfoBuffer, + _In_ UCHAR SenseInfoBufferLength, + _In_ SCSI_SENSE_OPTIONS Options, + _Out_opt_ PUCHAR SenseKey, + _Out_opt_ PUCHAR AdditionalSenseCode, + _Out_opt_ PUCHAR AdditionalSenseCodeQualifier) +{ + BOOLEAN succeed = FALSE; + + if (SenseInfoBuffer == NULL || SenseInfoBufferLength == 0) + { + return FALSE; + } + + if (IsDescriptorSenseDataFormat(SenseInfoBuffer)) + { + succeed = ScsiGetDescriptorSenseKeyAndCodes(SenseInfoBuffer, SenseInfoBufferLength, SenseKey, + AdditionalSenseCode, AdditionalSenseCodeQualifier); + } + else + { + if ((Options & SCSI_SENSE_OPTIONS_FIXED_FORMAT_IF_UNKNOWN_FORMAT_INDICATED) || + IsFixedSenseDataFormat(SenseInfoBuffer)) + { + + succeed = ScsiGetFixedSenseKeyAndCodes(SenseInfoBuffer, SenseInfoBufferLength, SenseKey, + AdditionalSenseCode, AdditionalSenseCodeQualifier); + } + } + + return succeed; +} + +_Success_(return != FALSE) +FORCEINLINE +BOOLEAN +ScsiGetSenseDescriptor( + _In_reads_bytes_(SenseInfoBufferLength) PVOID SenseInfoBuffer, + _In_ UCHAR SenseInfoBufferLength, + _Outptr_result_bytebuffer_(*DescriptorBufferLength) PVOID *DescriptorBuffer, + _Out_ UCHAR *DescriptorBufferLength) +{ + PDESCRIPTOR_SENSE_DATA descriptorSenseData; + BOOLEAN succeed = FALSE; + UCHAR dataLength = 0; + + if (SenseInfoBuffer == NULL || SenseInfoBufferLength == 0 || DescriptorBuffer == NULL || + DescriptorBufferLength == NULL) + { + return FALSE; + } + + *DescriptorBuffer = NULL; + *DescriptorBufferLength = 0; + + if (!IsDescriptorSenseDataFormat(SenseInfoBuffer)) + { + return FALSE; + } + + descriptorSenseData = (PDESCRIPTOR_SENSE_DATA)SenseInfoBuffer; + + if (RTL_CONTAINS_FIELD(descriptorSenseData, SenseInfoBufferLength, AdditionalSenseLength)) + { + if (descriptorSenseData->AdditionalSenseLength <= + (MAX_SENSE_BUFFER_SIZE - + RTL_SIZEOF_THROUGH_FIELD(DESCRIPTOR_SENSE_DATA, AdditionalSenseLength))) + { + dataLength = descriptorSenseData->AdditionalSenseLength + + RTL_SIZEOF_THROUGH_FIELD(DESCRIPTOR_SENSE_DATA, AdditionalSenseLength); + + if (dataLength > SenseInfoBufferLength) + { + dataLength = SenseInfoBufferLength; + } + + *DescriptorBufferLength = + dataLength - RTL_SIZEOF_THROUGH_FIELD(DESCRIPTOR_SENSE_DATA, AdditionalSenseLength); + + if (*DescriptorBufferLength > 0) + { + *DescriptorBuffer = (PVOID)(descriptorSenseData->DescriptorBuffer); + succeed = TRUE; + } + } + } + + return succeed; +} + +_Success_(return != FALSE) +FORCEINLINE +BOOLEAN +ScsiValidateInformationSenseDescriptor( + _In_reads_bytes_(DescriptorBufferLength) PVOID DescriptorBuffer, + _In_ UCHAR DescriptorBufferLength) +{ + PSCSI_SENSE_DESCRIPTOR_INFORMATION descriptor; + UCHAR additionalLength; + + if (DescriptorBuffer == NULL || + DescriptorBufferLength < sizeof(SCSI_SENSE_DESCRIPTOR_INFORMATION)) + { + return FALSE; + } + + descriptor = (PSCSI_SENSE_DESCRIPTOR_INFORMATION)DescriptorBuffer; + + if (descriptor->Header.DescriptorType != SCSI_SENSE_DESCRIPTOR_TYPE_INFORMATION) + { + return FALSE; + } + + additionalLength = sizeof(SCSI_SENSE_DESCRIPTOR_INFORMATION) - + RTL_SIZEOF_THROUGH_FIELD(SCSI_SENSE_DESCRIPTOR_INFORMATION, Header); + + if (descriptor->Header.AdditionalLength != additionalLength) + { + return FALSE; + } + + if (descriptor->Valid == 0) + { + return FALSE; + } + + return TRUE; +} + +_Success_(return != FALSE) +FORCEINLINE +BOOLEAN +ScsiValidateBlockCommandSenseDescriptor( + _In_reads_bytes_(DescriptorBufferLength) PVOID DescriptorBuffer, + _In_ UCHAR DescriptorBufferLength) +{ + PSCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND descriptor; + UCHAR additionalLength; + + if (DescriptorBuffer == NULL || + DescriptorBufferLength < sizeof(SCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND)) + { + return FALSE; + } + + descriptor = (PSCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND)DescriptorBuffer; + + if (descriptor->Header.DescriptorType != SCSI_SENSE_DESCRIPTOR_TYPE_BLOCK_COMMAND) + { + return FALSE; + } + + additionalLength = sizeof(SCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND) - + RTL_SIZEOF_THROUGH_FIELD(SCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND, Header); + + if (descriptor->Header.AdditionalLength != additionalLength) + { + return FALSE; + } + + return TRUE; +} + +_Success_(return != FALSE) +FORCEINLINE +BOOLEAN +ScsiConvertToFixedSenseFormat( + _In_reads_bytes_(SenseInfoBufferLength) PVOID SenseInfoBuffer, + _In_ UCHAR SenseInfoBufferLength, + _Out_writes_bytes_(OutBufferLength) PVOID OutBuffer, + _In_ UCHAR OutBufferLength) +{ + BOOLEAN succeed = FALSE; + BOOLEAN validSense = FALSE; + UCHAR senseKey = 0; + UCHAR additionalSenseCode = 0; + UCHAR additionalSenseCodeQualifier = 0; + PFIXED_SENSE_DATA outBuffer = (PFIXED_SENSE_DATA)OutBuffer; + + if (SenseInfoBuffer == NULL || SenseInfoBufferLength == 0 || OutBuffer == NULL || + OutBufferLength < sizeof(FIXED_SENSE_DATA)) + { + return FALSE; + } + + if (IsDescriptorSenseDataFormat(SenseInfoBuffer)) + { + RtlZeroMemory(OutBuffer, OutBufferLength); + + validSense = + ScsiGetSenseKeyAndCodes(SenseInfoBuffer, SenseInfoBufferLength, SCSI_SENSE_OPTIONS_NONE, + &senseKey, &additionalSenseCode, &additionalSenseCodeQualifier); + if (validSense) + { + + if (IsSenseDataCurrentError(SenseInfoBuffer)) + { + outBuffer->ErrorCode = SCSI_SENSE_ERRORCODE_FIXED_CURRENT; + } + else + { + outBuffer->ErrorCode = SCSI_SENSE_ERRORCODE_FIXED_DEFERRED; + } + outBuffer->AdditionalSenseLength = + sizeof(FIXED_SENSE_DATA) - + RTL_SIZEOF_THROUGH_FIELD(FIXED_SENSE_DATA, AdditionalSenseLength); + outBuffer->SenseKey = senseKey; + outBuffer->AdditionalSenseCode = additionalSenseCode; + outBuffer->AdditionalSenseCodeQualifier = additionalSenseCodeQualifier; + + succeed = TRUE; + } + } + + return succeed; +} + +_Success_(return != FALSE) +FORCEINLINE +BOOLEAN +ScsiGetNextSenseDescriptorByType( + _In_reads_bytes_(BufferLength) PVOID Buffer, + _In_ UCHAR BufferLength, + _In_reads_(TypeListCount) PUCHAR TypeList, + _In_ ULONG TypeListCount, + _Out_ PUCHAR OutType, + _Outptr_result_bytebuffer_(*OutBufferLength) PVOID *OutBuffer, + _Out_ UCHAR *OutBufferLength) +{ + PUCHAR remainingBuffer; + UCHAR remainingBufferLength; + UCHAR type; + ULONG i; + UCHAR descriptorLength; + + if (Buffer == NULL || BufferLength == 0 || TypeList == NULL || TypeListCount == 0 || + OutType == NULL || OutBuffer == NULL || OutBufferLength == NULL) + { + return FALSE; + } + + *OutBuffer = NULL; + *OutBufferLength = 0; + *OutType = 0; + + remainingBuffer = (PUCHAR)Buffer; + remainingBufferLength = BufferLength; + + while (remainingBufferLength >= sizeof(SCSI_SENSE_DESCRIPTOR_HEADER)) + { + for (i = 0; i < TypeListCount; i++) + { + type = TypeList[i]; + + if (((PSCSI_SENSE_DESCRIPTOR_HEADER)remainingBuffer)->DescriptorType == type) + { + *OutBuffer = (PVOID)remainingBuffer; + *OutBufferLength = remainingBufferLength; + *OutType = type; + return TRUE; + } + } + + descriptorLength = ScsiGetSenseDescriptorLength(remainingBuffer); + + if (remainingBufferLength > descriptorLength) + { + remainingBuffer += descriptorLength; + remainingBufferLength -= descriptorLength; + } + else + { + break; + } + } + + return FALSE; +} + #ifdef __cplusplus } #endif diff --git a/sdk/include/ddk/scsiwmi.h b/sdk/include/ddk/scsiwmi.h index c527203fe7e..5a45f8c3be7 100644 --- a/sdk/include/ddk/scsiwmi.h +++ b/sdk/include/ddk/scsiwmi.h @@ -146,7 +146,7 @@ typedef struct _SCSIWMILIB_CONTEXT { } SCSI_WMILIB_CONTEXT, *PSCSI_WMILIB_CONTEXT; _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API BOOLEAN NTAPI ScsiPortWmiDispatchFunction( @@ -189,7 +189,7 @@ ScsiPortWmiDispatchFunction( #define ScsiPortWmiGetReturnStatus(RequestContext) \ ((RequestContext)->ReturnStatus) -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWmiPostProcess( @@ -197,7 +197,7 @@ ScsiPortWmiPostProcess( _In_ UCHAR SrbStatus, _In_ ULONG BufferUsed); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWmiFireLogicalUnitEvent( diff --git a/sdk/include/ddk/srb.h b/sdk/include/ddk/srb.h index 0aead0d097f..297be69d073 100644 --- a/sdk/include/ddk/srb.h +++ b/sdk/include/ddk/srb.h @@ -67,32 +67,39 @@ extern "C" { Target = (UCHAR) ((((Value) >> 8) & ~(0x20 - 1)) | ((Value) & (0x20 - 1)))) /* SCSI_REQUEST_BLOCK.Function constants */ -#define SRB_FUNCTION_EXECUTE_SCSI 0x00 -#define SRB_FUNCTION_CLAIM_DEVICE 0x01 -#define SRB_FUNCTION_IO_CONTROL 0x02 -#define SRB_FUNCTION_RECEIVE_EVENT 0x03 -#define SRB_FUNCTION_RELEASE_QUEUE 0x04 -#define SRB_FUNCTION_ATTACH_DEVICE 0x05 -#define SRB_FUNCTION_RELEASE_DEVICE 0x06 -#define SRB_FUNCTION_SHUTDOWN 0x07 -#define SRB_FUNCTION_FLUSH 0x08 -#define SRB_FUNCTION_ABORT_COMMAND 0x10 -#define SRB_FUNCTION_RELEASE_RECOVERY 0x11 -#define SRB_FUNCTION_RESET_BUS 0x12 -#define SRB_FUNCTION_RESET_DEVICE 0x13 -#define SRB_FUNCTION_TERMINATE_IO 0x14 -#define SRB_FUNCTION_FLUSH_QUEUE 0x15 -#define SRB_FUNCTION_REMOVE_DEVICE 0x16 -#define SRB_FUNCTION_WMI 0x17 -#define SRB_FUNCTION_LOCK_QUEUE 0x18 -#define SRB_FUNCTION_UNLOCK_QUEUE 0x19 -#define SRB_FUNCTION_RESET_LOGICAL_UNIT 0x20 -#define SRB_FUNCTION_SET_LINK_TIMEOUT 0x21 -#define SRB_FUNCTION_LINK_TIMEOUT_OCCURRED 0x22 -#define SRB_FUNCTION_LINK_TIMEOUT_COMPLETE 0x23 -#define SRB_FUNCTION_POWER 0x24 -#define SRB_FUNCTION_PNP 0x25 -#define SRB_FUNCTION_DUMP_POINTERS 0x26 +#define SRB_FUNCTION_EXECUTE_SCSI 0x00 +#define SRB_FUNCTION_CLAIM_DEVICE 0x01 +#define SRB_FUNCTION_IO_CONTROL 0x02 +#define SRB_FUNCTION_RECEIVE_EVENT 0x03 +#define SRB_FUNCTION_RELEASE_QUEUE 0x04 +#define SRB_FUNCTION_ATTACH_DEVICE 0x05 +#define SRB_FUNCTION_RELEASE_DEVICE 0x06 +#define SRB_FUNCTION_SHUTDOWN 0x07 +#define SRB_FUNCTION_FLUSH 0x08 +#define SRB_FUNCTION_PROTOCOL_COMMAND 0x09 +#define SRB_FUNCTION_ABORT_COMMAND 0x10 +#define SRB_FUNCTION_RELEASE_RECOVERY 0x11 +#define SRB_FUNCTION_RESET_BUS 0x12 +#define SRB_FUNCTION_RESET_DEVICE 0x13 +#define SRB_FUNCTION_TERMINATE_IO 0x14 +#define SRB_FUNCTION_FLUSH_QUEUE 0x15 +#define SRB_FUNCTION_REMOVE_DEVICE 0x16 +#define SRB_FUNCTION_WMI 0x17 +#define SRB_FUNCTION_LOCK_QUEUE 0x18 +#define SRB_FUNCTION_UNLOCK_QUEUE 0x19 +#define SRB_FUNCTION_QUIESCE_DEVICE 0x1a +#define SRB_FUNCTION_RESET_LOGICAL_UNIT 0x20 +#define SRB_FUNCTION_SET_LINK_TIMEOUT 0x21 +#define SRB_FUNCTION_LINK_TIMEOUT_OCCURRED 0x22 +#define SRB_FUNCTION_LINK_TIMEOUT_COMPLETE 0x23 +#define SRB_FUNCTION_POWER 0x24 +#define SRB_FUNCTION_PNP 0x25 +#define SRB_FUNCTION_DUMP_POINTERS 0x26 +#define SRB_FUNCTION_FREE_DUMP_POINTERS 0x27 +#define SRB_FUNCTION_STORAGE_REQUEST_BLOCK 0x28 // special value +#define SRB_FUNCTION_CRYPTO_OPERATION 0x29 +#define SRB_FUNCTION_GET_DUMP_INFO 0x2a +#define SRB_FUNCTION_FREE_DUMP_INFO 0x2b /* SCSI_REQUEST_BLOCK.SrbStatus constants */ #define SRB_STATUS_PENDING 0x00 @@ -123,6 +130,8 @@ extern "C" { #define SRB_STATUS_ERROR_RECOVERY 0x23 #define SRB_STATUS_NOT_POWERED 0x24 #define SRB_STATUS_LINK_DOWN 0x25 +#define SRB_STATUS_INSUFFICIENT_RESOURCES 0x26 +#define SRB_STATUS_THROTTLED_REQUEST 0x27 #define SRB_STATUS_INTERNAL_ERROR 0x30 #define SRB_STATUS_QUEUE_FROZEN 0x40 @@ -144,6 +153,8 @@ extern "C" { #define SRB_FLAGS_NO_QUEUE_FREEZE 0x00000100 #define SRB_FLAGS_ADAPTER_CACHE_ENABLE 0x00000200 #define SRB_FLAGS_FREE_SENSE_BUFFER 0x00000400 +#define SRB_FLAGS_D3_PROCESSING 0x00000800 +#define SRB_FLAGS_SEQUENTIAL_REQUIRED 0x00001000 #define SRB_FLAGS_IS_ACTIVE 0x00010000 #define SRB_FLAGS_ALLOCATED_FROM_ZONE 0x00020000 #define SRB_FLAGS_SGLIST_FROM_POOL 0x00040000 @@ -424,6 +435,228 @@ typedef struct _SCSI_PNP_REQUEST_BLOCK { UCHAR Reserved4[16]; } SCSI_PNP_REQUEST_BLOCK, *PSCSI_PNP_REQUEST_BLOCK; +#if (NTDDI_VERSION >= NTDDI_WIN8) +#if defined(_WIN64) +#define SRB_ALIGN DECLSPEC_ALIGN(8) +#define POINTER_ALIGN DECLSPEC_ALIGN(8) +#else +#define SRB_ALIGN +#define POINTER_ALIGN +#endif + +typedef enum _SRBEXDATATYPE { + SrbExDataTypeUnknown = 0, + SrbExDataTypeBidirectional, + SrbExDataTypeScsiCdb16 = 0x40, + SrbExDataTypeScsiCdb32, + SrbExDataTypeScsiCdbVar, + SrbExDataTypeWmi = 0x60, + SrbExDataTypePower, + SrbExDataTypePnP, + SrbExDataTypeIoInfo = 0x80, + SrbExDataTypeMSReservedStart = 0xf0000000, + SrbExDataTypeReserved = 0xffffffff +} SRBEXDATATYPE, *PSRBEXDATATYPE; + +typedef struct SRB_ALIGN _SRBEX_DATA { + SRBEXDATATYPE Type; + ULONG Length; + _Field_size_bytes_(Length) UCHAR Data[ANYSIZE_ARRAY]; +} SRBEX_DATA, *PSRBEX_DATA; + +#define SRBEX_DATA_BIDIRECTIONAL_LENGTH ((2 * sizeof(ULONG)) + sizeof(PVOID)) + +typedef struct SRB_ALIGN _SRBEX_DATA_BIDIRECTIONAL { + _Field_range_(SrbExDataTypeBidirectional, SrbExDataTypeBidirectional) + SRBEXDATATYPE Type; + _Field_range_(SRBEX_DATA_BIDIRECTIONAL_LENGTH, SRBEX_DATA_BIDIRECTIONAL_LENGTH) + ULONG Length; + ULONG DataInTransferLength; + ULONG Reserved1; + _Field_size_bytes_full_(DataInTransferLength) + PVOID POINTER_ALIGN DataInBuffer; +} SRBEX_DATA_BIDIRECTIONAL, *PSRBEX_DATA_BIDIRECTIONAL; + +#define SRBEX_DATA_SCSI_CDB16_LENGTH ((20 * sizeof(UCHAR)) + sizeof(ULONG) + sizeof(PVOID)) + +typedef struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 { + _Field_range_(SrbExDataTypeScsiCdb16, SrbExDataTypeScsiCdb16) + SRBEXDATATYPE Type; + _Field_range_(SRBEX_DATA_SCSI_CDB16_LENGTH, SRBEX_DATA_SCSI_CDB16_LENGTH) + ULONG Length; + UCHAR ScsiStatus; + UCHAR SenseInfoBufferLength; + UCHAR CdbLength; + UCHAR Reserved; + ULONG Reserved1; + _Field_size_bytes_full_(SenseInfoBufferLength) + PVOID POINTER_ALIGN SenseInfoBuffer; + UCHAR POINTER_ALIGN Cdb[16]; +} SRBEX_DATA_SCSI_CDB16, *PSRBEX_DATA_SCSI_CDB16; + +#define SRBEX_DATA_SCSI_CDB32_LENGTH ((36 * sizeof(UCHAR)) + sizeof(ULONG) + sizeof(PVOID)) + +typedef struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB32 { + _Field_range_(SrbExDataTypeScsiCdb32, SrbExDataTypeScsiCdb32) + SRBEXDATATYPE Type; + _Field_range_(SRBEX_DATA_SCSI_CDB32_LENGTH, SRBEX_DATA_SCSI_CDB32_LENGTH) + ULONG Length; + UCHAR ScsiStatus; + UCHAR SenseInfoBufferLength; + UCHAR CdbLength; + UCHAR Reserved; + ULONG Reserved1; + _Field_size_bytes_full_(SenseInfoBufferLength) + PVOID POINTER_ALIGN SenseInfoBuffer; + UCHAR POINTER_ALIGN Cdb[32]; +} SRBEX_DATA_SCSI_CDB32, *PSRBEX_DATA_SCSI_CDB32; + +#define SRBEX_DATA_SCSI_CDB_VAR_LENGTH_MIN ((4 * sizeof(UCHAR)) + (3 * sizeof(ULONG)) + sizeof(PVOID)) +#define SRBEX_DATA_SCSI_CDB_VAR_LENGTH_MAX 0xffffffffUL + +typedef struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB_VAR { + _Field_range_(SrbExDataTypeScsiCdbVar, SrbExDataTypeScsiCdbVar) + SRBEXDATATYPE Type; + _Field_range_(SRBEX_DATA_SCSI_CDB_VAR_LENGTH_MIN, SRBEX_DATA_SCSI_CDB_VAR_LENGTH_MAX) + ULONG Length; + UCHAR ScsiStatus; + UCHAR SenseInfoBufferLength; + UCHAR Reserved[2]; + ULONG CdbLength; + ULONG Reserved1[2]; + _Field_size_bytes_full_(SenseInfoBufferLength) + PVOID POINTER_ALIGN SenseInfoBuffer; + _Field_size_bytes_full_(CdbLength) + UCHAR POINTER_ALIGN Cdb[ANYSIZE_ARRAY]; +} SRBEX_DATA_SCSI_CDB_VAR, *PSRBEX_DATA_SCSI_CDB_VAR; + +#define SRBEX_DATA_WMI_LENGTH ((4 * sizeof(UCHAR)) + sizeof(ULONG) + sizeof(PVOID)) + +typedef struct SRB_ALIGN _SRBEX_DATA_WMI { + _Field_range_(SrbExDataTypeWmi, SrbExDataTypeWmi) + SRBEXDATATYPE Type; + _Field_range_(SRBEX_DATA_WMI_LENGTH, SRBEX_DATA_WMI_LENGTH) + ULONG Length; + UCHAR WMISubFunction; + UCHAR WMIFlags; + UCHAR Reserved[2]; + ULONG Reserved1; + PVOID POINTER_ALIGN DataPath; +} SRBEX_DATA_WMI, *PSRBEX_DATA_WMI; + +#define SRBEX_DATA_POWER_LENGTH ((4 * sizeof(UCHAR)) + sizeof(STOR_DEVICE_POWER_STATE) + sizeof(STOR_POWER_ACTION)) + +typedef struct SRB_ALIGN _SRBEX_DATA_POWER { + _Field_range_(SrbExDataTypePower, SrbExDataTypePower) + SRBEXDATATYPE Type; + _Field_range_(SRBEX_DATA_POWER_LENGTH, SRBEX_DATA_POWER_LENGTH) + ULONG Length; + UCHAR SrbPowerFlags; + UCHAR Reserved[3]; + STOR_DEVICE_POWER_STATE DevicePowerState; + STOR_POWER_ACTION PowerAction; +} SRBEX_DATA_POWER, *PSRBEX_DATA_POWER; + +#define SRBEX_DATA_PNP_LENGTH ((4 * sizeof(UCHAR)) + sizeof(STOR_PNP_ACTION) + (2 * sizeof(ULONG))) + +typedef struct SRB_ALIGN _SRBEX_DATA_PNP { + _Field_range_(SrbExDataTypePnP, SrbExDataTypePnP) + SRBEXDATATYPE Type; + _Field_range_(SRBEX_DATA_PNP_LENGTH, SRBEX_DATA_PNP_LENGTH) + ULONG Length; + UCHAR PnPSubFunction; + UCHAR Reserved[3]; + STOR_PNP_ACTION PnPAction; + ULONG SrbPnPFlags; + ULONG Reserved1; +} SRBEX_DATA_PNP, *PSRBEX_DATA_PNP; + +#define SRBEX_DATA_IO_INFO_LENGTH ((5 * sizeof(ULONG)) + (4 * sizeof(UCHAR))) + +#define REQUEST_INFO_NO_CACHE_FLAG 0x00000001 +#define REQUEST_INFO_PAGING_IO_FLAG 0x00000002 +#define REQUEST_INFO_SEQUENTIAL_IO_FLAG 0x00000004 +#define REQUEST_INFO_TEMPORARY_FLAG 0x00000008 +#define REQUEST_INFO_WRITE_THROUGH_FLAG 0x00000010 +#define REQUEST_INFO_HYBRID_WRITE_THROUGH_FLAG 0x00000020 + +#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) + +#define REQUEST_INFO_NO_FILE_OBJECT_FLAG 0x00000040 +#define REQUEST_INFO_VOLSNAP_IO_FLAG 0x00000080 +#define REQUEST_INFO_STREAM_FLAG 0x00000100 + +#endif /* (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) */ + +#define REQUEST_INFO_VALID_CACHEPRIORITY_FLAG 0x80000000 + +typedef struct SRB_ALIGN _SRBEX_DATA_IO_INFO { + _Field_range_(SrbExDataTypeIoInfo, SrbExDataTypeIoInfo) + SRBEXDATATYPE Type; + _Field_range_(SRBEX_DATA_IO_INFO_LENGTH, SRBEX_DATA_IO_INFO_LENGTH) + ULONG Length; + ULONG Flags; + ULONG Key; + ULONG RWLength; + BOOLEAN IsWriteRequest; + UCHAR CachePriority; + UCHAR Reserved[2]; + ULONG Reserved1[2]; +} SRBEX_DATA_IO_INFO, *PSRBEX_DATA_IO_INFO; + +#define SRB_SIGNATURE 0x53524258 +#define STORAGE_REQUEST_BLOCK_VERSION_1 0x1 + +typedef struct SRB_ALIGN _STORAGE_REQUEST_BLOCK_HEADER { + USHORT Length; + _Field_range_(SRB_FUNCTION_STORAGE_REQUEST_BLOCK, SRB_FUNCTION_STORAGE_REQUEST_BLOCK) + UCHAR Function; + UCHAR SrbStatus; +} STORAGE_REQUEST_BLOCK_HEADER, *PSTORAGE_REQUEST_BLOCK_HEADER; + +typedef _Struct_size_bytes_(SrbLength) struct SRB_ALIGN _STORAGE_REQUEST_BLOCK { + USHORT Length; + _Field_range_(SRB_FUNCTION_STORAGE_REQUEST_BLOCK, SRB_FUNCTION_STORAGE_REQUEST_BLOCK) + UCHAR Function; + UCHAR SrbStatus; + UCHAR ReservedUchar[4]; + _Field_range_(SRB_SIGNATURE, SRB_SIGNATURE) + ULONG Signature; + _Field_range_(STORAGE_REQUEST_BLOCK_VERSION_1, STORAGE_REQUEST_BLOCK_VERSION_1) + ULONG Version; + ULONG SrbLength; + ULONG SrbFunction; + ULONG SrbFlags; + ULONG ReservedUlong; + ULONG RequestTag; + USHORT RequestPriority; + USHORT RequestAttribute; + ULONG TimeOutValue; + ULONG SystemStatus; + ULONG ZeroGuard1; + _Field_range_(sizeof(STORAGE_REQUEST_BLOCK), SrbLength - sizeof(STOR_ADDRESS)) + ULONG AddressOffset; + ULONG NumSrbExData; + ULONG DataTransferLength; + _Field_size_bytes_full_(DataTransferLength) + PVOID POINTER_ALIGN DataBuffer; + PVOID POINTER_ALIGN ZeroGuard2; + PVOID POINTER_ALIGN OriginalRequest; + PVOID POINTER_ALIGN ClassContext; + PVOID POINTER_ALIGN PortContext; + PVOID POINTER_ALIGN MiniportContext; + struct _STORAGE_REQUEST_BLOCK POINTER_ALIGN *NextSrb; + _At_buffer_(SrbExDataOffset, _Iter_, NumSrbExData, _Field_range_(0, SrbLength - sizeof(SRBEX_DATA))) + _Field_size_(NumSrbExData) + ULONG SrbExDataOffset[ANYSIZE_ARRAY]; +} STORAGE_REQUEST_BLOCK, *PSTORAGE_REQUEST_BLOCK; + +#define SRB_TYPE_SCSI_REQUEST_BLOCK 0 +#define SRB_TYPE_STORAGE_REQUEST_BLOCK 1 + +#define STORAGE_ADDRESS_TYPE_BTL8 0 +#endif /* (NTDDI_VERSION >= NTDDI_WIN8) */ + typedef _Must_inspect_result_ BOOLEAN @@ -536,12 +769,12 @@ typedef struct _HW_INITIALIZATION_DATA { } HW_INITIALIZATION_DATA, *PHW_INITIALIZATION_DATA; #if defined(_NTDDK_) -#define SCSIPORTAPI +#define SCSIPORT_API #else -#define SCSIPORTAPI DECLSPEC_IMPORT +#define SCSIPORT_API DECLSPEC_IMPORT #endif -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortCompleteRequest( @@ -552,7 +785,7 @@ ScsiPortCompleteRequest( _In_ UCHAR SrbStatus); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API ULONG NTAPI ScsiPortConvertPhysicalAddressToUlong( @@ -562,19 +795,19 @@ ScsiPortConvertPhysicalAddressToUlong( #define ScsiPortConvertPhysicalAddressToULongPtr(Address) ((ULONG_PTR)((Address).QuadPart)) _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API SCSI_PHYSICAL_ADDRESS NTAPI ScsiPortConvertUlongToPhysicalAddress( _In_ ULONG_PTR UlongAddress); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortFlushDma( _In_ PVOID DeviceExtension); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortFreeDeviceBase( @@ -582,7 +815,7 @@ ScsiPortFreeDeviceBase( _In_ PVOID MappedAddress); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API ULONG NTAPI ScsiPortGetBusData( @@ -594,7 +827,7 @@ ScsiPortGetBusData( _In_ ULONG Length); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API PVOID NTAPI ScsiPortGetDeviceBase( @@ -606,7 +839,7 @@ ScsiPortGetDeviceBase( _In_ BOOLEAN InIoSpace); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API PVOID NTAPI ScsiPortGetLogicalUnit( @@ -616,7 +849,7 @@ ScsiPortGetLogicalUnit( _In_ UCHAR Lun); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API SCSI_PHYSICAL_ADDRESS NTAPI ScsiPortGetPhysicalAddress( @@ -626,7 +859,7 @@ ScsiPortGetPhysicalAddress( _Out_ ULONG *Length); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API PSCSI_REQUEST_BLOCK NTAPI ScsiPortGetSrb( @@ -637,7 +870,7 @@ ScsiPortGetSrb( _In_ LONG QueueTag); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API PVOID NTAPI ScsiPortGetUncachedExtension( @@ -646,7 +879,7 @@ ScsiPortGetUncachedExtension( _In_ ULONG NumberOfBytes); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API PVOID NTAPI ScsiPortGetVirtualAddress( @@ -655,7 +888,7 @@ ScsiPortGetVirtualAddress( _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) -SCSIPORTAPI +SCSIPORT_API ULONG NTAPI ScsiPortInitialize( @@ -664,7 +897,7 @@ ScsiPortInitialize( _In_ struct _HW_INITIALIZATION_DATA *HwInitializationData, _In_ PVOID HwContext); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortIoMapTransfer( @@ -673,7 +906,7 @@ ScsiPortIoMapTransfer( _In_ PVOID LogicalAddress, _In_ ULONG Length); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortLogError( @@ -685,7 +918,7 @@ ScsiPortLogError( _In_ ULONG ErrorCode, _In_ ULONG UniqueId); -SCSIPORTAPI +SCSIPORT_API VOID __cdecl ScsiPortNotification( @@ -693,14 +926,14 @@ ScsiPortNotification( _In_ PVOID HwDeviceExtension, ...); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortQuerySystemTime( _Out_ PLARGE_INTEGER CurrentTime); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API ULONG NTAPI ScsiPortSetBusDataByOffset( @@ -712,14 +945,14 @@ ScsiPortSetBusDataByOffset( _In_ ULONG Offset, _In_ ULONG Length); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortStallExecution( _In_ ULONG Delay); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API BOOLEAN NTAPI ScsiPortValidateRange( @@ -730,7 +963,7 @@ ScsiPortValidateRange( _In_ ULONG NumberOfBytes, _In_ BOOLEAN InIoSpace); -SCSIPORTAPI +SCSIPORT_API VOID __cdecl ScsiDebugPrint( @@ -777,27 +1010,27 @@ ScsiDebugPrint( #else _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API UCHAR NTAPI ScsiPortReadPortUchar( _In_ PUCHAR Port); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API ULONG NTAPI ScsiPortReadPortUlong( _In_ PULONG Port); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API USHORT NTAPI ScsiPortReadPortUshort( _In_ PUSHORT Port); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortReadPortBufferUchar( @@ -805,7 +1038,7 @@ ScsiPortReadPortBufferUchar( _In_ PUCHAR Buffer, _In_ ULONG Count); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortReadPortBufferUlong( @@ -813,7 +1046,7 @@ ScsiPortReadPortBufferUlong( _In_ PULONG Buffer, _In_ ULONG Count); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortReadPortBufferUshort( @@ -822,27 +1055,27 @@ ScsiPortReadPortBufferUshort( _In_ ULONG Count); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API UCHAR NTAPI ScsiPortReadRegisterUchar( _In_ PUCHAR Register); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API ULONG NTAPI ScsiPortReadRegisterUlong( _In_ PULONG Register); _Must_inspect_result_ -SCSIPORTAPI +SCSIPORT_API USHORT NTAPI ScsiPortReadRegisterUshort( _In_ PUSHORT Register); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortReadRegisterBufferUchar( @@ -850,7 +1083,7 @@ ScsiPortReadRegisterBufferUchar( _In_ PUCHAR Buffer, _In_ ULONG Count); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortReadRegisterBufferUlong( @@ -858,7 +1091,7 @@ ScsiPortReadRegisterBufferUlong( _In_ PULONG Buffer, _In_ ULONG Count); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortReadRegisterBufferUshort( @@ -866,28 +1099,28 @@ ScsiPortReadRegisterBufferUshort( _In_ PUSHORT Buffer, _In_ ULONG Count); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWritePortUchar( _In_ PUCHAR Port, _In_ UCHAR Value); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWritePortUlong( _In_ PULONG Port, _In_ ULONG Value); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWritePortUshort( _In_ PUSHORT Port, _In_ USHORT Value); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWritePortBufferUchar( @@ -895,7 +1128,7 @@ ScsiPortWritePortBufferUchar( _In_ PUCHAR Buffer, _In_ ULONG Count); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWritePortBufferUlong( @@ -903,7 +1136,7 @@ ScsiPortWritePortBufferUlong( _In_ PULONG Buffer, _In_ ULONG Count); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWritePortBufferUshort( @@ -911,28 +1144,28 @@ ScsiPortWritePortBufferUshort( _In_ PUSHORT Buffer, _In_ ULONG Count); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWriteRegisterUchar( _In_ PUCHAR Register, _In_ UCHAR Value); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWriteRegisterUlong( _In_ PULONG Register, _In_ ULONG Value); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWriteRegisterUshort( _In_ PUSHORT Register, _In_ USHORT Value); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWriteRegisterBufferUchar( @@ -940,7 +1173,7 @@ ScsiPortWriteRegisterBufferUchar( _In_ PUCHAR Buffer, _In_ ULONG Count); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWriteRegisterBufferUlong( @@ -948,7 +1181,7 @@ ScsiPortWriteRegisterBufferUlong( _In_ PULONG Buffer, _In_ ULONG Count); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortWriteRegisterBufferUshort( @@ -956,7 +1189,7 @@ ScsiPortWriteRegisterBufferUshort( _In_ PUSHORT Buffer, _In_ ULONG Count); -SCSIPORTAPI +SCSIPORT_API VOID NTAPI ScsiPortMoveMemory(