ReactOS 0.4.15-dev-6712-g46b4b55
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
16IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine;
17
22 PIRP Irp,
24{
25 if (Irp->PendingReturned)
26 {
28 }
30}
31
37{
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
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;
92
93 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
94 if (!Irp)
95 {
97 }
98
100
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
124PVOID
128{
130
131 if (Item)
132 {
134 }
135
136 return Item;
137}
138
139VOID
141 IN PVOID Item)
142{
144}
145
149 IN PFDO_DEVICE_EXTENSION DeviceExtension,
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;
173
175
176 FreeItem(Urb);
177 return Status;
178}
179
183 IN PFDO_DEVICE_EXTENSION DeviceExtension)
184{
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
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
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
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
Definition: bufpool.h:45
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine
Definition: misc.c:18
NTSTATUS NTAPI USBSTOR_SyncForwardIrpCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: misc.c:22
NTSTATUS USBSTOR_SyncUrbRequest(IN PDEVICE_OBJECT DeviceObject, OUT PURB UrbRequest)
Definition: misc.c:84
NTSTATUS USBSTOR_GetMaxLUN(IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension)
Definition: misc.c:181
NTSTATUS USBSTOR_ResetDevice(IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension)
Definition: misc.c:227
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
NTSTATUS NTAPI USBSTOR_GetBusInterface(IN PDEVICE_OBJECT DeviceObject, OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface)
Definition: misc.c:34
BOOLEAN USBSTOR_IsFloppy(IN PUCHAR Buffer, IN ULONG BufferLength, OUT PUCHAR MediumTypeCode)
Definition: misc.c:427
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define NonPagedPool
Definition: env_spec_w32.h:307
Status
Definition: gdiplustypes.h:25
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:34
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ NotificationEvent
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
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
unsigned short USHORT
Definition: pedump.c:61
GUID * LPGUID
Definition: guiddef.h:81
struct _INTERFACE * PINTERFACE
static UCHAR ItemSize[4]
Definition: parser.c:16
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
Definition: usb.h:529
struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST UrbControlVendorClassRequest
Definition: usb.h:548
INT POOL_TYPE
Definition: typedefs.h:78
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define URB_FUNCTION_CLASS_INTERFACE
Definition: usb.h:113
struct _URB * PURB
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define USBD_TRANSFER_DIRECTION_OUT
Definition: usb.h:159
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
#define USB_BULK_GET_MAX_LUN
Definition: usbstor.h:54
#define MAX_LUN
Definition: usbstor.h:61
#define USB_STOR_TAG
Definition: usbstor.h:10
#define USB_BULK_RESET_DEVICE
Definition: usbstor.h:55
struct UFI_CAPACITY_FORMAT_HEADER * PUFI_CAPACITY_FORMAT_HEADER
struct UFI_CAPACITY_DESCRIPTOR * PUFI_CAPACITY_DESCRIPTOR
#define NTOHL(n)
Definition: usbstor.h:22
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ WDFCOLLECTION _In_ WDFOBJECT Item
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFQUEUE _In_ _Strict_type_match_ WDF_REQUEST_TYPE RequestType
Definition: wdfdevice.h:4233
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_QUERY_INTERFACE
struct _BUS_INTERFACE_STANDARD BUS_INTERFACE_STANDARD
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
@ Executive
Definition: ketypes.h:415
unsigned char UCHAR
Definition: xmlstorage.h:181