[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 4/5] Rationalize SCSIOP_* handlers
From: Owen Smith <owen.smith@xxxxxxxxxx> * Use same error handling for invalid buffers, etc. * Allow for SCSIOP_MODE_SENSE10 * Correctly report VDISK_READONLY flag Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xenvbd/frontend.c | 40 ++++ src/xenvbd/frontend.h | 5 + src/xenvbd/target.c | 555 +++++++++++++++++++++++++++----------------------- 3 files changed, 348 insertions(+), 252 deletions(-) diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c index d7fff89..b7e61c2 100644 --- a/src/xenvbd/frontend.c +++ b/src/xenvbd/frontend.c @@ -1889,5 +1889,45 @@ FrontendGetDiskInfo( { return &Frontend->DiskInfo; } +//FRONTEND_GET_PROPERTY(Connected, BOOLEAN) +BOOLEAN +FrontendGetConnected( + IN PXENVBD_FRONTEND Frontend + ) +{ + return Frontend->Caps.Connected; +} +//FRONTEND_GET_PROPERTY(ReadOnly, BOOLEAN) +BOOLEAN +FrontendGetReadOnly( + IN PXENVBD_FRONTEND Frontend + ) +{ + return !!(Frontend->DiskInfo.DiskInfo & VDISK_READONLY); +} +//FRONTEND_GET_PROPERTY(Discard, BOOLEAN) +BOOLEAN +FrontendGetDiscard( + IN PXENVBD_FRONTEND Frontend + ) +{ + return Frontend->DiskInfo.Discard; +} +//FRONTEND_GET_PROPERTY(FlushCache, BOOLEAN) +BOOLEAN +FrontendGetFlushCache( + IN PXENVBD_FRONTEND Frontend + ) +{ + return Frontend->DiskInfo.FlushCache; +} +//FRONTEND_GET_PROPERTY(Barrier, BOOLEAN) +BOOLEAN +FrontendGetBarrier( + IN PXENVBD_FRONTEND Frontend + ) +{ + return Frontend->DiskInfo.Barrier; +} #undef FRONTEND_GET_PROPERTY diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h index 46f2e39..1488476 100644 --- a/src/xenvbd/frontend.h +++ b/src/xenvbd/frontend.h @@ -162,6 +162,11 @@ FRONTEND_GET_PROPERTY(FrontendPath, PCHAR) FRONTEND_GET_PROPERTY(Caps, PXENVBD_CAPS) FRONTEND_GET_PROPERTY(Features, PXENVBD_FEATURES) FRONTEND_GET_PROPERTY(DiskInfo, PXENVBD_DISKINFO) +FRONTEND_GET_PROPERTY(Connected, BOOLEAN) +FRONTEND_GET_PROPERTY(ReadOnly, BOOLEAN) +FRONTEND_GET_PROPERTY(Discard, BOOLEAN) +FRONTEND_GET_PROPERTY(FlushCache, BOOLEAN) +FRONTEND_GET_PROPERTY(Barrier, BOOLEAN) #undef FRONTEND_GET_PROPERTY diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c index e624979..0956662 100644 --- a/src/xenvbd/target.c +++ b/src/xenvbd/target.c @@ -209,323 +209,354 @@ TargetSetDeviceObject( Target->DeviceObject = DeviceObject; } -__checkReturn -static FORCEINLINE BOOLEAN -__ValidateSectors( - __in ULONG64 SectorCount, - __in ULONG64 Start, - __in ULONG Length +static DECLSPEC_NOINLINE BOOLEAN +TargetReadWrite( + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb ) { - // Deal with overflow - return (Start < SectorCount) && ((Start + Length) <= SectorCount); -} + PXENVBD_SRBEXT SrbExt = Srb->SrbExtension; + PXENVBD_FRONTEND Frontend = Target->Frontend; + PXENVBD_RING Ring = FrontendGetRing(Frontend); + ULONG64 SectorCount; + ULONG64 SectorStart; + ULONG NumSectors; -__checkReturn -static FORCEINLINE BOOLEAN -__ValidateSrbBuffer( - __in PCHAR Caller, - __in PSCSI_REQUEST_BLOCK Srb, - __in ULONG MinLength - ) -{ - if (Srb->DataBuffer == NULL) { - Error("%s: Srb[0x%p].DataBuffer = NULL\n", Caller, Srb); - return FALSE; - } - if (MinLength) { - if (Srb->DataTransferLength < MinLength) { - Error("%s: Srb[0x%p].DataTransferLength < %d\n", Caller, Srb, MinLength); - return FALSE; - } - } else { - if (Srb->DataTransferLength == 0) { - Error("%s: Srb[0x%p].DataTransferLength = 0\n", Caller, Srb); - return FALSE; - } - } + Srb->SrbStatus = SRB_STATUS_ERROR; + if (!FrontendGetConnected(Frontend)) + goto fail1; - return TRUE; -} + // disallow writes to read-only disks + if (FrontendGetReadOnly(Frontend) && + Cdb_OperationEx(Srb) == SCSIOP_WRITE) + goto fail2; -__checkReturn -static DECLSPEC_NOINLINE BOOLEAN -TargetReadWrite( - __in PXENVBD_TARGET Target, - __in PSCSI_REQUEST_BLOCK Srb - ) -{ - PXENVBD_DISKINFO DiskInfo = FrontendGetDiskInfo(Target->Frontend); - PXENVBD_SRBEXT SrbExt = Srb->SrbExtension; - PXENVBD_RING Ring = FrontendGetRing(Target->Frontend); - - if (FrontendGetCaps(Target->Frontend)->Connected == FALSE) { - Trace("Target[%d] : Not Ready, fail SRB\n", TargetGetTargetId(Target)); - Srb->ScsiStatus = 0x40; // SCSI_ABORT; - return TRUE; - } + // check Sectors requested is on the disk + SectorCount = FrontendGetDiskInfo(Frontend)->SectorCount; + SectorStart = Cdb_LogicalBlock(Srb); + NumSectors = Cdb_TransferBlock(Srb); - // check valid sectors - if (!__ValidateSectors(DiskInfo->SectorCount, Cdb_LogicalBlock(Srb), Cdb_TransferBlock(Srb))) { - Trace("Target[%d] : Invalid Sector (%d @ %lld < %lld)\n", TargetGetTargetId(Target), Cdb_TransferBlock(Srb), Cdb_LogicalBlock(Srb), DiskInfo->SectorCount); - Srb->ScsiStatus = 0x40; // SCSI_ABORT - return TRUE; // Complete now - } + if (SectorStart >= SectorCount) + goto fail3; + if ((SectorStart + NumSectors) > SectorCount) + goto fail4; + Srb->SrbStatus = SRB_STATUS_PENDING; RingQueueRequest(Ring, SrbExt); return FALSE; + +fail4: + Error("fail4\n"); +fail3: + Error("fail3\n"); +fail2: + Error("fail2\n"); +fail1: + Error("fail1\n"); + return TRUE; } -__checkReturn static DECLSPEC_NOINLINE BOOLEAN TargetSyncCache( - __in PXENVBD_TARGET Target, - __in PSCSI_REQUEST_BLOCK Srb + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb ) { - PXENVBD_SRBEXT SrbExt = Srb->SrbExtension; - PXENVBD_RING Ring = FrontendGetRing(Target->Frontend); + PXENVBD_SRBEXT SrbExt = Srb->SrbExtension; + PXENVBD_FRONTEND Frontend = Target->Frontend; + PXENVBD_RING Ring = FrontendGetRing(Frontend); - if (FrontendGetCaps(Target->Frontend)->Connected == FALSE) { - Trace("Target[%d] : Not Ready, fail SRB\n", TargetGetTargetId(Target)); - Srb->ScsiStatus = 0x40; // SCSI_ABORT; - return TRUE; - } + Srb->SrbStatus = SRB_STATUS_ERROR; + if (!FrontendGetConnected(Frontend)) + goto fail1; - if (FrontendGetDiskInfo(Target->Frontend)->FlushCache == FALSE && - FrontendGetDiskInfo(Target->Frontend)->Barrier == FALSE) { - Trace("Target[%d] : FLUSH and BARRIER not supported, suppressing\n", TargetGetTargetId(Target)); - Srb->ScsiStatus = 0x00; // SCSI_GOOD - Srb->SrbStatus = SRB_STATUS_SUCCESS; - return TRUE; - } + if (FrontendGetReadOnly(Frontend)) + goto fail2; + + // If neither FLUSH or BARRIER is supported, just succceed the SRB + if (!(FrontendGetFlushCache(Frontend) || + FrontendGetBarrier(Frontend))) + goto succeed; + Srb->SrbStatus = SRB_STATUS_PENDING; RingQueueRequest(Ring, SrbExt); return FALSE; + +succeed: + Srb->SrbStatus = SRB_STATUS_SUCCESS; + return TRUE; + +fail2: + Error("fail2\n"); +fail1: + Error("fail1\n"); + return TRUE; } -__checkReturn static DECLSPEC_NOINLINE BOOLEAN TargetUnmap( - __in PXENVBD_TARGET Target, - __in PSCSI_REQUEST_BLOCK Srb + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb ) { - PXENVBD_SRBEXT SrbExt = Srb->SrbExtension; - PXENVBD_RING Ring = FrontendGetRing(Target->Frontend); + PXENVBD_SRBEXT SrbExt = Srb->SrbExtension; + PXENVBD_FRONTEND Frontend = Target->Frontend; + PXENVBD_RING Ring = FrontendGetRing(Frontend); - if (FrontendGetCaps(Target->Frontend)->Connected == FALSE) { - Trace("Target[%d] : Not Ready, fail SRB\n", TargetGetTargetId(Target)); - Srb->ScsiStatus = 0x40; // SCSI_ABORT; - return TRUE; - } + Srb->SrbStatus = SRB_STATUS_ERROR; + if (!FrontendGetConnected(Frontend)) + goto fail1; - if (FrontendGetDiskInfo(Target->Frontend)->Discard == FALSE) { - Trace("Target[%d] : DISCARD not supported, suppressing\n", TargetGetTargetId(Target)); - Srb->ScsiStatus = 0x00; // SCSI_GOOD - Srb->SrbStatus = SRB_STATUS_SUCCESS; - return TRUE; - } + if (FrontendGetReadOnly(Frontend)) + goto fail2; + if (!FrontendGetDiscard(Frontend)) + goto succeed; + + Srb->SrbStatus = SRB_STATUS_PENDING; RingQueueRequest(Ring, SrbExt); return FALSE; + +succeed: + Srb->SrbStatus = SRB_STATUS_SUCCESS; + return TRUE; + +fail2: + Error("fail2\n"); +fail1: + Error("fail1\n"); + return TRUE; } -#define MODE_CACHING_PAGE_LENGTH 20 -static DECLSPEC_NOINLINE VOID -TargetModeSense( - __in PXENVBD_TARGET Target, - __in PSCSI_REQUEST_BLOCK Srb +static FORCEINLINE VOID +__TargetModeSense( + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb, + IN PVOID Data, + IN ULONG Length, + OUT PULONG Size, + OUT PULONG ModeDataLength, + OUT PULONG BlockDescrLength ) { - PMODE_PARAMETER_HEADER Header = Srb->DataBuffer; - const UCHAR PageCode = Cdb_PageCode(Srb); - ULONG LengthLeft = Cdb_AllocationLength(Srb); - PVOID CurrentPage = Srb->DataBuffer; - - UNREFERENCED_PARAMETER(Target); - - RtlZeroMemory(Srb->DataBuffer, Srb->DataTransferLength); - - if (!__ValidateSrbBuffer(__FUNCTION__, Srb, (ULONG)sizeof(struct _MODE_SENSE))) { - Srb->ScsiStatus = 0x40; - Srb->SrbStatus = SRB_STATUS_DATA_OVERRUN; - Srb->DataTransferLength = 0; - return; - } - - // TODO : CDROM requires more ModePage entries - // Header - Header->ModeDataLength = sizeof(MODE_PARAMETER_HEADER) - 1; - Header->MediumType = 0; - Header->DeviceSpecificParameter = 0; - Header->BlockDescriptorLength = 0; - LengthLeft -= sizeof(MODE_PARAMETER_HEADER); - CurrentPage = ((PUCHAR)CurrentPage + sizeof(MODE_PARAMETER_HEADER)); + const UCHAR PageCode = Cdb_PageCode(Srb); // Fill in Block Parameters (if Specified and space) // when the DBD (Disable Block Descriptor) is set, ignore the block page if (Cdb_Dbd(Srb) == 0 && - LengthLeft >= sizeof(MODE_PARAMETER_BLOCK)) { - PMODE_PARAMETER_BLOCK Block = (PMODE_PARAMETER_BLOCK)CurrentPage; - // Fill in BlockParams - Block->DensityCode = 0; - Block->NumberOfBlocks[0] = 0; - Block->NumberOfBlocks[1] = 0; - Block->NumberOfBlocks[2] = 0; - Block->BlockLength[0] = 0; - Block->BlockLength[1] = 0; - Block->BlockLength[2] = 0; - - Header->BlockDescriptorLength = sizeof(MODE_PARAMETER_BLOCK); - Header->ModeDataLength += sizeof(MODE_PARAMETER_BLOCK); - LengthLeft -= sizeof(MODE_PARAMETER_BLOCK); - CurrentPage = ((PUCHAR)CurrentPage + sizeof(MODE_PARAMETER_BLOCK)); + Length - *Size >= sizeof(MODE_PARAMETER_BLOCK)) { + // PMODE_PARAMETER_BLOCK Block = (PMODE_PARAMETER_BLOCK)((PUCHAR)Data + *Size); + + // Fill in BlockParams - All Zeroes + + *BlockDescrLength = sizeof(MODE_PARAMETER_BLOCK); + *ModeDataLength += sizeof(MODE_PARAMETER_BLOCK); + *Size += sizeof(MODE_PARAMETER_BLOCK); } // Fill in Cache Parameters (if Specified and space) if ((PageCode == MODE_PAGE_CACHING || PageCode == MODE_SENSE_RETURN_ALL) && - LengthLeft >= MODE_CACHING_PAGE_LENGTH) { - PMODE_CACHING_PAGE Caching = (PMODE_CACHING_PAGE)CurrentPage; + Length - *Size >= sizeof(MODE_CACHING_PAGE)) { + PMODE_CACHING_PAGE Caching = (PMODE_CACHING_PAGE)((PUCHAR)Data + *Size); + // Fill in CachingParams - Caching->PageCode = MODE_PAGE_CACHING; - Caching->PageSavable = 0; - Caching->PageLength = MODE_CACHING_PAGE_LENGTH; - Caching->ReadDisableCache = 0; - Caching->MultiplicationFactor = 0; - Caching->WriteCacheEnable = FrontendGetDiskInfo(Target->Frontend)->FlushCache ? 1 : 0; - Caching->WriteRetensionPriority = 0; - Caching->ReadRetensionPriority = 0; - Caching->DisablePrefetchTransfer[0] = 0; - Caching->DisablePrefetchTransfer[1] = 0; - Caching->MinimumPrefetch[0] = 0; - Caching->MinimumPrefetch[1] = 0; - Caching->MaximumPrefetch[0] = 0; - Caching->MaximumPrefetch[1] = 0; - Caching->MaximumPrefetchCeiling[0] = 0; - Caching->MaximumPrefetchCeiling[1] = 0; - - Header->ModeDataLength += MODE_CACHING_PAGE_LENGTH; - LengthLeft -= MODE_CACHING_PAGE_LENGTH; - CurrentPage = ((PUCHAR)CurrentPage + MODE_CACHING_PAGE_LENGTH); + Caching->PageCode = MODE_PAGE_CACHING; + Caching->PageLength = sizeof(MODE_CACHING_PAGE); + Caching->WriteCacheEnable = FrontendGetFlushCache(Target->Frontend) ? 1 : 0; + + *ModeDataLength += sizeof(MODE_CACHING_PAGE); + *Size += sizeof(MODE_CACHING_PAGE); } // Fill in Informational Exception Parameters (if Specified and space) if ((PageCode == MODE_PAGE_FAULT_REPORTING || PageCode == MODE_SENSE_RETURN_ALL) && - LengthLeft >= sizeof(MODE_INFO_EXCEPTIONS)) { - PMODE_INFO_EXCEPTIONS Exceptions = (PMODE_INFO_EXCEPTIONS)CurrentPage; + Length - *Size >= sizeof(MODE_INFO_EXCEPTIONS)) { + PMODE_INFO_EXCEPTIONS Exceptions = (PMODE_INFO_EXCEPTIONS)((PUCHAR)Data + *Size); + // Fill in Exceptions - Exceptions->PageCode = MODE_PAGE_FAULT_REPORTING; - Exceptions->PSBit = 0; - Exceptions->PageLength = sizeof(MODE_INFO_EXCEPTIONS); - Exceptions->Flags = 0; - Exceptions->Dexcpt = 1; // disabled - Exceptions->ReportMethod = 0; - Exceptions->IntervalTimer[0] = 0; - Exceptions->IntervalTimer[1] = 0; - Exceptions->IntervalTimer[2] = 0; - Exceptions->IntervalTimer[3] = 0; - Exceptions->ReportCount[0] = 0; - Exceptions->ReportCount[1] = 0; - Exceptions->ReportCount[2] = 0; - Exceptions->ReportCount[3] = 0; - - Header->ModeDataLength += sizeof(MODE_INFO_EXCEPTIONS); - LengthLeft -= sizeof(MODE_INFO_EXCEPTIONS); - CurrentPage = ((PUCHAR)CurrentPage + sizeof(MODE_INFO_EXCEPTIONS)); + Exceptions->PageCode = MODE_PAGE_FAULT_REPORTING; + Exceptions->PageLength = sizeof(MODE_INFO_EXCEPTIONS); + Exceptions->Dexcpt = 1; // disabled + + *ModeDataLength += sizeof(MODE_INFO_EXCEPTIONS); + *Size += sizeof(MODE_INFO_EXCEPTIONS); } +} + +static DECLSPEC_NOINLINE VOID +TargetModeSense( + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb + ) +{ + PMODE_PARAMETER_HEADER Data = Srb->DataBuffer; + ULONG Length = Srb->DataTransferLength; + ULONG BlockDescrLength = 0; + ULONG ModeDataLength = 0; + ULONG Size; + + Srb->SrbStatus = SRB_STATUS_ERROR; + + if (Data == NULL) + return; + RtlZeroMemory(Data, Length); + + if (Length < sizeof(MODE_PARAMETER_HEADER)) + return; + + // Header + Data->MediumType = 0; + Data->DeviceSpecificParameter = FrontendGetReadOnly(Target->Frontend) ? + MODE_DSP_WRITE_PROTECT : 0; + Size = sizeof(MODE_PARAMETER_HEADER); + + __TargetModeSense(Target, + Srb, + Data, + Length, + &Size, + &ModeDataLength, + &BlockDescrLength); + ASSERT3U(ModeDataLength, <=, 255 - (sizeof(MODE_PARAMETER_HEADER) - 1)); + ASSERT3U(BlockDescrLength, <=, 255); + + Data->ModeDataLength = (UCHAR)(ModeDataLength + sizeof(MODE_PARAMETER_HEADER) - 1); + Data->BlockDescriptorLength = (UCHAR)BlockDescrLength; + + ASSERT3U(Size, <=, Length); + Srb->DataTransferLength = Size; + Srb->SrbStatus = SRB_STATUS_SUCCESS; +} + +static DECLSPEC_NOINLINE VOID +TargetModeSense10( + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb + ) +{ + PMODE_PARAMETER_HEADER10 Data = Srb->DataBuffer; + ULONG Length = Srb->DataTransferLength; + ULONG BlockDescrLength = 0; + ULONG ModeDataLength = 0; + ULONG Size; + + Srb->SrbStatus = SRB_STATUS_ERROR; + + if (Data == NULL) + return; + RtlZeroMemory(Data, Length); + + if (Length < sizeof(MODE_PARAMETER_HEADER10)) + return; - // Finish this SRB + // Header + Data->MediumType = 0; + Data->DeviceSpecificParameter = FrontendGetReadOnly(Target->Frontend) ? + MODE_DSP_WRITE_PROTECT : 0; + Size = sizeof(MODE_PARAMETER_HEADER10); + + __TargetModeSense(Target, + Srb, + Data, + Length, + &Size, + &ModeDataLength, + &BlockDescrLength); + ASSERT3U(ModeDataLength, <=, 65535 - (sizeof(MODE_PARAMETER_HEADER10) - 2)); + ASSERT3U(BlockDescrLength, <=, 65535); + + *(PUSHORT)Data->ModeDataLength = _byteswap_ushort((USHORT)ModeDataLength + + sizeof(MODE_PARAMETER_HEADER10) - 2); + *(PUSHORT)Data->BlockDescriptorLength = _byteswap_ushort((USHORT)BlockDescrLength); + + ASSERT3U(Size, <=, Length); + Srb->DataTransferLength = Size; Srb->SrbStatus = SRB_STATUS_SUCCESS; - Srb->DataTransferLength = __min(Cdb_AllocationLength(Srb), (ULONG)(Header->ModeDataLength + 1)); } static DECLSPEC_NOINLINE VOID TargetRequestSense( - __in PXENVBD_TARGET Target, - __in PSCSI_REQUEST_BLOCK Srb + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb ) { - PSENSE_DATA Sense = Srb->DataBuffer; + PSENSE_DATA Data = Srb->DataBuffer; + ULONG Length = Srb->DataTransferLength; UNREFERENCED_PARAMETER(Target); - if (!__ValidateSrbBuffer(__FUNCTION__, Srb, (ULONG)sizeof(SENSE_DATA))) { - Srb->ScsiStatus = 0x40; - Srb->SrbStatus = SRB_STATUS_DATA_OVERRUN; + Srb->SrbStatus = SRB_STATUS_ERROR; + + if (Data == NULL) return; - } + RtlZeroMemory(Data, Length); - RtlZeroMemory(Sense, sizeof(SENSE_DATA)); + if (Length < sizeof(SENSE_DATA)) + return; + + Data->ErrorCode = 0x70; + Data->Valid = 1; + Data->AdditionalSenseCodeQualifier = 0; + Data->SenseKey = SCSI_SENSE_NO_SENSE; + Data->AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE; - Sense->ErrorCode = 0x70; - Sense->Valid = 1; - Sense->AdditionalSenseCodeQualifier = 0; - Sense->SenseKey = SCSI_SENSE_NO_SENSE; - Sense->AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE; Srb->DataTransferLength = sizeof(SENSE_DATA); Srb->SrbStatus = SRB_STATUS_SUCCESS; } static DECLSPEC_NOINLINE VOID TargetReportLuns( - __in PXENVBD_TARGET Target, - __in PSCSI_REQUEST_BLOCK Srb + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb ) { - ULONG Length; - ULONG Offset; - ULONG AllocLength = Cdb_AllocationLength(Srb); - PUCHAR Buffer = Srb->DataBuffer; + PLUN_LIST Data = Srb->DataBuffer; + ULONG Length = Srb->DataTransferLength; UNREFERENCED_PARAMETER(Target); - if (!__ValidateSrbBuffer(__FUNCTION__, Srb, 8)) { - Srb->ScsiStatus = 0x40; - Srb->SrbStatus = SRB_STATUS_DATA_OVERRUN; - Srb->DataTransferLength = 0; - return; - } - - RtlZeroMemory(Buffer, AllocLength); - - Length = 0; - Offset = 8; + Srb->SrbStatus = SRB_STATUS_ERROR; - if (Offset + 8 <= AllocLength) { - Buffer[Offset] = 0; - Offset += 8; - Length += 8; - } + if (Data == NULL) + return; + RtlZeroMemory(Data, Length); - if (Offset + 8 <= AllocLength) { - Buffer[Offset] = XENVBD_MAX_TARGETS; - Offset += 8; - Length += 8; - } + if (Length < 16) + return; - REVERSE_BYTES(Buffer, &Length); + // UCHAR[4] @ Data + *(PULONG)Data->LunListLength = _byteswap_ulong(8); + // UCHAR[8] @ Data + 8 + *(PULONG64)Data->Lun[0] = _byteswap_uint64(XENVBD_MAX_TARGETS); - Srb->DataTransferLength = __min(Length, AllocLength); + Srb->DataTransferLength = 16; Srb->SrbStatus = SRB_STATUS_SUCCESS; } static DECLSPEC_NOINLINE VOID TargetReadCapacity( - __in PXENVBD_TARGET Target, - __in PSCSI_REQUEST_BLOCK Srb + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb ) { - PREAD_CAPACITY_DATA Capacity = Srb->DataBuffer; + PREAD_CAPACITY_DATA Data = Srb->DataBuffer; + ULONG Length = Srb->DataTransferLength; PXENVBD_DISKINFO DiskInfo = FrontendGetDiskInfo(Target->Frontend); ULONG64 SectorCount; ULONG SectorSize; ULONG LastBlock; - if (Cdb_PMI(Srb) == 0 && Cdb_LogicalBlock(Srb) != 0) { - Srb->ScsiStatus = 0x02; // CHECK_CONDITION + Srb->SrbStatus = SRB_STATUS_ERROR; + + if (Data == NULL) + return; + RtlZeroMemory(Data, Length); + + if (Length < sizeof(READ_CAPACITY_DATA)) + return; + + if (Cdb_PMI(Srb) == 0 && Cdb_LogicalBlock(Srb) != 0) return; - } SectorCount = DiskInfo->SectorCount; SectorSize = DiskInfo->SectorSize; @@ -535,21 +566,21 @@ TargetReadCapacity( else LastBlock = ~(ULONG)0; - if (Capacity) { - Capacity->LogicalBlockAddress = _byteswap_ulong(LastBlock); - Capacity->BytesPerBlock = _byteswap_ulong(SectorSize); - } + Data->LogicalBlockAddress = _byteswap_ulong(LastBlock); + Data->BytesPerBlock = _byteswap_ulong(SectorSize); + Srb->DataTransferLength = sizeof(READ_CAPACITY_DATA); Srb->SrbStatus = SRB_STATUS_SUCCESS; } static DECLSPEC_NOINLINE VOID TargetReadCapacity16( - __in PXENVBD_TARGET Target, - __in PSCSI_REQUEST_BLOCK Srb + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb ) { - PREAD_CAPACITY16_DATA Capacity = Srb->DataBuffer; + PREAD_CAPACITY16_DATA Data = Srb->DataBuffer; + ULONG Length = Srb->DataTransferLength; PXENVBD_DISKINFO DiskInfo = FrontendGetDiskInfo(Target->Frontend); ULONG64 SectorCount; ULONG SectorSize; @@ -557,10 +588,17 @@ TargetReadCapacity16( ULONG LogicalPerPhysical; ULONG LogicalPerPhysicalExponent; - if (Cdb_PMI(Srb) == 0 && Cdb_LogicalBlock(Srb) != 0) { - Srb->ScsiStatus = 0x02; // CHECK_CONDITION + Srb->SrbStatus = SRB_STATUS_ERROR; + + if (Data == NULL) + return; + RtlZeroMemory(Data, Length); + + if (Length < sizeof(READ_CAPACITY16_DATA)) + return; + + if (Cdb_PMI(Srb) == 0 && Cdb_LogicalBlock(Srb) != 0) return; - } SectorCount = DiskInfo->SectorCount; SectorSize = DiskInfo->SectorSize; @@ -571,12 +609,11 @@ TargetReadCapacity16( if (!_BitScanReverse(&LogicalPerPhysicalExponent, LogicalPerPhysical)) LogicalPerPhysicalExponent = 0; - if (Capacity) { - Capacity->LogicalBlockAddress.QuadPart = _byteswap_uint64(SectorCount - 1); - Capacity->BytesPerBlock = _byteswap_ulong(SectorSize); - Capacity->LogicalPerPhysicalExponent = (UCHAR)LogicalPerPhysicalExponent; - } + Data->LogicalBlockAddress.QuadPart = _byteswap_uint64(SectorCount - 1); + Data->BytesPerBlock = _byteswap_ulong(SectorSize); + Data->LogicalPerPhysicalExponent = (UCHAR)LogicalPerPhysicalExponent; + Srb->DataTransferLength = sizeof(READ_CAPACITY16_DATA); Srb->SrbStatus = SRB_STATUS_SUCCESS; } @@ -592,6 +629,11 @@ TargetInquiryStd( UNREFERENCED_PARAMETER(Target); Srb->SrbStatus = SRB_STATUS_ERROR; + + if (Data == NULL) + return; + RtlZeroMemory(Data, Length); + if (Length < INQUIRYDATABUFFERSIZE) return; @@ -621,9 +663,12 @@ TargetInquiry00( UNREFERENCED_PARAMETER(Target); + Srb->SrbStatus = SRB_STATUS_ERROR; + + if (Data == NULL) + return; RtlZeroMemory(Data, Length); - Srb->SrbStatus = SRB_STATUS_ERROR; if (Length < 7) return; @@ -647,18 +692,18 @@ TargetInquiry80( PVOID Page; ULONG Size; - Page = FrontendGetInquiryOverride(Target->Frontend, 0x80, &Size); + Srb->SrbStatus = SRB_STATUS_ERROR; + if (Data == NULL) + return; RtlZeroMemory(Data, Length); - Srb->SrbStatus = SRB_STATUS_ERROR; + Page = FrontendGetInquiryOverride(Target->Frontend, 0x80, &Size); if (Page && Size) { if (Length < Size) return; RtlCopyMemory(Data, Page, Size); - - Srb->DataTransferLength = Size; } else { CHAR Serial[5]; @@ -673,9 +718,10 @@ TargetInquiry80( TargetGetTargetId(Target)); RtlCopyMemory(Data->SerialNumber, Serial, 4); - Srb->DataTransferLength = sizeof(VPD_SERIAL_NUMBER_PAGE) + 4; + Size = sizeof(VPD_SERIAL_NUMBER_PAGE) + 4; } + Srb->DataTransferLength = Size; Srb->SrbStatus = SRB_STATUS_SUCCESS; } @@ -690,18 +736,18 @@ TargetInquiry83( PVOID Page; ULONG Size; - Page = FrontendGetInquiryOverride(Target->Frontend, 0x83, &Size); + Srb->SrbStatus = SRB_STATUS_ERROR; + if (Data == NULL) + return; RtlZeroMemory(Data, Length); - Srb->SrbStatus = SRB_STATUS_ERROR; + Page = FrontendGetInquiryOverride(Target->Frontend, 0x83, &Size); if (Page && Size) { if (Length < Size) return; RtlCopyMemory(Data, Page, Size); - - Srb->DataTransferLength = Size; } else { PVPD_IDENTIFICATION_DESCRIPTOR Id = (PVPD_IDENTIFICATION_DESCRIPTOR)&Data->Descriptors[0]; CHAR Identifier[17]; @@ -722,10 +768,11 @@ TargetInquiry83( TargetGetTargetId(Target)); RtlCopyMemory(Id->Identifier, Identifier, 16); - Srb->DataTransferLength = sizeof(VPD_IDENTIFICATION_PAGE) + - sizeof(VPD_IDENTIFICATION_DESCRIPTOR) + 16; + Size = sizeof(VPD_IDENTIFICATION_PAGE) + + sizeof(VPD_IDENTIFICATION_DESCRIPTOR) + 16; } + Srb->DataTransferLength = Size; Srb->SrbStatus = SRB_STATUS_SUCCESS; } @@ -845,6 +892,10 @@ TargetStartIo( TargetModeSense(Target, Srb); break; + case SCSIOP_MODE_SENSE10: + TargetModeSense10(Target, Srb); + break; + case SCSIOP_REQUEST_SENSE: TargetRequestSense(Target, Srb); break; -- 2.8.3 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |