Home | History | Annotate | Download | only in ddk
      1 
      2 #pragma once
      3 
      4 #define _CLASS_
      5 
      6 #include <ntdddisk.h>
      7 #include <ntddcdrm.h>
      8 #include <ntddtape.h>
      9 #include <ntddscsi.h>
     10 #include <ntddstor.h>
     11 
     12 #include <stdio.h>
     13 
     14 #include <scsi.h>
     15 
     16 #define max(a,b) (((a) > (b)) ? (a) : (b))
     17 #define min(a,b) (((a) < (b)) ? (a) : (b))
     18 
     19 #define SRB_CLASS_FLAGS_LOW_PRIORITY      0x10000000
     20 #define SRB_CLASS_FLAGS_PERSISTANT        0x20000000
     21 #define SRB_CLASS_FLAGS_PAGING            0x40000000
     22 #define SRB_CLASS_FLAGS_FREE_MDL          0x80000000
     23 
     24 #define ASSERT_FDO(x) \
     25   ASSERT(((PCOMMON_DEVICE_EXTENSION) (x)->DeviceExtension)->IsFdo)
     26 
     27 #define ASSERT_PDO(x) \
     28   ASSERT(!(((PCOMMON_DEVICE_EXTENSION) (x)->DeviceExtension)->IsFdo))
     29 
     30 #define IS_CLEANUP_REQUEST(majorFunction)   \
     31   ((majorFunction == IRP_MJ_CLOSE) ||       \
     32    (majorFunction == IRP_MJ_CLEANUP) ||     \
     33    (majorFunction == IRP_MJ_SHUTDOWN))
     34 
     35 #define DO_MCD(fdoExtension)                                 \
     36   (((fdoExtension)->MediaChangeDetectionInfo != NULL) &&     \
     37    ((fdoExtension)->MediaChangeDetectionInfo->MediaChangeDetectionDisableCount == 0))
     38 
     39 #define IS_SCSIOP_READ(opCode)     \
     40   ((opCode == SCSIOP_READ6)   ||   \
     41    (opCode == SCSIOP_READ)    ||   \
     42    (opCode == SCSIOP_READ12)  ||   \
     43    (opCode == SCSIOP_READ16))
     44 
     45 #define IS_SCSIOP_WRITE(opCode)     \
     46   ((opCode == SCSIOP_WRITE6)   ||   \
     47    (opCode == SCSIOP_WRITE)    ||   \
     48    (opCode == SCSIOP_WRITE12)  ||   \
     49    (opCode == SCSIOP_WRITE16))
     50 
     51 #define IS_SCSIOP_READWRITE(opCode) (IS_SCSIOP_READ(opCode) || IS_SCSIOP_WRITE(opCode))
     52 
     53 #define ADJUST_FUA_FLAG(fdoExt) {                                                       \
     54     if (TEST_FLAG(fdoExt->DeviceFlags, DEV_WRITE_CACHE) &&                              \
     55         !TEST_FLAG(fdoExt->DeviceFlags, DEV_POWER_PROTECTED) &&                         \
     56         !TEST_FLAG(fdoExt->ScanForSpecialFlags, CLASS_SPECIAL_FUA_NOT_SUPPORTED) ) {    \
     57         fdoExt->CdbForceUnitAccess = TRUE;                                              \
     58     } else {                                                                            \
     59         fdoExt->CdbForceUnitAccess = FALSE;                                             \
     60     }                                                                                   \
     61 }
     62 
     63 #define FREE_POOL(_PoolPtr)     \
     64     if (_PoolPtr != NULL) {     \
     65         ExFreePool(_PoolPtr);   \
     66         _PoolPtr = NULL;        \
     67     }
     68 
     69 #ifdef POOL_TAGGING
     70 #undef ExAllocatePool
     71 #undef ExAllocatePoolWithQuota
     72 #define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'nUcS')
     73 //#define ExAllocatePool(a,b) #assert(0)
     74 #define ExAllocatePoolWithQuota(a,b) ExAllocatePoolWithQuotaTag(a,b,'nUcS')
     75 #endif
     76 
     77 #define CLASS_TAG_AUTORUN_DISABLE           'ALcS'
     78 #define CLASS_TAG_FILE_OBJECT_EXTENSION     'FLcS'
     79 #define CLASS_TAG_MEDIA_CHANGE_DETECTION    'MLcS'
     80 #define CLASS_TAG_MOUNT                     'mLcS'
     81 #define CLASS_TAG_RELEASE_QUEUE             'qLcS'
     82 #define CLASS_TAG_POWER                     'WLcS'
     83 #define CLASS_TAG_WMI                       'wLcS'
     84 #define CLASS_TAG_FAILURE_PREDICT           'fLcS'
     85 #define CLASS_TAG_DEVICE_CONTROL            'OIcS'
     86 #define CLASS_TAG_MODE_DATA                 'oLcS'
     87 #define CLASS_TAG_MULTIPATH                 'mPcS'
     88 
     89 #define MAXIMUM_RETRIES 4
     90 
     91 #define CLASS_DRIVER_EXTENSION_KEY ((PVOID) ClassInitialize)
     92 
     93 #define NO_REMOVE                         0
     94 #define REMOVE_PENDING                    1
     95 #define REMOVE_COMPLETE                   2
     96 
     97 #define ClassAcquireRemoveLock(devobj, tag) \
     98   ClassAcquireRemoveLockEx(devobj, tag, __FILE__, __LINE__)
     99 
    100 #ifdef TRY
    101 #undef TRY
    102 #endif
    103 #ifdef LEAVE
    104 #undef LEAVE
    105 #endif
    106 
    107 #ifdef FINALLY
    108 #undef FINALLY
    109 #endif
    110 
    111 #define TRY
    112 #define LEAVE             goto __tryLabel;
    113 #define FINALLY           __tryLabel:
    114 
    115 #if defined DebugPrint
    116 #undef DebugPrint
    117 #endif
    118 
    119 #if DBG
    120 #define DebugPrint(x) ClassDebugPrint x
    121 #else
    122 #define DebugPrint(x)
    123 #endif
    124 
    125 #define DEBUG_BUFFER_LENGTH                        256
    126 
    127 #define START_UNIT_TIMEOUT                         (60 * 4)
    128 
    129 #define MEDIA_CHANGE_DEFAULT_TIME                  1
    130 #define MEDIA_CHANGE_TIMEOUT_TIME                  300
    131 
    132 #define MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS 0x3b9aca00
    133 
    134 #ifdef ALLOCATE_SRB_FROM_POOL
    135 
    136 #define ClasspAllocateSrb(ext)                      \
    137   ExAllocatePoolWithTag(NonPagedPool,               \
    138                         sizeof(SCSI_REQUEST_BLOCK), \
    139                         'sBRS')
    140 
    141 #define ClasspFreeSrb(ext, srb) ExFreePool((srb));
    142 
    143 #else /* ALLOCATE_SRB_FROM_POOL */
    144 
    145 #define ClasspAllocateSrb(ext)                      \
    146   ExAllocateFromNPagedLookasideList(                \
    147       &((ext)->CommonExtension.SrbLookasideList))
    148 
    149 #define ClasspFreeSrb(ext, srb)                   \
    150   ExFreeToNPagedLookasideList(                    \
    151       &((ext)->CommonExtension.SrbLookasideList), \
    152       (srb))
    153 
    154 #endif /* ALLOCATE_SRB_FROM_POOL */
    155 
    156 #define SET_FLAG(Flags, Bit)    ((Flags) |= (Bit))
    157 #define CLEAR_FLAG(Flags, Bit)  ((Flags) &= ~(Bit))
    158 #define TEST_FLAG(Flags, Bit)   (((Flags) & (Bit)) != 0)
    159 
    160 #define CLASS_WORKING_SET_MAXIMUM                         2048
    161 
    162 #define CLASS_INTERPRET_SENSE_INFO2_MAXIMUM_HISTORY_COUNT 30000
    163 
    164 #define CLASS_SPECIAL_DISABLE_SPIN_DOWN                 0x00000001
    165 #define CLASS_SPECIAL_DISABLE_SPIN_UP                   0x00000002
    166 #define CLASS_SPECIAL_NO_QUEUE_LOCK                     0x00000008
    167 #define CLASS_SPECIAL_DISABLE_WRITE_CACHE               0x00000010
    168 #define CLASS_SPECIAL_CAUSE_NOT_REPORTABLE_HACK         0x00000020
    169 #if ((NTDDI_VERSION == NTDDI_WIN2KSP3) || (OSVER(NTDDI_VERSION) == NTDDI_WINXP))
    170 #define CLASS_SPECIAL_DISABLE_WRITE_CACHE_NOT_SUPPORTED 0x00000040
    171 #endif
    172 #define CLASS_SPECIAL_MODIFY_CACHE_UNSUCCESSFUL         0x00000040
    173 #define CLASS_SPECIAL_FUA_NOT_SUPPORTED                 0x00000080
    174 #define CLASS_SPECIAL_VALID_MASK                        0x000000FB
    175 #define CLASS_SPECIAL_RESERVED         (~CLASS_SPECIAL_VALID_MASK)
    176 
    177 #define DEV_WRITE_CACHE                                 0x00000001
    178 #define DEV_USE_SCSI1                                   0x00000002
    179 #define DEV_SAFE_START_UNIT                             0x00000004
    180 #define DEV_NO_12BYTE_CDB                               0x00000008
    181 #define DEV_POWER_PROTECTED                             0x00000010
    182 #define DEV_USE_16BYTE_CDB                              0x00000020
    183 
    184 #define GUID_CLASSPNP_QUERY_REGINFOEX {0x00e34b11, 0x2444, 0x4745, {0xa5, 0x3d, 0x62, 0x01, 0x00, 0xcd, 0x82, 0xf7}}
    185 #define GUID_CLASSPNP_SENSEINFO2      {0x509a8c5f, 0x71d7, 0x48f6, {0x82, 0x1e, 0x17, 0x3c, 0x49, 0xbf, 0x2f, 0x18}}
    186 #define GUID_CLASSPNP_WORKING_SET     {0x105701b0, 0x9e9b, 0x47cb, {0x97, 0x80, 0x81, 0x19, 0x8a, 0xf7, 0xb5, 0x24}}
    187 
    188 #define DEFAULT_FAILURE_PREDICTION_PERIOD 60 * 60 * 1
    189 
    190 static inline ULONG CountOfSetBitsUChar(UCHAR _X)
    191 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
    192 static inline ULONG CountOfSetBitsULong(ULONG _X)
    193 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
    194 static inline ULONG CountOfSetBitsULong32(ULONG32 _X)
    195 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
    196 static inline ULONG CountOfSetBitsULong64(ULONG64 _X)
    197 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
    198 static inline ULONG CountOfSetBitsUlongPtr(ULONG_PTR _X)
    199 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
    200 
    201 typedef enum _MEDIA_CHANGE_DETECTION_STATE {
    202   MediaUnknown,
    203   MediaPresent,
    204   MediaNotPresent,
    205   MediaUnavailable
    206 } MEDIA_CHANGE_DETECTION_STATE, *PMEDIA_CHANGE_DETECTION_STATE;
    207 
    208 typedef enum _CLASS_DEBUG_LEVEL {
    209   ClassDebugError = 0,
    210   ClassDebugWarning = 1,
    211   ClassDebugTrace = 2,
    212   ClassDebugInfo = 3,
    213   ClassDebugMediaLocks = 8,
    214   ClassDebugMCN = 9,
    215   ClassDebugDelayedRetry = 10,
    216   ClassDebugSenseInfo = 11,
    217   ClassDebugRemoveLock = 12,
    218   ClassDebugExternal4 = 13,
    219   ClassDebugExternal3 = 14,
    220   ClassDebugExternal2 = 15,
    221   ClassDebugExternal1 = 16
    222 } CLASS_DEBUG_LEVEL, *PCLASS_DEBUG_LEVEL;
    223 
    224 typedef enum {
    225   EventGeneration,
    226   DataBlockCollection
    227 } CLASSENABLEDISABLEFUNCTION;
    228 
    229 typedef enum {
    230   FailurePredictionNone = 0,
    231   FailurePredictionIoctl,
    232   FailurePredictionSmart,
    233   FailurePredictionSense
    234 } FAILURE_PREDICTION_METHOD, *PFAILURE_PREDICTION_METHOD;
    235 
    236 typedef enum {
    237   PowerDownDeviceInitial,
    238   PowerDownDeviceLocked,
    239   PowerDownDeviceStopped,
    240   PowerDownDeviceOff,
    241   PowerDownDeviceUnlocked
    242 } CLASS_POWER_DOWN_STATE;
    243 
    244 typedef enum {
    245   PowerDownDeviceInitial2,
    246   PowerDownDeviceLocked2,
    247   PowerDownDeviceFlushed2,
    248   PowerDownDeviceStopped2,
    249   PowerDownDeviceOff2,
    250   PowerDownDeviceUnlocked2
    251 } CLASS_POWER_DOWN_STATE2;
    252 
    253 typedef enum {
    254   PowerUpDeviceInitial,
    255   PowerUpDeviceLocked,
    256   PowerUpDeviceOn,
    257   PowerUpDeviceStarted,
    258   PowerUpDeviceUnlocked
    259 } CLASS_POWER_UP_STATE;
    260 
    261 struct _CLASS_INIT_DATA;
    262 typedef struct _CLASS_INIT_DATA CLASS_INIT_DATA, *PCLASS_INIT_DATA;
    263 
    264 struct _CLASS_PRIVATE_FDO_DATA;
    265 typedef struct _CLASS_PRIVATE_FDO_DATA CLASS_PRIVATE_FDO_DATA, *PCLASS_PRIVATE_FDO_DATA;
    266 
    267 struct _CLASS_PRIVATE_PDO_DATA;
    268 typedef struct _CLASS_PRIVATE_PDO_DATA CLASS_PRIVATE_PDO_DATA, *PCLASS_PRIVATE_PDO_DATA;
    269 
    270 struct _CLASS_PRIVATE_COMMON_DATA;
    271 typedef struct _CLASS_PRIVATE_COMMON_DATA CLASS_PRIVATE_COMMON_DATA, *PCLASS_PRIVATE_COMMON_DATA;
    272 
    273 struct _MEDIA_CHANGE_DETECTION_INFO;
    274 typedef struct _MEDIA_CHANGE_DETECTION_INFO MEDIA_CHANGE_DETECTION_INFO, *PMEDIA_CHANGE_DETECTION_INFO;
    275 
    276 typedef struct _DICTIONARY {
    277   ULONGLONG Signature;
    278   struct _DICTIONARY_HEADER* List;
    279   KSPIN_LOCK SpinLock;
    280 } DICTIONARY, *PDICTIONARY;
    281 
    282 typedef struct _CLASSPNP_SCAN_FOR_SPECIAL_INFO {
    283   PCHAR VendorId;
    284   PCHAR ProductId;
    285   PCHAR ProductRevision;
    286   ULONG_PTR Data;
    287 } CLASSPNP_SCAN_FOR_SPECIAL_INFO, *PCLASSPNP_SCAN_FOR_SPECIAL_INFO;
    288 
    289 typedef VOID
    290 (NTAPI *PCLASS_ERROR)(
    291   PDEVICE_OBJECT DeviceObject,
    292   PSCSI_REQUEST_BLOCK Srb,
    293   NTSTATUS *Status,
    294   BOOLEAN *Retry);
    295 
    296 typedef NTSTATUS
    297 (NTAPI *PCLASS_ADD_DEVICE)(
    298   PDRIVER_OBJECT DriverObject,
    299   PDEVICE_OBJECT Pdo);
    300 
    301 typedef NTSTATUS
    302 (NTAPI *PCLASS_POWER_DEVICE)(
    303   PDEVICE_OBJECT DeviceObject,
    304   PIRP Irp);
    305 
    306 typedef NTSTATUS
    307 (NTAPI *PCLASS_START_DEVICE)(
    308   PDEVICE_OBJECT DeviceObject);
    309 
    310 typedef NTSTATUS
    311 (NTAPI *PCLASS_STOP_DEVICE)(
    312   PDEVICE_OBJECT DeviceObject,
    313   UCHAR Type);
    314 
    315 typedef NTSTATUS
    316 (NTAPI *PCLASS_INIT_DEVICE)(
    317   PDEVICE_OBJECT DeviceObject);
    318 
    319 typedef NTSTATUS
    320 (NTAPI *PCLASS_ENUM_DEVICE)(
    321   PDEVICE_OBJECT DeviceObject);
    322 
    323 typedef NTSTATUS
    324 (NTAPI *PCLASS_READ_WRITE)(
    325   PDEVICE_OBJECT DeviceObject,
    326   PIRP Irp);
    327 
    328 typedef NTSTATUS
    329 (NTAPI *PCLASS_DEVICE_CONTROL)(
    330   PDEVICE_OBJECT DeviceObject,
    331   PIRP Irp);
    332 
    333 typedef NTSTATUS
    334 (NTAPI *PCLASS_SHUTDOWN_FLUSH)(
    335   PDEVICE_OBJECT DeviceObject,
    336   PIRP Irp);
    337 
    338 typedef NTSTATUS
    339 (NTAPI *PCLASS_CREATE_CLOSE)(
    340   PDEVICE_OBJECT DeviceObject,
    341   PIRP Irp);
    342 
    343 typedef NTSTATUS
    344 (NTAPI *PCLASS_QUERY_ID)(
    345   PDEVICE_OBJECT DeviceObject,
    346   BUS_QUERY_ID_TYPE IdType,
    347   PUNICODE_STRING IdString);
    348 
    349 typedef NTSTATUS
    350 (NTAPI *PCLASS_REMOVE_DEVICE)(
    351   PDEVICE_OBJECT DeviceObject,
    352   UCHAR Type);
    353 
    354 typedef VOID
    355 (NTAPI *PCLASS_UNLOAD)(
    356   PDRIVER_OBJECT DriverObject);
    357 
    358 typedef NTSTATUS
    359 (NTAPI *PCLASS_QUERY_PNP_CAPABILITIES)(
    360   PDEVICE_OBJECT PhysicalDeviceObject,
    361   PDEVICE_CAPABILITIES Capabilities);
    362 
    363 typedef VOID
    364 (NTAPI *PCLASS_TICK)(
    365   PDEVICE_OBJECT DeviceObject);
    366 
    367 typedef NTSTATUS
    368 (NTAPI *PCLASS_QUERY_WMI_REGINFO_EX)(
    369   PDEVICE_OBJECT DeviceObject,
    370   ULONG *RegFlags,
    371   PUNICODE_STRING Name,
    372   PUNICODE_STRING MofResouceName);
    373 
    374 typedef NTSTATUS
    375 (NTAPI *PCLASS_QUERY_WMI_REGINFO)(
    376   PDEVICE_OBJECT DeviceObject,
    377   ULONG *RegFlags,
    378   PUNICODE_STRING Name);
    379 
    380 typedef NTSTATUS
    381 (NTAPI *PCLASS_QUERY_WMI_DATABLOCK)(
    382   PDEVICE_OBJECT DeviceObject,
    383   PIRP Irp,
    384   ULONG GuidIndex,
    385   ULONG BufferAvail,
    386   PUCHAR Buffer);
    387 
    388 typedef NTSTATUS
    389 (NTAPI *PCLASS_SET_WMI_DATABLOCK)(
    390   PDEVICE_OBJECT DeviceObject,
    391   PIRP Irp,
    392   ULONG GuidIndex,
    393   ULONG BufferSize,
    394   PUCHAR Buffer);
    395 
    396 typedef NTSTATUS
    397 (NTAPI *PCLASS_SET_WMI_DATAITEM)(
    398   PDEVICE_OBJECT DeviceObject,
    399   PIRP Irp,
    400   ULONG GuidIndex,
    401   ULONG DataItemId,
    402   ULONG BufferSize,
    403   PUCHAR Buffer);
    404 
    405 typedef NTSTATUS
    406 (NTAPI *PCLASS_EXECUTE_WMI_METHOD)(
    407   PDEVICE_OBJECT DeviceObject,
    408   PIRP Irp,
    409   ULONG GuidIndex,
    410   ULONG MethodId,
    411   ULONG InBufferSize,
    412   ULONG OutBufferSize,
    413   PUCHAR Buffer);
    414 
    415 typedef NTSTATUS
    416 (NTAPI *PCLASS_WMI_FUNCTION_CONTROL)(
    417   PDEVICE_OBJECT DeviceObject,
    418   PIRP Irp,
    419   ULONG GuidIndex,
    420   CLASSENABLEDISABLEFUNCTION Function,
    421   BOOLEAN Enable);
    422 
    423 typedef struct _SRB_HISTORY_ITEM {
    424   LARGE_INTEGER TickCountSent;
    425   LARGE_INTEGER TickCountCompleted;
    426   ULONG MillisecondsDelayOnRetry;
    427   SENSE_DATA NormalizedSenseData;
    428   UCHAR SrbStatus;
    429   UCHAR ClassDriverUse;
    430 } SRB_HISTORY_ITEM, *PSRB_HISTORY_ITEM;
    431 
    432 typedef struct _SRB_HISTORY {
    433   ULONG_PTR ClassDriverUse[4];
    434   ULONG TotalHistoryCount;
    435   ULONG UsedHistoryCount;
    436   SRB_HISTORY_ITEM History[1];
    437 } SRB_HISTORY, *PSRB_HISTORY;
    438 
    439 typedef BOOLEAN
    440 (NTAPI *PCLASS_INTERPRET_SENSE_INFO)(
    441   PDEVICE_OBJECT Fdo,
    442   PIRP OriginalRequest,
    443   PSCSI_REQUEST_BLOCK Srb,
    444   UCHAR MajorFunctionCode,
    445   ULONG IoDeviceCode,
    446   ULONG PreviousRetryCount,
    447   SRB_HISTORY *RequestHistory,
    448   NTSTATUS *Status,
    449   LONGLONG *RetryIn100nsUnits);
    450 
    451 typedef VOID
    452 (NTAPI *PCLASS_COMPRESS_RETRY_HISTORY_DATA)(
    453   PDEVICE_OBJECT DeviceObject,
    454   PSRB_HISTORY RequestHistory);
    455 
    456 typedef struct {
    457   GUID Guid;
    458   ULONG InstanceCount;
    459   ULONG Flags;
    460 } GUIDREGINFO, *PGUIDREGINFO;
    461 
    462 typedef struct _CLASS_WMI_INFO {
    463   ULONG GuidCount;
    464   PGUIDREGINFO GuidRegInfo;
    465   PCLASS_QUERY_WMI_REGINFO ClassQueryWmiRegInfo;
    466   PCLASS_QUERY_WMI_DATABLOCK ClassQueryWmiDataBlock;
    467   PCLASS_SET_WMI_DATABLOCK ClassSetWmiDataBlock;
    468   PCLASS_SET_WMI_DATAITEM ClassSetWmiDataItem;
    469   PCLASS_EXECUTE_WMI_METHOD ClassExecuteWmiMethod;
    470   PCLASS_WMI_FUNCTION_CONTROL ClassWmiFunctionControl;
    471 } CLASS_WMI_INFO, *PCLASS_WMI_INFO;
    472 
    473 typedef struct _CLASS_DEV_INFO {
    474   ULONG DeviceExtensionSize;
    475   DEVICE_TYPE DeviceType;
    476   UCHAR StackSize;
    477   ULONG DeviceCharacteristics;
    478   PCLASS_ERROR ClassError;
    479   PCLASS_READ_WRITE ClassReadWriteVerification;
    480   PCLASS_DEVICE_CONTROL ClassDeviceControl;
    481   PCLASS_SHUTDOWN_FLUSH ClassShutdownFlush;
    482   PCLASS_CREATE_CLOSE ClassCreateClose;
    483   PCLASS_INIT_DEVICE ClassInitDevice;
    484   PCLASS_START_DEVICE ClassStartDevice;
    485   PCLASS_POWER_DEVICE ClassPowerDevice;
    486   PCLASS_STOP_DEVICE ClassStopDevice;
    487   PCLASS_REMOVE_DEVICE ClassRemoveDevice;
    488   PCLASS_QUERY_PNP_CAPABILITIES ClassQueryPnpCapabilities;
    489   CLASS_WMI_INFO ClassWmiInfo;
    490 } CLASS_DEV_INFO, *PCLASS_DEV_INFO;
    491 
    492 struct _CLASS_INIT_DATA {
    493   ULONG InitializationDataSize;
    494   CLASS_DEV_INFO FdoData;
    495   CLASS_DEV_INFO PdoData;
    496   PCLASS_ADD_DEVICE ClassAddDevice;
    497   PCLASS_ENUM_DEVICE ClassEnumerateDevice;
    498   PCLASS_QUERY_ID ClassQueryId;
    499   PDRIVER_STARTIO ClassStartIo;
    500   PCLASS_UNLOAD ClassUnload;
    501   PCLASS_TICK ClassTick;
    502 };
    503 
    504 typedef struct _FILE_OBJECT_EXTENSION {
    505   PFILE_OBJECT FileObject;
    506   PDEVICE_OBJECT DeviceObject;
    507   ULONG LockCount;
    508   ULONG McnDisableCount;
    509 } FILE_OBJECT_EXTENSION, *PFILE_OBJECT_EXTENSION;
    510 
    511 typedef struct _CLASS_WORKING_SET {
    512   ULONG Size;
    513   ULONG XferPacketsWorkingSetMaximum;
    514   ULONG XferPacketsWorkingSetMinimum;
    515 } CLASS_WORKING_SET, *PCLASS_WORKING_SET;
    516 
    517 typedef struct _CLASS_INTERPRET_SENSE_INFO2 {
    518   ULONG Size;
    519   ULONG HistoryCount;
    520   PCLASS_COMPRESS_RETRY_HISTORY_DATA Compress;
    521   PCLASS_INTERPRET_SENSE_INFO Interpret;
    522 } CLASS_INTERPRET_SENSE_INFO2, *PCLASS_INTERPRET_SENSE_INFO2;
    523 
    524 C_ASSERT((MAXULONG - sizeof(SRB_HISTORY)) / 30000 >= sizeof(SRB_HISTORY_ITEM));
    525 
    526 typedef struct _CLASS_DRIVER_EXTENSION {
    527   UNICODE_STRING RegistryPath;
    528   CLASS_INIT_DATA InitData;
    529   ULONG DeviceCount;
    530 #if (NTDDI_VERSION >= NTDDI_WINXP)
    531   PCLASS_QUERY_WMI_REGINFO_EX ClassFdoQueryWmiRegInfoEx;
    532   PCLASS_QUERY_WMI_REGINFO_EX ClassPdoQueryWmiRegInfoEx;
    533 #endif
    534 #if (NTDDI_VERSION >= NTDDI_VISTA)
    535   REGHANDLE EtwHandle;
    536   PDRIVER_DISPATCH DeviceMajorFunctionTable[IRP_MJ_MAXIMUM_FUNCTION + 1];
    537   PDRIVER_DISPATCH MpDeviceMajorFunctionTable[IRP_MJ_MAXIMUM_FUNCTION + 1];
    538   PCLASS_INTERPRET_SENSE_INFO2 InterpretSenseInfo;
    539   PCLASS_WORKING_SET WorkingSet;
    540 #endif
    541 } CLASS_DRIVER_EXTENSION, *PCLASS_DRIVER_EXTENSION;
    542 
    543 typedef struct _COMMON_DEVICE_EXTENSION {
    544   ULONG Version;
    545   PDEVICE_OBJECT DeviceObject;
    546   PDEVICE_OBJECT LowerDeviceObject;
    547   struct _FUNCTIONAL_DEVICE_EXTENSION *PartitionZeroExtension;
    548   PCLASS_DRIVER_EXTENSION DriverExtension;
    549   LONG RemoveLock;
    550   KEVENT RemoveEvent;
    551   KSPIN_LOCK RemoveTrackingSpinlock;
    552   PVOID RemoveTrackingList;
    553   LONG RemoveTrackingUntrackedCount;
    554   PVOID DriverData;
    555   _ANONYMOUS_STRUCT struct {
    556     BOOLEAN IsFdo:1;
    557     BOOLEAN IsInitialized:1;
    558     BOOLEAN IsSrbLookasideListInitialized:1;
    559   } DUMMYSTRUCTNAME;
    560   UCHAR PreviousState;
    561   UCHAR CurrentState;
    562   ULONG IsRemoved;
    563   UNICODE_STRING DeviceName;
    564   struct _PHYSICAL_DEVICE_EXTENSION *ChildList;
    565   ULONG PartitionNumber;
    566   LARGE_INTEGER PartitionLength;
    567   LARGE_INTEGER StartingOffset;
    568   PCLASS_DEV_INFO DevInfo;
    569   ULONG PagingPathCount;
    570   ULONG DumpPathCount;
    571   ULONG HibernationPathCount;
    572   KEVENT PathCountEvent;
    573 #ifndef ALLOCATE_SRB_FROM_POOL
    574   NPAGED_LOOKASIDE_LIST SrbLookasideList;
    575 #endif
    576   UNICODE_STRING MountedDeviceInterfaceName;
    577   ULONG GuidCount;
    578   PGUIDREGINFO GuidRegInfo;
    579   DICTIONARY FileObjectDictionary;
    580 #if (NTDDI_VERSION >= NTDDI_WINXP)
    581   PCLASS_PRIVATE_COMMON_DATA PrivateCommonData;
    582 #else
    583   ULONG_PTR Reserved1;
    584 #endif
    585 #if (NTDDI_VERSION >= NTDDI_VISTA)
    586   PDRIVER_DISPATCH *DispatchTable;
    587 #else
    588   ULONG_PTR Reserved2;
    589 #endif
    590   ULONG_PTR Reserved3;
    591   ULONG_PTR Reserved4;
    592 } COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
    593 
    594 typedef struct _PHYSICAL_DEVICE_EXTENSION {
    595   _ANONYMOUS_UNION union {
    596     _ANONYMOUS_STRUCT struct {
    597       ULONG Version;
    598       PDEVICE_OBJECT DeviceObject;
    599     } DUMMYSTRUCTNAME;
    600     COMMON_DEVICE_EXTENSION CommonExtension;
    601   } DUMMYUNIONNAME;
    602   BOOLEAN IsMissing;
    603   BOOLEAN IsEnumerated;
    604 #if (NTDDI_VERSION >= NTDDI_WINXP)
    605   PCLASS_PRIVATE_PDO_DATA PrivatePdoData;
    606 #else
    607   ULONG_PTR Reserved1;
    608 #endif
    609   ULONG_PTR Reserved2;
    610   ULONG_PTR Reserved3;
    611   ULONG_PTR Reserved4;
    612 } PHYSICAL_DEVICE_EXTENSION, *PPHYSICAL_DEVICE_EXTENSION;
    613 
    614 typedef struct _CLASS_POWER_OPTIONS {
    615   ULONG PowerDown:1;
    616   ULONG LockQueue:1;
    617   ULONG HandleSpinDown:1;
    618   ULONG HandleSpinUp:1;
    619   ULONG Reserved:27;
    620 } CLASS_POWER_OPTIONS, *PCLASS_POWER_OPTIONS;
    621 
    622 typedef struct _CLASS_POWER_CONTEXT {
    623   union {
    624     CLASS_POWER_DOWN_STATE PowerDown;
    625     CLASS_POWER_DOWN_STATE2 PowerDown2;
    626     CLASS_POWER_UP_STATE PowerUp;
    627   } PowerChangeState;
    628   CLASS_POWER_OPTIONS Options;
    629   BOOLEAN InUse;
    630   BOOLEAN QueueLocked;
    631   NTSTATUS FinalStatus;
    632   ULONG RetryCount;
    633   ULONG RetryInterval;
    634   PIO_COMPLETION_ROUTINE CompletionRoutine;
    635   PDEVICE_OBJECT DeviceObject;
    636   PIRP Irp;
    637   SCSI_REQUEST_BLOCK Srb;
    638 } CLASS_POWER_CONTEXT, *PCLASS_POWER_CONTEXT;
    639 
    640 typedef struct _COMPLETION_CONTEXT {
    641   PDEVICE_OBJECT DeviceObject;
    642   SCSI_REQUEST_BLOCK Srb;
    643 } COMPLETION_CONTEXT, *PCOMPLETION_CONTEXT;
    644 
    645 SCSIPORTAPI
    646 ULONG
    647 NTAPI
    648 ClassInitialize(
    649   PVOID Argument1,
    650   PVOID Argument2,
    651   PCLASS_INIT_DATA InitializationData);
    652 
    653 typedef struct _CLASS_QUERY_WMI_REGINFO_EX_LIST {
    654   ULONG Size;
    655   PCLASS_QUERY_WMI_REGINFO_EX ClassFdoQueryWmiRegInfoEx;
    656   PCLASS_QUERY_WMI_REGINFO_EX ClassPdoQueryWmiRegInfoEx;
    657 } CLASS_QUERY_WMI_REGINFO_EX_LIST, *PCLASS_QUERY_WMI_REGINFO_EX_LIST;
    658 
    659 typedef struct _FUNCTIONAL_DEVICE_EXTENSION {
    660   _ANONYMOUS_UNION union {
    661     _ANONYMOUS_STRUCT struct {
    662       ULONG Version;
    663       PDEVICE_OBJECT DeviceObject;
    664     } DUMMYSTRUCTNAME;
    665     COMMON_DEVICE_EXTENSION CommonExtension;
    666   } DUMMYUNIONNAME;
    667   PDEVICE_OBJECT LowerPdo;
    668   PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor;
    669   PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor;
    670   DEVICE_POWER_STATE DevicePowerState;
    671   ULONG DMByteSkew;
    672   ULONG DMSkew;
    673   BOOLEAN DMActive;
    674   DISK_GEOMETRY DiskGeometry;
    675   PSENSE_DATA SenseData;
    676   ULONG TimeOutValue;
    677   ULONG DeviceNumber;
    678   ULONG SrbFlags;
    679   ULONG ErrorCount;
    680   LONG LockCount;
    681   LONG ProtectedLockCount;
    682   LONG InternalLockCount;
    683   KEVENT EjectSynchronizationEvent;
    684   USHORT DeviceFlags;
    685   UCHAR SectorShift;
    686 #if (NTDDI_VERSION >= NTDDI_VISTA)
    687   UCHAR CdbForceUnitAccess;
    688 #else
    689   UCHAR ReservedByte;
    690 #endif
    691   PMEDIA_CHANGE_DETECTION_INFO MediaChangeDetectionInfo;
    692   PKEVENT Unused1;
    693   HANDLE Unused2;
    694   FILE_OBJECT_EXTENSION KernelModeMcnContext;
    695   ULONG MediaChangeCount;
    696   HANDLE DeviceDirectory;
    697   KSPIN_LOCK ReleaseQueueSpinLock;
    698   PIRP ReleaseQueueIrp;
    699   SCSI_REQUEST_BLOCK ReleaseQueueSrb;
    700   BOOLEAN ReleaseQueueNeeded;
    701   BOOLEAN ReleaseQueueInProgress;
    702   BOOLEAN ReleaseQueueIrpFromPool;
    703   BOOLEAN FailurePredicted;
    704   ULONG FailureReason;
    705   struct _FAILURE_PREDICTION_INFO* FailurePredictionInfo;
    706   BOOLEAN PowerDownInProgress;
    707   ULONG EnumerationInterlock;
    708   KEVENT ChildLock;
    709   PKTHREAD ChildLockOwner;
    710   ULONG ChildLockAcquisitionCount;
    711   ULONG ScanForSpecialFlags;
    712   KDPC PowerRetryDpc;
    713   KTIMER PowerRetryTimer;
    714   CLASS_POWER_CONTEXT PowerContext;
    715 
    716 #if (NTDDI_VERSION <= NTDDI_WIN2K)
    717 
    718 #if (SPVER(NTDDI_VERSION) < 2))
    719   ULONG_PTR Reserved1;
    720   ULONG_PTR Reserved2;
    721   ULONG_PTR Reserved3;
    722   ULONG_PTR Reserved4;
    723 #else
    724   ULONG CompletionSuccessCount;
    725   ULONG SavedSrbFlags;
    726   ULONG SavedErrorCount;
    727   ULONG_PTR Reserved1;
    728 #endif
    729 
    730 #else /* (NTDDI_VERSION <= NTDDI_WIN2K) */
    731 
    732   PCLASS_PRIVATE_FDO_DATA PrivateFdoData;
    733   ULONG_PTR Reserved2;
    734   ULONG_PTR Reserved3;
    735   ULONG_PTR Reserved4;
    736 
    737 #endif /* (NTDDI_VERSION <= NTDDI_WIN2K) */
    738 
    739 } FUNCTIONAL_DEVICE_EXTENSION, *PFUNCTIONAL_DEVICE_EXTENSION;
    740 
    741 SCSIPORTAPI
    742 ULONG
    743 NTAPI
    744 ClassInitializeEx(
    745   PDRIVER_OBJECT DriverObject,
    746   LPGUID Guid,
    747   PVOID Data);
    748 
    749 SCSIPORTAPI
    750 NTSTATUS
    751 NTAPI
    752 ClassCreateDeviceObject(
    753   PDRIVER_OBJECT DriverObject,
    754   PCCHAR ObjectNameBuffer,
    755   PDEVICE_OBJECT LowerDeviceObject,
    756   BOOLEAN IsFdo,
    757   PDEVICE_OBJECT *DeviceObject);
    758 
    759 SCSIPORTAPI
    760 NTSTATUS
    761 NTAPI
    762 ClassReadDriveCapacity(
    763   PDEVICE_OBJECT DeviceObject);
    764 
    765 SCSIPORTAPI
    766 VOID
    767 NTAPI
    768 ClassReleaseQueue(
    769   PDEVICE_OBJECT DeviceObject);
    770 
    771 SCSIPORTAPI
    772 VOID
    773 NTAPI
    774 ClassSplitRequest(
    775   PDEVICE_OBJECT DeviceObject,
    776   PIRP Irp,
    777   ULONG MaximumBytes);
    778 
    779 SCSIPORTAPI
    780 NTSTATUS
    781 NTAPI
    782 ClassDeviceControl(
    783   PDEVICE_OBJECT DeviceObject,
    784   PIRP Irp);
    785 
    786 SCSIPORTAPI
    787 NTSTATUS
    788 NTAPI
    789 ClassIoComplete(
    790   PDEVICE_OBJECT DeviceObject,
    791   PIRP Irp,
    792   PVOID Context);
    793 
    794 SCSIPORTAPI
    795 NTSTATUS
    796 NTAPI
    797 ClassIoCompleteAssociated(
    798   PDEVICE_OBJECT DeviceObject,
    799   PIRP Irp,
    800   PVOID Context);
    801 
    802 SCSIPORTAPI
    803 BOOLEAN
    804 NTAPI
    805 ClassInterpretSenseInfo(
    806   PDEVICE_OBJECT DeviceObject,
    807   PSCSI_REQUEST_BLOCK Srb,
    808   UCHAR MajorFunctionCode,
    809   ULONG IoDeviceCode,
    810   ULONG RetryCount,
    811   NTSTATUS *Status,
    812   ULONG *RetryInterval);
    813 
    814 VOID
    815 NTAPI
    816 ClassSendDeviceIoControlSynchronous(
    817   ULONG IoControlCode,
    818   PDEVICE_OBJECT TargetDeviceObject,
    819   PVOID Buffer,
    820   ULONG InputBufferLength,
    821   ULONG OutputBufferLength,
    822   BOOLEAN InternalDeviceIoControl,
    823   PIO_STATUS_BLOCK IoStatus);
    824 
    825 SCSIPORTAPI
    826 NTSTATUS
    827 NTAPI
    828 ClassSendIrpSynchronous(
    829   PDEVICE_OBJECT TargetDeviceObject,
    830   PIRP Irp);
    831 
    832 SCSIPORTAPI
    833 NTSTATUS
    834 NTAPI
    835 ClassForwardIrpSynchronous(
    836   PCOMMON_DEVICE_EXTENSION CommonExtension,
    837   PIRP Irp);
    838 
    839 SCSIPORTAPI
    840 NTSTATUS
    841 NTAPI
    842 ClassSendSrbSynchronous(
    843   PDEVICE_OBJECT DeviceObject,
    844   PSCSI_REQUEST_BLOCK Srb,
    845   PVOID BufferAddress,
    846   ULONG BufferLength,
    847   BOOLEAN WriteToDevice);
    848 
    849 SCSIPORTAPI
    850 NTSTATUS
    851 NTAPI
    852 ClassSendSrbAsynchronous(
    853   PDEVICE_OBJECT DeviceObject,
    854   PSCSI_REQUEST_BLOCK Srb,
    855   PIRP Irp,
    856   PVOID BufferAddress,
    857   ULONG BufferLength,
    858   BOOLEAN WriteToDevice);
    859 
    860 SCSIPORTAPI
    861 NTSTATUS
    862 NTAPI
    863 ClassBuildRequest(
    864   PDEVICE_OBJECT DeviceObject,
    865   PIRP Irp);
    866 
    867 SCSIPORTAPI
    868 ULONG
    869 NTAPI
    870 ClassModeSense(
    871   PDEVICE_OBJECT DeviceObject,
    872   PCHAR ModeSenseBuffer,
    873   ULONG Length,
    874   UCHAR PageMode);
    875 
    876 SCSIPORTAPI
    877 PVOID
    878 NTAPI
    879 ClassFindModePage(
    880   PCHAR ModeSenseBuffer,
    881   ULONG Length,
    882   UCHAR PageMode,
    883   BOOLEAN Use6Byte);
    884 
    885 SCSIPORTAPI
    886 NTSTATUS
    887 NTAPI
    888 ClassClaimDevice(
    889   PDEVICE_OBJECT LowerDeviceObject,
    890   BOOLEAN Release);
    891 
    892 SCSIPORTAPI
    893 NTSTATUS
    894 NTAPI
    895 ClassInternalIoControl (
    896   PDEVICE_OBJECT DeviceObject,
    897   PIRP Irp);
    898 
    899 SCSIPORTAPI
    900 VOID
    901 NTAPI
    902 ClassInitializeSrbLookasideList(
    903   PCOMMON_DEVICE_EXTENSION CommonExtension,
    904   ULONG NumberElements);
    905 
    906 SCSIPORTAPI
    907 VOID
    908 NTAPI
    909 ClassDeleteSrbLookasideList(
    910   PCOMMON_DEVICE_EXTENSION CommonExtension);
    911 
    912 SCSIPORTAPI
    913 ULONG
    914 NTAPI
    915 ClassQueryTimeOutRegistryValue(
    916   PDEVICE_OBJECT DeviceObject);
    917 
    918 SCSIPORTAPI
    919 NTSTATUS
    920 NTAPI
    921 ClassGetDescriptor(
    922   PDEVICE_OBJECT DeviceObject,
    923   PSTORAGE_PROPERTY_ID PropertyId,
    924   PSTORAGE_DESCRIPTOR_HEADER *Descriptor);
    925 
    926 SCSIPORTAPI
    927 VOID
    928 NTAPI
    929 ClassInvalidateBusRelations(
    930   PDEVICE_OBJECT Fdo);
    931 
    932 SCSIPORTAPI
    933 VOID
    934 NTAPI
    935 ClassMarkChildrenMissing(
    936   PFUNCTIONAL_DEVICE_EXTENSION Fdo);
    937 
    938 SCSIPORTAPI
    939 BOOLEAN
    940 NTAPI
    941 ClassMarkChildMissing(
    942   PPHYSICAL_DEVICE_EXTENSION PdoExtension,
    943   BOOLEAN AcquireChildLock);
    944 
    945 SCSIPORTAPI
    946 VOID
    947 ClassDebugPrint(
    948   CLASS_DEBUG_LEVEL DebugPrintLevel,
    949   PCCHAR DebugMessage,
    950   ...);
    951 
    952 SCSIPORTAPI
    953 PCLASS_DRIVER_EXTENSION
    954 NTAPI
    955 ClassGetDriverExtension(
    956   PDRIVER_OBJECT DriverObject);
    957 
    958 SCSIPORTAPI
    959 VOID
    960 NTAPI
    961 ClassCompleteRequest(
    962   PDEVICE_OBJECT DeviceObject,
    963   PIRP Irp,
    964   CCHAR PriorityBoost);
    965 
    966 SCSIPORTAPI
    967 VOID
    968 NTAPI
    969 ClassReleaseRemoveLock(
    970   PDEVICE_OBJECT DeviceObject,
    971   PIRP Tag);
    972 
    973 SCSIPORTAPI
    974 ULONG
    975 NTAPI
    976 ClassAcquireRemoveLockEx(
    977   PDEVICE_OBJECT DeviceObject,
    978   PVOID Tag,
    979   PCSTR File,
    980   ULONG Line);
    981 
    982 SCSIPORTAPI
    983 VOID
    984 NTAPI
    985 ClassUpdateInformationInRegistry(
    986   PDEVICE_OBJECT Fdo,
    987   PCHAR DeviceName,
    988   ULONG DeviceNumber,
    989   PINQUIRYDATA InquiryData,
    990   ULONG InquiryDataLength);
    991 
    992 SCSIPORTAPI
    993 NTSTATUS
    994 NTAPI
    995 ClassWmiCompleteRequest(
    996   PDEVICE_OBJECT DeviceObject,
    997   PIRP Irp,
    998   NTSTATUS Status,
    999   ULONG BufferUsed,
   1000   CCHAR PriorityBoost);
   1001 
   1002 SCSIPORTAPI
   1003 NTSTATUS
   1004 NTAPI
   1005 ClassWmiFireEvent(
   1006   PDEVICE_OBJECT DeviceObject,
   1007   LPGUID Guid,
   1008   ULONG InstanceIndex,
   1009   ULONG EventDataSize,
   1010   PVOID EventData);
   1011 
   1012 SCSIPORTAPI
   1013 VOID
   1014 NTAPI
   1015 ClassResetMediaChangeTimer(
   1016   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
   1017 
   1018 SCSIPORTAPI
   1019 VOID
   1020 NTAPI
   1021 ClassInitializeMediaChangeDetection(
   1022   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
   1023   PUCHAR EventPrefix);
   1024 
   1025 SCSIPORTAPI
   1026 NTSTATUS
   1027 NTAPI
   1028 ClassInitializeTestUnitPolling(
   1029   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
   1030   BOOLEAN AllowDriveToSleep);
   1031 
   1032 SCSIPORTAPI
   1033 PVPB
   1034 NTAPI
   1035 ClassGetVpb(
   1036   PDEVICE_OBJECT DeviceObject);
   1037 
   1038 SCSIPORTAPI
   1039 NTSTATUS
   1040 NTAPI
   1041 ClassSpinDownPowerHandler(
   1042   PDEVICE_OBJECT DeviceObject,
   1043   PIRP Irp);
   1044 
   1045 NTSTATUS
   1046 NTAPI
   1047 ClassStopUnitPowerHandler(
   1048   PDEVICE_OBJECT DeviceObject,
   1049   PIRP Irp);
   1050 
   1051 NTSTATUS
   1052 NTAPI
   1053 ClassSetFailurePredictionPoll(
   1054   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
   1055   FAILURE_PREDICTION_METHOD FailurePredictionMethod,
   1056   ULONG PollingPeriod);
   1057 
   1058 VOID
   1059 NTAPI
   1060 ClassNotifyFailurePredicted(
   1061   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
   1062   PUCHAR Buffer,
   1063   ULONG BufferSize,
   1064   BOOLEAN LogError,
   1065   ULONG UniqueErrorValue,
   1066   UCHAR PathId,
   1067   UCHAR TargetId,
   1068   UCHAR Lun);
   1069 
   1070 SCSIPORTAPI
   1071 VOID
   1072 NTAPI
   1073 ClassAcquireChildLock(
   1074   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
   1075 
   1076 SCSIPORTAPI
   1077 VOID
   1078 NTAPI
   1079 ClassReleaseChildLock(
   1080   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
   1081 
   1082 NTSTATUS
   1083 NTAPI
   1084 ClassSignalCompletion(
   1085   PDEVICE_OBJECT DeviceObject,
   1086   PIRP Irp,
   1087   PKEVENT Event);
   1088 
   1089 VOID
   1090 NTAPI
   1091 ClassSendStartUnit(
   1092   PDEVICE_OBJECT DeviceObject);
   1093 
   1094 SCSIPORTAPI
   1095 NTSTATUS
   1096 NTAPI
   1097 ClassRemoveDevice(
   1098   PDEVICE_OBJECT DeviceObject,
   1099   UCHAR RemoveType);
   1100 
   1101 SCSIPORTAPI
   1102 NTSTATUS
   1103 NTAPI
   1104 ClassAsynchronousCompletion(
   1105   PDEVICE_OBJECT DeviceObject,
   1106   PIRP Irp,
   1107   PVOID Event);
   1108 
   1109 SCSIPORTAPI
   1110 VOID
   1111 NTAPI
   1112 ClassCheckMediaState(
   1113   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
   1114 
   1115 SCSIPORTAPI
   1116 NTSTATUS
   1117 NTAPI
   1118 ClassCheckVerifyComplete(
   1119   PDEVICE_OBJECT DeviceObject,
   1120   PIRP Irp,
   1121   PVOID Context);
   1122 
   1123 SCSIPORTAPI
   1124 VOID
   1125 NTAPI
   1126 ClassSetMediaChangeState(
   1127   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
   1128   MEDIA_CHANGE_DETECTION_STATE State,
   1129   BOOLEAN Wait);
   1130 
   1131 SCSIPORTAPI
   1132 VOID
   1133 NTAPI
   1134 ClassEnableMediaChangeDetection(
   1135   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
   1136 
   1137 SCSIPORTAPI
   1138 VOID
   1139 NTAPI
   1140 ClassDisableMediaChangeDetection(
   1141   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
   1142 
   1143 SCSIPORTAPI
   1144 VOID
   1145 NTAPI
   1146 ClassCleanupMediaChangeDetection(
   1147   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
   1148 
   1149 VOID
   1150 NTAPI
   1151 ClassGetDeviceParameter(
   1152   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
   1153   PWSTR SubkeyName,
   1154   PWSTR ParameterName,
   1155   PULONG ParameterValue);
   1156 
   1157 NTSTATUS
   1158 NTAPI
   1159 ClassSetDeviceParameter(
   1160   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
   1161   PWSTR SubkeyName,
   1162   PWSTR ParameterName,
   1163   ULONG ParameterValue);
   1164 
   1165 #if (NTDDI_VERSION >= NTDDI_VISTA)
   1166 
   1167 PFILE_OBJECT_EXTENSION
   1168 NTAPI
   1169 ClassGetFsContext(
   1170   PCOMMON_DEVICE_EXTENSION CommonExtension,
   1171   PFILE_OBJECT FileObject);
   1172 
   1173 VOID
   1174 NTAPI
   1175 ClassSendNotification(
   1176   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
   1177   const GUID *Guid,
   1178   ULONG ExtraDataSize,
   1179   PVOID ExtraData);
   1180 
   1181 #endif /* (NTDDI_VERSION >= NTDDI_VISTA) */
   1182 
   1183 static __inline
   1184 BOOLEAN
   1185 PORT_ALLOCATED_SENSE(
   1186   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
   1187   PSCSI_REQUEST_BLOCK Srb)
   1188 {
   1189   return ((BOOLEAN)((TEST_FLAG(Srb->SrbFlags, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE) &&
   1190           TEST_FLAG(Srb->SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER))                &&
   1191           (Srb->SenseInfoBuffer != FdoExtension->SenseData)));
   1192 }
   1193 
   1194 static __inline
   1195 VOID
   1196 FREE_PORT_ALLOCATED_SENSE_BUFFER(
   1197   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
   1198   PSCSI_REQUEST_BLOCK Srb)
   1199 {
   1200   ASSERT(TEST_FLAG(Srb->SrbFlags, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE));
   1201   ASSERT(TEST_FLAG(Srb->SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER));
   1202   ASSERT(Srb->SenseInfoBuffer != FdoExtension->SenseData);
   1203 
   1204   ExFreePool(Srb->SenseInfoBuffer);
   1205   Srb->SenseInfoBuffer = FdoExtension->SenseData;
   1206   Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
   1207   CLEAR_FLAG(Srb->SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER);
   1208   return;
   1209 }
   1210 
   1211 typedef VOID
   1212 (NTAPI *PCLASS_SCAN_FOR_SPECIAL_HANDLER)(
   1213   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
   1214   ULONG_PTR Data);
   1215 
   1216 VOID
   1217 NTAPI
   1218 ClassScanForSpecial(
   1219   PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
   1220   CLASSPNP_SCAN_FOR_SPECIAL_INFO DeviceList[],
   1221   PCLASS_SCAN_FOR_SPECIAL_HANDLER Function);
   1222