⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 processscsi.cpp

📁 虚拟磁盘源码,完整的虚拟磁盘源码,支持大硬盘数据
💻 CPP
📖 第 1 页 / 共 2 页
字号:

//**************************************************************************************
//	日期:	1:7:2004   
//	创建:	tiamo	
//	描述:	miniport scsi process
//**************************************************************************************

#include "stdafx.h"

// convert cdb6 to 10 for read write
VOID ConvertCdb6To10(PSCSI_REQUEST_BLOCK pSrb)
{
	PCDB pCdb10 = reinterpret_cast<PCDB>(pSrb->Cdb);
	PCDB pCdb6 = reinterpret_cast<PCDB>(pSrb->Cdb);

	pCdb10->CDB10.Control = pCdb6->CDB6READWRITE.Control;
	pCdb10->CDB10.TransferBlocksMsb = 0;
	pCdb10->CDB10.TransferBlocksLsb = pCdb6->CDB6READWRITE.TransferBlocks;

	pCdb10->CDB10.LogicalBlockByte3 = pCdb6->CDB6READWRITE.LogicalBlockLsb;
	pCdb10->CDB10.LogicalBlockByte2 = pCdb6->CDB6READWRITE.LogicalBlockMsb0;
	pCdb10->CDB10.LogicalBlockByte1 = pCdb6->CDB6READWRITE.LogicalBlockMsb1;
	pCdb10->CDB10.LogicalBlockByte0 = 0;

	pCdb10->CDB10.LogicalUnitNumber = pCdb6->CDB6READWRITE.LogicalUnitNumber;
}

// swap big endian to little endian
VOID SwapReadWriteCBD10(PSCSI_REQUEST_BLOCK pSrb)
{
	PCDB pCdb10 = reinterpret_cast<PCDB>(pSrb->Cdb);

	UCHAR temp = pCdb10->CDB10.LogicalBlockByte0;
	pCdb10->CDB10.LogicalBlockByte0 = pCdb10->CDB10.LogicalBlockByte3;
	pCdb10->CDB10.LogicalBlockByte3 = temp;

	temp = pCdb10->CDB10.LogicalBlockByte1;
	pCdb10->CDB10.LogicalBlockByte1 = pCdb10->CDB10.LogicalBlockByte2;
	pCdb10->CDB10.LogicalBlockByte2 = temp;

	temp = pCdb10->CDB10.TransferBlocksLsb;
	pCdb10->CDB10.TransferBlocksLsb = pCdb10->CDB10.TransferBlocksMsb;
	pCdb10->CDB10.TransferBlocksMsb = temp;
}

// check bound
BOOLEAN CheckBound(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb,PULONG pulStart,PULONG pulLen)
{
	PCDB pCdb10 = reinterpret_cast<PCDB>(pSrb->Cdb);
	*pulStart = *reinterpret_cast<PULONG>(&pCdb10->CDB10.LogicalBlockByte0);
	*pulLen = *reinterpret_cast<PUSHORT>(&pCdb10->CDB10.TransferBlocksMsb);

	if(!*pulLen)
	{
		SetSrbSenseCode(pSrb,INVALID_SUB_REQUEST);
		return FALSE;
	}

	if(*pulStart + *pulLen > pExt->m_ulBlockCount[pSrb->TargetId])
	{
		SetSrbSenseCode(pSrb,OUT_BOUND_ACCESS);
		return FALSE;
	}

	return TRUE;
}

// test unit ready
BOOLEAN TestUnitReady(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)
{
	if(!pExt->m_hFileHandle[pSrb->TargetId])
	{
		devDebugPrint(DRIVER_NAME"*******TestUnitReady..no media in device\n");
		SetSrbSenseCode(pSrb,NO_MEDIA_IN_DEVICE);
	}

	return TRUE;
}

// rezero unit
BOOLEAN RezeroUnit(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)						
{
	return TRUE;
}

// invalid scsi cmd
BOOLEAN InvalidScsiCmd(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)
{
	SetSrbSenseCode(pSrb,INVALID_REQUEST);
	return TRUE;
}

// request sense...because we use auto request sense ,so this is not needed
BOOLEAN RequestSense(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)
{
	return TRUE;
}

// format unit
BOOLEAN FormatUnit(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)						
{
	return TRUE;
}

// seek6...no need to seek
BOOLEAN Seek6(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)							
{
	return TRUE;
}

