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