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