xref: /reactos/drivers/storage/class/disk/disk.h (revision 3088717b)
1*3088717bSVictor Perevertkin /*++
2*3088717bSVictor Perevertkin 
3*3088717bSVictor Perevertkin Copyright (C) Microsoft Corporation, 1991 - 2010
4*3088717bSVictor Perevertkin 
5*3088717bSVictor Perevertkin Module Name:
6*3088717bSVictor Perevertkin 
7*3088717bSVictor Perevertkin     disk.c
8*3088717bSVictor Perevertkin 
9*3088717bSVictor Perevertkin Abstract:
10*3088717bSVictor Perevertkin 
11*3088717bSVictor Perevertkin     SCSI disk class driver
12*3088717bSVictor Perevertkin 
13*3088717bSVictor Perevertkin Environment:
14*3088717bSVictor Perevertkin 
15*3088717bSVictor Perevertkin     kernel mode only
16*3088717bSVictor Perevertkin 
17*3088717bSVictor Perevertkin Notes:
18*3088717bSVictor Perevertkin 
19*3088717bSVictor Perevertkin Revision History:
20*3088717bSVictor Perevertkin 
21*3088717bSVictor Perevertkin --*/
22*3088717bSVictor Perevertkin 
23*3088717bSVictor Perevertkin #include "ntddk.h"
24*3088717bSVictor Perevertkin #include "scsi.h"
25*3088717bSVictor Perevertkin #include <wmidata.h>
26*3088717bSVictor Perevertkin #include "classpnp.h"
27*3088717bSVictor Perevertkin 
28*3088717bSVictor Perevertkin #include <wmistr.h>
29*3088717bSVictor Perevertkin #include "ntstrsafe.h"
30*3088717bSVictor Perevertkin 
31*3088717bSVictor Perevertkin //
32*3088717bSVictor Perevertkin // Set component ID for DbgPrintEx calls
33*3088717bSVictor Perevertkin //
34*3088717bSVictor Perevertkin #ifndef DEBUG_COMP_ID
35*3088717bSVictor Perevertkin #define DEBUG_COMP_ID   DPFLTR_DISK_ID
36*3088717bSVictor Perevertkin #endif
37*3088717bSVictor Perevertkin 
38*3088717bSVictor Perevertkin //
39*3088717bSVictor Perevertkin // Include header file and setup GUID for tracing
40*3088717bSVictor Perevertkin //
41*3088717bSVictor Perevertkin #include <storswtr.h>
42*3088717bSVictor Perevertkin #define WPP_GUID_DISK           (945186BF, 3DD6, 4f3f, 9C8E, 9EDD3FC9D558)
43*3088717bSVictor Perevertkin #ifndef WPP_CONTROL_GUIDS
44*3088717bSVictor Perevertkin #define WPP_CONTROL_GUIDS       WPP_CONTROL_GUIDS_NORMAL_FLAGS(WPP_GUID_DISK)
45*3088717bSVictor Perevertkin #endif
46*3088717bSVictor Perevertkin 
47*3088717bSVictor Perevertkin 
48*3088717bSVictor Perevertkin #ifdef ExAllocatePool
49*3088717bSVictor Perevertkin #undef ExAllocatePool
50*3088717bSVictor Perevertkin #define ExAllocatePool #NT_ASSERT(FALSE)
51*3088717bSVictor Perevertkin #endif
52*3088717bSVictor Perevertkin 
53*3088717bSVictor Perevertkin #define DISK_TAG_GENERAL        ' DcS'  // "ScD " - generic tag
54*3088717bSVictor Perevertkin #define DISK_TAG_SMART          'aDcS'  // "ScDa" - SMART allocations
55*3088717bSVictor Perevertkin #define DISK_TAG_INFO_EXCEPTION 'ADcS'  // "ScDA" - Info Exceptions
56*3088717bSVictor Perevertkin #define DISK_TAG_DISABLE_CACHE  'CDcS'  // "ScDC" - disable cache paths
57*3088717bSVictor Perevertkin #define DISK_TAG_CCONTEXT       'cDcS'  // "ScDc" - disk allocated completion context
58*3088717bSVictor Perevertkin #define DISK_TAG_DISK_GEOM      'GDcS'  // "ScDG" - disk geometry buffer
59*3088717bSVictor Perevertkin #define DISK_TAG_UPDATE_GEOM    'gDcS'  // "ScDg" - update disk geometry paths
60*3088717bSVictor Perevertkin #define DISK_TAG_SENSE_INFO     'IDcS'  // "ScDI" - sense info buffers
61*3088717bSVictor Perevertkin #define DISK_TAG_PNP_ID         'iDcS'  // "ScDp" - pnp ids
62*3088717bSVictor Perevertkin #define DISK_TAG_MODE_DATA      'MDcS'  // "ScDM" - mode data buffer
63*3088717bSVictor Perevertkin #define DISK_CACHE_MBR_CHECK    'mDcS'  // "ScDM" - mbr checksum code
64*3088717bSVictor Perevertkin #define DISK_TAG_NAME           'NDcS'  // "ScDN" - disk name code
65*3088717bSVictor Perevertkin #define DISK_TAG_READ_CAP       'PDcS'  // "ScDP" - read capacity buffer
66*3088717bSVictor Perevertkin #define DISK_TAG_PART_LIST      'pDcS'  // "ScDp" - disk partition lists
67*3088717bSVictor Perevertkin #define DISK_TAG_SRB            'SDcS'  // "ScDS" - srb allocation
68*3088717bSVictor Perevertkin #define DISK_TAG_START          'sDcS'  // "ScDs" - start device paths
69*3088717bSVictor Perevertkin #define DISK_TAG_UPDATE_CAP     'UDcS'  // "ScDU" - update capacity path
70*3088717bSVictor Perevertkin #define DISK_TAG_WI_CONTEXT     'WDcS'  // "ScDW" - work-item context
71*3088717bSVictor Perevertkin 
72*3088717bSVictor Perevertkin #ifdef __REACTOS__
73*3088717bSVictor Perevertkin #undef MdlMappingNoExecute
74*3088717bSVictor Perevertkin #define MdlMappingNoExecute 0
75*3088717bSVictor Perevertkin #define NonPagedPoolNx NonPagedPool
76*3088717bSVictor Perevertkin #define NonPagedPoolNxCacheAligned NonPagedPoolCacheAligned
77*3088717bSVictor Perevertkin #undef POOL_NX_ALLOCATION
78*3088717bSVictor Perevertkin #define POOL_NX_ALLOCATION 0
79*3088717bSVictor Perevertkin #endif
80*3088717bSVictor Perevertkin 
81*3088717bSVictor Perevertkin 
82*3088717bSVictor Perevertkin #if defined(_X86_) || defined(_AMD64_)
83*3088717bSVictor Perevertkin 
84*3088717bSVictor Perevertkin //
85*3088717bSVictor Perevertkin // Disk device data
86*3088717bSVictor Perevertkin //
87*3088717bSVictor Perevertkin 
88*3088717bSVictor Perevertkin typedef enum _DISK_GEOMETRY_SOURCE {
89*3088717bSVictor Perevertkin     DiskGeometryUnknown,
90*3088717bSVictor Perevertkin     DiskGeometryFromBios,
91*3088717bSVictor Perevertkin     DiskGeometryFromPort,
92*3088717bSVictor Perevertkin     DiskGeometryFromNec98,
93*3088717bSVictor Perevertkin     DiskGeometryGuessedFromBios,
94*3088717bSVictor Perevertkin     DiskGeometryFromDefault,
95*3088717bSVictor Perevertkin     DiskGeometryFromNT4
96*3088717bSVictor Perevertkin } DISK_GEOMETRY_SOURCE, *PDISK_GEOMETRY_SOURCE;
97*3088717bSVictor Perevertkin #endif
98*3088717bSVictor Perevertkin 
99*3088717bSVictor Perevertkin //
100*3088717bSVictor Perevertkin // Context for requests that can be combined and sent down
101*3088717bSVictor Perevertkin //
102*3088717bSVictor Perevertkin 
103*3088717bSVictor Perevertkin typedef struct _DISK_GROUP_CONTEXT
104*3088717bSVictor Perevertkin {
105*3088717bSVictor Perevertkin     //
106*3088717bSVictor Perevertkin     // Queue of requests whose representative is currently outstanding at the port driver
107*3088717bSVictor Perevertkin     //
108*3088717bSVictor Perevertkin     LIST_ENTRY CurrList;
109*3088717bSVictor Perevertkin 
110*3088717bSVictor Perevertkin     //
111*3088717bSVictor Perevertkin     // The representative for the above queue
112*3088717bSVictor Perevertkin     //
113*3088717bSVictor Perevertkin     PIRP CurrIrp;
114*3088717bSVictor Perevertkin 
115*3088717bSVictor Perevertkin     //
116*3088717bSVictor Perevertkin     // Queue of requests whose representative is waiting to go down
117*3088717bSVictor Perevertkin     //
118*3088717bSVictor Perevertkin     LIST_ENTRY NextList;
119*3088717bSVictor Perevertkin 
120*3088717bSVictor Perevertkin     //
121*3088717bSVictor Perevertkin     // The representative for the above queue
122*3088717bSVictor Perevertkin     //
123*3088717bSVictor Perevertkin     PIRP NextIrp;
124*3088717bSVictor Perevertkin 
125*3088717bSVictor Perevertkin     //
126*3088717bSVictor Perevertkin     // The srb associated with this group
127*3088717bSVictor Perevertkin     //
128*3088717bSVictor Perevertkin #if (NTDDI_VERSION >= NTDDI_WIN8)
129*3088717bSVictor Perevertkin 
130*3088717bSVictor Perevertkin     union {
131*3088717bSVictor Perevertkin         SCSI_REQUEST_BLOCK Srb;
132*3088717bSVictor Perevertkin         STORAGE_REQUEST_BLOCK SrbEx;
133*3088717bSVictor Perevertkin         UCHAR SrbExBuffer[CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE];
134*3088717bSVictor Perevertkin     } Srb;
135*3088717bSVictor Perevertkin 
136*3088717bSVictor Perevertkin #else
137*3088717bSVictor Perevertkin     SCSI_REQUEST_BLOCK Srb;
138*3088717bSVictor Perevertkin #endif
139*3088717bSVictor Perevertkin 
140*3088717bSVictor Perevertkin     //
141*3088717bSVictor Perevertkin     // The spinlock that will synchronize access to this context
142*3088717bSVictor Perevertkin     //
143*3088717bSVictor Perevertkin     KSPIN_LOCK Spinlock;
144*3088717bSVictor Perevertkin 
145*3088717bSVictor Perevertkin     //
146*3088717bSVictor Perevertkin     // This event will allow for the requests to be sent down synchronously
147*3088717bSVictor Perevertkin     //
148*3088717bSVictor Perevertkin     KEVENT Event;
149*3088717bSVictor Perevertkin 
150*3088717bSVictor Perevertkin 
151*3088717bSVictor Perevertkin #if DBG
152*3088717bSVictor Perevertkin 
153*3088717bSVictor Perevertkin     //
154*3088717bSVictor Perevertkin     // This counter maintains the number of requests currently tagged
155*3088717bSVictor Perevertkin     // to the request that is waiting to go down
156*3088717bSVictor Perevertkin     //
157*3088717bSVictor Perevertkin     ULONG DbgTagCount;
158*3088717bSVictor Perevertkin 
159*3088717bSVictor Perevertkin     //
160*3088717bSVictor Perevertkin     // This counter maintains the number of requests that were avoided
161*3088717bSVictor Perevertkin     //
162*3088717bSVictor Perevertkin     ULONG DbgSavCount;
163*3088717bSVictor Perevertkin 
164*3088717bSVictor Perevertkin     //
165*3088717bSVictor Perevertkin     // This counter maintains the total number of times that we combined
166*3088717bSVictor Perevertkin     // requests and  the respective number of  requests that were tagged
167*3088717bSVictor Perevertkin     //
168*3088717bSVictor Perevertkin     ULONG DbgRefCount[64];
169*3088717bSVictor Perevertkin 
170*3088717bSVictor Perevertkin #endif
171*3088717bSVictor Perevertkin 
172*3088717bSVictor Perevertkin } DISK_GROUP_CONTEXT, *PDISK_GROUP_CONTEXT;
173*3088717bSVictor Perevertkin 
174*3088717bSVictor Perevertkin //
175*3088717bSVictor Perevertkin // Write cache setting as defined by the user
176*3088717bSVictor Perevertkin //
177*3088717bSVictor Perevertkin typedef enum _DISK_USER_WRITE_CACHE_SETTING
178*3088717bSVictor Perevertkin {
179*3088717bSVictor Perevertkin     DiskWriteCacheDisable =  0,
180*3088717bSVictor Perevertkin     DiskWriteCacheEnable  =  1,
181*3088717bSVictor Perevertkin     DiskWriteCacheDefault = -1
182*3088717bSVictor Perevertkin 
183*3088717bSVictor Perevertkin } DISK_USER_WRITE_CACHE_SETTING, *PDISK_USER_WRITE_CACHE_SETTING;
184*3088717bSVictor Perevertkin 
185*3088717bSVictor Perevertkin typedef struct _DISK_DATA {
186*3088717bSVictor Perevertkin 
187*3088717bSVictor Perevertkin     //
188*3088717bSVictor Perevertkin     // This field is the ordinal of a partition as it appears on a disk.
189*3088717bSVictor Perevertkin     //
190*3088717bSVictor Perevertkin 
191*3088717bSVictor Perevertkin     ULONG PartitionOrdinal;
192*3088717bSVictor Perevertkin 
193*3088717bSVictor Perevertkin     //
194*3088717bSVictor Perevertkin     // How has this disk been partitioned? Either EFI or MBR.
195*3088717bSVictor Perevertkin     //
196*3088717bSVictor Perevertkin 
197*3088717bSVictor Perevertkin     PARTITION_STYLE PartitionStyle;
198*3088717bSVictor Perevertkin 
199*3088717bSVictor Perevertkin     union {
200*3088717bSVictor Perevertkin 
201*3088717bSVictor Perevertkin         struct {
202*3088717bSVictor Perevertkin 
203*3088717bSVictor Perevertkin             //
204*3088717bSVictor Perevertkin             // Disk signature (from MBR)
205*3088717bSVictor Perevertkin             //
206*3088717bSVictor Perevertkin 
207*3088717bSVictor Perevertkin             ULONG Signature;
208*3088717bSVictor Perevertkin 
209*3088717bSVictor Perevertkin             //
210*3088717bSVictor Perevertkin             // MBR checksum
211*3088717bSVictor Perevertkin             //
212*3088717bSVictor Perevertkin 
213*3088717bSVictor Perevertkin             ULONG MbrCheckSum;
214*3088717bSVictor Perevertkin 
215*3088717bSVictor Perevertkin             //
216*3088717bSVictor Perevertkin             // Number of hidden sectors for BPB.
217*3088717bSVictor Perevertkin             //
218*3088717bSVictor Perevertkin 
219*3088717bSVictor Perevertkin             ULONG HiddenSectors;
220*3088717bSVictor Perevertkin 
221*3088717bSVictor Perevertkin             //
222*3088717bSVictor Perevertkin             // Partition type of this device object
223*3088717bSVictor Perevertkin             //
224*3088717bSVictor Perevertkin             // This field is set by:
225*3088717bSVictor Perevertkin             //
226*3088717bSVictor Perevertkin             //     1. Initially set according to the partition list entry
227*3088717bSVictor Perevertkin             //        partition type returned by IoReadPartitionTable.
228*3088717bSVictor Perevertkin             //
229*3088717bSVictor Perevertkin             //     2. Subsequently set by the
230*3088717bSVictor Perevertkin             //        IOCTL_DISK_SET_PARTITION_INFORMATION I/O control
231*3088717bSVictor Perevertkin             //        function when IoSetPartitionInformation function
232*3088717bSVictor Perevertkin             //        successfully updates the partition type on the disk.
233*3088717bSVictor Perevertkin             //
234*3088717bSVictor Perevertkin 
235*3088717bSVictor Perevertkin             UCHAR PartitionType;
236*3088717bSVictor Perevertkin 
237*3088717bSVictor Perevertkin             //
238*3088717bSVictor Perevertkin             // Boot indicator - indicates whether this partition is a
239*3088717bSVictor Perevertkin             // bootable (active) partition for this device
240*3088717bSVictor Perevertkin             //
241*3088717bSVictor Perevertkin             // This field is set according to the partition list entry boot
242*3088717bSVictor Perevertkin             // indicator returned by IoReadPartitionTable.
243*3088717bSVictor Perevertkin             //
244*3088717bSVictor Perevertkin 
245*3088717bSVictor Perevertkin             BOOLEAN BootIndicator;
246*3088717bSVictor Perevertkin 
247*3088717bSVictor Perevertkin         } Mbr;
248*3088717bSVictor Perevertkin 
249*3088717bSVictor Perevertkin         struct {
250*3088717bSVictor Perevertkin 
251*3088717bSVictor Perevertkin             //
252*3088717bSVictor Perevertkin             // The DiskGUID field from the EFI partition header.
253*3088717bSVictor Perevertkin             //
254*3088717bSVictor Perevertkin 
255*3088717bSVictor Perevertkin             GUID DiskId;
256*3088717bSVictor Perevertkin 
257*3088717bSVictor Perevertkin             //
258*3088717bSVictor Perevertkin             // Partition type of this device object.
259*3088717bSVictor Perevertkin             //
260*3088717bSVictor Perevertkin 
261*3088717bSVictor Perevertkin             GUID PartitionType;
262*3088717bSVictor Perevertkin 
263*3088717bSVictor Perevertkin             //
264*3088717bSVictor Perevertkin             // Unique partition identifier for this partition.
265*3088717bSVictor Perevertkin             //
266*3088717bSVictor Perevertkin 
267*3088717bSVictor Perevertkin             GUID PartitionId;
268*3088717bSVictor Perevertkin 
269*3088717bSVictor Perevertkin             //
270*3088717bSVictor Perevertkin             // EFI partition attributes for this partition.
271*3088717bSVictor Perevertkin             //
272*3088717bSVictor Perevertkin 
273*3088717bSVictor Perevertkin             ULONG64 Attributes;
274*3088717bSVictor Perevertkin 
275*3088717bSVictor Perevertkin             //
276*3088717bSVictor Perevertkin             // EFI partition name of this partition.
277*3088717bSVictor Perevertkin             //
278*3088717bSVictor Perevertkin 
279*3088717bSVictor Perevertkin             WCHAR PartitionName[36];
280*3088717bSVictor Perevertkin 
281*3088717bSVictor Perevertkin         } Efi;
282*3088717bSVictor Perevertkin 
283*3088717bSVictor Perevertkin #ifdef _MSC_VER
284*3088717bSVictor Perevertkin #pragma warning(suppress: 4201) //this is intended to be an unnamed union
285*3088717bSVictor Perevertkin #endif
286*3088717bSVictor Perevertkin     };
287*3088717bSVictor Perevertkin 
288*3088717bSVictor Perevertkin     struct {
289*3088717bSVictor Perevertkin         //
290*3088717bSVictor Perevertkin         // This flag is set when the well known name is created (through
291*3088717bSVictor Perevertkin         // DiskCreateSymbolicLinks) and cleared when destroying it
292*3088717bSVictor Perevertkin         // (by calling DiskDeleteSymbolicLinks).
293*3088717bSVictor Perevertkin         //
294*3088717bSVictor Perevertkin 
295*3088717bSVictor Perevertkin         unsigned int WellKnownNameCreated : 1;
296*3088717bSVictor Perevertkin 
297*3088717bSVictor Perevertkin         //
298*3088717bSVictor Perevertkin         // This flag is set when the PhysicalDriveN link is created (through
299*3088717bSVictor Perevertkin         // DiskCreateSymbolicLinks) and is cleared when destroying it (through
300*3088717bSVictor Perevertkin         // DiskDeleteSymbolicLinks)
301*3088717bSVictor Perevertkin         //
302*3088717bSVictor Perevertkin 
303*3088717bSVictor Perevertkin         unsigned int PhysicalDriveLinkCreated : 1;
304*3088717bSVictor Perevertkin 
305*3088717bSVictor Perevertkin     } LinkStatus;
306*3088717bSVictor Perevertkin 
307*3088717bSVictor Perevertkin     //
308*3088717bSVictor Perevertkin     // ReadyStatus - STATUS_SUCCESS indicates that the drive is ready for
309*3088717bSVictor Perevertkin     // use.  Any error status is to be returned as an explaination for why
310*3088717bSVictor Perevertkin     // a request is failed.
311*3088717bSVictor Perevertkin     //
312*3088717bSVictor Perevertkin     // This was done solely for the zero-length partition case of having no
313*3088717bSVictor Perevertkin     // media in a removable disk drive.  When that occurs, and a read is sent
314*3088717bSVictor Perevertkin     // to the zero-length non-partition-zero PDO that was created, we had to
315*3088717bSVictor Perevertkin     // be able to fail the request with a reasonable value.  This may not have
316*3088717bSVictor Perevertkin     // been the best way to do this, but it works.
317*3088717bSVictor Perevertkin     //
318*3088717bSVictor Perevertkin 
319*3088717bSVictor Perevertkin     NTSTATUS ReadyStatus;
320*3088717bSVictor Perevertkin 
321*3088717bSVictor Perevertkin     //
322*3088717bSVictor Perevertkin     // SCSI address used for SMART operations.
323*3088717bSVictor Perevertkin     //
324*3088717bSVictor Perevertkin 
325*3088717bSVictor Perevertkin     SCSI_ADDRESS ScsiAddress;
326*3088717bSVictor Perevertkin 
327*3088717bSVictor Perevertkin     //
328*3088717bSVictor Perevertkin     // What type of failure prediction mechanism is available
329*3088717bSVictor Perevertkin     //
330*3088717bSVictor Perevertkin 
331*3088717bSVictor Perevertkin     FAILURE_PREDICTION_METHOD FailurePredictionCapability;
332*3088717bSVictor Perevertkin     BOOLEAN AllowFPPerfHit;
333*3088717bSVictor Perevertkin 
334*3088717bSVictor Perevertkin     //
335*3088717bSVictor Perevertkin     // Indicates that the SCSI Informational Exceptions mode page is supported.
336*3088717bSVictor Perevertkin     // Note that this only indicates *support* and does not necessarily
337*3088717bSVictor Perevertkin     // indicate that Informational Exception reporting via sense code is
338*3088717bSVictor Perevertkin     // actually enabled.
339*3088717bSVictor Perevertkin     //
340*3088717bSVictor Perevertkin     BOOLEAN ScsiInfoExceptionsSupported;
341*3088717bSVictor Perevertkin 
342*3088717bSVictor Perevertkin     //
343*3088717bSVictor Perevertkin     // Indicates if failure prediction is actually enabled (via whatever)
344*3088717bSVictor Perevertkin     // method is applicable as indicated by FailurePredictionCapability.
345*3088717bSVictor Perevertkin     //
346*3088717bSVictor Perevertkin     BOOLEAN FailurePredictionEnabled;
347*3088717bSVictor Perevertkin 
348*3088717bSVictor Perevertkin #if defined(_X86_) || defined(_AMD64_)
349*3088717bSVictor Perevertkin     //
350*3088717bSVictor Perevertkin     // This flag indiciates that a non-default geometry for this drive has
351*3088717bSVictor Perevertkin     // already been determined by the disk driver.  This field is ignored
352*3088717bSVictor Perevertkin     // for removable media drives.
353*3088717bSVictor Perevertkin     //
354*3088717bSVictor Perevertkin 
355*3088717bSVictor Perevertkin     DISK_GEOMETRY_SOURCE GeometrySource;
356*3088717bSVictor Perevertkin 
357*3088717bSVictor Perevertkin     //
358*3088717bSVictor Perevertkin     // If GeometryDetermined is TRUE this will contain the geometry which was
359*3088717bSVictor Perevertkin     // reported by the firmware or by the BIOS.  For removable media drives
360*3088717bSVictor Perevertkin     // this will contain the last geometry used when media was present.
361*3088717bSVictor Perevertkin     //
362*3088717bSVictor Perevertkin 
363*3088717bSVictor Perevertkin     DISK_GEOMETRY RealGeometry;
364*3088717bSVictor Perevertkin #endif
365*3088717bSVictor Perevertkin 
366*3088717bSVictor Perevertkin     //
367*3088717bSVictor Perevertkin     // This mutex prevents more than one IOCTL_DISK_VERIFY from being
368*3088717bSVictor Perevertkin     // sent down to the disk. This greatly reduces the possibility of
369*3088717bSVictor Perevertkin     // a Denial-of-Service attack
370*3088717bSVictor Perevertkin     //
371*3088717bSVictor Perevertkin 
372*3088717bSVictor Perevertkin     KMUTEX VerifyMutex;
373*3088717bSVictor Perevertkin 
374*3088717bSVictor Perevertkin     //
375*3088717bSVictor Perevertkin     // This allows for parallel flush requests to be combined into one so as to
376*3088717bSVictor Perevertkin     // reduce the number of outstanding requests that are sent down to the disk
377*3088717bSVictor Perevertkin     //
378*3088717bSVictor Perevertkin 
379*3088717bSVictor Perevertkin     DISK_GROUP_CONTEXT FlushContext;
380*3088717bSVictor Perevertkin 
381*3088717bSVictor Perevertkin     //
382*3088717bSVictor Perevertkin     // The user-specified disk write cache setting
383*3088717bSVictor Perevertkin     //
384*3088717bSVictor Perevertkin 
385*3088717bSVictor Perevertkin     DISK_USER_WRITE_CACHE_SETTING WriteCacheOverride;
386*3088717bSVictor Perevertkin 
387*3088717bSVictor Perevertkin 
388*3088717bSVictor Perevertkin } DISK_DATA, *PDISK_DATA;
389*3088717bSVictor Perevertkin 
390*3088717bSVictor Perevertkin //
391*3088717bSVictor Perevertkin // Define a general structure of identfing disk controllers with bad
392*3088717bSVictor Perevertkin // hardware.
393*3088717bSVictor Perevertkin //
394*3088717bSVictor Perevertkin 
395*3088717bSVictor Perevertkin #define HackDisableTaggedQueuing            (0x01)
396*3088717bSVictor Perevertkin #define HackDisableSynchronousTransfers     (0x02)
397*3088717bSVictor Perevertkin #define HackDisableSpinDown                 (0x04)
398*3088717bSVictor Perevertkin #define HackDisableWriteCache               (0x08)
399*3088717bSVictor Perevertkin #define HackCauseNotReportableHack          (0x10)
400*3088717bSVictor Perevertkin #define HackRequiresStartUnitCommand        (0x20)
401*3088717bSVictor Perevertkin 
402*3088717bSVictor Perevertkin 
403*3088717bSVictor Perevertkin #define DiskDeviceParameterSubkey           L"Disk"
404*3088717bSVictor Perevertkin #define DiskDeviceUserWriteCacheSetting     L"UserWriteCacheSetting"
405*3088717bSVictor Perevertkin #define DiskDeviceCacheIsPowerProtected     L"CacheIsPowerProtected"
406*3088717bSVictor Perevertkin 
407*3088717bSVictor Perevertkin 
408*3088717bSVictor Perevertkin #define FUNCTIONAL_EXTENSION_SIZE sizeof(FUNCTIONAL_DEVICE_EXTENSION) + sizeof(DISK_DATA)
409*3088717bSVictor Perevertkin 
410*3088717bSVictor Perevertkin #define MODE_DATA_SIZE      192
411*3088717bSVictor Perevertkin #define VALUE_BUFFER_SIZE  2048
412*3088717bSVictor Perevertkin #define SCSI_DISK_TIMEOUT    10
413*3088717bSVictor Perevertkin #define PARTITION0_LIST_SIZE  4
414*3088717bSVictor Perevertkin 
415*3088717bSVictor Perevertkin #define MAX_MEDIA_TYPES 4
416*3088717bSVictor Perevertkin typedef struct _DISK_MEDIA_TYPES_LIST {
417*3088717bSVictor Perevertkin     PCCHAR VendorId;
418*3088717bSVictor Perevertkin     PCCHAR ProductId;
419*3088717bSVictor Perevertkin     PCCHAR Revision;
420*3088717bSVictor Perevertkin     const ULONG NumberOfTypes;
421*3088717bSVictor Perevertkin     const ULONG NumberOfSides;
422*3088717bSVictor Perevertkin     const STORAGE_MEDIA_TYPE MediaTypes[MAX_MEDIA_TYPES];
423*3088717bSVictor Perevertkin } DISK_MEDIA_TYPES_LIST, *PDISK_MEDIA_TYPES_LIST;
424*3088717bSVictor Perevertkin 
425*3088717bSVictor Perevertkin //
426*3088717bSVictor Perevertkin // WMI reregistration structures used for reregister work item
427*3088717bSVictor Perevertkin //
428*3088717bSVictor Perevertkin typedef struct
429*3088717bSVictor Perevertkin {
430*3088717bSVictor Perevertkin     SINGLE_LIST_ENTRY Next;
431*3088717bSVictor Perevertkin     PDEVICE_OBJECT DeviceObject;
432*3088717bSVictor Perevertkin     PIRP Irp;
433*3088717bSVictor Perevertkin } DISKREREGREQUEST, *PDISKREREGREQUEST;
434*3088717bSVictor Perevertkin 
435*3088717bSVictor Perevertkin #define MAX_SECTORS_PER_VERIFY              0x100
436*3088717bSVictor Perevertkin 
437*3088717bSVictor Perevertkin //
438*3088717bSVictor Perevertkin // This is based off 100ns units
439*3088717bSVictor Perevertkin //
440*3088717bSVictor Perevertkin #define ONE_MILLI_SECOND   ((ULONGLONG)10 * 1000)
441*3088717bSVictor Perevertkin 
442*3088717bSVictor Perevertkin //
443*3088717bSVictor Perevertkin // Context for the work-item
444*3088717bSVictor Perevertkin //
445*3088717bSVictor Perevertkin typedef struct _DISK_VERIFY_WORKITEM_CONTEXT
446*3088717bSVictor Perevertkin {
447*3088717bSVictor Perevertkin     PIRP Irp;
448*3088717bSVictor Perevertkin     PSCSI_REQUEST_BLOCK Srb;
449*3088717bSVictor Perevertkin     PIO_WORKITEM WorkItem;
450*3088717bSVictor Perevertkin 
451*3088717bSVictor Perevertkin } DISK_VERIFY_WORKITEM_CONTEXT, *PDISK_VERIFY_WORKITEM_CONTEXT;
452*3088717bSVictor Perevertkin 
453*3088717bSVictor Perevertkin //
454*3088717bSVictor Perevertkin // Poll for Failure Prediction every hour
455*3088717bSVictor Perevertkin //
456*3088717bSVictor Perevertkin #define DISK_DEFAULT_FAILURE_POLLING_PERIOD 1 * 60 * 60
457*3088717bSVictor Perevertkin 
458*3088717bSVictor Perevertkin #define CHECK_IRQL()                                    \
459*3088717bSVictor Perevertkin     if (KeGetCurrentIrql() >= DISPATCH_LEVEL) {         \
460*3088717bSVictor Perevertkin         NT_ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);    \
461*3088717bSVictor Perevertkin         return STATUS_INVALID_LEVEL;                    \
462*3088717bSVictor Perevertkin     }
463*3088717bSVictor Perevertkin 
464*3088717bSVictor Perevertkin //
465*3088717bSVictor Perevertkin // Static global lookup tables.
466*3088717bSVictor Perevertkin //
467*3088717bSVictor Perevertkin 
468*3088717bSVictor Perevertkin extern CLASSPNP_SCAN_FOR_SPECIAL_INFO DiskBadControllers[];
469*3088717bSVictor Perevertkin extern const DISK_MEDIA_TYPES_LIST DiskMediaTypes[];
470*3088717bSVictor Perevertkin extern const DISK_MEDIA_TYPES_LIST DiskMediaTypesExclude[];
471*3088717bSVictor Perevertkin 
472*3088717bSVictor Perevertkin #if defined(__REACTOS__) && defined(_MSC_VER)
473*3088717bSVictor Perevertkin # pragma section("PAGECONS", read)
474*3088717bSVictor Perevertkin # pragma section("PAGEDATA", read,write)
475*3088717bSVictor Perevertkin #endif
476*3088717bSVictor Perevertkin //
477*3088717bSVictor Perevertkin // Macros
478*3088717bSVictor Perevertkin //
479*3088717bSVictor Perevertkin 
480*3088717bSVictor Perevertkin //
481*3088717bSVictor Perevertkin // Routine prototypes.
482*3088717bSVictor Perevertkin //
483*3088717bSVictor Perevertkin 
484*3088717bSVictor Perevertkin 
485*3088717bSVictor Perevertkin DRIVER_INITIALIZE DriverEntry;
486*3088717bSVictor Perevertkin 
487*3088717bSVictor Perevertkin VOID
488*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
489*3088717bSVictor Perevertkin DiskUnload(
490*3088717bSVictor Perevertkin     IN PDRIVER_OBJECT DriverObject
491*3088717bSVictor Perevertkin     );
492*3088717bSVictor Perevertkin 
493*3088717bSVictor Perevertkin NTSTATUS
494*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
495*3088717bSVictor Perevertkin DiskAddDevice(
496*3088717bSVictor Perevertkin     IN PDRIVER_OBJECT DriverObject,
497*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT Pdo
498*3088717bSVictor Perevertkin     );
499*3088717bSVictor Perevertkin 
500*3088717bSVictor Perevertkin NTSTATUS
501*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
502*3088717bSVictor Perevertkin DiskInitFdo(
503*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT Fdo
504*3088717bSVictor Perevertkin     );
505*3088717bSVictor Perevertkin 
506*3088717bSVictor Perevertkin NTSTATUS
507*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
508*3088717bSVictor Perevertkin DiskStartFdo(
509*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT Fdo
510*3088717bSVictor Perevertkin     );
511*3088717bSVictor Perevertkin 
512*3088717bSVictor Perevertkin NTSTATUS
513*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
514*3088717bSVictor Perevertkin DiskStopDevice(
515*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
516*3088717bSVictor Perevertkin     IN UCHAR Type
517*3088717bSVictor Perevertkin     );
518*3088717bSVictor Perevertkin 
519*3088717bSVictor Perevertkin NTSTATUS
520*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
521*3088717bSVictor Perevertkin DiskRemoveDevice(
522*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
523*3088717bSVictor Perevertkin     IN UCHAR Type
524*3088717bSVictor Perevertkin     );
525*3088717bSVictor Perevertkin 
526*3088717bSVictor Perevertkin NTSTATUS
527*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
528*3088717bSVictor Perevertkin DiskReadWriteVerification(
529*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
530*3088717bSVictor Perevertkin     IN PIRP Irp
531*3088717bSVictor Perevertkin     );
532*3088717bSVictor Perevertkin 
533*3088717bSVictor Perevertkin NTSTATUS
534*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
535*3088717bSVictor Perevertkin DiskDeviceControl(
536*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
537*3088717bSVictor Perevertkin     IN PIRP Irp
538*3088717bSVictor Perevertkin     );
539*3088717bSVictor Perevertkin 
540*3088717bSVictor Perevertkin VOID
541*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
542*3088717bSVictor Perevertkin DiskFdoProcessError(
543*3088717bSVictor Perevertkin     PDEVICE_OBJECT DeviceObject,
544*3088717bSVictor Perevertkin     PSCSI_REQUEST_BLOCK Srb,
545*3088717bSVictor Perevertkin     NTSTATUS *Status,
546*3088717bSVictor Perevertkin     BOOLEAN *Retry
547*3088717bSVictor Perevertkin     );
548*3088717bSVictor Perevertkin 
549*3088717bSVictor Perevertkin NTSTATUS
550*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
551*3088717bSVictor Perevertkin DiskShutdownFlush(
552*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
553*3088717bSVictor Perevertkin     IN PIRP Irp
554*3088717bSVictor Perevertkin     );
555*3088717bSVictor Perevertkin 
556*3088717bSVictor Perevertkin NTSTATUS
557*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
558*3088717bSVictor Perevertkin DiskGetCacheInformation(
559*3088717bSVictor Perevertkin     IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
560*3088717bSVictor Perevertkin     IN PDISK_CACHE_INFORMATION CacheInfo
561*3088717bSVictor Perevertkin     );
562*3088717bSVictor Perevertkin 
563*3088717bSVictor Perevertkin NTSTATUS
564*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
565*3088717bSVictor Perevertkin DiskSetCacheInformation(
566*3088717bSVictor Perevertkin     IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
567*3088717bSVictor Perevertkin     IN PDISK_CACHE_INFORMATION CacheInfo
568*3088717bSVictor Perevertkin     );
569*3088717bSVictor Perevertkin 
570*3088717bSVictor Perevertkin VOID
571*3088717bSVictor Perevertkin DiskLogCacheInformation(
572*3088717bSVictor Perevertkin     IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
573*3088717bSVictor Perevertkin     IN PDISK_CACHE_INFORMATION CacheInfo,
574*3088717bSVictor Perevertkin     IN NTSTATUS Status
575*3088717bSVictor Perevertkin     );
576*3088717bSVictor Perevertkin 
577*3088717bSVictor Perevertkin NTSTATUS
578*3088717bSVictor Perevertkin DiskIoctlGetCacheSetting(
579*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
580*3088717bSVictor Perevertkin     IN PIRP Irp
581*3088717bSVictor Perevertkin     );
582*3088717bSVictor Perevertkin 
583*3088717bSVictor Perevertkin NTSTATUS
584*3088717bSVictor Perevertkin DiskIoctlSetCacheSetting(
585*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
586*3088717bSVictor Perevertkin     IN PIRP Irp
587*3088717bSVictor Perevertkin     );
588*3088717bSVictor Perevertkin 
589*3088717bSVictor Perevertkin IO_WORKITEM_ROUTINE DisableWriteCache;
590*3088717bSVictor Perevertkin 
591*3088717bSVictor Perevertkin IO_WORKITEM_ROUTINE DiskIoctlVerifyThread;
592*3088717bSVictor Perevertkin 
593*3088717bSVictor Perevertkin VOID
594*3088717bSVictor Perevertkin DiskFlushDispatch(
595*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT Fdo,
596*3088717bSVictor Perevertkin     IN PDISK_GROUP_CONTEXT FlushContext
597*3088717bSVictor Perevertkin     );
598*3088717bSVictor Perevertkin 
599*3088717bSVictor Perevertkin IO_COMPLETION_ROUTINE DiskFlushComplete;
600*3088717bSVictor Perevertkin 
601*3088717bSVictor Perevertkin 
602*3088717bSVictor Perevertkin NTSTATUS
603*3088717bSVictor Perevertkin DiskModeSelect(
604*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
605*3088717bSVictor Perevertkin     _In_reads_bytes_(Length) PCHAR ModeSelectBuffer,
606*3088717bSVictor Perevertkin     IN ULONG Length,
607*3088717bSVictor Perevertkin     IN BOOLEAN SavePage
608*3088717bSVictor Perevertkin     );
609*3088717bSVictor Perevertkin 
610*3088717bSVictor Perevertkin //
611*3088717bSVictor Perevertkin // We need to validate that the self test subcommand is valid and
612*3088717bSVictor Perevertkin // appropriate. Right now we allow subcommands 0, 1 and 2 which are non
613*3088717bSVictor Perevertkin // captive mode tests. Once we figure out a way to know if it is safe to
614*3088717bSVictor Perevertkin // run a captive test then we can allow captive mode tests. Also if the
615*3088717bSVictor Perevertkin // atapi 5 spec is ever updated to denote that bit 7 is the captive
616*3088717bSVictor Perevertkin // mode bit, we can allow any request that does not have bit 7 set. Until
617*3088717bSVictor Perevertkin // that is done we want to be sure
618*3088717bSVictor Perevertkin //
619*3088717bSVictor Perevertkin #define DiskIsValidSmartSelfTest(Subcommand) \
620*3088717bSVictor Perevertkin     ( ((Subcommand) == SMART_OFFLINE_ROUTINE_OFFLINE) || \
621*3088717bSVictor Perevertkin       ((Subcommand) == SMART_SHORT_SELFTEST_OFFLINE) || \
622*3088717bSVictor Perevertkin       ((Subcommand) == SMART_EXTENDED_SELFTEST_OFFLINE) )
623*3088717bSVictor Perevertkin 
624*3088717bSVictor Perevertkin 
625*3088717bSVictor Perevertkin NTSTATUS
626*3088717bSVictor Perevertkin DiskPerformSmartCommand(
627*3088717bSVictor Perevertkin     IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
628*3088717bSVictor Perevertkin     IN ULONG SrbControlCode,
629*3088717bSVictor Perevertkin     IN UCHAR Command,
630*3088717bSVictor Perevertkin     IN UCHAR Feature,
631*3088717bSVictor Perevertkin     IN UCHAR SectorCount,
632*3088717bSVictor Perevertkin     IN UCHAR SectorNumber,
633*3088717bSVictor Perevertkin     IN OUT PSRB_IO_CONTROL SrbControl,
634*3088717bSVictor Perevertkin     OUT PULONG BufferSize
635*3088717bSVictor Perevertkin     );
636*3088717bSVictor Perevertkin 
637*3088717bSVictor Perevertkin NTSTATUS
638*3088717bSVictor Perevertkin DiskGetInfoExceptionInformation(
639*3088717bSVictor Perevertkin     IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
640*3088717bSVictor Perevertkin     OUT PMODE_INFO_EXCEPTIONS ReturnPageData
641*3088717bSVictor Perevertkin     );
642*3088717bSVictor Perevertkin 
643*3088717bSVictor Perevertkin NTSTATUS
644*3088717bSVictor Perevertkin DiskSetInfoExceptionInformation(
645*3088717bSVictor Perevertkin     IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
646*3088717bSVictor Perevertkin     IN PMODE_INFO_EXCEPTIONS PageData
647*3088717bSVictor Perevertkin     );
648*3088717bSVictor Perevertkin 
649*3088717bSVictor Perevertkin #if (NTDDI_VERSION >= NTDDI_WINBLUE)
650*3088717bSVictor Perevertkin NTSTATUS
651*3088717bSVictor Perevertkin DiskGetModePage(
652*3088717bSVictor Perevertkin     _In_ PDEVICE_OBJECT Fdo,
653*3088717bSVictor Perevertkin     _In_ UCHAR PageMode,
654*3088717bSVictor Perevertkin     _In_ UCHAR PageControl,
655*3088717bSVictor Perevertkin     _In_ PMODE_PARAMETER_HEADER ModeData,
656*3088717bSVictor Perevertkin     _Inout_ PULONG ModeDataSize,
657*3088717bSVictor Perevertkin     _Out_ PVOID* PageData
658*3088717bSVictor Perevertkin     );
659*3088717bSVictor Perevertkin 
660*3088717bSVictor Perevertkin NTSTATUS
661*3088717bSVictor Perevertkin DiskEnableInfoExceptions(
662*3088717bSVictor Perevertkin     _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
663*3088717bSVictor Perevertkin     _In_ BOOLEAN Enable
664*3088717bSVictor Perevertkin     );
665*3088717bSVictor Perevertkin #endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
666*3088717bSVictor Perevertkin 
667*3088717bSVictor Perevertkin NTSTATUS
668*3088717bSVictor Perevertkin DiskDetectFailurePrediction(
669*3088717bSVictor Perevertkin     PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
670*3088717bSVictor Perevertkin     PFAILURE_PREDICTION_METHOD FailurePredictCapability,
671*3088717bSVictor Perevertkin     BOOLEAN ScsiAddressAvailable
672*3088717bSVictor Perevertkin     );
673*3088717bSVictor Perevertkin 
674*3088717bSVictor Perevertkin NTSTATUS
675*3088717bSVictor Perevertkin DiskCreateFdo(
676*3088717bSVictor Perevertkin     IN PDRIVER_OBJECT DriverObject,
677*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT LowerDeviceObject,
678*3088717bSVictor Perevertkin     IN PULONG DeviceCount,
679*3088717bSVictor Perevertkin     IN BOOLEAN DasdAccessOnly
680*3088717bSVictor Perevertkin     );
681*3088717bSVictor Perevertkin 
682*3088717bSVictor Perevertkin VOID
683*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
684*3088717bSVictor Perevertkin DiskSetSpecialHacks(
685*3088717bSVictor Perevertkin     IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
686*3088717bSVictor Perevertkin     IN ULONG_PTR Data
687*3088717bSVictor Perevertkin     );
688*3088717bSVictor Perevertkin 
689*3088717bSVictor Perevertkin VOID
690*3088717bSVictor Perevertkin ResetBus(
691*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject
692*3088717bSVictor Perevertkin     );
693*3088717bSVictor Perevertkin 
694*3088717bSVictor Perevertkin NTSTATUS
695*3088717bSVictor Perevertkin DiskGenerateDeviceName(
696*3088717bSVictor Perevertkin     IN ULONG DeviceNumber,
697*3088717bSVictor Perevertkin     OUT PCCHAR *RawName
698*3088717bSVictor Perevertkin     );
699*3088717bSVictor Perevertkin 
700*3088717bSVictor Perevertkin VOID
701*3088717bSVictor Perevertkin DiskCreateSymbolicLinks(
702*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject
703*3088717bSVictor Perevertkin     );
704*3088717bSVictor Perevertkin 
705*3088717bSVictor Perevertkin VOID
706*3088717bSVictor Perevertkin DiskDeleteSymbolicLinks(
707*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject
708*3088717bSVictor Perevertkin     );
709*3088717bSVictor Perevertkin 
710*3088717bSVictor Perevertkin 
711*3088717bSVictor Perevertkin NTSTATUS
712*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
713*3088717bSVictor Perevertkin DiskFdoQueryWmiRegInfo(
714*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
715*3088717bSVictor Perevertkin     OUT ULONG *RegFlags,
716*3088717bSVictor Perevertkin     OUT PUNICODE_STRING InstanceName
717*3088717bSVictor Perevertkin     );
718*3088717bSVictor Perevertkin 
719*3088717bSVictor Perevertkin NTSTATUS
720*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
721*3088717bSVictor Perevertkin DiskFdoQueryWmiRegInfoEx(
722*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
723*3088717bSVictor Perevertkin     OUT ULONG *RegFlags,
724*3088717bSVictor Perevertkin     OUT PUNICODE_STRING InstanceName,
725*3088717bSVictor Perevertkin     OUT PUNICODE_STRING MofName
726*3088717bSVictor Perevertkin     );
727*3088717bSVictor Perevertkin 
728*3088717bSVictor Perevertkin NTSTATUS
729*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
730*3088717bSVictor Perevertkin DiskFdoQueryWmiDataBlock(
731*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
732*3088717bSVictor Perevertkin     IN PIRP Irp,
733*3088717bSVictor Perevertkin     IN ULONG GuidIndex,
734*3088717bSVictor Perevertkin     IN ULONG BufferAvail,
735*3088717bSVictor Perevertkin     OUT PUCHAR Buffer
736*3088717bSVictor Perevertkin     );
737*3088717bSVictor Perevertkin 
738*3088717bSVictor Perevertkin NTSTATUS
739*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
740*3088717bSVictor Perevertkin DiskFdoSetWmiDataBlock(
741*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
742*3088717bSVictor Perevertkin     IN PIRP Irp,
743*3088717bSVictor Perevertkin     IN ULONG GuidIndex,
744*3088717bSVictor Perevertkin     IN ULONG BufferSize,
745*3088717bSVictor Perevertkin     IN PUCHAR Buffer
746*3088717bSVictor Perevertkin     );
747*3088717bSVictor Perevertkin 
748*3088717bSVictor Perevertkin NTSTATUS
749*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
750*3088717bSVictor Perevertkin DiskFdoSetWmiDataItem(
751*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
752*3088717bSVictor Perevertkin     IN PIRP Irp,
753*3088717bSVictor Perevertkin     IN ULONG GuidIndex,
754*3088717bSVictor Perevertkin     IN ULONG DataItemId,
755*3088717bSVictor Perevertkin     IN ULONG BufferSize,
756*3088717bSVictor Perevertkin     IN PUCHAR Buffer
757*3088717bSVictor Perevertkin     );
758*3088717bSVictor Perevertkin 
759*3088717bSVictor Perevertkin NTSTATUS
760*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
761*3088717bSVictor Perevertkin DiskFdoExecuteWmiMethod(
762*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
763*3088717bSVictor Perevertkin     IN PIRP Irp,
764*3088717bSVictor Perevertkin     IN ULONG GuidIndex,
765*3088717bSVictor Perevertkin     IN ULONG MethodId,
766*3088717bSVictor Perevertkin     IN ULONG InBufferSize,
767*3088717bSVictor Perevertkin     IN ULONG OutBufferSize,
768*3088717bSVictor Perevertkin     IN PUCHAR Buffer
769*3088717bSVictor Perevertkin     );
770*3088717bSVictor Perevertkin 
771*3088717bSVictor Perevertkin NTSTATUS
772*3088717bSVictor Perevertkin NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
773*3088717bSVictor Perevertkin DiskWmiFunctionControl(
774*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
775*3088717bSVictor Perevertkin     IN PIRP Irp,
776*3088717bSVictor Perevertkin     IN ULONG GuidIndex,
777*3088717bSVictor Perevertkin     IN CLASSENABLEDISABLEFUNCTION Function,
778*3088717bSVictor Perevertkin     IN BOOLEAN Enable
779*3088717bSVictor Perevertkin     );
780*3088717bSVictor Perevertkin 
781*3088717bSVictor Perevertkin NTSTATUS
782*3088717bSVictor Perevertkin DiskReadFailurePredictStatus(
783*3088717bSVictor Perevertkin     PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
784*3088717bSVictor Perevertkin     PSTORAGE_FAILURE_PREDICT_STATUS DiskSmartStatus
785*3088717bSVictor Perevertkin     );
786*3088717bSVictor Perevertkin 
787*3088717bSVictor Perevertkin NTSTATUS
788*3088717bSVictor Perevertkin DiskReadFailurePredictData(
789*3088717bSVictor Perevertkin     PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
790*3088717bSVictor Perevertkin     PSTORAGE_FAILURE_PREDICT_DATA DiskSmartData
791*3088717bSVictor Perevertkin     );
792*3088717bSVictor Perevertkin 
793*3088717bSVictor Perevertkin NTSTATUS
794*3088717bSVictor Perevertkin DiskEnableDisableFailurePrediction(
795*3088717bSVictor Perevertkin     PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
796*3088717bSVictor Perevertkin     BOOLEAN Enable
797*3088717bSVictor Perevertkin     );
798*3088717bSVictor Perevertkin 
799*3088717bSVictor Perevertkin NTSTATUS
800*3088717bSVictor Perevertkin DiskEnableDisableFailurePredictPolling(
801*3088717bSVictor Perevertkin     PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
802*3088717bSVictor Perevertkin     BOOLEAN Enable,
803*3088717bSVictor Perevertkin     ULONG PollTimeInSeconds
804*3088717bSVictor Perevertkin     );
805*3088717bSVictor Perevertkin 
806*3088717bSVictor Perevertkin NTSTATUS DiskInitializeReregistration(
807*3088717bSVictor Perevertkin     VOID
808*3088717bSVictor Perevertkin     );
809*3088717bSVictor Perevertkin 
810*3088717bSVictor Perevertkin extern GUIDREGINFO DiskWmiFdoGuidList[];
811*3088717bSVictor Perevertkin 
812*3088717bSVictor Perevertkin #if defined(_X86_) || defined(_AMD64_)
813*3088717bSVictor Perevertkin NTSTATUS
814*3088717bSVictor Perevertkin DiskReadDriveCapacity(
815*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT Fdo
816*3088717bSVictor Perevertkin     );
817*3088717bSVictor Perevertkin #else
818*3088717bSVictor Perevertkin #define DiskReadDriveCapacity(Fdo)  ClassReadDriveCapacity(Fdo)
819*3088717bSVictor Perevertkin #endif
820*3088717bSVictor Perevertkin 
821*3088717bSVictor Perevertkin 
822*3088717bSVictor Perevertkin #if defined(_X86_) || defined(_AMD64_)
823*3088717bSVictor Perevertkin 
824*3088717bSVictor Perevertkin NTSTATUS
825*3088717bSVictor Perevertkin DiskSaveDetectInfo(
826*3088717bSVictor Perevertkin     PDRIVER_OBJECT DriverObject
827*3088717bSVictor Perevertkin     );
828*3088717bSVictor Perevertkin 
829*3088717bSVictor Perevertkin VOID
830*3088717bSVictor Perevertkin DiskCleanupDetectInfo(
831*3088717bSVictor Perevertkin     IN PDRIVER_OBJECT DriverObject
832*3088717bSVictor Perevertkin     );
833*3088717bSVictor Perevertkin 
834*3088717bSVictor Perevertkin VOID
835*3088717bSVictor Perevertkin DiskDriverReinitialization (
836*3088717bSVictor Perevertkin     IN PDRIVER_OBJECT DriverObject,
837*3088717bSVictor Perevertkin     IN PVOID Nothing,
838*3088717bSVictor Perevertkin     IN ULONG Count
839*3088717bSVictor Perevertkin     );
840*3088717bSVictor Perevertkin 
841*3088717bSVictor Perevertkin #endif
842*3088717bSVictor Perevertkin 
843*3088717bSVictor Perevertkin #if defined(_X86_) || defined(_AMD64_)
844*3088717bSVictor Perevertkin NTSTATUS
845*3088717bSVictor Perevertkin DiskGetDetectInfo(
846*3088717bSVictor Perevertkin     IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
847*3088717bSVictor Perevertkin     OUT PDISK_DETECTION_INFO DetectInfo
848*3088717bSVictor Perevertkin     );
849*3088717bSVictor Perevertkin 
850*3088717bSVictor Perevertkin NTSTATUS
851*3088717bSVictor Perevertkin DiskReadSignature(
852*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT Fdo
853*3088717bSVictor Perevertkin     );
854*3088717bSVictor Perevertkin 
855*3088717bSVictor Perevertkin BOOLEAN
856*3088717bSVictor Perevertkin DiskIsNT4Geometry(
857*3088717bSVictor Perevertkin     IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
858*3088717bSVictor Perevertkin     );
859*3088717bSVictor Perevertkin 
860*3088717bSVictor Perevertkin #else
861*3088717bSVictor Perevertkin #define DiskGetDetectInfo(FdoExtension, DetectInfo) (STATUS_UNSUCCESSFUL)
862*3088717bSVictor Perevertkin #endif
863*3088717bSVictor Perevertkin 
864*3088717bSVictor Perevertkin 
865*3088717bSVictor Perevertkin #define DiskHashGuid(Guid) (((PULONG) &Guid)[0] ^ ((PULONG) &Guid)[0] ^ ((PULONG) &Guid)[0] ^ ((PULONG) &Guid)[0])
866*3088717bSVictor Perevertkin 
867*3088717bSVictor Perevertkin 
868*3088717bSVictor Perevertkin NTSTATUS
869*3088717bSVictor Perevertkin DiskDetermineMediaTypes(
870*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT Fdo,
871*3088717bSVictor Perevertkin     IN PIRP     Irp,
872*3088717bSVictor Perevertkin     IN UCHAR    MediumType,
873*3088717bSVictor Perevertkin     IN UCHAR    DensityCode,
874*3088717bSVictor Perevertkin     IN BOOLEAN  MediaPresent,
875*3088717bSVictor Perevertkin     IN BOOLEAN  IsWritable
876*3088717bSVictor Perevertkin     );
877*3088717bSVictor Perevertkin 
878*3088717bSVictor Perevertkin NTSTATUS
879*3088717bSVictor Perevertkin DiskIoctlGetLengthInfo(
880*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
881*3088717bSVictor Perevertkin     IN PIRP Irp
882*3088717bSVictor Perevertkin     );
883*3088717bSVictor Perevertkin 
884*3088717bSVictor Perevertkin NTSTATUS
885*3088717bSVictor Perevertkin DiskIoctlGetDriveGeometry(
886*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
887*3088717bSVictor Perevertkin     IN OUT PIRP Irp
888*3088717bSVictor Perevertkin     );
889*3088717bSVictor Perevertkin 
890*3088717bSVictor Perevertkin NTSTATUS
891*3088717bSVictor Perevertkin DiskIoctlGetDriveGeometryEx(
892*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
893*3088717bSVictor Perevertkin     IN PIRP Irp
894*3088717bSVictor Perevertkin     );
895*3088717bSVictor Perevertkin 
896*3088717bSVictor Perevertkin NTSTATUS
897*3088717bSVictor Perevertkin DiskIoctlGetCacheInformation(
898*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
899*3088717bSVictor Perevertkin     IN OUT PIRP Irp
900*3088717bSVictor Perevertkin     );
901*3088717bSVictor Perevertkin 
902*3088717bSVictor Perevertkin NTSTATUS
903*3088717bSVictor Perevertkin DiskIoctlSetCacheInformation(
904*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
905*3088717bSVictor Perevertkin     IN OUT PIRP Irp
906*3088717bSVictor Perevertkin     );
907*3088717bSVictor Perevertkin 
908*3088717bSVictor Perevertkin NTSTATUS
909*3088717bSVictor Perevertkin DiskIoctlGetMediaTypesEx(
910*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
911*3088717bSVictor Perevertkin     IN OUT PIRP Irp
912*3088717bSVictor Perevertkin     );
913*3088717bSVictor Perevertkin 
914*3088717bSVictor Perevertkin NTSTATUS
915*3088717bSVictor Perevertkin DiskIoctlPredictFailure(
916*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
917*3088717bSVictor Perevertkin     IN OUT PIRP Irp
918*3088717bSVictor Perevertkin     );
919*3088717bSVictor Perevertkin 
920*3088717bSVictor Perevertkin NTSTATUS
921*3088717bSVictor Perevertkin DiskIoctlEnableFailurePrediction(
922*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
923*3088717bSVictor Perevertkin     IN OUT PIRP Irp
924*3088717bSVictor Perevertkin     );
925*3088717bSVictor Perevertkin 
926*3088717bSVictor Perevertkin NTSTATUS
927*3088717bSVictor Perevertkin DiskIoctlVerify(
928*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
929*3088717bSVictor Perevertkin     IN OUT PIRP Irp
930*3088717bSVictor Perevertkin     );
931*3088717bSVictor Perevertkin 
932*3088717bSVictor Perevertkin NTSTATUS
933*3088717bSVictor Perevertkin DiskIoctlReassignBlocks(
934*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
935*3088717bSVictor Perevertkin     IN OUT PIRP Irp
936*3088717bSVictor Perevertkin     );
937*3088717bSVictor Perevertkin 
938*3088717bSVictor Perevertkin NTSTATUS
939*3088717bSVictor Perevertkin DiskIoctlReassignBlocksEx(
940*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
941*3088717bSVictor Perevertkin     IN OUT PIRP Irp
942*3088717bSVictor Perevertkin     );
943*3088717bSVictor Perevertkin 
944*3088717bSVictor Perevertkin NTSTATUS
945*3088717bSVictor Perevertkin DiskIoctlIsWritable(
946*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
947*3088717bSVictor Perevertkin     IN OUT PIRP Irp
948*3088717bSVictor Perevertkin     );
949*3088717bSVictor Perevertkin 
950*3088717bSVictor Perevertkin NTSTATUS
951*3088717bSVictor Perevertkin DiskIoctlSetVerify(
952*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
953*3088717bSVictor Perevertkin     IN OUT PIRP Irp
954*3088717bSVictor Perevertkin     );
955*3088717bSVictor Perevertkin 
956*3088717bSVictor Perevertkin NTSTATUS
957*3088717bSVictor Perevertkin DiskIoctlClearVerify(
958*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
959*3088717bSVictor Perevertkin     IN OUT PIRP Irp
960*3088717bSVictor Perevertkin     );
961*3088717bSVictor Perevertkin 
962*3088717bSVictor Perevertkin NTSTATUS
963*3088717bSVictor Perevertkin DiskIoctlUpdateDriveSize(
964*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
965*3088717bSVictor Perevertkin     IN OUT PIRP Irp
966*3088717bSVictor Perevertkin     );
967*3088717bSVictor Perevertkin 
968*3088717bSVictor Perevertkin NTSTATUS
969*3088717bSVictor Perevertkin DiskIoctlGetVolumeDiskExtents(
970*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
971*3088717bSVictor Perevertkin     IN OUT PIRP Irp
972*3088717bSVictor Perevertkin     );
973*3088717bSVictor Perevertkin 
974*3088717bSVictor Perevertkin NTSTATUS
975*3088717bSVictor Perevertkin DiskIoctlSmartGetVersion(
976*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
977*3088717bSVictor Perevertkin     IN OUT PIRP Irp
978*3088717bSVictor Perevertkin     );
979*3088717bSVictor Perevertkin 
980*3088717bSVictor Perevertkin NTSTATUS
981*3088717bSVictor Perevertkin DiskIoctlSmartReceiveDriveData(
982*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
983*3088717bSVictor Perevertkin     IN OUT PIRP Irp
984*3088717bSVictor Perevertkin     );
985*3088717bSVictor Perevertkin 
986*3088717bSVictor Perevertkin NTSTATUS
987*3088717bSVictor Perevertkin DiskIoctlSmartSendDriveCommand(
988*3088717bSVictor Perevertkin     IN PDEVICE_OBJECT DeviceObject,
989*3088717bSVictor Perevertkin     IN OUT PIRP Irp
990*3088717bSVictor Perevertkin     );
991*3088717bSVictor Perevertkin 
992*3088717bSVictor Perevertkin FORCEINLINE // __REACTOS__
993*3088717bSVictor Perevertkin PCDB
GetSrbScsiData(_In_ PSTORAGE_REQUEST_BLOCK SrbEx,_In_opt_ PUCHAR CdbLength8,_In_opt_ PULONG CdbLength32,_In_opt_ PUCHAR ScsiStatus,_In_opt_ PVOID * SenseInfoBuffer,_In_opt_ PUCHAR SenseInfoBufferLength)994*3088717bSVictor Perevertkin GetSrbScsiData(
995*3088717bSVictor Perevertkin     _In_ PSTORAGE_REQUEST_BLOCK SrbEx,
996*3088717bSVictor Perevertkin     _In_opt_ PUCHAR CdbLength8,
997*3088717bSVictor Perevertkin     _In_opt_ PULONG CdbLength32,
998*3088717bSVictor Perevertkin     _In_opt_ PUCHAR ScsiStatus,
999*3088717bSVictor Perevertkin     _In_opt_ PVOID *SenseInfoBuffer,
1000*3088717bSVictor Perevertkin     _In_opt_ PUCHAR SenseInfoBufferLength
1001*3088717bSVictor Perevertkin     )
1002*3088717bSVictor Perevertkin /*++
1003*3088717bSVictor Perevertkin 
1004*3088717bSVictor Perevertkin Routine Description:
1005*3088717bSVictor Perevertkin 
1006*3088717bSVictor Perevertkin     Helper function to retrieve SCSI related fields from an extended SRB. If SRB is
1007*3088717bSVictor Perevertkin     not a SRB_FUNCTION_EXECUTE_SCSI or not an extended SRB, default values will be returned.
1008*3088717bSVictor Perevertkin 
1009*3088717bSVictor Perevertkin Arguments:
1010*3088717bSVictor Perevertkin 
1011*3088717bSVictor Perevertkin     SrbEx - Pointer to extended SRB.
1012*3088717bSVictor Perevertkin 
1013*3088717bSVictor Perevertkin     CdbLength8 - Pointer to buffer to hold CdbLength field value for
1014*3088717bSVictor Perevertkin                  SRBEX_DATA_SCSI_CDB16 or SRBEX_DATA_SCSI_CDB32
1015*3088717bSVictor Perevertkin 
1016*3088717bSVictor Perevertkin     CdbLength32 - Pointer to buffer to hold CdbLength field value for
1017*3088717bSVictor Perevertkin                   SRBEX_DATA_SCSI_CDB_VAR
1018*3088717bSVictor Perevertkin 
1019*3088717bSVictor Perevertkin     ScsiStatus - Pointer to buffer to hold ScsiStatus field value.
1020*3088717bSVictor Perevertkin 
1021*3088717bSVictor Perevertkin     SenseInfoBuffer - Pointer to buffer to hold SenseInfoBuffer value.
1022*3088717bSVictor Perevertkin 
1023*3088717bSVictor Perevertkin     SenseInfoBufferLength - Pointer to buffer to hold SenseInfoBufferLength value.
1024*3088717bSVictor Perevertkin 
1025*3088717bSVictor Perevertkin Return Value:
1026*3088717bSVictor Perevertkin 
1027*3088717bSVictor Perevertkin     Pointer to Cdb field or NULL if SRB is not a SRB_FUNCTION_EXECUTE_SCSI.
1028*3088717bSVictor Perevertkin 
1029*3088717bSVictor Perevertkin --*/
1030*3088717bSVictor Perevertkin {
1031*3088717bSVictor Perevertkin     PCDB Cdb = NULL;
1032*3088717bSVictor Perevertkin     ULONG i;
1033*3088717bSVictor Perevertkin     PSRBEX_DATA SrbExData = NULL;
1034*3088717bSVictor Perevertkin     BOOLEAN FoundEntry = FALSE;
1035*3088717bSVictor Perevertkin 
1036*3088717bSVictor Perevertkin     if ((SrbEx->Function == SRB_FUNCTION_STORAGE_REQUEST_BLOCK) &&
1037*3088717bSVictor Perevertkin         (SrbEx->SrbFunction == SRB_FUNCTION_EXECUTE_SCSI)) {
1038*3088717bSVictor Perevertkin         NT_ASSERT(SrbEx->NumSrbExData > 0);
1039*3088717bSVictor Perevertkin 
1040*3088717bSVictor Perevertkin         for (i = 0; i < SrbEx->NumSrbExData; i++) {
1041*3088717bSVictor Perevertkin 
1042*3088717bSVictor Perevertkin             // Skip any invalid offsets
1043*3088717bSVictor Perevertkin             if ((SrbEx->SrbExDataOffset[i] < sizeof(STORAGE_REQUEST_BLOCK)) ||
1044*3088717bSVictor Perevertkin                 (SrbEx->SrbExDataOffset[i] > SrbEx->SrbLength)){
1045*3088717bSVictor Perevertkin                 // Catch any invalid offsets
1046*3088717bSVictor Perevertkin                 NT_ASSERT(FALSE);
1047*3088717bSVictor Perevertkin                 continue;
1048*3088717bSVictor Perevertkin             }
1049*3088717bSVictor Perevertkin 
1050*3088717bSVictor Perevertkin             SrbExData = (PSRBEX_DATA)((PUCHAR)SrbEx + SrbEx->SrbExDataOffset[i]);
1051*3088717bSVictor Perevertkin 
1052*3088717bSVictor Perevertkin             switch (SrbExData->Type) {
1053*3088717bSVictor Perevertkin 
1054*3088717bSVictor Perevertkin                 case SrbExDataTypeScsiCdb16:
1055*3088717bSVictor Perevertkin                     if (SrbEx->SrbExDataOffset[i] + sizeof(SRBEX_DATA_SCSI_CDB16) <= SrbEx->SrbLength) {
1056*3088717bSVictor Perevertkin                         FoundEntry = TRUE;
1057*3088717bSVictor Perevertkin                         if (CdbLength8) {
1058*3088717bSVictor Perevertkin                             *CdbLength8 = ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->CdbLength;
1059*3088717bSVictor Perevertkin                         }
1060*3088717bSVictor Perevertkin 
1061*3088717bSVictor Perevertkin                         if (((PSRBEX_DATA_SCSI_CDB16) SrbExData)->CdbLength > 0) {
1062*3088717bSVictor Perevertkin                             Cdb = (PCDB)((PSRBEX_DATA_SCSI_CDB16) SrbExData)->Cdb;
1063*3088717bSVictor Perevertkin                         }
1064*3088717bSVictor Perevertkin 
1065*3088717bSVictor Perevertkin                         if (ScsiStatus) {
1066*3088717bSVictor Perevertkin                             *ScsiStatus =
1067*3088717bSVictor Perevertkin                                 ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->ScsiStatus;
1068*3088717bSVictor Perevertkin                         }
1069*3088717bSVictor Perevertkin 
1070*3088717bSVictor Perevertkin                         if (SenseInfoBuffer) {
1071*3088717bSVictor Perevertkin                             *SenseInfoBuffer =
1072*3088717bSVictor Perevertkin                                 ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->SenseInfoBuffer;
1073*3088717bSVictor Perevertkin                         }
1074*3088717bSVictor Perevertkin 
1075*3088717bSVictor Perevertkin                         if (SenseInfoBufferLength) {
1076*3088717bSVictor Perevertkin                             *SenseInfoBufferLength =
1077*3088717bSVictor Perevertkin                                 ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->SenseInfoBufferLength;
1078*3088717bSVictor Perevertkin                         }
1079*3088717bSVictor Perevertkin 
1080*3088717bSVictor Perevertkin                     } else {
1081*3088717bSVictor Perevertkin                         // Catch invalid offset
1082*3088717bSVictor Perevertkin                         NT_ASSERT(FALSE);
1083*3088717bSVictor Perevertkin                     }
1084*3088717bSVictor Perevertkin                     break;
1085*3088717bSVictor Perevertkin 
1086*3088717bSVictor Perevertkin                 case SrbExDataTypeScsiCdb32:
1087*3088717bSVictor Perevertkin                     if (SrbEx->SrbExDataOffset[i] + sizeof(SRBEX_DATA_SCSI_CDB32) <= SrbEx->SrbLength) {
1088*3088717bSVictor Perevertkin                         FoundEntry = TRUE;
1089*3088717bSVictor Perevertkin                         if (CdbLength8) {
1090*3088717bSVictor Perevertkin                             *CdbLength8 = ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->CdbLength;
1091*3088717bSVictor Perevertkin                         }
1092*3088717bSVictor Perevertkin 
1093*3088717bSVictor Perevertkin                         if (((PSRBEX_DATA_SCSI_CDB32) SrbExData)->CdbLength > 0) {
1094*3088717bSVictor Perevertkin                             Cdb = (PCDB)((PSRBEX_DATA_SCSI_CDB32) SrbExData)->Cdb;
1095*3088717bSVictor Perevertkin                         }
1096*3088717bSVictor Perevertkin 
1097*3088717bSVictor Perevertkin                         if (ScsiStatus) {
1098*3088717bSVictor Perevertkin                             *ScsiStatus =
1099*3088717bSVictor Perevertkin                                 ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->ScsiStatus;
1100*3088717bSVictor Perevertkin                         }
1101*3088717bSVictor Perevertkin 
1102*3088717bSVictor Perevertkin                         if (SenseInfoBuffer) {
1103*3088717bSVictor Perevertkin                             *SenseInfoBuffer =
1104*3088717bSVictor Perevertkin                                 ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->SenseInfoBuffer;
1105*3088717bSVictor Perevertkin                         }
1106*3088717bSVictor Perevertkin 
1107*3088717bSVictor Perevertkin                         if (SenseInfoBufferLength) {
1108*3088717bSVictor Perevertkin                             *SenseInfoBufferLength =
1109*3088717bSVictor Perevertkin                                 ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->SenseInfoBufferLength;
1110*3088717bSVictor Perevertkin                         }
1111*3088717bSVictor Perevertkin 
1112*3088717bSVictor Perevertkin                     } else {
1113*3088717bSVictor Perevertkin                         // Catch invalid offset
1114*3088717bSVictor Perevertkin                         NT_ASSERT(FALSE);
1115*3088717bSVictor Perevertkin                     }
1116*3088717bSVictor Perevertkin                     break;
1117*3088717bSVictor Perevertkin 
1118*3088717bSVictor Perevertkin                 case SrbExDataTypeScsiCdbVar:
1119*3088717bSVictor Perevertkin                     if (SrbEx->SrbExDataOffset[i] + sizeof(SRBEX_DATA_SCSI_CDB_VAR) <= SrbEx->SrbLength) {
1120*3088717bSVictor Perevertkin                         FoundEntry = TRUE;
1121*3088717bSVictor Perevertkin                         if (CdbLength32) {
1122*3088717bSVictor Perevertkin                             *CdbLength32 = ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->CdbLength;
1123*3088717bSVictor Perevertkin                         }
1124*3088717bSVictor Perevertkin 
1125*3088717bSVictor Perevertkin                         if (((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->CdbLength > 0) {
1126*3088717bSVictor Perevertkin                             Cdb = (PCDB)((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->Cdb;
1127*3088717bSVictor Perevertkin                         }
1128*3088717bSVictor Perevertkin 
1129*3088717bSVictor Perevertkin                         if (ScsiStatus) {
1130*3088717bSVictor Perevertkin                             *ScsiStatus =
1131*3088717bSVictor Perevertkin                                 ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->ScsiStatus;
1132*3088717bSVictor Perevertkin                         }
1133*3088717bSVictor Perevertkin 
1134*3088717bSVictor Perevertkin                         if (SenseInfoBuffer) {
1135*3088717bSVictor Perevertkin                             *SenseInfoBuffer =
1136*3088717bSVictor Perevertkin                                 ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->SenseInfoBuffer;
1137*3088717bSVictor Perevertkin                         }
1138*3088717bSVictor Perevertkin 
1139*3088717bSVictor Perevertkin                         if (SenseInfoBufferLength) {
1140*3088717bSVictor Perevertkin                             *SenseInfoBufferLength =
1141*3088717bSVictor Perevertkin                                 ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->SenseInfoBufferLength;
1142*3088717bSVictor Perevertkin                         }
1143*3088717bSVictor Perevertkin 
1144*3088717bSVictor Perevertkin                     } else {
1145*3088717bSVictor Perevertkin                         // Catch invalid offset
1146*3088717bSVictor Perevertkin                         NT_ASSERT(FALSE);
1147*3088717bSVictor Perevertkin                     }
1148*3088717bSVictor Perevertkin                     break;
1149*3088717bSVictor Perevertkin             }
1150*3088717bSVictor Perevertkin 
1151*3088717bSVictor Perevertkin             if (FoundEntry) {
1152*3088717bSVictor Perevertkin                 break;
1153*3088717bSVictor Perevertkin             }
1154*3088717bSVictor Perevertkin         }
1155*3088717bSVictor Perevertkin 
1156*3088717bSVictor Perevertkin     } else {
1157*3088717bSVictor Perevertkin 
1158*3088717bSVictor Perevertkin         if (CdbLength8) {
1159*3088717bSVictor Perevertkin             *CdbLength8 = 0;
1160*3088717bSVictor Perevertkin         }
1161*3088717bSVictor Perevertkin 
1162*3088717bSVictor Perevertkin         if (CdbLength32) {
1163*3088717bSVictor Perevertkin             *CdbLength32 = 0;
1164*3088717bSVictor Perevertkin         }
1165*3088717bSVictor Perevertkin 
1166*3088717bSVictor Perevertkin         if (ScsiStatus) {
1167*3088717bSVictor Perevertkin             *ScsiStatus = 0;
1168*3088717bSVictor Perevertkin         }
1169*3088717bSVictor Perevertkin 
1170*3088717bSVictor Perevertkin         if (SenseInfoBuffer) {
1171*3088717bSVictor Perevertkin             *SenseInfoBuffer = NULL;
1172*3088717bSVictor Perevertkin         }
1173*3088717bSVictor Perevertkin 
1174*3088717bSVictor Perevertkin         if (SenseInfoBufferLength) {
1175*3088717bSVictor Perevertkin             *SenseInfoBufferLength = 0;
1176*3088717bSVictor Perevertkin         }
1177*3088717bSVictor Perevertkin     }
1178*3088717bSVictor Perevertkin 
1179*3088717bSVictor Perevertkin     return Cdb;
1180*3088717bSVictor Perevertkin }
1181*3088717bSVictor Perevertkin 
1182*3088717bSVictor Perevertkin FORCEINLINE // __REACTOS__
1183*3088717bSVictor Perevertkin VOID
SetSrbScsiData(_In_ PSTORAGE_REQUEST_BLOCK SrbEx,_In_ UCHAR CdbLength8,_In_ ULONG CdbLength32,_In_ UCHAR ScsiStatus,_In_opt_ PVOID SenseInfoBuffer,_In_ UCHAR SenseInfoBufferLength)1184*3088717bSVictor Perevertkin SetSrbScsiData(
1185*3088717bSVictor Perevertkin     _In_ PSTORAGE_REQUEST_BLOCK SrbEx,
1186*3088717bSVictor Perevertkin     _In_ UCHAR CdbLength8,
1187*3088717bSVictor Perevertkin     _In_ ULONG CdbLength32,
1188*3088717bSVictor Perevertkin     _In_ UCHAR ScsiStatus,
1189*3088717bSVictor Perevertkin     _In_opt_ PVOID SenseInfoBuffer,
1190*3088717bSVictor Perevertkin     _In_ UCHAR SenseInfoBufferLength
1191*3088717bSVictor Perevertkin     )
1192*3088717bSVictor Perevertkin /*++
1193*3088717bSVictor Perevertkin 
1194*3088717bSVictor Perevertkin Routine Description:
1195*3088717bSVictor Perevertkin 
1196*3088717bSVictor Perevertkin     Helper function to set SCSI related fields from an extended SRB. If SRB is
1197*3088717bSVictor Perevertkin     not a SRB_FUNCTION_EXECUTE_SCSI or not an extended SRB, no modifications will
1198*3088717bSVictor Perevertkin     be made
1199*3088717bSVictor Perevertkin 
1200*3088717bSVictor Perevertkin Arguments:
1201*3088717bSVictor Perevertkin 
1202*3088717bSVictor Perevertkin     SrbEx - Pointer to extended SRB.
1203*3088717bSVictor Perevertkin 
1204*3088717bSVictor Perevertkin     CdbLength8 - CdbLength field value for SRBEX_DATA_SCSI_CDB16
1205*3088717bSVictor Perevertkin                  or SRBEX_DATA_SCSI_CDB32
1206*3088717bSVictor Perevertkin 
1207*3088717bSVictor Perevertkin     CdbLength32 - CdbLength field value for SRBEX_DATA_SCSI_CDB_VAR
1208*3088717bSVictor Perevertkin 
1209*3088717bSVictor Perevertkin     ScsiStatus - ScsiStatus field value.
1210*3088717bSVictor Perevertkin 
1211*3088717bSVictor Perevertkin     SenseInfoBuffer - SenseInfoBuffer value.
1212*3088717bSVictor Perevertkin 
1213*3088717bSVictor Perevertkin     SenseInfoBufferLength - SenseInfoBufferLength value.
1214*3088717bSVictor Perevertkin 
1215*3088717bSVictor Perevertkin Return Value:
1216*3088717bSVictor Perevertkin 
1217*3088717bSVictor Perevertkin     None
1218*3088717bSVictor Perevertkin 
1219*3088717bSVictor Perevertkin --*/
1220*3088717bSVictor Perevertkin {
1221*3088717bSVictor Perevertkin     ULONG i;
1222*3088717bSVictor Perevertkin     PSRBEX_DATA SrbExData = NULL;
1223*3088717bSVictor Perevertkin     BOOLEAN FoundEntry = FALSE;
1224*3088717bSVictor Perevertkin 
1225*3088717bSVictor Perevertkin     if ((SrbEx->Function == SRB_FUNCTION_STORAGE_REQUEST_BLOCK) &&
1226*3088717bSVictor Perevertkin         (SrbEx->SrbFunction == SRB_FUNCTION_EXECUTE_SCSI)) {
1227*3088717bSVictor Perevertkin         NT_ASSERT(SrbEx->NumSrbExData > 0);
1228*3088717bSVictor Perevertkin 
1229*3088717bSVictor Perevertkin         for (i = 0; i < SrbEx->NumSrbExData; i++) {
1230*3088717bSVictor Perevertkin 
1231*3088717bSVictor Perevertkin             // Skip any invalid offsets
1232*3088717bSVictor Perevertkin             if ((SrbEx->SrbExDataOffset[i] < sizeof(STORAGE_REQUEST_BLOCK)) ||
1233*3088717bSVictor Perevertkin                 (SrbEx->SrbExDataOffset[i] > SrbEx->SrbLength)){
1234*3088717bSVictor Perevertkin                 // Catch any invalid offsets
1235*3088717bSVictor Perevertkin                 NT_ASSERT(FALSE);
1236*3088717bSVictor Perevertkin                 continue;
1237*3088717bSVictor Perevertkin             }
1238*3088717bSVictor Perevertkin 
1239*3088717bSVictor Perevertkin             SrbExData = (PSRBEX_DATA)((PUCHAR)SrbEx + SrbEx->SrbExDataOffset[i]);
1240*3088717bSVictor Perevertkin 
1241*3088717bSVictor Perevertkin             switch (SrbExData->Type) {
1242*3088717bSVictor Perevertkin 
1243*3088717bSVictor Perevertkin                 case SrbExDataTypeScsiCdb16:
1244*3088717bSVictor Perevertkin                     if (SrbEx->SrbExDataOffset[i] + sizeof(SRBEX_DATA_SCSI_CDB16) <= SrbEx->SrbLength) {
1245*3088717bSVictor Perevertkin                         FoundEntry = TRUE;
1246*3088717bSVictor Perevertkin                         ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->CdbLength = CdbLength8;
1247*3088717bSVictor Perevertkin                         ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->ScsiStatus = ScsiStatus;
1248*3088717bSVictor Perevertkin                         ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->SenseInfoBuffer = SenseInfoBuffer;
1249*3088717bSVictor Perevertkin                         ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->SenseInfoBufferLength = SenseInfoBufferLength;
1250*3088717bSVictor Perevertkin                     } else {
1251*3088717bSVictor Perevertkin                         // Catch invalid offset
1252*3088717bSVictor Perevertkin                         NT_ASSERT(FALSE);
1253*3088717bSVictor Perevertkin                     }
1254*3088717bSVictor Perevertkin                     break;
1255*3088717bSVictor Perevertkin 
1256*3088717bSVictor Perevertkin                 case SrbExDataTypeScsiCdb32:
1257*3088717bSVictor Perevertkin                     if (SrbEx->SrbExDataOffset[i] + sizeof(SRBEX_DATA_SCSI_CDB32) <= SrbEx->SrbLength) {
1258*3088717bSVictor Perevertkin                         FoundEntry = TRUE;
1259*3088717bSVictor Perevertkin                         ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->CdbLength = CdbLength8;
1260*3088717bSVictor Perevertkin                         ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->ScsiStatus = ScsiStatus;
1261*3088717bSVictor Perevertkin                         ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->SenseInfoBuffer = SenseInfoBuffer;
1262*3088717bSVictor Perevertkin                         ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->SenseInfoBufferLength = SenseInfoBufferLength;
1263*3088717bSVictor Perevertkin                     } else {
1264*3088717bSVictor Perevertkin                         // Catch invalid offset
1265*3088717bSVictor Perevertkin                         NT_ASSERT(FALSE);
1266*3088717bSVictor Perevertkin                     }
1267*3088717bSVictor Perevertkin                     break;
1268*3088717bSVictor Perevertkin 
1269*3088717bSVictor Perevertkin                 case SrbExDataTypeScsiCdbVar:
1270*3088717bSVictor Perevertkin                     if (SrbEx->SrbExDataOffset[i] + sizeof(SRBEX_DATA_SCSI_CDB_VAR) <= SrbEx->SrbLength) {
1271*3088717bSVictor Perevertkin                         FoundEntry = TRUE;
1272*3088717bSVictor Perevertkin                         ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->CdbLength = CdbLength32;
1273*3088717bSVictor Perevertkin                         ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->ScsiStatus = ScsiStatus;
1274*3088717bSVictor Perevertkin                         ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->SenseInfoBuffer = SenseInfoBuffer;
1275*3088717bSVictor Perevertkin                         ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->SenseInfoBufferLength = SenseInfoBufferLength;
1276*3088717bSVictor Perevertkin                     } else {
1277*3088717bSVictor Perevertkin                         // Catch invalid offset
1278*3088717bSVictor Perevertkin                         NT_ASSERT(FALSE);
1279*3088717bSVictor Perevertkin                     }
1280*3088717bSVictor Perevertkin                     break;
1281*3088717bSVictor Perevertkin             }
1282*3088717bSVictor Perevertkin 
1283*3088717bSVictor Perevertkin             if (FoundEntry) {
1284*3088717bSVictor Perevertkin                 break;
1285*3088717bSVictor Perevertkin             }
1286*3088717bSVictor Perevertkin         }
1287*3088717bSVictor Perevertkin 
1288*3088717bSVictor Perevertkin     }
1289*3088717bSVictor Perevertkin 
1290*3088717bSVictor Perevertkin     return;
1291*3088717bSVictor Perevertkin }
1292*3088717bSVictor Perevertkin 
1293