ReactOS  0.4.13-dev-101-g0ca4b50
misc.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: drivers/usb/usbstor/misc.c
5  * PURPOSE: USB block storage device driver.
6  * PROGRAMMERS:
7  * James Tabor
8  * Michael Martin (michael.martin@reactos.org)
9  * Johannes Anderwald (johannes.anderwald@reactos.org)
10  */
11 
12 #include "usbstor.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 //
18 // driver verifier
19 //
20 IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine;
21 
23 NTAPI
26  PIRP Irp,
27  PVOID Context)
28 {
29  if (Irp->PendingReturned)
30  {
32  }
34 }
35 
37 NTAPI
39 {
40  KEVENT Event;
42 
43  //
44  // initialize event
45  //
47 
48  //
49  // copy irp stack location
50  //
52 
53  //
54  // set completion routine
55  //
57 
58 
59  //
60  // call driver
61  //
63 
64  //
65  // check if pending
66  //
67  if (Status == STATUS_PENDING)
68  {
69  //
70  // wait for the request to finish
71  //
73 
74  //
75  // copy status code
76  //
77  Status = Irp->IoStatus.Status;
78  }
79 
80  //
81  // done
82  //
83  return Status;
84 }
85 
87 NTAPI
90  OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface)
91 {
92  KEVENT Event;
94  PIRP Irp;
96  PIO_STACK_LOCATION Stack;
97 
98  //
99  // sanity checks
100  //
102  ASSERT(BusInterface);
103 
104 
105  //
106  // initialize event
107  //
109 
110 
111  //
112  // create irp
113  //
115  DeviceObject,
116  NULL,
117  0,
118  NULL,
119  &Event,
120  &IoStatus);
121 
122  //
123  // was irp built
124  //
125  if (Irp == NULL)
126  {
127  //
128  // no memory
129  //
131  }
132 
133  //
134  // initialize request
135  //
137  Stack->MajorFunction = IRP_MJ_PNP;
139  Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
140  Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&USB_BUS_INTERFACE_USBDI_GUID;
141  Stack->Parameters.QueryInterface.Version = 2;
142  Stack->Parameters.QueryInterface.Interface = (PINTERFACE)BusInterface;
143  Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
144  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
145 
146  //
147  // call driver
148  //
150 
151  //
152  // did operation complete
153  //
154  if (Status == STATUS_PENDING)
155  {
156  //
157  // wait for completion
158  //
160 
161  //
162  // collect status
163  //
164  Status=IoStatus.Status;
165  }
166 
167  return Status;
168 }
169 
170 NTSTATUS
173  OUT PURB UrbRequest)
174 {
175  PIRP Irp;
176  PIO_STACK_LOCATION IoStack;
177  KEVENT Event;
179 
180  //
181  // allocate irp
182  //
184  if (!Irp)
185  {
186  //
187  // no memory
188  //
190  }
191 
192  //
193  // initialize event
194  //
196 
197 
198  //
199  // get next stack location
200  //
201  IoStack = IoGetNextIrpStackLocation(Irp);
202 
203  //
204  // initialize stack location
205  //
207  IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
208  IoStack->Parameters.Others.Argument1 = (PVOID)UrbRequest;
209  IoStack->Parameters.DeviceIoControl.InputBufferLength = UrbRequest->UrbHeader.Length;
210  Irp->IoStatus.Status = STATUS_SUCCESS;
211 
212  //
213  // setup completion routine
214  //
216 
217  //
218  // call driver
219  //
221 
222  //
223  // check if request is pending
224  //
225  if (Status == STATUS_PENDING)
226  {
227  //
228  // wait for completion
229  //
231 
232  //
233  // update status
234  //
235  Status = Irp->IoStatus.Status;
236  }
237 
238  //
239  // free irp
240  //
241  IoFreeIrp(Irp);
242 
243  //
244  // done
245  //
246  return Status;
247 }
248 
249 PVOID
252  IN ULONG ItemSize)
253 {
254  //
255  // allocate item
256  //
258 
259  if (Item)
260  {
261  //
262  // zero item
263  //
264  RtlZeroMemory(Item, ItemSize);
265  }
266 
267  //
268  // return element
269  //
270  return Item;
271 }
272 
273 VOID
275  IN PVOID Item)
276 {
277  //
278  // free item
279  //
281 }
282 
283 NTSTATUS
286  IN PFDO_DEVICE_EXTENSION DeviceExtension,
287  IN UCHAR RequestType,
288  IN USHORT Index,
289  IN ULONG TransferFlags,
290  IN ULONG TransferBufferLength,
291  IN PVOID TransferBuffer)
292 
293 {
294  PURB Urb;
296 
297  //
298  // first allocate urb
299  //
301  if (!Urb)
302  {
303  //
304  // no memory
305  //
307  }
308 
309  //
310  // initialize vendor request
311  //
314  Urb->UrbControlVendorClassRequest.TransferFlags = TransferFlags;
315  Urb->UrbControlVendorClassRequest.TransferBufferLength = TransferBufferLength;
316  Urb->UrbControlVendorClassRequest.TransferBuffer = TransferBuffer;
317  Urb->UrbControlVendorClassRequest.Request = RequestType;
318  Urb->UrbControlVendorClassRequest.Index = Index;
319 
320  //
321  // submit request
322  //
324 
325  //
326  // free urb
327  //
328  FreeItem(Urb);
329 
330  //
331  // done
332  //
333  return Status;
334 }
335 
336 
337 NTSTATUS
340  IN PFDO_DEVICE_EXTENSION DeviceExtension)
341 {
342  PUCHAR Buffer;
344 
345  //
346  // allocate 1-byte buffer
347  //
349  if (!Buffer)
350  {
351  //
352  // no memory
353  //
354  FreeItem(Buffer);
356  }
357 
358  //
359  // execute request
360  //
361  Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_GET_MAX_LUN, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_IN, sizeof(UCHAR), Buffer);
362 
363  DPRINT("MaxLUN: %x\n", *Buffer);
364 
365  if (NT_SUCCESS(Status))
366  {
367  if (*Buffer > 0xF)
368  {
369  //
370  // invalid response documented in usb mass storage specification
371  //
373  }
374  else
375  {
376  //
377  // store maxlun
378  //
379  DeviceExtension->MaxLUN = *Buffer;
380  }
381  }
382  else
383  {
384  //
385  // "USB Mass Storage Class. Bulk-Only Transport. Revision 1.0"
386  // 3.2 Get Max LUN (class-specific request) :
387  // Devices that do not support multiple LUNs may STALL this command.
388  //
389  USBSTOR_ResetDevice(DeviceExtension->LowerDeviceObject, DeviceExtension);
390 
391  DeviceExtension->MaxLUN = 0;
393  }
394 
395  //
396  // free buffer
397  //
398  FreeItem(Buffer);
399 
400  //
401  // done
402  //
403  return Status;
404 
405 }
406 
407 NTSTATUS
410  IN PFDO_DEVICE_EXTENSION DeviceExtension)
411 {
413 
414  //
415  // execute request
416  //
417  Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_RESET_DEVICE, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_OUT, 0, NULL);
418 
419  //
420  // done
421  //
422  return Status;
423 
424 }
425 
426 BOOLEAN
428  IN PUCHAR Buffer,
430  OUT PUCHAR MediumTypeCode)
431 {
432  PUFI_CAPACITY_FORMAT_HEADER FormatHeader;
434  ULONG Length, Index, BlockCount, BlockLength;
435 
436  //
437  // get format header
438  //
439  FormatHeader = (PUFI_CAPACITY_FORMAT_HEADER)Buffer;
440 
441  //
442  // sanity checks
443  //
444  ASSERT(FormatHeader->Reserved1 == 0x00);
445  ASSERT(FormatHeader->Reserved2 == 0x00);
446  ASSERT(FormatHeader->Reserved3 == 0x00);
447 
448  //
449  // is there capacity data
450  //
451  if (!FormatHeader->CapacityLength)
452  {
453  //
454  // no data provided
455  //
456  DPRINT1("[USBSTOR] No capacity length\n");
457  return FALSE;
458  }
459 
460  //
461  // the format header are always 8 bytes in length
462  //
463  ASSERT((FormatHeader->CapacityLength & 0x7) == 0);
464  DPRINT1("CapacityLength %x\n", FormatHeader->CapacityLength);
465 
466  //
467  // grab length and locate first descriptor
468  //
469  Length = FormatHeader->CapacityLength;
470  Descriptor = (PUFI_CAPACITY_DESCRIPTOR)(FormatHeader + 1);
471  for(Index = 0; Index < Length / sizeof(UFI_CAPACITY_DESCRIPTOR); Index++)
472  {
473  //
474  // blocks are little endian format
475  //
476  BlockCount = NTOHL(Descriptor->BlockCount);
477 
478  //
479  // get block length
480  //
481  BlockLength = NTOHL((Descriptor->BlockLengthByte0 << 24 | Descriptor->BlockLengthByte1 << 16 | Descriptor->BlockLengthByte2 << 8));
482 
483  DPRINT1("BlockCount %x BlockLength %x Code %x\n", BlockCount, BlockLength, Descriptor->Code);
484 
485  if (BlockLength == 512 && BlockCount == 1440)
486  {
487  //
488  // 720 KB DD
489  //
490  *MediumTypeCode = 0x1E;
491  return TRUE;
492  }
493  else if (BlockLength == 1024 && BlockCount == 1232)
494  {
495  //
496  // 1,25 MB
497  //
498  *MediumTypeCode = 0x93;
499  return TRUE;
500  }
501  else if (BlockLength == 512 && BlockCount == 2880)
502  {
503  //
504  // 1,44MB KB DD
505  //
506  *MediumTypeCode = 0x94;
507  return TRUE;
508  }
509 
510  //
511  // move to next descriptor
512  //
513  Descriptor = (Descriptor + 1);
514  }
515 
516  //
517  // no floppy detected
518  //
519  return FALSE;
520 }
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
#define IN
Definition: typedefs.h:38
#define USB_BULK_RESET_DEVICE
Definition: usbstor.h:86
struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST UrbControlVendorClassRequest
Definition: usb.h:548
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
BOOLEAN USBSTOR_IsFloppy(IN PUCHAR Buffer, IN ULONG BufferLength, OUT PUCHAR MediumTypeCode)
Definition: misc.c:427
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
_In_ PIRP Irp
Definition: csq.h:116
unsigned char * PUCHAR
Definition: retypes.h:3
NTSTATUS NTAPI USBSTOR_GetBusInterface(IN PDEVICE_OBJECT DeviceObject, OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface)
Definition: misc.c:88
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
struct UFI_CAPACITY_DESCRIPTOR * PUFI_CAPACITY_DESCRIPTOR
_In_ ULONG BufferLength
Definition: usbdlib.h:225
NTSTATUS USBSTOR_ResetDevice(IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension)
Definition: misc.c:408
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:434
NTSTATUS USBSTOR_ClassRequest(IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension, IN UCHAR RequestType, IN USHORT Index, IN ULONG TransferFlags, IN ULONG TransferBufferLength, IN PVOID TransferBuffer)
Definition: misc.c:284
#define USBD_TRANSFER_DIRECTION_OUT
Definition: usb.h:159
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI USBSTOR_SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: misc.c:38
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
struct _INTERFACE * PINTERFACE
NTSTATUS NTAPI USBSTOR_SyncForwardIrpCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: misc.c:22
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
INT POOL_TYPE
Definition: typedefs.h:76
static const UCHAR Index[8]
Definition: usbohci.c:18
#define IRP_MN_QUERY_INTERFACE
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine
Definition: misc.c:18
unsigned char UCHAR
Definition: xmlstorage.h:181
#define USB_STOR_TAG
Definition: usbstor.h:10
#define NTOHL(n)
Definition: usbstor.h:22
static UCHAR ItemSize[4]
Definition: parser.c:16
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
struct _URB * PURB
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
struct _BUS_INTERFACE_STANDARD BUS_INTERFACE_STANDARD
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
Definition: usb.h:529
unsigned short USHORT
Definition: pedump.c:61
struct UFI_CAPACITY_FORMAT_HEADER * PUFI_CAPACITY_FORMAT_HEADER
#define URB_FUNCTION_CLASS_INTERFACE
Definition: usb.h:113
#define USB_BULK_GET_MAX_LUN
Definition: usbstor.h:85
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
NTSTATUS USBSTOR_SyncUrbRequest(IN PDEVICE_OBJECT DeviceObject, OUT PURB UrbRequest)
Definition: misc.c:171
#define DPRINT1
Definition: precomp.h:8
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
#define OUT
Definition: typedefs.h:39
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
static PVOID
Definition: misc.c:50
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2725
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T _In_ POOL_TYPE PoolType
Definition: fltkernel.h:1444
NTSTATUS USBSTOR_GetMaxLUN(IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension)
Definition: misc.c:338
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
GUID * LPGUID
Definition: guiddef.h:76
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966