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