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
IsRequestValid(PIRP Irp)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
USBSTOR_HandleInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)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
USBSTOR_GetFieldLength(IN PUCHAR Name,IN ULONG MaxLength)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
USBSTOR_HandleQueryProperty(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)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
USBSTOR_HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)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