xref: /reactos/drivers/usb/usbstor/disk.c (revision 7115d7ba)
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  *              2017 Vadim Galyant
9  */
10 
11 #include "usbstor.h"
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 
17 static
18 BOOLEAN
19 IsRequestValid(PIRP Irp)
20 {
21     ULONG TransferLength;
22     PIO_STACK_LOCATION IoStack;
23     PSCSI_REQUEST_BLOCK Srb;
24 
25     IoStack = IoGetCurrentIrpStackLocation(Irp);
26     Srb = IoStack->Parameters.Scsi.Srb;
27 
28     if (Srb->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT))
29     {
30         if ((Srb->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION) == SRB_FLAGS_UNSPECIFIED_DIRECTION)
31         {
32             DPRINT1("IsRequestValid: Invalid Srb. Srb->SrbFlags - %X\n", Srb->SrbFlags);
33             return FALSE;
34         }
35 
36         TransferLength = Srb->DataTransferLength;
37 
38         if (Irp->MdlAddress == NULL)
39         {
40             DPRINT1("IsRequestValid: Invalid Srb. Irp->MdlAddress == NULL\n");
41             return FALSE;
42         }
43 
44         if (TransferLength == 0)
45         {
46             DPRINT1("IsRequestValid: Invalid Srb. TransferLength == 0\n");
47             return FALSE;
48         }
49 
50         if (TransferLength > USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH)
51         {
52             DPRINT1("IsRequestValid: Invalid Srb. TransferLength > 0x10000\n");
53             return FALSE;
54         }
55     }
56     else
57     {
58         if (Srb->DataTransferLength)
59         {
60             DPRINT1("IsRequestValid: Invalid Srb. Srb->DataTransferLength != 0\n");
61             return FALSE;
62         }
63 
64         if (Srb->DataBuffer)
65         {
66             DPRINT1("IsRequestValid: Invalid Srb. Srb->DataBuffer != NULL\n");
67             return FALSE;
68         }
69 
70         if (Irp->MdlAddress)
71         {
72             DPRINT1("IsRequestValid: Invalid Srb. Irp->MdlAddress != NULL\n");
73             return FALSE;
74         }
75     }
76 
77     return TRUE;
78 }
79 
80 NTSTATUS
81 USBSTOR_HandleInternalDeviceControl(
82     IN PDEVICE_OBJECT DeviceObject,
83     IN PIRP Irp)
84 {
85     PIO_STACK_LOCATION IoStack;
86     PSCSI_REQUEST_BLOCK Request;
87     PPDO_DEVICE_EXTENSION PDODeviceExtension;
88     NTSTATUS Status;
89 
90     IoStack = IoGetCurrentIrpStackLocation(Irp);
91     Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
92     ASSERT(Request);
93     PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
94     ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
95 
96     switch(Request->Function)
97     {
98         case SRB_FUNCTION_EXECUTE_SCSI:
99         {
100             DPRINT("SRB_FUNCTION_EXECUTE_SCSI\n");
101 
102             if (!IsRequestValid(Irp))
103             {
104                 Status = STATUS_INVALID_PARAMETER;
105                 break;
106             }
107 
108             if (Request->Cdb[0] == SCSIOP_MODE_SENSE)
109             {
110                 DPRINT("USBSTOR_Scsi: SRB_FUNCTION_EXECUTE_SCSI - FIXME SCSIOP_MODE_SENSE\n");
111                 // FIXME Get from registry WriteProtect for StorageDevicePolicies;
112                 // L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\StorageDevicePolicies"
113                 // QueryTable[0].Name = L"WriteProtect"
114             }
115 
116             IoMarkIrpPending(Irp);
117             Request->SrbStatus = SRB_STATUS_PENDING;
118 
119             // add the request
120             if (!USBSTOR_QueueAddIrp(PDODeviceExtension->LowerDeviceObject, Irp))
121             {
122                 IoStartPacket(PDODeviceExtension->LowerDeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo);
123             }
124 
125             return STATUS_PENDING;
126         }
127         case SRB_FUNCTION_RELEASE_DEVICE:
128         {
129             DPRINT1("SRB_FUNCTION_RELEASE_DEVICE\n");
130             ASSERT(PDODeviceExtension->Claimed == TRUE);
131 
132             // release claim
133             PDODeviceExtension->Claimed = FALSE;
134             Status = STATUS_SUCCESS;
135             break;
136         }
137         case SRB_FUNCTION_CLAIM_DEVICE:
138         {
139             DPRINT1("SRB_FUNCTION_CLAIM_DEVICE\n");
140 
141             // check if the device has been claimed
142             if (PDODeviceExtension->Claimed)
143             {
144                 // device has already been claimed
145                 Status = STATUS_DEVICE_BUSY;
146                 Request->SrbStatus = SRB_STATUS_BUSY;
147                 break;
148             }
149 
150             // claim device
151             PDODeviceExtension->Claimed = TRUE;
152 
153             // output device object
154             Request->DataBuffer = DeviceObject;
155 
156             Status = STATUS_SUCCESS;
157             break;
158         }
159         case SRB_FUNCTION_RELEASE_QUEUE:
160         {
161             DPRINT1("SRB_FUNCTION_RELEASE_QUEUE\n");
162 
163             USBSTOR_QueueRelease(PDODeviceExtension->LowerDeviceObject);
164 
165             Request->SrbStatus = SRB_STATUS_SUCCESS;
166             Status = STATUS_SUCCESS;
167             break;
168         }
169 
170         case SRB_FUNCTION_SHUTDOWN:
171         case SRB_FUNCTION_FLUSH:
172         case SRB_FUNCTION_FLUSH_QUEUE:
173         {
174             DPRINT1("SRB_FUNCTION_FLUSH / SRB_FUNCTION_FLUSH_QUEUE / SRB_FUNCTION_SHUTDOWN\n");
175 
176             // HACK: don't flush pending requests
177 #if 0       // we really need a proper storage stack
178             //
179             // wait for pending requests to finish
180             //
181             USBSTOR_QueueWaitForPendingRequests(PDODeviceExtension->LowerDeviceObject);
182 #endif
183 
184             Request->SrbStatus = SRB_STATUS_SUCCESS;
185             Status = STATUS_SUCCESS;
186             break;
187         }
188         default:
189         {
190             //
191             // not supported
192             //
193             Status = STATUS_NOT_SUPPORTED;
194             Request->SrbStatus = SRB_STATUS_ERROR;
195         }
196     }
197 
198     Irp->IoStatus.Status = Status;
199     IoCompleteRequest(Irp, IO_NO_INCREMENT);
200     return Status;
201 }
202 
203 ULONG
204 USBSTOR_GetFieldLength(
205     IN PUCHAR Name,
206     IN ULONG MaxLength)
207 {
208     ULONG Index;
209     ULONG LastCharacterPosition = 0;
210 
211     // scan the field and return last position which contains a valid character
212     for(Index = 0; Index < MaxLength; Index++)
213     {
214         if (Name[Index] != ' ')
215         {
216             // trim white spaces from field
217             LastCharacterPosition = Index;
218         }
219     }
220 
221     // convert from zero based index to length
222     return LastCharacterPosition + 1;
223 }
224 
225 NTSTATUS
226 USBSTOR_HandleQueryProperty(
227     IN PDEVICE_OBJECT DeviceObject,
228     IN PIRP Irp)
229 {
230     PIO_STACK_LOCATION IoStack;
231     PSTORAGE_PROPERTY_QUERY PropertyQuery;
232     PSTORAGE_DESCRIPTOR_HEADER DescriptorHeader;
233     PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor;
234     ULONG FieldLengthVendor, FieldLengthProduct, FieldLengthRevision, TotalLength, FieldLengthSerialNumber;
235     PPDO_DEVICE_EXTENSION PDODeviceExtension;
236     PINQUIRYDATA InquiryData;
237     PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor;
238     PUCHAR Buffer;
239     PFDO_DEVICE_EXTENSION FDODeviceExtension;
240     UNICODE_STRING SerialNumber;
241     ANSI_STRING AnsiString;
242     NTSTATUS Status;
243 
244     DPRINT("USBSTOR_HandleQueryProperty\n");
245 
246     IoStack = IoGetCurrentIrpStackLocation(Irp);
247     ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(STORAGE_PROPERTY_QUERY));
248     ASSERT(Irp->AssociatedIrp.SystemBuffer);
249 
250     PropertyQuery = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer;
251 
252     // check property type
253     if (PropertyQuery->PropertyId != StorageDeviceProperty &&
254         PropertyQuery->PropertyId != StorageAdapterProperty)
255     {
256         // only device property / adapter property are supported
257         return STATUS_INVALID_PARAMETER_1;
258     }
259 
260     // check query type
261     if (PropertyQuery->QueryType == PropertyExistsQuery)
262     {
263         // device property / adapter property is supported
264         return STATUS_SUCCESS;
265     }
266 
267     if (PropertyQuery->QueryType != PropertyStandardQuery)
268     {
269         // only standard query and exists query are supported
270         return STATUS_INVALID_PARAMETER_2;
271     }
272 
273     // check if it is a device property
274     if (PropertyQuery->PropertyId == StorageDeviceProperty)
275     {
276         DPRINT("USBSTOR_HandleQueryProperty StorageDeviceProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
277 
278         PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
279         ASSERT(PDODeviceExtension);
280         ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
281 
282         FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
283         ASSERT(FDODeviceExtension);
284         ASSERT(FDODeviceExtension->Common.IsFDO);
285 
286         InquiryData = (PINQUIRYDATA)&PDODeviceExtension->InquiryData;
287 
288         // compute extra parameters length
289         FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->VendorId, 8);
290         FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->ProductId, 16);
291         FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->ProductRevisionLevel, 4);
292 
293         if (FDODeviceExtension->SerialNumber)
294         {
295             FieldLengthSerialNumber = wcslen(FDODeviceExtension->SerialNumber->bString);
296         }
297         else
298         {
299             FieldLengthSerialNumber = 0;
300         }
301 
302         // total length required is sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLength + 4 extra null bytes - 1
303         // -1 due STORAGE_DEVICE_DESCRIPTOR contains one byte length of parameter data
304         TotalLength = sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3;
305 
306         // check if output buffer is long enough
307         if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < TotalLength)
308         {
309             // buffer too small
310             DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
311             ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
312 
313             // return required size
314             DescriptorHeader->Version = TotalLength;
315             DescriptorHeader->Size = TotalLength;
316 
317             Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
318             return STATUS_SUCCESS;
319         }
320 
321         // initialize the device descriptor
322         DeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
323 
324         DeviceDescriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR);
325         DeviceDescriptor->Size = TotalLength;
326         DeviceDescriptor->DeviceType = InquiryData->DeviceType;
327         DeviceDescriptor->DeviceTypeModifier = InquiryData->DeviceTypeModifier;
328         DeviceDescriptor->RemovableMedia = InquiryData->RemovableMedia;
329         DeviceDescriptor->CommandQueueing = FALSE;
330         DeviceDescriptor->BusType = BusTypeUsb;
331         DeviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR);
332         DeviceDescriptor->ProductIdOffset = DeviceDescriptor->VendorIdOffset + FieldLengthVendor + 1;
333         DeviceDescriptor->ProductRevisionOffset = DeviceDescriptor->ProductIdOffset + FieldLengthProduct + 1;
334         DeviceDescriptor->SerialNumberOffset = (FieldLengthSerialNumber > 0 ? DeviceDescriptor->ProductRevisionOffset + FieldLengthRevision + 1 : 0);
335         DeviceDescriptor->RawPropertiesLength = FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3 + (FieldLengthSerialNumber > 0 ? + 1 : 0);
336 
337         // copy descriptors
338         Buffer = (PUCHAR)((ULONG_PTR)DeviceDescriptor + sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR));
339 
340         RtlCopyMemory(Buffer, InquiryData->VendorId, FieldLengthVendor);
341         Buffer[FieldLengthVendor] = '\0';
342         Buffer += FieldLengthVendor + 1;
343 
344         RtlCopyMemory(Buffer, InquiryData->ProductId, FieldLengthProduct);
345         Buffer[FieldLengthProduct] = '\0';
346         Buffer += FieldLengthProduct + 1;
347 
348         RtlCopyMemory(Buffer, InquiryData->ProductRevisionLevel, FieldLengthRevision);
349         Buffer[FieldLengthRevision] = '\0';
350         Buffer += FieldLengthRevision + 1;
351 
352         if (FieldLengthSerialNumber)
353         {
354             RtlInitUnicodeString(&SerialNumber, FDODeviceExtension->SerialNumber->bString);
355 
356             AnsiString.Buffer = (PCHAR)Buffer;
357             AnsiString.Length = 0;
358             AnsiString.MaximumLength = FieldLengthSerialNumber * sizeof(WCHAR);
359 
360             Status = RtlUnicodeStringToAnsiString(&AnsiString, &SerialNumber, FALSE);
361             ASSERT(Status == STATUS_SUCCESS);
362         }
363 
364         DPRINT("Vendor %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->VendorIdOffset));
365         DPRINT("Product %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductIdOffset));
366         DPRINT("Revision %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductRevisionOffset));
367         DPRINT("Serial %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->SerialNumberOffset));
368 
369         Irp->IoStatus.Information = TotalLength;
370         return STATUS_SUCCESS;
371     }
372     else
373     {
374         // adapter property query request
375 
376         DPRINT("USBSTOR_HandleQueryProperty StorageAdapterProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
377 
378         if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_ADAPTER_DESCRIPTOR))
379         {
380             // buffer too small
381             DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
382             ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
383 
384             // return required size
385             DescriptorHeader->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
386             DescriptorHeader->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
387 
388             Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
389             return STATUS_SUCCESS;
390         }
391 
392         // get adapter descriptor, information is returned in the same buffer
393         AdapterDescriptor = (PSTORAGE_ADAPTER_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
394 
395         // fill out descriptor
396         AdapterDescriptor->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
397         AdapterDescriptor->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
398         AdapterDescriptor->MaximumTransferLength = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH;
399         AdapterDescriptor->MaximumPhysicalPages = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH / PAGE_SIZE + 1; // See CORE-10515 and CORE-10755
400         AdapterDescriptor->AlignmentMask = 0;
401         AdapterDescriptor->AdapterUsesPio = FALSE;
402         AdapterDescriptor->AdapterScansDown = FALSE;
403         AdapterDescriptor->CommandQueueing = FALSE;
404         AdapterDescriptor->AcceleratedTransfer = FALSE;
405         AdapterDescriptor->BusType = BusTypeUsb;
406         AdapterDescriptor->BusMajorVersion = 0x2; //FIXME verify
407         AdapterDescriptor->BusMinorVersion = 0x00; //FIXME
408 
409         // store returned length
410         Irp->IoStatus.Information = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
411 
412         return STATUS_SUCCESS;
413     }
414 }
415 
416 NTSTATUS
417 USBSTOR_HandleDeviceControl(
418     IN PDEVICE_OBJECT DeviceObject,
419     IN PIRP Irp)
420 {
421     PIO_STACK_LOCATION IoStack;
422     NTSTATUS Status;
423     PPDO_DEVICE_EXTENSION PDODeviceExtension;
424     PSCSI_ADAPTER_BUS_INFO BusInfo;
425     PSCSI_INQUIRY_DATA ScsiInquiryData;
426     PINQUIRYDATA InquiryData;
427 
428     IoStack = IoGetCurrentIrpStackLocation(Irp);
429 
430     switch (IoStack->Parameters.DeviceIoControl.IoControlCode)
431     {
432         case IOCTL_STORAGE_QUERY_PROPERTY:
433             Status = USBSTOR_HandleQueryProperty(DeviceObject, Irp);
434             break;
435         case IOCTL_SCSI_PASS_THROUGH:
436             DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH NOT implemented\n");
437             Status = STATUS_NOT_SUPPORTED;
438             break;
439         case IOCTL_SCSI_PASS_THROUGH_DIRECT:
440             DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH_DIRECT NOT implemented\n");
441             Status = STATUS_NOT_SUPPORTED;
442             break;
443         case IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER:
444             DPRINT1("USBSTOR_HandleDeviceControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER NOT implemented\n");
445             Status = STATUS_NOT_SUPPORTED;
446             break;
447         case IOCTL_SCSI_GET_CAPABILITIES:
448         {
449             PIO_SCSI_CAPABILITIES Capabilities;
450 
451             // Legacy port capability query
452             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(PVOID))
453             {
454                 Capabilities = *((PVOID *)Irp->AssociatedIrp.SystemBuffer) = ExAllocatePoolWithTag(NonPagedPool,
455                                                                                                    sizeof(IO_SCSI_CAPABILITIES),
456                                                                                                    USB_STOR_TAG);
457                 Irp->IoStatus.Information = sizeof(PVOID);
458             }
459             else
460             {
461                 Capabilities = Irp->AssociatedIrp.SystemBuffer;
462                 Irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES);
463             }
464 
465             if (Capabilities)
466             {
467                 Capabilities->MaximumTransferLength = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH;
468                 Capabilities->MaximumPhysicalPages = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH / PAGE_SIZE + 1; // See CORE-10515 and CORE-10755
469                 Capabilities->SupportedAsynchronousEvents = 0;
470                 Capabilities->AlignmentMask = 0;
471                 Capabilities->TaggedQueuing = FALSE;
472                 Capabilities->AdapterScansDown = FALSE;
473                 Capabilities->AdapterUsesPio = FALSE;
474                 Status = STATUS_SUCCESS;
475             }
476             else
477             {
478                 Status = STATUS_INSUFFICIENT_RESOURCES;
479             }
480 
481             break;
482         }
483         case IOCTL_SCSI_GET_INQUIRY_DATA:
484         {
485             PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
486             ASSERT(PDODeviceExtension);
487             ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
488 
489             // get parameters
490             BusInfo = Irp->AssociatedIrp.SystemBuffer;
491             ScsiInquiryData = (PSCSI_INQUIRY_DATA)(BusInfo + 1);
492             InquiryData = (PINQUIRYDATA)ScsiInquiryData->InquiryData;
493 
494 
495             BusInfo->NumberOfBuses = 1;
496             BusInfo->BusData[0].NumberOfLogicalUnits = 1; //FIXME
497             BusInfo->BusData[0].InitiatorBusId = 0;
498             BusInfo->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
499 
500             ScsiInquiryData->PathId = 0;
501             ScsiInquiryData->TargetId = 0;
502             ScsiInquiryData->Lun = PDODeviceExtension->LUN & MAX_LUN;
503             ScsiInquiryData->DeviceClaimed = PDODeviceExtension->Claimed;
504             ScsiInquiryData->InquiryDataLength = sizeof(INQUIRYDATA);
505             ScsiInquiryData->NextInquiryDataOffset = 0;
506 
507             // Note: INQUIRYDATA structure is larger than INQUIRYDATABUFFERSIZE
508             RtlZeroMemory(InquiryData, sizeof(INQUIRYDATA));
509             RtlCopyMemory(InquiryData, &PDODeviceExtension->InquiryData, sizeof(PDODeviceExtension->InquiryData));
510 
511             InquiryData->Versions = 0x04;
512             InquiryData->ResponseDataFormat = 0x02; // some devices set this to 1
513 
514             Irp->IoStatus.Information = sizeof(SCSI_ADAPTER_BUS_INFO) + sizeof(SCSI_INQUIRY_DATA) + sizeof(INQUIRYDATA) - 1;
515             Status = STATUS_SUCCESS;
516 
517             break;
518         }
519         case IOCTL_SCSI_GET_ADDRESS:
520         {
521             PSCSI_ADDRESS Address = Irp->AssociatedIrp.SystemBuffer;
522 
523             Address->Length = sizeof(SCSI_ADDRESS);
524             Address->PortNumber = 0;
525             Address->PathId = 0;
526             Address->TargetId = 0;
527             Address->Lun = (((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LUN & MAX_LUN);
528             Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
529 
530             Status = STATUS_SUCCESS;
531 
532             break;
533         }
534         default:
535             DPRINT("USBSTOR_HandleDeviceControl IoControl %x not supported\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
536             Status = STATUS_NOT_SUPPORTED;
537             break;
538     }
539 
540     return Status;
541 }
542