ReactOS  0.4.15-dev-5079-gf79e80c
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
36  OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface)
37 {
38  KEVENT Event;
40  PIRP Irp;
43 
45  ASSERT(BusInterface);
46 
48 
51  NULL,
52  0,
53  NULL,
54  &Event,
55  &IoStatus);
56  if (Irp == NULL)
57  {
59  }
60 
61  // initialize request
63  Stack->MajorFunction = IRP_MJ_PNP;
64  Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
65  Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
66  Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&USB_BUS_INTERFACE_USBDI_GUID;
67  Stack->Parameters.QueryInterface.Version = 2;
68  Stack->Parameters.QueryInterface.Interface = (PINTERFACE)BusInterface;
69  Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
70  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
71 
73 
74  if (Status == STATUS_PENDING)
75  {
77  Status = IoStatus.Status;
78  }
79 
80  return Status;
81 }
82 
86  OUT PURB UrbRequest)
87 {
88  PIRP Irp;
89  PIO_STACK_LOCATION IoStack;
90  KEVENT Event;
92 
93  Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
94  if (!Irp)
95  {
97  }
98 
100 
101  IoStack = IoGetNextIrpStackLocation(Irp);
102 
103  // initialize stack location
105  IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
106  IoStack->Parameters.Others.Argument1 = (PVOID)UrbRequest;
107  IoStack->Parameters.DeviceIoControl.InputBufferLength = UrbRequest->UrbHeader.Length;
108  Irp->IoStatus.Status = STATUS_SUCCESS;
109 
111 
113 
114  if (Status == STATUS_PENDING)
115  {
117  Status = Irp->IoStatus.Status;
118  }
119 
120  IoFreeIrp(Irp);
121  return Status;
122 }
123 
124 PVOID
127  IN ULONG ItemSize)
128 {
130 
131  if (Item)
132  {
134  }
135 
136  return Item;
137 }
138 
139 VOID
141  IN PVOID Item)
142 {
144 }
145 
146 NTSTATUS
149  IN PFDO_DEVICE_EXTENSION DeviceExtension,
151  IN USHORT Index,
152  IN ULONG TransferFlags,
153  IN ULONG TransferBufferLength,
154  IN PVOID TransferBuffer)
155 
156 {
157  PURB Urb;
159 
161  if (!Urb)
162  {
164  }
165 
168  Urb->UrbControlVendorClassRequest.TransferFlags = TransferFlags;
169  Urb->UrbControlVendorClassRequest.TransferBufferLength = TransferBufferLength;
170  Urb->UrbControlVendorClassRequest.TransferBuffer = TransferBuffer;
172  Urb->UrbControlVendorClassRequest.Index = Index;
173 
175 
176  FreeItem(Urb);
177  return Status;
178 }
179 
180 NTSTATUS
183  IN PFDO_DEVICE_EXTENSION DeviceExtension)
184 {
185  PUCHAR Buffer;
187 
189  if (!Buffer)
190  {
192  }
193 
194  Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_GET_MAX_LUN, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_IN, sizeof(UCHAR), Buffer);
195 
196  DPRINT("MaxLUN: %x\n", *Buffer);
197 
198  if (NT_SUCCESS(Status))
199  {
200  if (*Buffer > MAX_LUN)
201  {
202  // invalid response documented in usb mass storage specification
204  }
205  else
206  {
207  // store maxlun
208  DeviceExtension->MaxLUN = *Buffer;
209  }
210  }
211  else
212  {
213  // "USB Mass Storage Class. Bulk-Only Transport. Revision 1.0"
214  // 3.2 Get Max LUN (class-specific request) :
215  // Devices that do not support multiple LUNs may STALL this command.
216  USBSTOR_ResetDevice(DeviceExtension->LowerDeviceObject, DeviceExtension);
217 
218  DeviceExtension->MaxLUN = 0;
220  }
221 
223  return Status;
224 }
225 
226 NTSTATUS
229  IN PFDO_DEVICE_EXTENSION DeviceExtension)
230 {
232 
233  Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_RESET_DEVICE, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_OUT, 0, NULL);
234  return Status;
235 }
236 
237 // if somebody wants to add UFI support, here is a useful function
238 #if 0
239 BOOLEAN
241  IN PUCHAR Buffer,
243  OUT PUCHAR MediumTypeCode)
244 {
245  PUFI_CAPACITY_FORMAT_HEADER FormatHeader;
247  ULONG Length, Index, BlockCount, BlockLength;
248 
249  FormatHeader = (PUFI_CAPACITY_FORMAT_HEADER)Buffer;
250  ASSERT(FormatHeader->Reserved1 == 0x00);
251  ASSERT(FormatHeader->Reserved2 == 0x00);
252  ASSERT(FormatHeader->Reserved3 == 0x00);
253 
254  // is there capacity data
255  if (!FormatHeader->CapacityLength)
256  {
257  DPRINT1("[USBSTOR] No capacity length\n");
258  return FALSE;
259  }
260 
261  // the format header are always 8 bytes in length
262  ASSERT((FormatHeader->CapacityLength & 0x7) == 0);
263  DPRINT1("CapacityLength %x\n", FormatHeader->CapacityLength);
264 
265  // grab length and locate first descriptor
266  Length = FormatHeader->CapacityLength;
267  Descriptor = (PUFI_CAPACITY_DESCRIPTOR)(FormatHeader + 1);
268  for (Index = 0; Index < Length / sizeof(UFI_CAPACITY_DESCRIPTOR); Index++)
269  {
270  // blocks are little endian format
271  BlockCount = NTOHL(Descriptor->BlockCount);
272  BlockLength = NTOHL((Descriptor->BlockLengthByte0 << 24 | Descriptor->BlockLengthByte1 << 16 | Descriptor->BlockLengthByte2 << 8));
273 
274  DPRINT1("BlockCount %x BlockLength %x Code %x\n", BlockCount, BlockLength, Descriptor->Code);
275 
276  if (BlockLength == 512 && BlockCount == 1440)
277  {
278  // 720 KB DD
279  *MediumTypeCode = 0x1E;
280  return TRUE;
281  }
282  else if (BlockLength == 1024 && BlockCount == 1232)
283  {
284  // 1,25 MB
285  *MediumTypeCode = 0x93;
286  return TRUE;
287  }
288  else if (BlockLength == 512 && BlockCount == 2880)
289  {
290  // 1,44MB KB DD
291  *MediumTypeCode = 0x94;
292  return TRUE;
293  }
294 
295  Descriptor++;
296  }
297 
298  return FALSE;
299 }
300 #endif
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
#define IN
Definition: typedefs.h:39
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
return STATUS_NOT_SUPPORTED
#define USB_BULK_RESET_DEVICE
Definition: usbstor.h:55
struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST UrbControlVendorClassRequest
Definition: usb.h:548
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:339
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
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 BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define TRUE
Definition: types.h:120
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:34
#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 NTOHL(n)
Definition: usbstor.h:22
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFQUEUE _In_ _Strict_type_match_ WDF_REQUEST_TYPE RequestType
Definition: wdfdevice.h:4227
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
NTSTATUS USBSTOR_ResetDevice(IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension)
Definition: misc.c:227
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:467
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:147
#define USBD_TRANSFER_DIRECTION_OUT
Definition: usb.h:159
unsigned char BOOLEAN
struct UFI_CAPACITY_DESCRIPTOR * PUFI_CAPACITY_DESCRIPTOR
Definition: bufpool.h:45
struct _INTERFACE * PINTERFACE
NTSTATUS NTAPI USBSTOR_SyncForwardIrpCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: misc.c:22
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define MAX_LUN
Definition: usbstor.h:61
INT POOL_TYPE
Definition: typedefs.h:78
_In_ WDFCOLLECTION _In_ ULONG Index
#define IRP_MN_QUERY_INTERFACE
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#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
static UCHAR ItemSize[4]
Definition: parser.c:16
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
BOOLEAN USBSTOR_IsFloppy(IN PUCHAR Buffer, IN ULONG BufferLength, OUT PUCHAR MediumTypeCode)
Definition: misc.c:427
struct _URB * PURB
struct UFI_CAPACITY_FORMAT_HEADER * PUFI_CAPACITY_FORMAT_HEADER
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
#define URB_FUNCTION_CLASS_INTERFACE
Definition: usb.h:113
#define USB_BULK_GET_MAX_LUN
Definition: usbstor.h:54
#define NULL
Definition: types.h:112
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:84
_In_ WDFCOLLECTION _In_ WDFOBJECT Item
#define DPRINT1
Definition: precomp.h:8
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
#define OUT
Definition: typedefs.h:40
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3810
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:155
static PVOID
Definition: misc.c:50
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
NTSTATUS USBSTOR_GetMaxLUN(IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension)
Definition: misc.c:181
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
GUID * LPGUID
Definition: guiddef.h:81