master
   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
 190static inline ULONG CountOfSetBitsUChar(UCHAR _X)
 191{ ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
 192static inline ULONG CountOfSetBitsULong(ULONG _X)
 193{ ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
 194static inline ULONG CountOfSetBitsULong32(ULONG32 _X)
 195{ ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
 196static inline ULONG CountOfSetBitsULong64(ULONG64 _X)
 197{ ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
 198static inline ULONG CountOfSetBitsUlongPtr(ULONG_PTR _X)
 199{ ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
 200
 201typedef enum _MEDIA_CHANGE_DETECTION_STATE {
 202  MediaUnknown,
 203  MediaPresent,
 204  MediaNotPresent,
 205  MediaUnavailable
 206} MEDIA_CHANGE_DETECTION_STATE, *PMEDIA_CHANGE_DETECTION_STATE;
 207
 208typedef 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
 224typedef enum {
 225  EventGeneration,
 226  DataBlockCollection
 227} CLASSENABLEDISABLEFUNCTION;
 228
 229typedef enum {
 230  FailurePredictionNone = 0,
 231  FailurePredictionIoctl,
 232  FailurePredictionSmart,
 233  FailurePredictionSense
 234} FAILURE_PREDICTION_METHOD, *PFAILURE_PREDICTION_METHOD;
 235
 236typedef enum {
 237  PowerDownDeviceInitial,
 238  PowerDownDeviceLocked,
 239  PowerDownDeviceStopped,
 240  PowerDownDeviceOff,
 241  PowerDownDeviceUnlocked
 242} CLASS_POWER_DOWN_STATE;
 243
 244typedef enum {
 245  PowerDownDeviceInitial2,
 246  PowerDownDeviceLocked2,
 247  PowerDownDeviceFlushed2,
 248  PowerDownDeviceStopped2,
 249  PowerDownDeviceOff2,
 250  PowerDownDeviceUnlocked2
 251} CLASS_POWER_DOWN_STATE2;
 252
 253typedef enum {
 254  PowerUpDeviceInitial,
 255  PowerUpDeviceLocked,
 256  PowerUpDeviceOn,
 257  PowerUpDeviceStarted,
 258  PowerUpDeviceUnlocked
 259} CLASS_POWER_UP_STATE;
 260
 261struct _CLASS_INIT_DATA;
 262typedef struct _CLASS_INIT_DATA CLASS_INIT_DATA, *PCLASS_INIT_DATA;
 263
 264struct _CLASS_PRIVATE_FDO_DATA;
 265typedef struct _CLASS_PRIVATE_FDO_DATA CLASS_PRIVATE_FDO_DATA, *PCLASS_PRIVATE_FDO_DATA;
 266
 267struct _CLASS_PRIVATE_PDO_DATA;
 268typedef struct _CLASS_PRIVATE_PDO_DATA CLASS_PRIVATE_PDO_DATA, *PCLASS_PRIVATE_PDO_DATA;
 269
 270struct _CLASS_PRIVATE_COMMON_DATA;
 271typedef struct _CLASS_PRIVATE_COMMON_DATA CLASS_PRIVATE_COMMON_DATA, *PCLASS_PRIVATE_COMMON_DATA;
 272
 273struct _MEDIA_CHANGE_DETECTION_INFO;
 274typedef struct _MEDIA_CHANGE_DETECTION_INFO MEDIA_CHANGE_DETECTION_INFO, *PMEDIA_CHANGE_DETECTION_INFO;
 275
 276typedef struct _DICTIONARY {
 277  ULONGLONG Signature;
 278  struct _DICTIONARY_HEADER* List;
 279  KSPIN_LOCK SpinLock;
 280} DICTIONARY, *PDICTIONARY;
 281
 282typedef 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
 289typedef VOID
 290(NTAPI *PCLASS_ERROR)(
 291  PDEVICE_OBJECT DeviceObject,
 292  PSCSI_REQUEST_BLOCK Srb,
 293  NTSTATUS *Status,
 294  BOOLEAN *Retry);
 295
 296typedef NTSTATUS
 297(NTAPI *PCLASS_ADD_DEVICE)(
 298  PDRIVER_OBJECT DriverObject,
 299  PDEVICE_OBJECT Pdo);
 300
 301typedef NTSTATUS
 302(NTAPI *PCLASS_POWER_DEVICE)(
 303  PDEVICE_OBJECT DeviceObject,
 304  PIRP Irp);
 305
 306typedef NTSTATUS
 307(NTAPI *PCLASS_START_DEVICE)(
 308  PDEVICE_OBJECT DeviceObject);
 309
 310typedef NTSTATUS
 311(NTAPI *PCLASS_STOP_DEVICE)(
 312  PDEVICE_OBJECT DeviceObject,
 313  UCHAR Type);
 314
 315typedef NTSTATUS
 316(NTAPI *PCLASS_INIT_DEVICE)(
 317  PDEVICE_OBJECT DeviceObject);
 318
 319typedef NTSTATUS
 320(NTAPI *PCLASS_ENUM_DEVICE)(
 321  PDEVICE_OBJECT DeviceObject);
 322
 323typedef NTSTATUS
 324(NTAPI *PCLASS_READ_WRITE)(
 325  PDEVICE_OBJECT DeviceObject,
 326  PIRP Irp);
 327
 328typedef NTSTATUS
 329(NTAPI *PCLASS_DEVICE_CONTROL)(
 330  PDEVICE_OBJECT DeviceObject,
 331  PIRP Irp);
 332
 333typedef NTSTATUS
 334(NTAPI *PCLASS_SHUTDOWN_FLUSH)(
 335  PDEVICE_OBJECT DeviceObject,
 336  PIRP Irp);
 337
 338typedef NTSTATUS
 339(NTAPI *PCLASS_CREATE_CLOSE)(
 340  PDEVICE_OBJECT DeviceObject,
 341  PIRP Irp);
 342
 343typedef NTSTATUS
 344(NTAPI *PCLASS_QUERY_ID)(
 345  PDEVICE_OBJECT DeviceObject,
 346  BUS_QUERY_ID_TYPE IdType,
 347  PUNICODE_STRING IdString);
 348
 349typedef NTSTATUS
 350(NTAPI *PCLASS_REMOVE_DEVICE)(
 351  PDEVICE_OBJECT DeviceObject,
 352  UCHAR Type);
 353
 354typedef VOID
 355(NTAPI *PCLASS_UNLOAD)(
 356  PDRIVER_OBJECT DriverObject);
 357
 358typedef NTSTATUS
 359(NTAPI *PCLASS_QUERY_PNP_CAPABILITIES)(
 360  PDEVICE_OBJECT PhysicalDeviceObject,
 361  PDEVICE_CAPABILITIES Capabilities);
 362
 363typedef VOID
 364(NTAPI *PCLASS_TICK)(
 365  PDEVICE_OBJECT DeviceObject);
 366
 367typedef NTSTATUS
 368(NTAPI *PCLASS_QUERY_WMI_REGINFO_EX)(
 369  PDEVICE_OBJECT DeviceObject,
 370  ULONG *RegFlags,
 371  PUNICODE_STRING Name,
 372  PUNICODE_STRING MofResouceName);
 373
 374typedef NTSTATUS
 375(NTAPI *PCLASS_QUERY_WMI_REGINFO)(
 376  PDEVICE_OBJECT DeviceObject,
 377  ULONG *RegFlags,
 378  PUNICODE_STRING Name);
 379
 380typedef NTSTATUS
 381(NTAPI *PCLASS_QUERY_WMI_DATABLOCK)(
 382  PDEVICE_OBJECT DeviceObject,
 383  PIRP Irp,
 384  ULONG GuidIndex,
 385  ULONG BufferAvail,
 386  PUCHAR Buffer);
 387
 388typedef NTSTATUS
 389(NTAPI *PCLASS_SET_WMI_DATABLOCK)(
 390  PDEVICE_OBJECT DeviceObject,
 391  PIRP Irp,
 392  ULONG GuidIndex,
 393  ULONG BufferSize,
 394  PUCHAR Buffer);
 395
 396typedef 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
 405typedef 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
 415typedef NTSTATUS
 416(NTAPI *PCLASS_WMI_FUNCTION_CONTROL)(
 417  PDEVICE_OBJECT DeviceObject,
 418  PIRP Irp,
 419  ULONG GuidIndex,
 420  CLASSENABLEDISABLEFUNCTION Function,
 421  BOOLEAN Enable);
 422
 423typedef 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
 432typedef 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
 439typedef 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
 451typedef VOID
 452(NTAPI *PCLASS_COMPRESS_RETRY_HISTORY_DATA)(
 453  PDEVICE_OBJECT DeviceObject,
 454  PSRB_HISTORY RequestHistory);
 455
 456typedef struct {
 457  GUID Guid;
 458  ULONG InstanceCount;
 459  ULONG Flags;
 460} GUIDREGINFO, *PGUIDREGINFO;
 461
 462typedef 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
 473typedef 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
 492struct _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
 504typedef 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
 511typedef struct _CLASS_WORKING_SET {
 512  ULONG Size;
 513  ULONG XferPacketsWorkingSetMaximum;
 514  ULONG XferPacketsWorkingSetMinimum;
 515} CLASS_WORKING_SET, *PCLASS_WORKING_SET;
 516
 517typedef 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
 524C_ASSERT((MAXULONG - sizeof(SRB_HISTORY)) / 30000 >= sizeof(SRB_HISTORY_ITEM));
 525
 526typedef 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
 543typedef 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
 594typedef 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
 614typedef 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
 622typedef 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
 640typedef struct _COMPLETION_CONTEXT {
 641  PDEVICE_OBJECT DeviceObject;
 642  SCSI_REQUEST_BLOCK Srb;
 643} COMPLETION_CONTEXT, *PCOMPLETION_CONTEXT;
 644
 645SCSIPORTAPI
 646ULONG
 647NTAPI
 648ClassInitialize(
 649  PVOID Argument1,
 650  PVOID Argument2,
 651  PCLASS_INIT_DATA InitializationData);
 652
 653typedef 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
 659typedef 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
 741SCSIPORTAPI
 742ULONG
 743NTAPI
 744ClassInitializeEx(
 745  PDRIVER_OBJECT DriverObject,
 746  LPGUID Guid,
 747  PVOID Data);
 748
 749SCSIPORTAPI
 750NTSTATUS
 751NTAPI
 752ClassCreateDeviceObject(
 753  PDRIVER_OBJECT DriverObject,
 754  PCCHAR ObjectNameBuffer,
 755  PDEVICE_OBJECT LowerDeviceObject,
 756  BOOLEAN IsFdo,
 757  PDEVICE_OBJECT *DeviceObject);
 758
 759SCSIPORTAPI
 760NTSTATUS
 761NTAPI
 762ClassReadDriveCapacity(
 763  PDEVICE_OBJECT DeviceObject);
 764
 765SCSIPORTAPI
 766VOID
 767NTAPI
 768ClassReleaseQueue(
 769  PDEVICE_OBJECT DeviceObject);
 770
 771SCSIPORTAPI
 772VOID
 773NTAPI
 774ClassSplitRequest(
 775  PDEVICE_OBJECT DeviceObject,
 776  PIRP Irp,
 777  ULONG MaximumBytes);
 778
 779SCSIPORTAPI
 780NTSTATUS
 781NTAPI
 782ClassDeviceControl(
 783  PDEVICE_OBJECT DeviceObject,
 784  PIRP Irp);
 785
 786SCSIPORTAPI
 787NTSTATUS
 788NTAPI
 789ClassIoComplete(
 790  PDEVICE_OBJECT DeviceObject,
 791  PIRP Irp,
 792  PVOID Context);
 793
 794SCSIPORTAPI
 795NTSTATUS
 796NTAPI
 797ClassIoCompleteAssociated(
 798  PDEVICE_OBJECT DeviceObject,
 799  PIRP Irp,
 800  PVOID Context);
 801
 802SCSIPORTAPI
 803BOOLEAN
 804NTAPI
 805ClassInterpretSenseInfo(
 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
 814VOID
 815NTAPI
 816ClassSendDeviceIoControlSynchronous(
 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
 825SCSIPORTAPI
 826NTSTATUS
 827NTAPI
 828ClassSendIrpSynchronous(
 829  PDEVICE_OBJECT TargetDeviceObject,
 830  PIRP Irp);
 831
 832SCSIPORTAPI
 833NTSTATUS
 834NTAPI
 835ClassForwardIrpSynchronous(
 836  PCOMMON_DEVICE_EXTENSION CommonExtension,
 837  PIRP Irp);
 838
 839SCSIPORTAPI
 840NTSTATUS
 841NTAPI
 842ClassSendSrbSynchronous(
 843  PDEVICE_OBJECT DeviceObject,
 844  PSCSI_REQUEST_BLOCK Srb,
 845  PVOID BufferAddress,
 846  ULONG BufferLength,
 847  BOOLEAN WriteToDevice);
 848
 849SCSIPORTAPI
 850NTSTATUS
 851NTAPI
 852ClassSendSrbAsynchronous(
 853  PDEVICE_OBJECT DeviceObject,
 854  PSCSI_REQUEST_BLOCK Srb,
 855  PIRP Irp,
 856  PVOID BufferAddress,
 857  ULONG BufferLength,
 858  BOOLEAN WriteToDevice);
 859
 860SCSIPORTAPI
 861NTSTATUS
 862NTAPI
 863ClassBuildRequest(
 864  PDEVICE_OBJECT DeviceObject,
 865  PIRP Irp);
 866
 867SCSIPORTAPI
 868ULONG
 869NTAPI
 870ClassModeSense(
 871  PDEVICE_OBJECT DeviceObject,
 872  PCHAR ModeSenseBuffer,
 873  ULONG Length,
 874  UCHAR PageMode);
 875
 876SCSIPORTAPI
 877PVOID
 878NTAPI
 879ClassFindModePage(
 880  PCHAR ModeSenseBuffer,
 881  ULONG Length,
 882  UCHAR PageMode,
 883  BOOLEAN Use6Byte);
 884
 885SCSIPORTAPI
 886NTSTATUS
 887NTAPI
 888ClassClaimDevice(
 889  PDEVICE_OBJECT LowerDeviceObject,
 890  BOOLEAN Release);
 891  
 892SCSIPORTAPI
 893NTSTATUS
 894NTAPI
 895ClassInternalIoControl (
 896  PDEVICE_OBJECT DeviceObject,
 897  PIRP Irp);
 898
 899SCSIPORTAPI
 900VOID
 901NTAPI
 902ClassInitializeSrbLookasideList(
 903  PCOMMON_DEVICE_EXTENSION CommonExtension,
 904  ULONG NumberElements);
 905
 906SCSIPORTAPI
 907VOID
 908NTAPI
 909ClassDeleteSrbLookasideList(
 910  PCOMMON_DEVICE_EXTENSION CommonExtension);
 911
 912SCSIPORTAPI
 913ULONG
 914NTAPI
 915ClassQueryTimeOutRegistryValue(
 916  PDEVICE_OBJECT DeviceObject);
 917
 918SCSIPORTAPI
 919NTSTATUS
 920NTAPI
 921ClassGetDescriptor(
 922  PDEVICE_OBJECT DeviceObject,
 923  PSTORAGE_PROPERTY_ID PropertyId,
 924  PSTORAGE_DESCRIPTOR_HEADER *Descriptor);
 925
 926SCSIPORTAPI
 927VOID
 928NTAPI
 929ClassInvalidateBusRelations(
 930  PDEVICE_OBJECT Fdo);
 931
 932SCSIPORTAPI
 933VOID
 934NTAPI
 935ClassMarkChildrenMissing(
 936  PFUNCTIONAL_DEVICE_EXTENSION Fdo);
 937
 938SCSIPORTAPI
 939BOOLEAN
 940NTAPI
 941ClassMarkChildMissing(
 942  PPHYSICAL_DEVICE_EXTENSION PdoExtension,
 943  BOOLEAN AcquireChildLock);
 944
 945SCSIPORTAPI
 946VOID
 947ClassDebugPrint(
 948  CLASS_DEBUG_LEVEL DebugPrintLevel,
 949  PCCHAR DebugMessage,
 950  ...);
 951
 952SCSIPORTAPI
 953PCLASS_DRIVER_EXTENSION
 954NTAPI
 955ClassGetDriverExtension(
 956  PDRIVER_OBJECT DriverObject);
 957
 958SCSIPORTAPI
 959VOID
 960NTAPI
 961ClassCompleteRequest(
 962  PDEVICE_OBJECT DeviceObject,
 963  PIRP Irp,
 964  CCHAR PriorityBoost);
 965
 966SCSIPORTAPI
 967VOID
 968NTAPI
 969ClassReleaseRemoveLock(
 970  PDEVICE_OBJECT DeviceObject,
 971  PIRP Tag);
 972
 973SCSIPORTAPI
 974ULONG
 975NTAPI
 976ClassAcquireRemoveLockEx(
 977  PDEVICE_OBJECT DeviceObject,
 978  PVOID Tag,
 979  PCSTR File,
 980  ULONG Line);
 981
 982SCSIPORTAPI
 983VOID
 984NTAPI
 985ClassUpdateInformationInRegistry(
 986  PDEVICE_OBJECT Fdo,
 987  PCHAR DeviceName,
 988  ULONG DeviceNumber,
 989  PINQUIRYDATA InquiryData,
 990  ULONG InquiryDataLength);
 991
 992SCSIPORTAPI
 993NTSTATUS
 994NTAPI
 995ClassWmiCompleteRequest(
 996  PDEVICE_OBJECT DeviceObject,
 997  PIRP Irp,
 998  NTSTATUS Status,
 999  ULONG BufferUsed,
1000  CCHAR PriorityBoost);
1001
1002SCSIPORTAPI
1003NTSTATUS
1004NTAPI
1005ClassWmiFireEvent(
1006  PDEVICE_OBJECT DeviceObject,
1007  LPGUID Guid,
1008  ULONG InstanceIndex,
1009  ULONG EventDataSize,
1010  PVOID EventData);
1011
1012SCSIPORTAPI
1013VOID
1014NTAPI
1015ClassResetMediaChangeTimer(
1016  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1017
1018SCSIPORTAPI
1019VOID
1020NTAPI
1021ClassInitializeMediaChangeDetection(
1022  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1023  PUCHAR EventPrefix);
1024
1025SCSIPORTAPI
1026NTSTATUS
1027NTAPI
1028ClassInitializeTestUnitPolling(
1029  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1030  BOOLEAN AllowDriveToSleep);
1031
1032SCSIPORTAPI
1033PVPB
1034NTAPI
1035ClassGetVpb(
1036  PDEVICE_OBJECT DeviceObject);
1037
1038SCSIPORTAPI
1039NTSTATUS
1040NTAPI
1041ClassSpinDownPowerHandler(
1042  PDEVICE_OBJECT DeviceObject,
1043  PIRP Irp);
1044
1045NTSTATUS
1046NTAPI
1047ClassStopUnitPowerHandler(
1048  PDEVICE_OBJECT DeviceObject,
1049  PIRP Irp);
1050
1051NTSTATUS
1052NTAPI
1053ClassSetFailurePredictionPoll(
1054  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1055  FAILURE_PREDICTION_METHOD FailurePredictionMethod,
1056  ULONG PollingPeriod);
1057
1058VOID
1059NTAPI
1060ClassNotifyFailurePredicted(
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
1070SCSIPORTAPI
1071VOID
1072NTAPI
1073ClassAcquireChildLock(
1074  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1075
1076SCSIPORTAPI
1077VOID
1078NTAPI
1079ClassReleaseChildLock(
1080  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1081
1082NTSTATUS
1083NTAPI
1084ClassSignalCompletion(
1085  PDEVICE_OBJECT DeviceObject,
1086  PIRP Irp,
1087  PKEVENT Event);
1088
1089VOID
1090NTAPI
1091ClassSendStartUnit(
1092  PDEVICE_OBJECT DeviceObject);
1093
1094SCSIPORTAPI
1095NTSTATUS
1096NTAPI
1097ClassRemoveDevice(
1098  PDEVICE_OBJECT DeviceObject,
1099  UCHAR RemoveType);
1100
1101SCSIPORTAPI
1102NTSTATUS
1103NTAPI
1104ClassAsynchronousCompletion(
1105  PDEVICE_OBJECT DeviceObject,
1106  PIRP Irp,
1107  PVOID Event);
1108
1109SCSIPORTAPI
1110VOID
1111NTAPI
1112ClassCheckMediaState(
1113  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1114
1115SCSIPORTAPI
1116NTSTATUS
1117NTAPI
1118ClassCheckVerifyComplete(
1119  PDEVICE_OBJECT DeviceObject,
1120  PIRP Irp,
1121  PVOID Context);
1122
1123SCSIPORTAPI
1124VOID
1125NTAPI
1126ClassSetMediaChangeState(
1127  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1128  MEDIA_CHANGE_DETECTION_STATE State,
1129  BOOLEAN Wait);
1130
1131SCSIPORTAPI
1132VOID
1133NTAPI
1134ClassEnableMediaChangeDetection(
1135  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1136
1137SCSIPORTAPI
1138VOID
1139NTAPI
1140ClassDisableMediaChangeDetection(
1141  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1142
1143SCSIPORTAPI
1144VOID
1145NTAPI
1146ClassCleanupMediaChangeDetection(
1147  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1148
1149VOID
1150NTAPI
1151ClassGetDeviceParameter(
1152  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1153  PWSTR SubkeyName,
1154  PWSTR ParameterName,
1155  PULONG ParameterValue);
1156
1157NTSTATUS
1158NTAPI
1159ClassSetDeviceParameter(
1160  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1161  PWSTR SubkeyName,
1162  PWSTR ParameterName,
1163  ULONG ParameterValue);
1164
1165#if (NTDDI_VERSION >= NTDDI_VISTA)
1166
1167PFILE_OBJECT_EXTENSION
1168NTAPI
1169ClassGetFsContext(
1170  PCOMMON_DEVICE_EXTENSION CommonExtension,
1171  PFILE_OBJECT FileObject);
1172
1173VOID
1174NTAPI
1175ClassSendNotification(
1176  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1177  const GUID *Guid,
1178  ULONG ExtraDataSize,
1179  PVOID ExtraData);
1180
1181#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */
1182
1183static __inline
1184BOOLEAN
1185PORT_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
1194static __inline
1195VOID
1196FREE_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
1211typedef VOID
1212(NTAPI *PCLASS_SCAN_FOR_SPECIAL_HANDLER)(
1213  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1214  ULONG_PTR Data);
1215
1216VOID
1217NTAPI
1218ClassScanForSpecial(
1219  PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1220  CLASSPNP_SCAN_FOR_SPECIAL_INFO DeviceList[],
1221  PCLASS_SCAN_FOR_SPECIAL_HANDLER Function);