// inquiry
BOOLEAN Inquiry(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)
{
	if(pSrb->TargetId >= pExt->m_ulDevices || pSrb->Lun)
	{
		devDebugPrint("\tInquiry...(target-lun)=(%d,%d)..not supported\n",pSrb->TargetId,pSrb->Lun);
		pSrb->SrbStatus = SRB_STATUS_SELECTION_TIMEOUT;
		return TRUE;
	}

	if(pSrb->Cdb[1] & CDB_INQUIRY_EVPD)
	{
		devDebugPrint("\tInquiry..not support evpd\n");
		SetSrbSenseCode(pSrb,INVALID_SUB_REQUEST);
		return TRUE;
	}

	PINQUIRYDATA pInquiryData = (PINQUIRYDATA)pSrb->DataBuffer;
	
	pInquiryData->DeviceType = DIRECT_ACCESS_DEVICE;
	pInquiryData->DeviceTypeQualifier = DEVICE_CONNECTED;

	pInquiryData->DeviceTypeModifier = 0;
	pInquiryData->RemovableMedia = 0;
	pInquiryData->ResponseDataFormat = 2;
	pInquiryData->Versions = 0;
	pInquiryData->AdditionalLength = sizeof(INQUIRYDATA) - 5;

	RtlMoveMemory(pInquiryData->VendorId,"Tiamo   ",8);

	RtlMoveMemory(pInquiryData->ProductId,"Virtual DISK    ",16);

	RtlMoveMemory(pInquiryData->ProductRevisionLevel,"1010",4);

	devDebugPrint("\tInquiry...succeeded(target-lun)=(%d,%d)\n",pSrb->TargetId,pSrb->Lun);

	return TRUE;
}

// reserve
BOOLEAN Reserve(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)							
{
	return TRUE;
}

// release
BOOLEAN Release(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)							
{
	return TRUE;
}

// start stop
BOOLEAN StartStopUnit(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)					
{
	return TRUE;
}

// send diagnostic
BOOLEAN SendDiagnostic(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)					
{
	return TRUE;
}

// read caps
BOOLEAN ReadCaps(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)
{
	if(!pExt->m_hFileHandle[pSrb->TargetId])
	{
		devDebugPrint(DRIVER_NAME"*******ReadCaps..no media in device\n");
		SetSrbSenseCode(pSrb,NO_MEDIA_IN_DEVICE);
		return TRUE;
	}

	PREAD_CAPACITY_DATA pReadCapsData = (PREAD_CAPACITY_DATA)pSrb->DataBuffer;

	ULONG ulValue = pExt->m_ulBlockCount[pSrb->TargetId] - 1;
	REVERSE_LONG(&ulValue);
	pReadCapsData->LogicalBlockAddress = ulValue;

	ulValue = 1 << pExt->m_ulBlockShift[pSrb->TargetId];
	REVERSE_LONG(&ulValue);
	pReadCapsData->BytesPerBlock = ulValue;

	return TRUE;
}

// read 10
BOOLEAN Read10(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)
{
	if(!pExt->m_hFileHandle[pSrb->TargetId])
	{
		devDebugPrint(DRIVER_NAME"*******Read10..no media in device\n");
		SetSrbSenseCode(pSrb,NO_MEDIA_IN_DEVICE);
		return TRUE;
	}

	SwapReadWriteCBD10(pSrb);

	ULONG ulStart,ulLen;
	if(!CheckBound(pExt,pSrb,&ulStart,&ulLen))
	{
		devDebugPrint(DRIVER_NAME"*******Read10..check bound failed\n");
		return FALSE;
	}

	LARGE_INTEGER pos;
	pos.QuadPart = ulStart;
	pos.QuadPart <<= pExt->m_ulBlockShift[pSrb->TargetId];

	IO_STATUS_BLOCK ioStatus;
	NTSTATUS status = ZwReadFile(pExt->m_hFileHandle[pSrb->TargetId],NULL,NULL,NULL,&ioStatus,pSrb->DataBuffer,
								 pSrb->DataTransferLength,&pos,NULL);

	if(!NT_SUCCESS(status))
	{
		devDebugPrint(DRIVER_NAME"*******Read10..read image file failed\n");
		SetSrbSenseCode(pSrb,MEDIA_ERROR);
	}

	return TRUE;
}

