[USBSTOR] Better validate SCSI IRPs.
[reactos.git] / drivers / usb / usbstor / disk.c
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 = PDODeviceExtension->InquiryData;
287 ASSERT(InquiryData);
288
289 // compute extra parameters length
290 FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->VendorId, 8);
291 FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->ProductId, 16);
292 FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->ProductRevisionLevel, 4);
293
294 if (FDODeviceExtension->SerialNumber)
295 {
296 FieldLengthSerialNumber = wcslen(FDODeviceExtension->SerialNumber->bString);
297 }
298 else
299 {
300 FieldLengthSerialNumber = 0;
301 }
302
303 // total length required is sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLength + 4 extra null bytes - 1
304 // -1 due STORAGE_DEVICE_DESCRIPTOR contains one byte length of parameter data
305 TotalLength = sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3;
306
307 // check if output buffer is long enough
308 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < TotalLength)
309 {
310 // buffer too small
311 DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
312 ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
313
314 // return required size
315 DescriptorHeader->Version = TotalLength;
316 DescriptorHeader->Size = TotalLength;
317
318 Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
319 return STATUS_SUCCESS;
320 }
321
322 // initialize the device descriptor
323 DeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
324
325 DeviceDescriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR);
326 DeviceDescriptor->Size = TotalLength;
327 DeviceDescriptor->DeviceType = InquiryData->DeviceType;
328 DeviceDescriptor->DeviceTypeModifier = InquiryData->DeviceTypeModifier;
329 DeviceDescriptor->RemovableMedia = InquiryData->RemovableMedia;
330 DeviceDescriptor->CommandQueueing = FALSE;
331 DeviceDescriptor->BusType = BusTypeUsb;
332 DeviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR);
333 DeviceDescriptor->ProductIdOffset = DeviceDescriptor->VendorIdOffset + FieldLengthVendor + 1;
334 DeviceDescriptor->ProductRevisionOffset = DeviceDescriptor->ProductIdOffset + FieldLengthProduct + 1;
335 DeviceDescriptor->SerialNumberOffset = (FieldLengthSerialNumber > 0 ? DeviceDescriptor->ProductRevisionOffset + FieldLengthRevision + 1 : 0);
336 DeviceDescriptor->RawPropertiesLength = FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3 + (FieldLengthSerialNumber > 0 ? + 1 : 0);
337
338 // copy descriptors
339 Buffer = (PUCHAR)((ULONG_PTR)DeviceDescriptor + sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR));
340
341 RtlCopyMemory(Buffer, InquiryData->VendorId, FieldLengthVendor);
342 Buffer[FieldLengthVendor] = '\0';
343 Buffer += FieldLengthVendor + 1;
344
345 RtlCopyMemory(Buffer, InquiryData->ProductId, FieldLengthProduct);
346 Buffer[FieldLengthProduct] = '\0';
347 Buffer += FieldLengthProduct + 1;
348
349 RtlCopyMemory(Buffer, InquiryData->ProductRevisionLevel, FieldLengthRevision);
350 Buffer[FieldLengthRevision] = '\0';
351 Buffer += FieldLengthRevision + 1;
352
353 if (FieldLengthSerialNumber)
354 {
355 RtlInitUnicodeString(&SerialNumber, FDODeviceExtension->SerialNumber->bString);
356
357 AnsiString.Buffer = (PCHAR)Buffer;
358 AnsiString.Length = 0;
359 AnsiString.MaximumLength = FieldLengthSerialNumber * sizeof(WCHAR);
360
361 Status = RtlUnicodeStringToAnsiString(&AnsiString, &SerialNumber, FALSE);
362 ASSERT(Status == STATUS_SUCCESS);
363 }
364
365 DPRINT("Vendor %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->VendorIdOffset));
366 DPRINT("Product %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductIdOffset));
367 DPRINT("Revision %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductRevisionOffset));
368 DPRINT("Serial %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->SerialNumberOffset));
369
370 Irp->IoStatus.Information = TotalLength;
371 return STATUS_SUCCESS;
372 }
373 else
374 {
375 // adapter property query request
376
377 DPRINT("USBSTOR_HandleQueryProperty StorageAdapterProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
378
379 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_ADAPTER_DESCRIPTOR))
380 {
381 // buffer too small
382 DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
383 ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
384
385 // return required size
386 DescriptorHeader->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
387 DescriptorHeader->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
388
389 Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
390 return STATUS_SUCCESS;
391 }
392
393 // get adapter descriptor, information is returned in the same buffer
394 AdapterDescriptor = (PSTORAGE_ADAPTER_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
395
396 // fill out descriptor
397 AdapterDescriptor->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
398 AdapterDescriptor->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
399 AdapterDescriptor->MaximumTransferLength = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH;
400 AdapterDescriptor->MaximumPhysicalPages = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH / PAGE_SIZE + 1; // See CORE-10515 and CORE-10755
401 AdapterDescriptor->AlignmentMask = 0;
402 AdapterDescriptor->AdapterUsesPio = FALSE;
403 AdapterDescriptor->AdapterScansDown = FALSE;
404 AdapterDescriptor->CommandQueueing = FALSE;
405 AdapterDescriptor->AcceleratedTransfer = FALSE;
406 AdapterDescriptor->BusType = BusTypeUsb;
407 AdapterDescriptor->BusMajorVersion = 0x2; //FIXME verify
408 AdapterDescriptor->BusMinorVersion = 0x00; //FIXME
409
410 // store returned length
411 Irp->IoStatus.Information = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
412
413 return STATUS_SUCCESS;
414 }
415 }
416
417 NTSTATUS
418 USBSTOR_HandleDeviceControl(
419 IN PDEVICE_OBJECT DeviceObject,
420 IN PIRP Irp)
421 {
422 PIO_STACK_LOCATION IoStack;
423 NTSTATUS Status;
424 PPDO_DEVICE_EXTENSION PDODeviceExtension;
425 PSCSI_ADAPTER_BUS_INFO BusInfo;
426 PSCSI_INQUIRY_DATA ScsiInquiryData;
427 PINQUIRYDATA InquiryData;
428
429 IoStack = IoGetCurrentIrpStackLocation(Irp);
430
431 switch (IoStack->Parameters.DeviceIoControl.IoControlCode)
432 {
433 case IOCTL_STORAGE_QUERY_PROPERTY:
434 Status = USBSTOR_HandleQueryProperty(DeviceObject, Irp);
435 break;
436 case IOCTL_SCSI_PASS_THROUGH:
437 DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH NOT implemented\n");
438 Status = STATUS_NOT_SUPPORTED;
439 break;
440 case IOCTL_SCSI_PASS_THROUGH_DIRECT:
441 DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH_DIRECT NOT implemented\n");
442 Status = STATUS_NOT_SUPPORTED;
443 break;
444 case IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER:
445 DPRINT1("USBSTOR_HandleDeviceControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER NOT implemented\n");
446 Status = STATUS_NOT_SUPPORTED;
447 break;
448 case IOCTL_SCSI_GET_CAPABILITIES:
449 {
450 PIO_SCSI_CAPABILITIES Capabilities;
451
452 // Legacy port capability query
453 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(PVOID))
454 {
455 Capabilities = *((PVOID *)Irp->AssociatedIrp.SystemBuffer) = ExAllocatePoolWithTag(NonPagedPool,
456 sizeof(IO_SCSI_CAPABILITIES),
457 USB_STOR_TAG);
458 Irp->IoStatus.Information = sizeof(PVOID);
459 }
460 else
461 {
462 Capabilities = Irp->AssociatedIrp.SystemBuffer;
463 Irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES);
464 }
465
466 if (Capabilities)
467 {
468 Capabilities->MaximumTransferLength = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH;
469 Capabilities->MaximumPhysicalPages = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH / PAGE_SIZE + 1; // See CORE-10515 and CORE-10755
470 Capabilities->SupportedAsynchronousEvents = 0;
471 Capabilities->AlignmentMask = 0;
472 Capabilities->TaggedQueuing = FALSE;
473 Capabilities->AdapterScansDown = FALSE;
474 Capabilities->AdapterUsesPio = FALSE;
475 Status = STATUS_SUCCESS;
476 }
477 else
478 {
479 Status = STATUS_INSUFFICIENT_RESOURCES;
480 }
481
482 break;
483 }
484 case IOCTL_SCSI_GET_INQUIRY_DATA:
485 {
486 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
487 ASSERT(PDODeviceExtension);
488 ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
489
490 // get parameters
491 BusInfo = Irp->AssociatedIrp.SystemBuffer;
492 ScsiInquiryData = (PSCSI_INQUIRY_DATA)(BusInfo + 1);
493 InquiryData = (PINQUIRYDATA)ScsiInquiryData->InquiryData;
494
495
496 BusInfo->NumberOfBuses = 1;
497 BusInfo->BusData[0].NumberOfLogicalUnits = 1; //FIXME
498 BusInfo->BusData[0].InitiatorBusId = 0;
499 BusInfo->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
500
501 ScsiInquiryData->PathId = 0;
502 ScsiInquiryData->TargetId = 0;
503 ScsiInquiryData->Lun = PDODeviceExtension->LUN & MAX_LUN;
504 ScsiInquiryData->DeviceClaimed = PDODeviceExtension->Claimed;
505 ScsiInquiryData->InquiryDataLength = sizeof(INQUIRYDATA);
506 ScsiInquiryData->NextInquiryDataOffset = 0;
507
508 // Note: INQUIRYDATA structure is larger than INQUIRYDATABUFFERSIZE
509 RtlZeroMemory(InquiryData, sizeof(INQUIRYDATA));
510 RtlCopyMemory(InquiryData, PDODeviceExtension->InquiryData, INQUIRYDATABUFFERSIZE);
511
512 InquiryData->Versions = 0x04;
513 InquiryData->ResponseDataFormat = 0x02; // some devices set this to 1
514
515 Irp->IoStatus.Information = sizeof(SCSI_ADAPTER_BUS_INFO) + sizeof(SCSI_INQUIRY_DATA) + sizeof(INQUIRYDATA) - 1;
516 Status = STATUS_SUCCESS;
517
518 break;
519 }
520 case IOCTL_SCSI_GET_ADDRESS:
521 {
522 PSCSI_ADDRESS Address = Irp->AssociatedIrp.SystemBuffer;
523
524 Address->Length = sizeof(SCSI_ADDRESS);
525 Address->PortNumber = 0;
526 Address->PathId = 0;
527 Address->TargetId = 0;
528 Address->Lun = (((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LUN & MAX_LUN);
529 Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
530
531 Status = STATUS_SUCCESS;
532
533 break;
534 }
535 default:
536 DPRINT("USBSTOR_HandleDeviceControl IoControl %x not supported\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
537 Status = STATUS_NOT_SUPPORTED;
538 break;
539 }
540
541 return Status;
542 }