xref: /reactos/drivers/usb/usbstor_new/disk.c (revision 7eead935)
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/disk.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 NTSTATUS
18 USBSTOR_HandleInternalDeviceControl(
19     IN PDEVICE_OBJECT DeviceObject,
20     IN PIRP Irp)
21 {
22     PIO_STACK_LOCATION IoStack;
23     PSCSI_REQUEST_BLOCK Request;
24     PPDO_DEVICE_EXTENSION PDODeviceExtension;
25     NTSTATUS Status;
26 
27     //
28     // get current stack location
29     //
30     IoStack = IoGetCurrentIrpStackLocation(Irp);
31 
32     //
33     // get request block
34     //
35     Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
36 
37     //
38     // sanity check
39     //
40     ASSERT(Request);
41 
42     //
43     // get device extension
44     //
45     PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
46 
47     //
48     // sanity check
49     //
50     ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
51 
52     switch(Request->Function)
53     {
54         case SRB_FUNCTION_EXECUTE_SCSI:
55         {
56             DPRINT("SRB_FUNCTION_EXECUTE_SCSI\n");
57 
58             //
59             // check if request is valid
60             //
61             if (Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT))
62             {
63                 //
64                 // data is transferred with this irp
65                 //
66                 if ((Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)) == (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT) ||
67                     Request->DataTransferLength == 0 ||
68                     Irp->MdlAddress == NULL)
69                 {
70                     //
71                     // invalid parameter
72                     //
73                     Status = STATUS_INVALID_PARAMETER;
74                     break;
75                 }
76             }
77             else
78             {
79                 //
80                 // sense buffer request
81                 //
82                 if (Request->DataTransferLength ||
83                     Request->DataBuffer ||
84                     Irp->MdlAddress)
85                 {
86                     //
87                     // invalid parameter
88                     //
89                     Status = STATUS_INVALID_PARAMETER;
90                     break;
91                 }
92             }
93 
94             //
95             // add the request
96             //
97             if (!USBSTOR_QueueAddIrp(PDODeviceExtension->LowerDeviceObject, Irp))
98             {
99                 //
100                 // irp was not added to the queue
101                 //
102                 IoStartPacket(PDODeviceExtension->LowerDeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo);
103             }
104 
105             //
106             // irp pending
107             //
108             return STATUS_PENDING;
109         }
110         case SRB_FUNCTION_RELEASE_DEVICE:
111         {
112             DPRINT1("SRB_FUNCTION_RELEASE_DEVICE\n");
113             //
114             // sanity check
115             //
116             ASSERT(PDODeviceExtension->Claimed == TRUE);
117 
118             //
119             // release claim
120             //
121             PDODeviceExtension->Claimed = FALSE;
122             Status = STATUS_SUCCESS;
123             break;
124         }
125         case SRB_FUNCTION_CLAIM_DEVICE:
126         {
127             DPRINT1("SRB_FUNCTION_CLAIM_DEVICE\n");
128             //
129             // check if the device has been claimed
130             //
131             if (PDODeviceExtension->Claimed)
132             {
133                 //
134                 // device has already been claimed
135                 //
136                 Status = STATUS_DEVICE_BUSY;
137                 Request->SrbStatus = SRB_STATUS_BUSY;
138                 break;
139             }
140 
141             //
142             // claim device
143             //
144             PDODeviceExtension->Claimed = TRUE;
145 
146             //
147             // output device object
148             //
149             Request->DataBuffer = DeviceObject;
150 
151             //
152             // completed successfully
153             //
154             Status = STATUS_SUCCESS;
155             break;
156         }
157         case SRB_FUNCTION_RELEASE_QUEUE:
158         {
159             DPRINT1("SRB_FUNCTION_RELEASE_QUEUE\n");
160 
161             //
162             // release queue
163             //
164             USBSTOR_QueueRelease(PDODeviceExtension->LowerDeviceObject);
165 
166             //
167             // set status success
168             //
169             Request->SrbStatus = SRB_STATUS_SUCCESS;
170             Status = STATUS_SUCCESS;
171             break;
172         }
173 
174         case SRB_FUNCTION_SHUTDOWN:
175         case SRB_FUNCTION_FLUSH:
176         case SRB_FUNCTION_FLUSH_QUEUE:
177         {
178             DPRINT1("SRB_FUNCTION_FLUSH / SRB_FUNCTION_FLUSH_QUEUE / SRB_FUNCTION_SHUTDOWN\n");
179 
180             // HACK: don't flush pending requests
181 #if 0       // we really need a proper storage stack
182             //
183             // wait for pending requests to finish
184             //
185             USBSTOR_QueueWaitForPendingRequests(PDODeviceExtension->LowerDeviceObject);
186 #endif
187             //
188             // set status success
189             //
190             Request->SrbStatus = SRB_STATUS_SUCCESS;
191             Status = STATUS_SUCCESS;
192             break;
193         }
194         default:
195         {
196             //
197             // not supported
198             //
199             Status = STATUS_NOT_SUPPORTED;
200             Request->SrbStatus = SRB_STATUS_ERROR;
201         }
202     }
203 
204     //
205     // complete request
206     //
207     Irp->IoStatus.Status = Status;
208     IoCompleteRequest(Irp, IO_NO_INCREMENT);
209     return Status;
210 }
211 
212 ULONG
213 USBSTOR_GetFieldLength(
214     IN PUCHAR Name,
215     IN ULONG MaxLength)
216 {
217     ULONG Index;
218     ULONG LastCharacterPosition = 0;
219 
220     //
221     // scan the field and return last position which contains a valid character
222     //
223     for(Index = 0; Index < MaxLength; Index++)
224     {
225         if (Name[Index] != ' ')
226         {
227             //
228             // trim white spaces from field
229             //
230             LastCharacterPosition = Index;
231         }
232     }
233 
234     //
235     // convert from zero based index to length
236     //
237     return LastCharacterPosition + 1;
238 }
239 
240 NTSTATUS
241 USBSTOR_HandleQueryProperty(
242     IN PDEVICE_OBJECT DeviceObject,
243     IN PIRP Irp)
244 {
245     PIO_STACK_LOCATION IoStack;
246     PSTORAGE_PROPERTY_QUERY PropertyQuery;
247     PSTORAGE_DESCRIPTOR_HEADER DescriptorHeader;
248     PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor;
249     ULONG FieldLengthVendor, FieldLengthProduct, FieldLengthRevision, TotalLength, FieldLengthSerialNumber;
250     PPDO_DEVICE_EXTENSION PDODeviceExtension;
251     PUFI_INQUIRY_RESPONSE InquiryData;
252     PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor;
253     PUCHAR Buffer;
254     PFDO_DEVICE_EXTENSION FDODeviceExtension;
255     UNICODE_STRING SerialNumber;
256     ANSI_STRING AnsiString;
257     NTSTATUS Status;
258 
259     DPRINT("USBSTOR_HandleQueryProperty\n");
260 
261     //
262     // get current stack location
263     //
264     IoStack = IoGetCurrentIrpStackLocation(Irp);
265 
266     //
267     // sanity check
268     //
269     ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(STORAGE_PROPERTY_QUERY));
270     ASSERT(Irp->AssociatedIrp.SystemBuffer);
271 
272     //
273     // get property query
274     //
275     PropertyQuery = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer;
276 
277     //
278     // check property type
279     //
280     if (PropertyQuery->PropertyId != StorageDeviceProperty &&
281         PropertyQuery->PropertyId != StorageAdapterProperty)
282     {
283         //
284         // only device property / adapter property are supported
285         //
286         return STATUS_INVALID_PARAMETER_1;
287     }
288 
289     //
290     // check query type
291     //
292     if (PropertyQuery->QueryType == PropertyExistsQuery)
293     {
294         //
295         // device property / adapter property is supported
296         //
297         return STATUS_SUCCESS;
298     }
299 
300     if (PropertyQuery->QueryType != PropertyStandardQuery)
301     {
302         //
303         // only standard query and exists query are supported
304         //
305         return STATUS_INVALID_PARAMETER_2;
306     }
307 
308     //
309     // check if it is a device property
310     //
311     if (PropertyQuery->PropertyId == StorageDeviceProperty)
312     {
313         DPRINT("USBSTOR_HandleQueryProperty StorageDeviceProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
314 
315         //
316         // get device extension
317         //
318         PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
319         ASSERT(PDODeviceExtension);
320         ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
321 
322         //
323         // get device extension
324         //
325         FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
326         ASSERT(FDODeviceExtension);
327         ASSERT(FDODeviceExtension->Common.IsFDO);
328 
329         //
330         // get inquiry data
331         //
332         InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
333         ASSERT(InquiryData);
334 
335         //
336         // compute extra parameters length
337         //
338         FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->Vendor, 8);
339         FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->Product, 16);
340         FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->Revision, 4);
341 
342         //
343         // is there a serial number
344         //
345         if (FDODeviceExtension->SerialNumber)
346         {
347             //
348             // get length
349             //
350             FieldLengthSerialNumber = wcslen(FDODeviceExtension->SerialNumber->bString);
351         }
352         else
353         {
354             //
355             // no serial number
356             //
357             FieldLengthSerialNumber = 0;
358         }
359 
360         //
361         // total length required is sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLength + 4 extra null bytes - 1
362         // -1 due STORAGE_DEVICE_DESCRIPTOR contains one byte length of parameter data
363         //
364         TotalLength = sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3;
365 
366         //
367         // check if output buffer is long enough
368         //
369         if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < TotalLength)
370         {
371             //
372             // buffer too small
373             //
374             DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
375             ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
376 
377             //
378             // return required size
379             //
380             DescriptorHeader->Version = TotalLength;
381             DescriptorHeader->Size = TotalLength;
382 
383             Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
384             return STATUS_SUCCESS;
385         }
386 
387         //
388         // get device descriptor
389         //
390         DeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
391 
392         //
393         // initialize device descriptor
394         //
395         DeviceDescriptor->Version = TotalLength;
396         DeviceDescriptor->Size = TotalLength;
397         DeviceDescriptor->DeviceType = InquiryData->DeviceType;
398         DeviceDescriptor->DeviceTypeModifier = (InquiryData->RMB & 0x7F);
399         DeviceDescriptor->RemovableMedia = (InquiryData->RMB & 0x80) ? TRUE : FALSE;
400         DeviceDescriptor->CommandQueueing = FALSE;
401         DeviceDescriptor->BusType = BusTypeUsb;
402         DeviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR);
403         DeviceDescriptor->ProductIdOffset = DeviceDescriptor->VendorIdOffset + FieldLengthVendor + 1;
404         DeviceDescriptor->ProductRevisionOffset = DeviceDescriptor->ProductIdOffset + FieldLengthProduct + 1;
405         DeviceDescriptor->SerialNumberOffset = (FieldLengthSerialNumber > 0 ? DeviceDescriptor->ProductRevisionOffset + FieldLengthRevision + 1 : 0);
406         DeviceDescriptor->RawPropertiesLength = FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3 + (FieldLengthSerialNumber > 0 ? + 1 : 0);
407 
408         //
409         // copy descriptors
410         //
411         Buffer = (PUCHAR)((ULONG_PTR)DeviceDescriptor + sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR));
412 
413         //
414         // copy vendor
415         //
416         RtlCopyMemory(Buffer, InquiryData->Vendor, FieldLengthVendor);
417         Buffer[FieldLengthVendor] = '\0';
418         Buffer += FieldLengthVendor + 1;
419 
420         //
421         // copy product
422         //
423         RtlCopyMemory(Buffer, InquiryData->Product, FieldLengthProduct);
424         Buffer[FieldLengthProduct] = '\0';
425         Buffer += FieldLengthProduct + 1;
426 
427         //
428         // copy revision
429         //
430         RtlCopyMemory(Buffer, InquiryData->Revision, FieldLengthRevision);
431         Buffer[FieldLengthRevision] = '\0';
432         Buffer += FieldLengthRevision + 1;
433 
434         //
435         // copy serial number
436         //
437         if (FieldLengthSerialNumber)
438         {
439             //
440             // init unicode string
441             //
442             RtlInitUnicodeString(&SerialNumber, FDODeviceExtension->SerialNumber->bString);
443 
444             //
445             // init ansi string
446             //
447             AnsiString.Buffer = (PCHAR)Buffer;
448             AnsiString.Length = 0;
449             AnsiString.MaximumLength = FieldLengthSerialNumber * sizeof(WCHAR);
450 
451             //
452             // convert to ansi code
453             //
454             Status = RtlUnicodeStringToAnsiString(&AnsiString, &SerialNumber, FALSE);
455             ASSERT(Status == STATUS_SUCCESS);
456         }
457 
458 
459         DPRINT("Vendor %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->VendorIdOffset));
460         DPRINT("Product %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductIdOffset));
461         DPRINT("Revision %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductRevisionOffset));
462         DPRINT("Serial %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->SerialNumberOffset));
463 
464         //
465         // done
466         //
467         Irp->IoStatus.Information = TotalLength;
468         return STATUS_SUCCESS;
469     }
470     else
471     {
472         //
473         // adapter property query request
474         //
475         DPRINT("USBSTOR_HandleQueryProperty StorageAdapterProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
476 
477         if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_ADAPTER_DESCRIPTOR))
478         {
479             //
480             // buffer too small
481             //
482             DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
483             ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
484 
485             //
486             // return required size
487             //
488             DescriptorHeader->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
489             DescriptorHeader->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
490 
491             Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
492             return STATUS_SUCCESS;
493         }
494 
495         //
496         // get adapter descriptor, information is returned in the same buffer
497         //
498         AdapterDescriptor = (PSTORAGE_ADAPTER_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
499 
500         //
501         // fill out descriptor
502         //
503         AdapterDescriptor->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
504         AdapterDescriptor->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
505         AdapterDescriptor->MaximumTransferLength = MAXULONG; //FIXME compute some sane value
506         AdapterDescriptor->MaximumPhysicalPages = 25; //FIXME compute some sane value
507         AdapterDescriptor->AlignmentMask = 0;
508         AdapterDescriptor->AdapterUsesPio = FALSE;
509         AdapterDescriptor->AdapterScansDown = FALSE;
510         AdapterDescriptor->CommandQueueing = FALSE;
511         AdapterDescriptor->AcceleratedTransfer = FALSE;
512         AdapterDescriptor->BusType = BusTypeUsb;
513         AdapterDescriptor->BusMajorVersion = 0x2; //FIXME verify
514         AdapterDescriptor->BusMinorVersion = 0x00; //FIXME
515 
516         //
517         // store returned length
518         //
519         Irp->IoStatus.Information = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
520 
521         //
522         // done
523         //
524         return STATUS_SUCCESS;
525     }
526 }
527 
528 NTSTATUS
529 USBSTOR_HandleDeviceControl(
530     IN PDEVICE_OBJECT DeviceObject,
531     IN PIRP Irp)
532 {
533     PIO_STACK_LOCATION IoStack;
534     NTSTATUS Status;
535     PPDO_DEVICE_EXTENSION PDODeviceExtension;
536     PSCSI_ADAPTER_BUS_INFO BusInfo;
537     PSCSI_INQUIRY_DATA InquiryData;
538     PINQUIRYDATA ScsiInquiryData;
539     PUFI_INQUIRY_RESPONSE UFIInquiryResponse;
540 
541     //
542     // get current stack location
543     //
544     IoStack = IoGetCurrentIrpStackLocation(Irp);
545 
546     if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_QUERY_PROPERTY)
547     {
548         //
549         // query property
550         //
551         Status = USBSTOR_HandleQueryProperty(DeviceObject, Irp);
552     }
553     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH)
554     {
555         //
556         // query scsi pass through
557         //
558         DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH NOT implemented\n");
559         Status = STATUS_NOT_SUPPORTED;
560     }
561     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT)
562     {
563         //
564         // query scsi pass through direct
565         //
566         DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH_DIRECT NOT implemented\n");
567         Status = STATUS_NOT_SUPPORTED;
568     }
569     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER)
570     {
571         //
572         // query serial number
573         //
574         DPRINT1("USBSTOR_HandleDeviceControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER NOT implemented\n");
575         Status = STATUS_NOT_SUPPORTED;
576     }
577     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_CAPABILITIES)
578     {
579         PIO_SCSI_CAPABILITIES Capabilities;
580 
581         /* Legacy port capability query */
582         if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(PVOID))
583         {
584             Capabilities = *((PVOID *)Irp->AssociatedIrp.SystemBuffer) = ExAllocatePoolWithTag(NonPagedPool,
585                                                                                                sizeof(IO_SCSI_CAPABILITIES),
586                                                                                                USB_STOR_TAG);
587             Irp->IoStatus.Information = sizeof(PVOID);
588         }
589         else
590         {
591             Capabilities = Irp->AssociatedIrp.SystemBuffer;
592             Irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES);
593         }
594 
595         if (Capabilities)
596         {
597             Capabilities->MaximumTransferLength = MAXULONG;
598             Capabilities->MaximumPhysicalPages = 25;
599             Capabilities->SupportedAsynchronousEvents = 0;
600             Capabilities->AlignmentMask = 0;
601             Capabilities->TaggedQueuing = FALSE;
602             Capabilities->AdapterScansDown = FALSE;
603             Capabilities->AdapterUsesPio = FALSE;
604             Status = STATUS_SUCCESS;
605         }
606         else
607         {
608             Status = STATUS_INSUFFICIENT_RESOURCES;
609         }
610     }
611     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_INQUIRY_DATA)
612     {
613         //
614         // get device extension
615         //
616         PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
617         ASSERT(PDODeviceExtension);
618         ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
619 
620         //
621         // get parameters
622         //
623         BusInfo = Irp->AssociatedIrp.SystemBuffer;
624         InquiryData = (PSCSI_INQUIRY_DATA)(BusInfo + 1);
625         ScsiInquiryData = (PINQUIRYDATA)InquiryData->InquiryData;
626 
627 
628         //
629         // get inquiry data
630         //
631         UFIInquiryResponse = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
632         ASSERT(UFIInquiryResponse);
633 
634 
635         BusInfo->NumberOfBuses = 1;
636         BusInfo->BusData[0].NumberOfLogicalUnits = 1; //FIXME
637         BusInfo->BusData[0].InitiatorBusId = 0;
638         BusInfo->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
639 
640         InquiryData->PathId = 0;
641         InquiryData->TargetId = 0;
642         InquiryData->Lun = PDODeviceExtension->LUN & MAX_LUN;
643         InquiryData->DeviceClaimed = PDODeviceExtension->Claimed;
644         InquiryData->InquiryDataLength = sizeof(INQUIRYDATA);
645         InquiryData->NextInquiryDataOffset = 0;
646 
647         RtlZeroMemory(ScsiInquiryData, sizeof(INQUIRYDATA));
648         ScsiInquiryData->DeviceType = UFIInquiryResponse->DeviceType;
649         ScsiInquiryData->DeviceTypeQualifier = (UFIInquiryResponse->RMB & 0x7F);
650 
651         /* Hack for IoReadPartitionTable call in disk.sys */
652         ScsiInquiryData->RemovableMedia = ((ScsiInquiryData->DeviceType == DIRECT_ACCESS_DEVICE) ? ((UFIInquiryResponse->RMB & 0x80) ? 1 : 0) : 0);
653 
654         ScsiInquiryData->Versions = 0x04;
655         ScsiInquiryData->ResponseDataFormat = 0x02;
656         ScsiInquiryData->AdditionalLength = 31;
657         ScsiInquiryData->SoftReset = 0;
658         ScsiInquiryData->CommandQueue = 0;
659         ScsiInquiryData->LinkedCommands = 0;
660         ScsiInquiryData->RelativeAddressing = 0;
661 
662         RtlCopyMemory(&ScsiInquiryData->VendorId, UFIInquiryResponse->Vendor, USBSTOR_GetFieldLength(UFIInquiryResponse->Vendor, 8));
663         RtlCopyMemory(&ScsiInquiryData->ProductId, UFIInquiryResponse->Product, USBSTOR_GetFieldLength(UFIInquiryResponse->Product, 16));
664 
665         Irp->IoStatus.Information = sizeof(SCSI_ADAPTER_BUS_INFO) + sizeof(SCSI_INQUIRY_DATA) + sizeof(INQUIRYDATA) - 1;
666         Status = STATUS_SUCCESS;
667     }
668     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_ADDRESS)
669     {
670         PSCSI_ADDRESS Address = Irp->AssociatedIrp.SystemBuffer;
671 
672         Address->Length = sizeof(SCSI_ADDRESS);
673         Address->PortNumber = 0;
674         Address->PathId = 0;
675         Address->TargetId = 0;
676         Address->Lun = (((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LUN & MAX_LUN);
677         Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
678 
679         Status = STATUS_SUCCESS;
680     }
681     else
682     {
683         //
684         // unsupported
685         //
686         DPRINT("USBSTOR_HandleDeviceControl IoControl %x not supported\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
687         Status = STATUS_NOT_SUPPORTED;
688     }
689 
690     return Status;
691 }
692