43 Irp = IrpContext->Irp;
55 if (IrpContext->Srb.SenseInfoBuffer)
72 if (
Irp->PendingReturned)
140 DPRINT1(
"Failed to create IRP\n");
141 SptiFreeIrpContext(IrpContext);
203SptiSrbAppendSenseBuffer(
304 return WasCheckCondition;
339 (SenseData->AdditionalSenseCodeQualifier ==
342 WasCheckCondition =
TRUE;
345 return WasCheckCondition;
402#if defined(_WIN64) && defined(BUILD_WOW64_ENABLED)
403 if (IoIs32bitProcess(
Irp))
405 StructSize =
sizeof(ATA_PASS_THROUGH_EX32);
407 IsNativeStructSize =
FALSE;
414 IsNativeStructSize =
TRUE;
417 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < StructSize)
419 DPRINT1(
"Buffer too small %lu/%lu\n",
420 IoStack->Parameters.DeviceIoControl.InputBufferLength, StructSize);
424 if (Apt->Length != StructSize)
426 DPRINT1(
"Unknown structure size %lu\n", StructSize);
436 if (
BYTES_TO_PAGES(Apt->DataTransferLength) > MaximumPhysicalPages)
438 DPRINT1(
"Too large transfer %lu/%lu pages\n",
444#if defined(_WIN64) && defined(BUILD_WOW64_ENABLED)
445 AptData->Buffer =
NULL;
452 AptData->BufferOffset = Apt->DataBufferOffset;
455 if (Apt->DataTransferLength != 0)
457 if (IsDirectMemoryAccess)
458 *DataBuffer = AptData->Buffer;
471 DPRINT1(
"Unaligned data buffer %p:%lx\n",
476 if (Apt->DataTransferLength &
DeviceObject->AlignmentRequirement)
478 DPRINT1(
"Unaligned data transfer length %lx:%lx\n",
479 Apt->DataTransferLength,
DeviceObject->AlignmentRequirement);
484 (Apt->DataTransferLength == 0))
486 DPRINT1(
"Data buffer too small\n");
493 DPRINT1(
"Invalid timeout value %lu\n", Apt->TimeOutValue);
497 if (!IsDirectMemoryAccess)
502 Status = RtlULongPtrAdd(AptData->BufferOffset, Apt->DataTransferLength, &DataBufferEnd);
505 DPRINT1(
"Invalid data buffer offset\n");
509 if ((Apt->Length > AptData->BufferOffset) && (Apt->DataTransferLength != 0))
511 DPRINT1(
"Data buffer overlaps APT\n");
516 (DataBufferEnd > IoStack->Parameters.DeviceIoControl.OutputBufferLength))
518 DPRINT1(
"Data buffer outside of available space\n");
523 (DataBufferEnd > IoStack->Parameters.DeviceIoControl.InputBufferLength))
525 DPRINT1(
"Data buffer outside of available space\n");
545 Status = SptiSrbAppendSenseBuffer(
Srb, Spt->SenseInfoLength);
556 if (Spt->DataTransferLength != 0)
595 PULONG SenseInfoOffsetPtr;
599#if defined(_WIN64) && defined(BUILD_WOW64_ENABLED)
600 if (IoIs32bitProcess(
Irp))
602 StructSize =
sizeof(SCSI_PASS_THROUGH32);
606 IsNativeStructSize =
FALSE;
615 IsNativeStructSize =
TRUE;
618 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < StructSize)
620 DPRINT1(
"Buffer too small %lu/%lu\n",
621 IoStack->Parameters.DeviceIoControl.InputBufferLength, StructSize);
625 if (Spt->Length != StructSize)
627 DPRINT1(
"Unknown structure size %lu\n", StructSize);
637 if (
BYTES_TO_PAGES(Spt->DataTransferLength) > MaximumPhysicalPages)
639 DPRINT1(
"Too large transfer %lu/%lu pages\n",
645#if defined(_WIN64) && defined(BUILD_WOW64_ENABLED)
646 SptData->Buffer =
NULL;
653 SptData->BufferOffset = Spt->DataBufferOffset;
655 *SenseInfoOffset = *SenseInfoOffsetPtr;
657 if (Spt->DataTransferLength != 0)
659 if (IsDirectMemoryAccess)
660 *DataBuffer = SptData->Buffer;
673 DPRINT1(
"Unaligned data buffer %p:%lx\n",
678 if (Spt->DataTransferLength &
DeviceObject->AlignmentRequirement)
680 DPRINT1(
"Unaligned data transfer length %lx:%lx\n",
681 Spt->DataTransferLength,
DeviceObject->AlignmentRequirement);
688 DPRINT1(
"Invalid timeout value %lu\n", Spt->TimeOutValue);
694 DPRINT1(
"Invalid CDB size %u\n", Spt->CdbLength);
700 DPRINT1(
"Unknown DataIn value %u\n", Spt->DataIn);
704 if (Spt->SenseInfoLength != 0)
706 ULONG SenseBufferEnd;
709 Status = RtlULongAdd(*SenseInfoOffset, Spt->SenseInfoLength, &SenseBufferEnd);
712 DPRINT1(
"Invalid sense buffer offset\n");
716 if (Spt->Length > *SenseInfoOffset)
718 DPRINT1(
"Sense buffer overlaps SPT\n");
722 if (!IsDirectMemoryAccess)
724 if ((SenseBufferEnd > SptData->BufferOffset) && (Spt->DataTransferLength != 0))
726 DPRINT1(
"Sense buffer overlaps data buffer\n");
730 if (SenseBufferEnd > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
732 DPRINT1(
"Sense buffer outside of available space\n");
738 if (!IsDirectMemoryAccess)
743 Status = RtlULongPtrAdd(SptData->BufferOffset, Spt->DataTransferLength, &DataBufferEnd);
746 DPRINT1(
"Invalid data buffer offset\n");
750 if ((Spt->Length > SptData->BufferOffset) && (Spt->DataTransferLength != 0))
752 DPRINT1(
"Data buffer inside of structure bounds\n");
758 if (DataBufferEnd > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
760 DPRINT1(
"Data buffer outside of available space\n");
767 if (DataBufferEnd > IoStack->Parameters.DeviceIoControl.InputBufferLength)
769 DPRINT1(
"Data buffer outside of available space\n");
810 IsDirectMemoryAccess,
812 MaximumPhysicalPages,
821 DPRINT(
"APT: Curr %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
822 TaskFile[8 + 0], TaskFile[8 + 1], TaskFile[8 + 2], TaskFile[8 + 3],
823 TaskFile[8 + 4], TaskFile[8 + 5], TaskFile[8 + 6],
828 DPRINT(
"APT: Prev %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
829 TaskFile[0], TaskFile[1], TaskFile[2], TaskFile[3],
830 TaskFile[4], TaskFile[5], TaskFile[6]);
837 IsDirectMemoryAccess,
855 if (IsDirectMemoryAccess)
867 DPRINT(
"APT: Return %lx, DTL %lu, %lu bytes\n",
871 DPRINT(
"APT: Return curr %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
872 TaskFile[8 + 0], TaskFile[8 + 1], TaskFile[8 + 2], TaskFile[8 + 3],
873 TaskFile[8 + 4], TaskFile[8 + 5], TaskFile[8 + 6]);
876 DPRINT(
"APT: Return prev %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
877 TaskFile[0], TaskFile[1], TaskFile[2], TaskFile[3],
878 TaskFile[4], TaskFile[5], TaskFile[6]);
882 SptiFreeIrpContext(IrpContext);
898 ULONG SenseInfoOffset;
917 IsDirectMemoryAccess,
919 MaximumPhysicalPages,
928 DPRINT(
"SPT: Flags %u, DTL %lu, sense len %u\n",
932 DPRINT(
"SPT: CDB %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
939 IsDirectMemoryAccess,
979 if (IsDirectMemoryAccess)
996 DPRINT(
"SPT: Return %lx, DTL %lu, "
997 "Srb status %02x, SCSI status %02x, sense len %u, %lu bytes\n",
1006 SptiFreeIrpContext(IrpContext);
#define ExAllocatePoolUninitialized
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
_In_ PSCSI_REQUEST_BLOCK Srb
#define SCSISTAT_CHECK_CONDITION
#define SCSI_ADSENSE_NO_SENSE
#define SCSI_SENSE_RECOVERED_ERROR
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
#define NT_SUCCESS(StatCode)
static const WCHAR Cleanup[]
#define SRB_FUNCTION_EXECUTE_SCSI
#define SRB_STATUS_DATA_OVERRUN
#define SRB_FLAGS_DATA_OUT
#define SRB_STATUS_AUTOSENSE_VALID
#define SRB_FLAGS_DISABLE_AUTOSENSE
#define SRB_FLAGS_DATA_IN
#define SRB_FLAGS_UNSPECIFIED_DIRECTION
#define SRB_STATUS(Status)
#define SRB_FLAGS_NO_QUEUE_FREEZE
#define __drv_freesMem(kind)
#define __drv_allocatesMem(kind)
#define PsGetCurrentThread()
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
#define KeInitializeEvent(pEvt, foo, foo2)
#define KeSetEvent(pEvt, foo, foo2)
#define NonPagedPoolCacheAligned
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_opt_ GUID _In_ USHORT DataBufferLength
#define EXCEPTION_EXECUTE_HANDLER
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
#define RTL_FIELD_SIZE(type, field)
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
#define ExFreePoolWithTag(_P, _T)
FORCEINLINE PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
#define _In_reads_opt_(s)
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
#define UNREFERENCED_PARAMETER(P)
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
VOID NTAPI IoFreeIrp(IN PIRP Irp)
#define STATUS_REVISION_MISMATCH
#define _SEH2_EXCEPT(...)
#define _SEH2_YIELD(__stmt)
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
_In_opt_ WDFREQUEST _In_ ULONG MaximumTransferLength
#define IOCTL_SCSI_PASS_THROUGH
#define IOCTL_SCSI_PASS_THROUGH_DIRECT
#define SCSI_IOCTL_DATA_UNSPECIFIED
#define SCSI_IOCTL_DATA_IN
#define SCSI_IOCTL_DATA_OUT
struct _SCSI_PASS_THROUGH SCSI_PASS_THROUGH
struct _SCSI_SENSE_DESCRIPTOR_ATA_STATUS_RETURN * PSCSI_SENSE_DESCRIPTOR_ATA_STATUS_RETURN
#define SCSI_SENSE_ERRORCODE_DESCRIPTOR_CURRENT
#define SCSIOP_ATA_PASSTHROUGH16
#define SCSI_SENSE_DESCRIPTOR_TYPE_ATA_STATUS_RETURN
_In_ UCHAR _Outptr_result_bytebuffer_ DescriptorBufferLength PVOID * DescriptorBuffer
#define IOCTL_ATA_PASS_THROUGH_DIRECT
#define IOCTL_ATA_PASS_THROUGH
struct _ATA_PASS_THROUGH_EX ATA_PASS_THROUGH_EX
#define STATUS_MORE_PROCESSING_REQUIRED
#define STATUS_BUFFER_TOO_SMALL
NTSTATUS SptiHandleAtaPassthru(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _In_ ULONG MaximumTransferLength, _In_ ULONG MaximumPhysicalPages)
Handler for the IOCTL_ATA_PASS_THROUGH and IOCTL_ATA_PASS_THROUGH_DIRECT requests.
static VOID SptiTranslateTaskFileToCdb(_Out_ CDB *__restrict Cdb, _In_ UCHAR *__restrict TaskFile, _In_ USHORT AtaFlags)
static NTSTATUS SptiTranslateAptToSrb(_Out_ SCSI_REQUEST_BLOCK *__restrict Srb, _In_ ATA_PASS_THROUGH_EX *__restrict Apt, _In_ PUCHAR TaskFile)
static NTSTATUS SptiCallDriver(_In_ PDEVICE_OBJECT DeviceObject, _In_ PPASSTHROUGH_IRP_CONTEXT IrpContext)
static VOID SptiInitializeOutputBuffer(_In_ PIRP Irp)
static NTSTATUS SptiInitializeSpt(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PIO_STACK_LOCATION IoStack, _In_ BOOLEAN IsDirectMemoryAccess, _In_ ULONG MaximumTransferLength, _In_ ULONG MaximumPhysicalPages, _In_ PSCSI_PASS_THROUGH Spt, _Out_ PPASSTHROUGH_DATA SptData, _Out_ PULONG SenseInfoOffset, _Out_ PUCHAR *Cdb, _Out_ PVOID *DataBuffer)
static NTSTATUS SptiTranslateSptToSrb(_Out_ SCSI_REQUEST_BLOCK *__restrict Srb, _In_ SCSI_PASS_THROUGH *__restrict Spt, _In_ PUCHAR Cdb)
NTSTATUS SptiHandleScsiPassthru(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _In_ ULONG MaximumTransferLength, _In_ ULONG MaximumPhysicalPages)
Handler for the IOCTL_SCSI_PASS_THROUGH and IOCTL_SCSI_PASS_THROUGH_DIRECT requests.
static BOOLEAN SptiTranslateAtaStatusReturnToTaskFile(_In_ SCSI_REQUEST_BLOCK *__restrict Srb, _In_ DESCRIPTOR_SENSE_DATA *__restrict SenseData, _Out_ UCHAR *__restrict TaskFile)
static NTSTATUS SptiInitializeApt(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PIO_STACK_LOCATION IoStack, _In_ BOOLEAN IsDirectMemoryAccess, _In_ ULONG MaximumTransferLength, _In_ ULONG MaximumPhysicalPages, _In_ PATA_PASS_THROUGH_EX Apt, _Out_ PPASSTHROUGH_DATA AptData, _Out_ PUCHAR *TaskFile, _Out_ PVOID *DataBuffer)
static IO_COMPLETION_ROUTINE SptiCompletionRoutine
#define ATA_PASSTHROUGH_PROTOCOL_PIO_DATA_IN
#define ATA_PASSTHROUGH_PROTOCOL_NON_DATA
#define ATA_PASSTHROUGH_PROTOCOL_PIO_DATA_OUT
#define ATA_PASSTHROUGH_PROTOCOL_DMA
#define SCSI_SENSEQ_ATA_PASS_THROUGH_INFORMATION_AVAILABLE
#define GET_IOCTL(IoStack)
#define PASSTHROUGH_CMD_TIMEOUT_MIN_SEC
#define PASSTHROUGH_CMD_TIMEOUT_MAX_SEC
struct _IO_STACK_LOCATION::@4235::@4257 Scsi
struct _IO_STACK_LOCATION::@1701::@1702 DeviceIoControl
union _IO_STACK_LOCATION::@1701 Parameters
UCHAR SenseInfoBufferLength
#define FIELD_OFFSET(t, f)
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
#define ATA_FLAGS_USE_DMA
#define ATA_FLAGS_DATA_OUT
#define ATA_FLAGS_DATA_IN
#define ATA_FLAGS_48BIT_COMMAND
#define STATUS_INVALID_PARAMETER
#define STATUS_INSUFFICIENT_RESOURCES
struct _CDB::_ATA_PASSTHROUGH16 ATA_PASSTHROUGH16
_In_ PDEVICE_OBJECT DeviceObject
_In_ WDFREQUEST _In_ size_t OutputBufferLength
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
#define IRP_MN_SCSI_CLASS
#define BYTES_TO_PAGES(Size)