// write 10
BOOLEAN Write10(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)
{
	if(!pExt->m_hFileHandle[pSrb->TargetId])
	{
		devDebugPrint(DRIVER_NAME"*******Write10..no media in device\n");
		SetSrbSenseCode(pSrb,NO_MEDIA_IN_DEVICE);
		return TRUE;
	}

	SwapReadWriteCBD10(pSrb);

	ULONG ulStart,ulLen;
	if(!CheckBound(pExt,pSrb,&ulStart,&ulLen))
	{
		devDebugPrint(DRIVER_NAME"*******Write10..check bound failed\n");
		return FALSE;
	}

	LARGE_INTEGER pos;
	pos.QuadPart = ulStart;
	pos.QuadPart <<= pExt->m_ulBlockShift[pSrb->TargetId];

	IO_STATUS_BLOCK ioStatus;
	NTSTATUS status = ZwWriteFile(pExt->m_hFileHandle[pSrb->TargetId],NULL,NULL,NULL,&ioStatus,pSrb->DataBuffer,
								  pSrb->DataTransferLength,&pos,NULL);

	if(!NT_SUCCESS(status))
	{
		devDebugPrint(DRIVER_NAME"*******Write10..read image file failed\n");
		SetSrbSenseCode(pSrb,MEDIA_ERROR);
	}

	return TRUE;
}

// seek
BOOLEAN Seek10(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)							
{
	return TRUE;
}

// write verify
BOOLEAN WriteVerify(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)						
{
	return TRUE;
}

// verify
BOOLEAN Verify(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)							
{
	return TRUE;
}

// synchronize cache
BOOLEAN SynchronizeCache(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)				
{
	return TRUE;
}

// read6
BOOLEAN Read6(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)
{
	// convert to 10
	ConvertCdb6To10(pSrb);

	// read 10
	return Read10(pExt,pSrb);
}

// the same
BOOLEAN Write6(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb)
{
	ConvertCdb6To10(pSrb);
	return Write10(pExt,pSrb);
}

namespace
{
	typedef BOOLEAN (*fnScsiCmdHandler)(PMiniportExt pExt,PSCSI_REQUEST_BLOCK pSrb);

	fnScsiCmdHandler g_pfnScsiCmdHandler[] = 
	{
		TestUnitReady,									// test unit ready = 0
		RezeroUnit,										// rezero unit = 1
		InvalidScsiCmd,									// vendor specific = 2
		RequestSense,									// request sense = 3
		FormatUnit,										// format unit = 4
		InvalidScsiCmd,									// read block limits = 5
		InvalidScsiCmd,									// vendor specific = 6
		InvalidScsiCmd,									// initialize element status = 7
		Read6,											// read6 = 8
		InvalidScsiCmd,									// vendor specific = 9
		Write6,											// write6 = A
		Seek6,											// seek6 = B
		InvalidScsiCmd,									// vendor specific = C
		InvalidScsiCmd,									// vendor specific = D
		InvalidScsiCmd,									// vendor specific = E
		InvalidScsiCmd,									// vendor specific = F

		InvalidScsiCmd,									// synchronize buffer = 10
		InvalidScsiCmd,									// space = 11
		Inquiry,										// inquiry = 12
		InvalidScsiCmd,									// verify = 13
		InvalidScsiCmd,									// recover buffered data = 14
		InvalidScsiCmd,									// mode select6 = 15
		Reserve,										// reserve = 16
		Release,										// release = 17
		InvalidScsiCmd,									// copy = 18
		InvalidScsiCmd,									// erase = 19
		InvalidScsiCmd,									// mode sense6 = 1A
		StartStopUnit,									// stop start unit = 1B
		InvalidScsiCmd,									// receive diagnostic results = 1c
		SendDiagnostic,									// send diagnostic = 1d
		InvalidScsiCmd,									// prevent allow medium removal = 1e
		InvalidScsiCmd,									// 1f

		InvalidScsiCmd,									// vendor specific = 20
		InvalidScsiCmd,									// vendor specific = 21
		InvalidScsiCmd,									// vendor specific = 22
		InvalidScsiCmd,									// vendor specific = 23
		InvalidScsiCmd,									// set window = 24
		ReadCaps,										// read caps = 25
		InvalidScsiCmd,									// vendor specific = 26
		InvalidScsiCmd,									// vendor specific = 27
		Read10,											// read10 = 28
		InvalidScsiCmd,									// read generation = 29
		Write10,										// write10 = 2A
		Seek10,											// seek10 = 2B
		InvalidScsiCmd,									// erase10 = 2C
		InvalidScsiCmd,									// read updated block = 2D

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -