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);
1222