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
CountOfSetBitsUChar(UCHAR _X)190 static inline ULONG CountOfSetBitsUChar(UCHAR _X)
191 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
CountOfSetBitsULong(ULONG _X)192 static inline ULONG CountOfSetBitsULong(ULONG _X)
193 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
CountOfSetBitsULong32(ULONG32 _X)194 static inline ULONG CountOfSetBitsULong32(ULONG32 _X)
195 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
CountOfSetBitsULong64(ULONG64 _X)196 static inline ULONG CountOfSetBitsULong64(ULONG64 _X)
197 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
CountOfSetBitsUlongPtr(ULONG_PTR _X)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
PORT_ALLOCATED_SENSE(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,PSCSI_REQUEST_BLOCK Srb)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
FREE_PORT_ALLOCATED_SENSE_BUFFER(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,PSCSI_REQUEST_BLOCK Srb)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