xref: /reactos/drivers/usb/usbstor/disk.c (revision 53221834)
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             // wait for pending requests to finish
177             USBSTOR_QueueWaitForPendingRequests(PDODeviceExtension->LowerDeviceObject);
178 
179             Request->SrbStatus = SRB_STATUS_SUCCESS;
180             Status = STATUS_SUCCESS;
181             break;
182         }
183         default:
184         {
185             //
186             // not supported
187             //
188             Status = STATUS_NOT_SUPPORTED;
189             Request->SrbStatus = SRB_STATUS_ERROR;
190         }
191     }
192 
193     Irp->IoStatus.Status = Status;
194     IoCompleteRequest(Irp, IO_NO_INCREMENT);
195     return Status;
196 }
197 
198 ULONG
199 USBSTOR_GetFieldLength(
200     IN PUCHAR Name,
201     IN ULONG MaxLength)
202 {
203     ULONG Index;
204     ULONG LastCharacterPosition = 0;
205 
206     // scan the field and return last position which contains a valid character
207     for(Index = 0; Index < MaxLength; Index++)
208     {
209         if (Name[Index] != ' ')
210         {
211             // trim white spaces from field
212             LastCharacterPosition = Index;
213         }
214     }
215 
216     // convert from zero based index to length
217     return LastCharacterPosition + 1;
218 }
219 
220 NTSTATUS
221 USBSTOR_HandleQueryProperty(
222     IN PDEVICE_OBJECT DeviceObject,
223     IN PIRP Irp)
224 {
225     PIO_STACK_LOCATION IoStack;
226     PSTORAGE_PROPERTY_QUERY PropertyQuery;
227     PSTORAGE_DESCRIPTOR_HEADER DescriptorHeader;
228     PSTORAGE_ADAPTER_DESCRIPTOR_WIN8 AdapterDescriptor;
229     ULONG FieldLengthVendor, FieldLengthProduct, FieldLengthRevision, TotalLength, FieldLengthSerialNumber;
230     PPDO_DEVICE_EXTENSION PDODeviceExtension;
231     PINQUIRYDATA InquiryData;
232     PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor;
233     PUCHAR Buffer;
234     PFDO_DEVICE_EXTENSION FDODeviceExtension;
235     UNICODE_STRING SerialNumber;
236     ANSI_STRING AnsiString;
237     NTSTATUS Status;
238 
239     DPRINT("USBSTOR_HandleQueryProperty\n");
240 
241     IoStack = IoGetCurrentIrpStackLocation(Irp);
242     ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(STORAGE_PROPERTY_QUERY));
243     ASSERT(Irp->AssociatedIrp.SystemBuffer);
244 
245     PropertyQuery = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer;
246 
247     // check property type
248     if (PropertyQuery->PropertyId != StorageDeviceProperty &&
249         PropertyQuery->PropertyId != StorageAdapterProperty)
250     {
251         // only device property / adapter property are supported
252         return STATUS_INVALID_PARAMETER_1;
253     }
254 
255     // check query type
256     if (PropertyQuery->QueryType == PropertyExistsQuery)
257     {
258         // device property / adapter property is supported
259         return STATUS_SUCCESS;
260     }
261 
262     if (PropertyQuery->QueryType != PropertyStandardQuery)
263     {
264         // only standard query and exists query are supported
265         return STATUS_INVALID_PARAMETER_2;
266     }
267 
268     // check if it is a device property
269     if (PropertyQuery->PropertyId == StorageDeviceProperty)
270     {
271         DPRINT("USBSTOR_HandleQueryProperty StorageDeviceProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
272 
273         PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
274         ASSERT(PDODeviceExtension);
275         ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
276 
277         FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
278         ASSERT(FDODeviceExtension);
279         ASSERT(FDODeviceExtension->Common.IsFDO);
280 
281         InquiryData = (PINQUIRYDATA)&PDODeviceExtension->InquiryData;
282 
283         // compute extra parameters length
284         FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->VendorId, 8);
285         FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->ProductId, 16);
286         FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->ProductRevisionLevel, 4);
287 
288         if (FDODeviceExtension->SerialNumber)
289         {
290             FieldLengthSerialNumber = wcslen(FDODeviceExtension->SerialNumber->bString);
291         }
292         else
293         {
294             FieldLengthSerialNumber = 0;
295         }
296 
297         // total length required is sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLength + 4 extra null bytes - 1
298         // -1 due STORAGE_DEVICE_DESCRIPTOR contains one byte length of parameter data
299         TotalLength = sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3;
300 
301         // check if output buffer is long enough
302         if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < TotalLength)
303         {
304             // buffer too small
305             DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
306             ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
307 
308             // return required size
309             DescriptorHeader->Version = TotalLength;
310             DescriptorHeader->Size = TotalLength;
311 
312             Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
313             return STATUS_SUCCESS;
314         }
315 
316         // initialize the device descriptor
317         DeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
318 
319         DeviceDescriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR);
320         DeviceDescriptor->Size = TotalLength;
321         DeviceDescriptor->DeviceType = InquiryData->DeviceType;
322         DeviceDescriptor->DeviceTypeModifier = InquiryData->DeviceTypeModifier;
323         DeviceDescriptor->RemovableMedia = InquiryData->RemovableMedia;
324         DeviceDescriptor->CommandQueueing = FALSE;
325         DeviceDescriptor->BusType = BusTypeUsb;
326         DeviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR);
327         DeviceDescriptor->ProductIdOffset = DeviceDescriptor->VendorIdOffset + FieldLengthVendor + 1;
328         DeviceDescriptor->ProductRevisionOffset = DeviceDescriptor->ProductIdOffset + FieldLengthProduct + 1;
329         DeviceDescriptor->SerialNumberOffset = (FieldLengthSerialNumber > 0 ? DeviceDescriptor->ProductRevisionOffset + FieldLengthRevision + 1 : 0);
330         DeviceDescriptor->RawPropertiesLength = FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3 + (FieldLengthSerialNumber > 0 ? + 1 : 0);
331 
332         // copy descriptors
333         Buffer = (PUCHAR)((ULONG_PTR)DeviceDescriptor + sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR));
334 
335         RtlCopyMemory(Buffer, InquiryData->VendorId, FieldLengthVendor);
336         Buffer[FieldLengthVendor] = '\0';
337         Buffer += FieldLengthVendor + 1;
338 
339         RtlCopyMemory(Buffer, InquiryData->ProductId, FieldLengthProduct);
340         Buffer[FieldLengthProduct] = '\0';
341         Buffer += FieldLengthProduct + 1;
342 
343         RtlCopyMemory(Buffer, InquiryData->ProductRevisionLevel, FieldLengthRevision);
344         Buffer[FieldLengthRevision] = '\0';
345         Buffer += FieldLengthRevision + 1;
346 
347         if (FieldLengthSerialNumber)
348         {
349             RtlInitUnicodeString(&SerialNumber, FDODeviceExtension->SerialNumber->bString);
350 
351             AnsiString.Buffer = (PCHAR)Buffer;
352             AnsiString.Length = 0;
353             AnsiString.MaximumLength = FieldLengthSerialNumber * sizeof(WCHAR);
354 
355             Status = RtlUnicodeStringToAnsiString(&AnsiString, &SerialNumber, FALSE);
356             ASSERT(Status == STATUS_SUCCESS);
357         }
358 
359         DPRINT("Vendor %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->VendorIdOffset));
360         DPRINT("Product %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductIdOffset));
361         DPRINT("Revision %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductRevisionOffset));
362         DPRINT("Serial %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->SerialNumberOffset));
363 
364         Irp->IoStatus.Information = TotalLength;
365         return STATUS_SUCCESS;
366     }
367     else
368     {
369         // adapter property query request
370 
371         DPRINT("USBSTOR_HandleQueryProperty StorageAdapterProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
372 
373         if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_ADAPTER_DESCRIPTOR_WIN8))
374         {
375             // buffer too small
376             DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
377             ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
378 
379             // return required size
380             DescriptorHeader->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR_WIN8);
381             DescriptorHeader->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR_WIN8);
382 
383             Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
384             return STATUS_SUCCESS;
385         }
386 
387         // get adapter descriptor, information is returned in the same buffer
388         AdapterDescriptor = Irp->AssociatedIrp.SystemBuffer;
389 
390         // fill out descriptor
391         // NOTE: STORAGE_ADAPTER_DESCRIPTOR_WIN8 may vary in size, so it's important to zero out
392         // all unused fields
393         *AdapterDescriptor = (STORAGE_ADAPTER_DESCRIPTOR_WIN8) {
394             .Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR_WIN8),
395             .Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR_WIN8),
396             .MaximumTransferLength = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH,
397             .MaximumPhysicalPages = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH / PAGE_SIZE + 1, // See CORE-10515 and CORE-10755
398             .BusType = BusTypeUsb,
399             .BusMajorVersion = 2, //FIXME verify
400             .BusMinorVersion = 0 //FIXME
401         };
402 
403         // __debugbreak();
404 
405         // store returned length
406         Irp->IoStatus.Information = sizeof(STORAGE_ADAPTER_DESCRIPTOR_WIN8);
407 
408         return STATUS_SUCCESS;
409     }
410 }
411 
412 NTSTATUS
413 USBSTOR_HandleDeviceControl(
414     IN PDEVICE_OBJECT DeviceObject,
415     IN PIRP Irp)
416 {
417     PIO_STACK_LOCATION IoStack;
418     NTSTATUS Status;
419     PPDO_DEVICE_EXTENSION PDODeviceExtension;
420     PSCSI_ADAPTER_BUS_INFO BusInfo;
421     PSCSI_INQUIRY_DATA ScsiInquiryData;
422     PINQUIRYDATA InquiryData;
423 
424     IoStack = IoGetCurrentIrpStackLocation(Irp);
425 
426     switch (IoStack->Parameters.DeviceIoControl.IoControlCode)
427     {
428         case IOCTL_STORAGE_QUERY_PROPERTY:
429             Status = USBSTOR_HandleQueryProperty(DeviceObject, Irp);
430             break;
431         case IOCTL_SCSI_PASS_THROUGH:
432             DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH NOT implemented\n");
433             Status = STATUS_NOT_SUPPORTED;
434             break;
435         case IOCTL_SCSI_PASS_THROUGH_DIRECT:
436             DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH_DIRECT NOT implemented\n");
437             Status = STATUS_NOT_SUPPORTED;
438             break;
439         case IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER:
440             DPRINT1("USBSTOR_HandleDeviceControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER NOT implemented\n");
441             Status = STATUS_NOT_SUPPORTED;
442             break;
443         case IOCTL_SCSI_GET_CAPABILITIES:
444         {
445             PIO_SCSI_CAPABILITIES Capabilities;
446 
447             // Legacy port capability query
448             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(PVOID))
449             {
450                 Capabilities = *((PVOID *)Irp->AssociatedIrp.SystemBuffer) = ExAllocatePoolWithTag(NonPagedPool,
451                                                                                                    sizeof(IO_SCSI_CAPABILITIES),
452                                                                                                    USB_STOR_TAG);
453                 Irp->IoStatus.Information = sizeof(PVOID);
454             }
455             else
456             {
457                 Capabilities = Irp->AssociatedIrp.SystemBuffer;
458                 Irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES);
459             }
460 
461             if (Capabilities)
462             {
463                 Capabilities->MaximumTransferLength = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH;
464                 Capabilities->MaximumPhysicalPages = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH / PAGE_SIZE + 1; // See CORE-10515 and CORE-10755
465                 Capabilities->SupportedAsynchronousEvents = 0;
466                 Capabilities->AlignmentMask = 0;
467                 Capabilities->TaggedQueuing = FALSE;
468                 Capabilities->AdapterScansDown = FALSE;
469                 Capabilities->AdapterUsesPio = FALSE;
470                 Status = STATUS_SUCCESS;
471             }
472             else
473             {
474                 Status = STATUS_INSUFFICIENT_RESOURCES;
475             }
476 
477             break;
478         }
479         case IOCTL_SCSI_GET_INQUIRY_DATA:
480         {
481             PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
482             ASSERT(PDODeviceExtension);
483             ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
484 
485             // get parameters
486             BusInfo = Irp->AssociatedIrp.SystemBuffer;
487             ScsiInquiryData = (PSCSI_INQUIRY_DATA)(BusInfo + 1);
488             InquiryData = (PINQUIRYDATA)ScsiInquiryData->InquiryData;
489 
490 
491             BusInfo->NumberOfBuses = 1;
492             BusInfo->BusData[0].NumberOfLogicalUnits = 1; //FIXME
493             BusInfo->BusData[0].InitiatorBusId = 0;
494             BusInfo->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
495 
496             ScsiInquiryData->PathId = 0;
497             ScsiInquiryData->TargetId = 0;
498             ScsiInquiryData->Lun = PDODeviceExtension->LUN & MAX_LUN;
499             ScsiInquiryData->DeviceClaimed = PDODeviceExtension->Claimed;
500             ScsiInquiryData->InquiryDataLength = sizeof(INQUIRYDATA);
501             ScsiInquiryData->NextInquiryDataOffset = 0;
502 
503             // Note: INQUIRYDATA structure is larger than INQUIRYDATABUFFERSIZE
504             RtlZeroMemory(InquiryData, sizeof(INQUIRYDATA));
505             RtlCopyMemory(InquiryData, &PDODeviceExtension->InquiryData, sizeof(PDODeviceExtension->InquiryData));
506 
507             InquiryData->Versions = 0x04;
508             InquiryData->ResponseDataFormat = 0x02; // some devices set this to 1
509 
510             Irp->IoStatus.Information = sizeof(SCSI_ADAPTER_BUS_INFO) + sizeof(SCSI_INQUIRY_DATA) + sizeof(INQUIRYDATA) - 1;
511             Status = STATUS_SUCCESS;
512 
513             break;
514         }
515         case IOCTL_SCSI_GET_ADDRESS:
516         {
517             PSCSI_ADDRESS Address = Irp->AssociatedIrp.SystemBuffer;
518 
519             Address->Length = sizeof(SCSI_ADDRESS);
520             Address->PortNumber = 0;
521             Address->PathId = 0;
522             Address->TargetId = 0;
523             Address->Lun = (((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LUN & MAX_LUN);
524             Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
525 
526             Status = STATUS_SUCCESS;
527 
528             break;
529         }
530         default:
531             DPRINT("USBSTOR_HandleDeviceControl IoControl %x not supported\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
532             Status = STATUS_NOT_SUPPORTED;
533             break;
534     }
535 
536     return Status;
537 }
538