ReactOS  0.4.15-dev-1150-g593bcce
srblib.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (C) Microsoft Corporation 2010
4 
5 Module Name:
6 
7  srblib.c
8 
9 Abstract:
10 
11  Header for SRB utility functions
12 
13 Environment:
14 
15  kernel mode only
16 
17 Notes:
18 
19 
20 Revision History:
21 
22 --*/
23 
24 
25 #include "classp.h"
26 
27 PVOID
30  )
31 /*++
32 
33 Routine Description:
34 
35  Default allocation routine.
36 
37 Arguments:
38 
39  ByteSize - SRB size in bytes.
40 
41 Return Value:
42 
43  Pointer to the SRB buffer. NULL if SRB buffer could not be allocated.
44 
45 --*/
46 {
47  return ExAllocatePoolWithTag(NonPagedPoolNx, ByteSize, '+brs');
48 }
49 
50 
54  _In_ USHORT AddressType,
56  _In_ ULONG NumSrbExData,
58  )
59 /*++
60 
61 Routine Description:
62 
63  Initialize a STORAGE_REQUEST_BLOCK.
64 
65 Arguments:
66 
67  Srb - Pointer to STORAGE_REQUEST_BLOCK to initialize.
68 
69  AddressType - Storage address type.
70 
71  ByteSize - STORAGE_REQUEST_BLOCK size in bytes.
72 
73  NumSrbExData - Number of SRB extended data.
74 
75  ap - Variable argument list matching the SRB extended data in the
76  STORAGE_REQUEST_BLOCK.
77 
78 Return Value:
79 
80  NTSTATUS
81 
82 --*/
83 {
86  PSRBEX_DATA srbExData;
87  ULONG offset;
88  ULONG length = (ULONG)-1;
90  ULONG srbExDataLength = (ULONG)-1;
91  ULONG varLength;
92  ULONG i;
93 
94  if (ByteSize < sizeof(STORAGE_REQUEST_BLOCK)) {
96  }
97 
99 
102  Srb->Signature = SRB_SIGNATURE;
104  Srb->SrbLength = ByteSize;
105  Srb->NumSrbExData = NumSrbExData;
106 
107  offset = sizeof(STORAGE_REQUEST_BLOCK);
108  if (NumSrbExData > 0) {
109  offset += ((NumSrbExData - 1) * sizeof(ULONG));
110 
111  // Ensure offset is pointer type aligned
112  if (offset % sizeof(PVOID)) {
113  offset += (sizeof(PVOID) - (offset % sizeof(PVOID)));
114  }
115  }
116  Srb->AddressOffset = offset;
117 
118  if (AddressType == STORAGE_ADDRESS_TYPE_BTL8)
119  {
120  if ((ByteSize < offset) ||
121  (ByteSize < (offset + sizeof(STOR_ADDR_BTL8)))) {
122  return STATUS_BUFFER_OVERFLOW;
123  }
126  address->AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
127  offset += sizeof(STOR_ADDR_BTL8);
128  } else
129  {
131  }
132 
133  for (i = 0; i < NumSrbExData && status == STATUS_SUCCESS; i++)
134  {
135  if (ByteSize <= offset) {
137  break;
138  }
139  srbExData = (PSRBEX_DATA)((PUCHAR)Srb + offset);
140  Srb->SrbExDataOffset[i] = offset;
141 
143 
144  switch (type)
145  {
148  srbExDataLength = SRBEX_DATA_BIDIRECTIONAL_LENGTH;
149  break;
151  length = sizeof(SRBEX_DATA_SCSI_CDB16);
152  srbExDataLength = SRBEX_DATA_SCSI_CDB16_LENGTH;
153  break;
155  length = sizeof(SRBEX_DATA_SCSI_CDB32);
156  srbExDataLength = SRBEX_DATA_SCSI_CDB32_LENGTH;
157  break;
159  varLength = va_arg(ap, ULONG);
160  length = sizeof(SRBEX_DATA_SCSI_CDB_VAR) + varLength;
161  srbExDataLength = SRBEX_DATA_SCSI_CDB_VAR_LENGTH_MIN + varLength;
162  break;
163  case SrbExDataTypeWmi:
164  length = sizeof(SRBEX_DATA_WMI);
165  srbExDataLength = SRBEX_DATA_WMI_LENGTH;
166  break;
167  case SrbExDataTypePower:
168  length = sizeof(SRBEX_DATA_POWER);
169  srbExDataLength = SRBEX_DATA_POWER_LENGTH;
170  break;
171  case SrbExDataTypePnP:
172  length = sizeof(SRBEX_DATA_PNP);
173  srbExDataLength = SRBEX_DATA_PNP_LENGTH;
174  break;
175  case SrbExDataTypeIoInfo:
176  length = sizeof(SRBEX_DATA_IO_INFO);
177  srbExDataLength = SRBEX_DATA_IO_INFO_LENGTH;
178  break;
179  default:
181  break;
182  }
183 
184  if (status == STATUS_SUCCESS)
185  {
186  NT_ASSERT(length != (ULONG)-1);
187 
188  if (ByteSize < (offset + length)) {
190  break;
191  }
192 
193  NT_ASSERT(srbExDataLength != (ULONG)-1);
194 
195  srbExData->Type = type;
196  srbExData->Length = srbExDataLength;
197  offset += length;
198  }
199  }
200 
201  return status;
202 }
203 
204 
205 NTSTATUS
208  _In_ USHORT AddressType,
210  _In_ ULONG NumSrbExData,
211  ...
212  )
213 /*++
214 
215 Routine Description:
216 
217  Initialize an extended SRB.
218 
219 Arguments:
220 
221  Srb - Pointer to SRB buffer to initialize.
222 
223  AddressType - Storage address type.
224 
225  ByteSize - STORAGE_REQUEST_BLOCK size in bytes.
226 
227  NumSrbExData - Number of SRB extended data.
228 
229  ... - Variable argument list matching the SRB extended data in the
230  STORAGE_REQUEST_BLOCK.
231 
232 Return Value:
233 
234  NTSTATUS
235 
236 --*/
237 {
239  va_list ap;
240  va_start(ap, NumSrbExData);
241  status = pInitializeStorageRequestBlock(Srb, AddressType, ByteSize, NumSrbExData, ap);
242  va_end(ap);
243  return status;
244 }
245 
246 
247 
248 NTSTATUS
251  _In_ USHORT AddressType,
254  _In_ ULONG NumSrbExData,
255  ...
256  )
257 /*++
258 
259 Routine Description:
260 
261  Create an extended SRB.
262 
263 Arguments:
264 
265  Srb - Pointer to buffer to store SRB pointer.
266 
267  AddressType - Storage address type.
268 
269  AllocateRoutine - Buffer allocation function (optional).
270 
271  ByteSize - Pointer to ULONG to store size of SRB in bytes (optional).
272 
273  NumSrbExData - Number of SRB extended data.
274 
275  ... - Variable argument list matching the SRB extended data in the
276  STORAGE_REQUEST_BLOCK.
277 
278 Return Value:
279 
280  NTSTATUS
281 
282 --*/
283 {
284  ULONG sizeNeeded = 0;
285  va_list ap;
286  ULONG i;
288 
289  // Ensure SrbExData offsets are pointer type aligned
290  sizeNeeded = sizeof(STORAGE_REQUEST_BLOCK);
291  if (NumSrbExData > 0) {
292  sizeNeeded += ((NumSrbExData - 1) * sizeof(ULONG));
293  if (sizeNeeded % sizeof(PVOID)) {
294  sizeNeeded += (sizeof(PVOID) - (sizeNeeded % sizeof(PVOID)));
295  }
296  }
297 
298  if (AddressType == STORAGE_ADDRESS_TYPE_BTL8)
299  {
300  sizeNeeded += sizeof(STOR_ADDR_BTL8);
301  } else
302  {
304  }
305 
306  va_start(ap, NumSrbExData);
307 
308  for (i = 0; i < NumSrbExData && status == STATUS_SUCCESS; i++)
309  {
310  switch (va_arg(ap, SRBEXDATATYPE))
311  {
313  sizeNeeded += sizeof(SRBEX_DATA_BIDIRECTIONAL);
314  break;
316  sizeNeeded += sizeof(SRBEX_DATA_SCSI_CDB16);
317  break;
319  sizeNeeded += sizeof(SRBEX_DATA_SCSI_CDB32);
320  break;
322  sizeNeeded += sizeof(SRBEX_DATA_SCSI_CDB_VAR) + va_arg(ap, ULONG);
323  break;
324  case SrbExDataTypeWmi:
325  sizeNeeded += sizeof(SRBEX_DATA_WMI);
326  break;
327  case SrbExDataTypePower:
328  sizeNeeded += sizeof(SRBEX_DATA_POWER);
329  break;
330  case SrbExDataTypePnP:
331  sizeNeeded += sizeof(SRBEX_DATA_PNP);
332  break;
333  case SrbExDataTypeIoInfo:
334  sizeNeeded += sizeof(SRBEX_DATA_IO_INFO);
335  break;
336  default:
338  break;
339  }
340  }
341  va_end(ap);
342 
343  if (status == STATUS_SUCCESS)
344  {
345  if (AllocateRoutine)
346  {
347  *Srb = AllocateRoutine(sizeNeeded);
348  if (*Srb == NULL)
349  {
351  }
352  }
353 
354  if (ByteSize != NULL)
355  {
356  *ByteSize = sizeNeeded;
357  }
358 
359  if (*Srb)
360  {
361  va_start(ap, NumSrbExData);
362 #ifdef _MSC_VER
363  #pragma prefast(suppress:26015, "pInitializeStorageRequestBlock will set the SrbLength field")
364 #endif
365  status = pInitializeStorageRequestBlock(*Srb, AddressType, sizeNeeded, NumSrbExData, ap);
366  va_end(ap);
367  }
368 
369  }
370 
371  return status;
372 }
373 
374 
375 
376 
#define STOR_ADDRESS_TYPE_BTL8
Definition: scsi.h:3525
NTSTATUS InitializeStorageRequestBlock(_Inout_bytecount_(ByteSize) PSTORAGE_REQUEST_BLOCK Srb, _In_ USHORT AddressType, _In_ ULONG ByteSize, _In_ ULONG NumSrbExData,...)
Definition: srblib.c:206
struct SRB_ALIGN _SRBEX_DATA_BIDIRECTIONAL SRBEX_DATA_BIDIRECTIONAL
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB32 SRBEX_DATA_SCSI_CDB32
struct SRB_ALIGN _SRBEX_DATA_WMI SRBEX_DATA_WMI
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
enum _SRBEXDATATYPE SRBEXDATATYPE
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB_VAR SRBEX_DATA_SCSI_CDB_VAR
struct STOR_ADDRESS_ALIGN _STOR_ADDRESS * PSTOR_ADDRESS
#define STORAGE_REQUEST_BLOCK_VERSION_1
Definition: srb.h:608
#define SRBEX_DATA_WMI_LENGTH
Definition: srb.h:533
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define SRBEX_DATA_PNP_LENGTH
Definition: srb.h:560
struct SRB_ALIGN _SRBEX_DATA * PSRBEX_DATA
struct SRB_ALIGN _SRBEX_DATA_POWER SRBEX_DATA_POWER
struct SRB_ALIGN _SRBEX_DATA_PNP SRBEX_DATA_PNP
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
GLintptr offset
Definition: glext.h:5920
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define _In_opt_
Definition: no_sal2.h:213
#define SRBEX_DATA_SCSI_CDB32_LENGTH
Definition: srb.h:497
ULONG CLONG
Definition: umtypes.h:126
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 SRBEX_DATA_SCSI_CDB16
#define va_end(ap)
Definition: acmsvcex.h:90
#define STOR_ADDR_BTL8_ADDRESS_LENGTH
Definition: scsi.h:3528
struct SRB_ALIGN _SRBEX_DATA_IO_INFO SRBEX_DATA_IO_INFO
smooth NULL
Definition: ftsmooth.c:416
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
char * va_list
Definition: acmsvcex.h:78
NTSTATUS pInitializeStorageRequestBlock(_Inout_bytecount_(ByteSize) PSTORAGE_REQUEST_BLOCK Srb, _In_ USHORT AddressType, _In_ ULONG ByteSize, _In_ ULONG NumSrbExData, _In_ va_list ap)
Definition: srblib.c:52
void * PVOID
Definition: retypes.h:9
#define SRBEX_DATA_BIDIRECTIONAL_LENGTH
Definition: srb.h:467
PVOID(* PSRB_ALLOCATE_ROUTINE)(_In_ CLONG ByteSize)
Definition: classp.h:2409
NTSTATUS CreateStorageRequestBlock(_Inout_ PSTORAGE_REQUEST_BLOCK *Srb, _In_ USHORT AddressType, _In_opt_ PSRB_ALLOCATE_ROUTINE AllocateRoutine, _Inout_opt_ ULONG *ByteSize, _In_ ULONG NumSrbExData,...)
Definition: srblib.c:249
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
GLuint address
Definition: glext.h:9393
#define _Inout_
Definition: no_sal2.h:244
#define STORAGE_ADDRESS_TYPE_BTL8
Definition: srb.h:657
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define SRB_FUNCTION_STORAGE_REQUEST_BLOCK
Definition: srb.h:99
#define SRBEX_DATA_SCSI_CDB_VAR_LENGTH_MIN
Definition: srb.h:514
#define SRB_SIGNATURE
Definition: srb.h:607
PVOID DefaultStorageRequestBlockAllocateRoutine(_In_ CLONG ByteSize)
Definition: srblib.c:28
_In_ ULONG _Inout_bytecount_(cj) DRVENABLEDATA *pded)
Definition: winddi.h:3541
#define SRBEX_DATA_POWER_LENGTH
Definition: srb.h:547
#define _In_
Definition: no_sal2.h:204
#define va_arg(ap, T)
Definition: acmsvcex.h:89
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
unsigned short USHORT
Definition: pedump.c:61
STORAGE_REQUEST_BLOCK
Definition: srb.h:652
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define va_start(ap, A)
Definition: acmsvcex.h:91
struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 STOR_ADDR_BTL8
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
return STATUS_SUCCESS
Definition: btrfs.c:3014
_In_ PRTL_GENERIC_COMPARE_ROUTINE _In_ PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine
Definition: rtlfuncs.h:1089
static const WCHAR Signature[]
Definition: parser.c:141
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:393
static SERVICE_STATUS status
Definition: service.c:31
#define SRBEX_DATA_SCSI_CDB16_LENGTH
Definition: srb.h:480
#define _Inout_opt_
Definition: no_sal2.h:258
#define NT_ASSERT
Definition: rtlfuncs.h:3312
#define SRBEX_DATA_IO_INFO_LENGTH
Definition: srb.h:574
Definition: ps.c:97