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