ReactOS  0.4.14-dev-583-g2a1ba2c
misc.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: USB block storage device driver.
5  * COPYRIGHT: 2005-2006 James Tabor
6  * 2011-2012 Michael Martin (michael.martin@reactos.org)
7  * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
8  */
9 
10 #include "usbstor.h"
11 
12 #define NDEBUG
13 #include <debug.h>
14 
15 
16 IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine;
17 
19 NTAPI
22  PIRP Irp,
23  PVOID Context)
24 {
25  if (Irp->PendingReturned)
26  {
28  }
30 }
31 
33 NTAPI
35 {
36  KEVENT Event;
38 
42 
44 
45  if (Status == STATUS_PENDING)
46  {
47  // wait for the request to finish
49  Status = Irp->IoStatus.Status;
50  }
51 
52  return Status;
53 }
54 
56 NTAPI
59  OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface)
60 {
61  KEVENT Event;
63  PIRP Irp;
65  PIO_STACK_LOCATION Stack;
66 
68  ASSERT(BusInterface);
69 
71 
74  NULL,
75  0,
76  NULL,
77  &Event,
78  &IoStatus);
79  if (Irp == NULL)
80  {
82  }
83 
84  // initialize request
86  Stack->MajorFunction = IRP_MJ_PNP;
88  Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
89  Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&USB_BUS_INTERFACE_USBDI_GUID;
90  Stack->Parameters.QueryInterface.Version = 2;
91  Stack->Parameters.QueryInterface.Interface = (PINTERFACE)BusInterface;
92  Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
93  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
94 
96 
97  if (Status == STATUS_PENDING)
98  {
100  Status = IoStatus.Status;
101  }
102 
103  return Status;
104 }
105 
106 NTSTATUS
109  OUT PURB UrbRequest)
110 {
111  PIRP Irp;
112  PIO_STACK_LOCATION IoStack;
113  KEVENT Event;
115 
117  if (!Irp)
118  {
120  }
121 
123 
124  IoStack = IoGetNextIrpStackLocation(Irp);
125 
126  // initialize stack location
128  IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
129  IoStack->Parameters.Others.Argument1 = (PVOID)UrbRequest;
130  IoStack->Parameters.DeviceIoControl.InputBufferLength = UrbRequest->UrbHeader.Length;
131  Irp->IoStatus.Status = STATUS_SUCCESS;
132 
134 
136 
137  if (Status == STATUS_PENDING)
138  {
140  Status = Irp->IoStatus.Status;
141  }
142 
143  IoFreeIrp(Irp);
144  return Status;
145 }
146 
147 PVOID
150  IN ULONG ItemSize)
151 {
153 
154  if (Item)
155  {
156  RtlZeroMemory(Item, ItemSize);
157  }
158 
159  return Item;
160 }
161 
162 VOID
164  IN PVOID Item)
165 {
167 }
168 
169 NTSTATUS
172  IN PFDO_DEVICE_EXTENSION DeviceExtension,
173  IN UCHAR RequestType,
174  IN USHORT Index,
175  IN ULONG TransferFlags,
176  IN ULONG TransferBufferLength,
177  IN PVOID TransferBuffer)
178 
179 {
180  PURB Urb;
182 
184  if (!Urb)
185  {
187  }
188 
191  Urb->UrbControlVendorClassRequest.TransferFlags = TransferFlags;
192  Urb->UrbControlVendorClassRequest.TransferBufferLength = TransferBufferLength;
193  Urb->UrbControlVendorClassRequest.TransferBuffer = TransferBuffer;
194  Urb->UrbControlVendorClassRequest.Request = RequestType;
195  Urb->UrbControlVendorClassRequest.Index = Index;
196 
198 
199  FreeItem(Urb);
200  return Status;
201 }
202 
203 NTSTATUS
206  IN PFDO_DEVICE_EXTENSION DeviceExtension)
207 {
208  PUCHAR Buffer;
210 
212  if (!Buffer)
213  {
214  FreeItem(Buffer);
216  }
217 
218  Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_GET_MAX_LUN, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_IN, sizeof(UCHAR), Buffer);
219 
220  DPRINT("MaxLUN: %x\n", *Buffer);
221 
222  if (NT_SUCCESS(Status))
223  {
224  if (*Buffer > 0xF)
225  {
226  // invalid response documented in usb mass storage specification
228  }
229  else
230  {
231  // store maxlun
232  DeviceExtension->MaxLUN = *Buffer;
233  }
234  }
235  else
236  {
237  // "USB Mass Storage Class. Bulk-Only Transport. Revision 1.0"
238  // 3.2 Get Max LUN (class-specific request) :
239  // Devices that do not support multiple LUNs may STALL this command.
240  USBSTOR_ResetDevice(DeviceExtension->LowerDeviceObject, DeviceExtension);
241 
242  DeviceExtension->MaxLUN = 0;
244  }
245 
246  FreeItem(Buffer);
247  return Status;
248 }
249 
250 NTSTATUS
253  IN PFDO_DEVICE_EXTENSION DeviceExtension)
254 {
256 
257  Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_RESET_DEVICE, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_OUT, 0, NULL);
258  return Status;
259 }
260 
261 #if 0
262 BOOLEAN
264  IN PUCHAR Buffer,
266  OUT PUCHAR MediumTypeCode)
267 {
268  PUFI_CAPACITY_FORMAT_HEADER FormatHeader;
270  ULONG Length, Index, BlockCount, BlockLength;
271 
272  FormatHeader = (PUFI_CAPACITY_FORMAT_HEADER)Buffer;
273  ASSERT(FormatHeader->Reserved1 == 0x00);
274  ASSERT(FormatHeader->Reserved2 == 0x00);
275  ASSERT(FormatHeader->Reserved3 == 0x00);
276 
277  // is there capacity data
278  if (!FormatHeader->CapacityLength)
279  {
280  DPRINT1("[USBSTOR] No capacity length\n");
281  return FALSE;
282  }
283 
284  // the format header are always 8 bytes in length
285  ASSERT((FormatHeader->CapacityLength & 0x7) == 0);
286  DPRINT1("CapacityLength %x\n", FormatHeader->CapacityLength);
287 
288  // grab length and locate first descriptor
289  Length = FormatHeader->CapacityLength;
290  Descriptor = (PUFI_CAPACITY_DESCRIPTOR)(FormatHeader + 1);
291  for (Index = 0; Index < Length / sizeof(UFI_CAPACITY_DESCRIPTOR); Index++)
292  {
293  // blocks are little endian format
294  BlockCount = NTOHL(Descriptor->BlockCount);
295  BlockLength = NTOHL((Descriptor->BlockLengthByte0 << 24 | Descriptor->BlockLengthByte1 << 16 | Descriptor->BlockLengthByte2 << 8));
296 
297  DPRINT1("BlockCount %x BlockLength %x Code %x\n", BlockCount, BlockLength, Descriptor->Code);
298 
299  if (BlockLength == 512 && BlockCount == 1440)
300  {
301  // 720 KB DD
302  *MediumTypeCode = 0x1E;
303  return TRUE;
304  }
305  else if (BlockLength == 1024 && BlockCount == 1232)
306  {
307  // 1,25 MB
308  *MediumTypeCode = 0x93;
309  return TRUE;
310  }
311  else if (BlockLength == 512 && BlockCount == 2880)
312  {
313  // 1,44MB KB DD
314  *MediumTypeCode = 0x94;
315  return TRUE;
316  }
317 
318  Descriptor++;
319  }
320 
321  return FALSE;
322 }
323 #endif
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
#define IN
Definition: typedefs.h:38
#define USB_BULK_RESET_DEVICE
Definition: usbstor.h:99
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
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
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:57
#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:251
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
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:170
#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:34
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:23
static UCHAR ItemSize[4]
Definition: parser.c:16
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
BOOLEAN USBSTOR_IsFloppy(IN PUCHAR Buffer, IN ULONG BufferLength, OUT PUCHAR MediumTypeCode)
Definition: misc.c:427
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:98
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:107
#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:566
#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:2772
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2938
_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:204
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
GUID * LPGUID
Definition: guiddef.h:81
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966