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

📄 aspidriver.cpp

📁 一个SCSI的Tape设备读写等操作的软件.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	unsigned pf : 1;				//SCSI1 or standard ?
	unsigned lun : 3;				//logical unit number
	unsigned _reserved2 : 8;		//n/a
	unsigned _reserved3 : 8;		//n/a

	*/
	return RunCommand(&exec);				//send it..
}

/*\
 *<------------ DisplaySense ------------>
 @m create a displayable string from sense data
 *--> I N <-- @p
 * SRB_MyExecSCSICmd *p - scsi request block
 */
void CASPIDriver::DisplaySense (SRB_MyExecSCSICmd *p)
{
	if (p->SenseArea[0])
	{
		m_strSense.Format ("Sense Data: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
			p->SenseArea[0], p->SenseArea[1], p->SenseArea[2], p->SenseArea[3], 
			p->SenseArea[4], p->SenseArea[5], p->SenseArea[6], p->SenseArea[7], 
			p->SenseArea[8], p->SenseArea[9], p->SenseArea[10],p->SenseArea[11],
			p->SenseArea[12],p->SenseArea[13],p->SenseArea[14]);
	}
}

/*\
 *<------------ RequestSense ------------>
 @m request sense data 
 *--> I N <-- @p
 * BYTE adapter_id - host adapter id
 * BYTE device_id - device id
 * BYTE lun - lun id
 *<-- OUT --> @r
 * DWORD - ASPIERROR_xxx defined in AspiDriver.h
 */
DWORD CASPIDriver::RequestSense  (BYTE adapter_id,BYTE device_id,BYTE lun)
{
	SRB_MyExecSCSICmd exec;
	ZeroMemory (&exec,sizeof(SRB_MyExecSCSICmd));
	TRACE ("ASPIsnoop: requesting sense data... ");
	exec.SRB_Cmd		= SC_EXEC_SCSI_CMD;
	exec.SRB_HaId		= adapter_id;
	exec.SRB_Target		= device_id;
	exec.SRB_Lun		= lun;
	exec.SRB_Flags		= SRB_DIR_IN;
	exec.SRB_SenseLen	= SENSE_LEN;
	exec.SRB_CDBLen		= 6;
	exec.ccb.c6.cmd		= SCSI_REQ_SENSE;
	exec.ccb.c6.lun		= lun;
	
	return RunCommand(&exec);					//send it..
}

/*\
 *<------------ GetSenseString ------------>
 @m get last sense return string
 *--> I N <-- @p
 * CString &str - 
 */
void CASPIDriver::GetSenseString (CString &str)
{
	str=m_strSense;
}

/*\
 *<------------ GetError ------------>
 @m get an error code from our request answer
 *--> I N <-- @p
 * SRB_MyExecSCSICmd *srb - pointer to scsi request block
 *<-- OUT --> @r
 * DWORD - ASPIERROR_xxx defined in AspiDriver.h
 */
DWORD CASPIDriver::GetError (SRB_MyExecSCSICmd *srb)
{
	//
	// -% Advanced Sense Codes, Advance Sense Code Qualifier, My Error-Code %-
	//
	//SCSI2 really likes to chat ;o]
	//phew.... that list took 1 day...stupid type-work... fiddle in ANSI Dox ...
	const int asc[][3]=
	{
        {ASC_FILMRK,ASQ_FILMRK,ASPIERR_FILEMRK},        {ASC_EOM,ASQ_EOM,ASPIERR_EOM},
        {ASC_SETMRK,ASQ_SETMRK,ASPIERR_SETMRK},         {ASC_BOM,ASQ_BOM,ASPIERR_BOM},
        {ASC_EOD,ASQ_EOD,ASPIERR_EOD},                  {ASC_IOTERM,ASQ_IOTERM,ASPIERR_IOTERM},
        {ASC_PWRTFLT,ASQ_PWRTFLT,ASPIERR_PWRTFLT},      {ASC_NOWRT,ASC_NOWRT,ASPIERR_NOWRITE},
        {ASC_EWRTERR,ASQ_EWRTERR,ASPIERR_EWRTERR},      {ASC_LUNNRDNC,ASQ_LUNNRDNC,ASPIERR_LUNNRDNC},
        {ASC_LUNBRD,ASQ_LUNBRD,ASPIERR_LUNBRD},         {ASC_LUNNRDIR,ASQ_LUNNRDIR,ASPIERR_LUNNRDIR},
        {ASC_LUNNRDMI,ASQ_LUNNRDMI,ASPIERR_LUNNRDMI},   {ASC_LUNNRDFP,ASQ_LUNNRDFP,ASPIERR_LUNNRDFP},
        {ASC_LUNNSEL,ASQ_LUNNSEL,ASPIERR_LUNNSEL},      {ASC_MULTSEL,ASQ_MULTSEL,ASPIERR_MULTSEL},
        {ASC_LUNCFAIL,ASQ_LUNCFAIL,ASPIERR_LUNCFAIL},   {ASC_LUNCTIME,ASQ_LUNCTIME,ASPIERR_LUNCTIME},
        {ASC_LUNCPAR,ASQ_LUNCPAR,ASPIERR_LUNCPAR},      {ASC_TRKFOLOW,ASQ_TRKFOLOW,ASPIERR_TRKFOLOW},
        {ASC_LOGOVER,ASQ_LOGOVER,ASPIERR_LOGOVER},      {ASC_WRITE,ASQ_WRITE,ASPIERR_WRITE},
        {ASC_URREAD,ASQ_URREAD,ASPIERR_URREAD},         {ASC_RDRETRY,ASQ_RDRETRY,ASPIERR_RDRETRY},
        {ASC_TOOLONG,ASQ_TOOLONG,ASPIERR_TOOLONG},      {ASC_MULREAD,ASQ_MULREAD,ASPIERR_MULREAD},
        {ASC_IBLKRD,ASQ_IBLKRD,ASPIERR_IBLKRD},         {ASC_NOGAP,ASQ_NOGAP,ASPIERR_NOGAP},
        {ASC_MISCORR,ASQ_MISCORR,ASPIERR_MISCORR},      {ASC_RECENTI,ASQ_RECENTI,ASPIERR_RECENTI},
        {ASC_RECORD,ASQ_RECORD,ASPIERR_RECORD},         {ASC_FILESET,ASQ_FILESET,ASPIERR_FILSET},
        {ASC_NOEOD,ASQ_NOEOD,ASPIERR_NOEOD},            {ASC_BLKSEQ,ASQ_BLKSEQ,ASPIERR_BLKSEQ},
        {ASC_RNDPOS,ASQ_RNDPOS,ASPIERR_RNDPOS},         {ASC_MECHPOS,ASQ_MECHPOS,ASPIERR_MECHPOS},
        {ASC_RDPOSE,ASQ_RDPOSE,ASPIERR_RDPOSE},         {ASC_RECDNEC,ASQ_RECDNEC,ASPIERR_RECDNEC},
        {ASC_RECDRET,ASQ_RECDRET,ASPIERR_RECDRET},      {ASC_RECDPHO,ASQ_RECDPHO,ASPIERR_RECDPHO},
        {ASC_RECDNHO,ASQ_RECDNHO,ASPIERR_RECDNHO},      {ASC_RECDWEC,ASQ_RECDWEC,ASPIERR_RECDWEC},
        {ASC_PARLLEN,ASQ_PARLLEN,ASPIERR_PARLLEN},      {ASC_SYNCERR,ASQ_SYNCERR,ASPIERR_SYNCERR},
        {ASC_INVCOC,ASQ_INVCOC,ASPIERR_INVCOC},         {ASC_LBARNG,ASQ_LBARNG,ASPIERR_LBARNG},
        {ASC_INVFCDB,ASQ_INVFCDB,ASPIERR_INVFCDB},      {ASC_NOLOGUN,ASQ_NOLOGUN,ASPIERR_NOLOGUN},
        {ASC_INVFPL,ASQ_INVFPL,ASPIERR_INVFPL},         {ASC_PARNSUP,ASQ_PARNSUP,ASPIERR_PARNSUP},
        {ASC_PARVINV,ASQ_PARVINV,ASPIERR_PARVINV},      {ASC_NTHRPAR,ASQ_NTHRPAR,ASPIERR_NTHRPAR},
        {ASC_WRTPROT,ASQ_WRTPROT,ASPIERR_WRTPROT},      {ASC_NRDYRDY,ASQ_NRDYRDY,ASPIERR_NRDYRDY},
        {ASC_POWRON,ASQ_POWRON,ASPIERR_POWRON},         {ASC_PARCHN,ASQ_PARCHN,ASPIERR_PARCHN},
        {ASC_MPARCHN,ASQ_MPARCHN,ASPIERR_MPARCHN},      {ASC_LPARCHN,ASQ_LPARCHN,ASPIERR_LPARCHN},
        {ASC_NCPYDIS,ASQ_NCPYDIS,ASPIERR_NCPYDIS},      {ASC_CMDSEQ,ASQ_CMDSEQ,ASPIERR_CMDSEQ},
        {ASC_CMDCLR,ASQ_CMDCLR,ASPIERR_CMDCLR},         {ASC_INCPMED,ASQ_INCPMED,ASPIERR_INCPMED},
        {ASC_CANTRDU,ASQ_CANTRDU,ASPIERR_CANTRDU},      {ASC_CANTRDI,ASQ_CANTRDI,ASPIERR_CANTRDI},
        {ASC_CLNCARD,ASQ_CLNCARD,ASPIERR_CLNCARD},      {ASC_MFRMCRP,ASQ_MFRMCRP,ASPIERR_MFRMCRP},
        {ASC_TAPELEN,ASQ_TAPELEN,ASPIERR_TAPELEN},      {ASC_RNDPAR,ASQ_RNDPAR,ASPIERR_RNDPAR},
        {ASC_SAVPAR,ASQ_SAVPAR,ASPIERR_SAVPAR},         {ASC_NOTAPE,ASQ_NOTAPE,ASPIERR_NOTAPE},
        {ASC_SEQPOS,ASQ_SEQPOS,ASPIERR_SEQPOS},         {ASC_POSBOM,ASQ_POSBOM,ASPIERR_POSBOM},
        {ASC_POSEOM,ASQ_POSEOM,ASPIERR_POSEOM},         {ASC_REPOS,ASQ_REPOS,ASPIERR_REPOS},
        {ASC_INVBITS,ASQ_INVBITS,ASPIERR_INVBITS},      {ASC_LUNSCFG,ASQ_LUNSCFG,ASPIERR_LUNSCFG},
        {ASC_TRGOCHG,ASQ_TRGOCHG,ASPIERR_TRGOCHG},      {ASC_CHGUC,ASQ_CHGUC,ASPIERR_CHGUC},
        {ASC_CHGOD,ASQ_CHGOD,ASPIERR_CHGOD},            {ASC_CHGINQ,ASQ_CHGINQ,ASPIERR_CHGINQ},
        {ASC_DGFAIL,ASQ_DGFAIL,ASPIERR_DGFAIL},         {ASC_MSGERR,ASQ_MSGERR,ASPIERR_MSGERR},
        {ASC_INTTRGF,ASQ_INTTRGF,ASPIERR_INTTRGF},      {ASC_SELRESF,ASQ_SELRESF,ASPIERR_SELRESF},
        {ASC_SFTRSTF,ASQ_SFTRSTF,ASPIERR_SFTRSTF},      {ASC_INDEMSG,ASQ_INDEMSG,ASPIERR_INDEMSG},
        {ASC_INVMSGE,ASQ_INVMSGE,ASPIERR_INVMSGE},      {ASC_CMDPHSE,ASQ_CMDPHSE,ASPIERR_CMDPHSE},
        {ASC_DATPHSE,ASQ_DATPHSE,ASPIERR_DATPHSE},      {ASC_LGUFSLF,ASQ_LGUFSLF,ASPIERR_LGUFSLF},
        {ASC_OVRCMD,ASQ_OVRCMD,ASPIERR_OVRCMD},         {ASC_WRTAPE,ASQ_WRTAPE,ASPIERR_WRTAPE},
        {ASC_WRTAPSE,ASQ_WRTAPSE,ASPIERR_WRTAPSE},      {ASC_POSETIM,ASQ_POSETIM,ASPIERR_POSETIM},
        {ASC_ERSFAIL,ASQ_ERSFAIL,ASPIERR_ERSFAIL},      {ASC_CRDFAIL,ASQ_CRDFAIL,ASPIERR_CRDFAIL},
        {ASC_MDLFAIL,ASQ_MDLFAIL,ASPIERR_MDLFAIL},      {ASC_UNTAPF,ASQ_UNTAPF,ASPIERR_UNTAPF},
        {ASC_MDRMPRV,ASQ_MDRMPRV,ASPIERR_MDRMPRV},      {ASC_OPERREQ,ASQ_OPERREQ,ASPIERR_OPERREQ},
        {ASC_OPERMRR,ASQ_OPERMRR,ASPIERR_OPERMRR},      {ASC_OPERSWP,ASQ_OPERSWP,ASPIERR_OPERSWP},
        {ASC_OPERSWE,ASQ_OPERSWE,ASPIERR_OPERSWE},      {ASC_LOGTRAP,ASQ_LOGTRAP,ASPIERR_LOGTRAP},
        {ASC_THRCND,ASQ_THRCND,ASPIERR_THRCND},         {ASC_LGCNTMX,ASQ_LGCNTMX,ASPIERR_LGCNTMX},
        {ASC_LGLSCDE,ASQ_LGLSCDE,ASPIERR_LGLSCDE},      {0,0,0}
	};

	TRACE ("ASPIsnoop: error: %02X %02X %02X\n",srb->SRB_Status,
												srb->SRB_HaStat,
												srb->SRB_TargStat);

	switch (srb->SRB_Status)					//check normal status byte
	{
		case SS_COMP:		return ASPIERR_OK;
		case SS_PENDING:	return ASPIERR_PENDING;
		case SS_ABORTED:	return ASPIERR_ABORTED;
		case SS_ABORT_FAIL:	return ASPIERR_ABORTFAILED;
		case SS_ERR:
			if (srb->SRB_HaStat != HASTAT_OK)	//
			{
				switch (srb->SRB_HaStat)		//check host adapter status
				{
					case HASTAT_SEL_TO:					return ASPIERR_SELTIMEOUT;
					case HASTAT_DO_DU:					return ASPIERR_OVERUNDER;
					case HASTAT_BUS_FREE:				return ASPIERR_BUSFREE;
					case HASTAT_PHASE_ERR:				return ASPIERR_PHASE;
					case HASTAT_TIMEOUT:				return ASPIERR_TIMEOUT;
					case HASTAT_COMMAND_TIMEOUT:		return ASPIERR_CMDTIMEOUT;
					case HASTAT_MESSAGE_REJECT:			return ASPIERR_REJECT;
					case HASTAT_BUS_RESET:				return ASPIERR_RESET;
					case HASTAT_PARITY_ERROR:			return ASPIERR_PARITY;
					case HASTAT_REQUEST_SENSE_FAILED:	return ASPIERR_SENSE;
				}
			}
			else if (srb->SRB_TargStat)
			{
				switch (srb->SRB_TargStat)			//check target status
				{
					case STATUS_CHKCOND:
						if (srb->SRB_SenseLen && srb->SenseArea[0])
						{
							if (!((srb->SenseArea[12] == ASC_NOINFO) & (srb->SenseArea[13] == ASQ_NOINFO)))
							{
								BYTE basc=srb->SenseArea[12];
								BYTE bascq=srb->SenseArea[13];
								int i=0;
								while (asc[i][2] != 0)
								{
									if (asc[i][0] == basc &&
										asc[i][1] == bascq)
										return asc[i][2];
									i++;
								};
								TRACE ("WARNING: additional sense code %02X %02X not identified\n",basc,bascq);
								return ASPIERR_UNKNOWN;
							}
							else
							{
								switch (srb->SenseArea[2]&0x0F)
								{
									case KEY_NOSENSE:
										if (srb->SenseArea[2] & SENSE_FILEMRK)
											return ASPIERR_FILEMRK;
										else if (srb->SenseArea[2] & SENSE_EOM)
											return ASPIERR_EOM;
										else if (srb->SenseArea[2] & SENSE_ILI)
											return ASPIERR_ILI;
										TRACE ("WARNING: no sense data\n");
										return ASPIERR_OK;
									case KEY_RECERROR:		return ASPIERR_RECOVERED;
									case KEY_NOTREADY:		return ASPIERR_NOTREADY;
									case KEY_MEDIUMERR:		return ASPIERR_MEDIUMERR;
									case KEY_HARDERROR:		return ASPIERR_HARDERR;
									case KEY_ILLGLREQ:		return ASPIERR_ILLEGAL;
									case KEY_UNITATT:		return ASPIERR_UNITATT;
									case KEY_BLANKCHK:		return ASPIERR_BLANKCHK;
									case KEY_VENDSPEC:		return ASPIERR_VENDOR;
									case KEY_COPYABORT:		return ASPIERR_COPYABORT;
									case KEY_EQUAL:			return ASPIERR_EQUAL;
									case KEY_VOLOVRFLW:		return ASPIERR_TAPEFULL;
									case KEY_MISCOMP:		return ASPIERR_MISCOMP;
									case KEY_RESERVED:		return ASPIERR_RESERVED;
								}
							}
						}
						else
							return ASPIERR_CHKCOND;
					break;
					case STATUS_CONDMET:	return ASPIERR_COMDMET;
					case STATUS_INTERM:		return ASPIERR_INTERM;
					case STATUS_INTCDMET:	return ASPIERR_INTCDMET;
					case STATUS_RESCONF:	return ASPIERR_RESCONF;
					case STATUS_COMTERM:	return ASPIERR_COMTERM;
					case STATUS_QFULL:		return ASPIERR_QFULL;
				}
			}
		break;
		case SS_INVALID_CMD:		return ASPIERR_COMMAND;
		case SS_INVALID_HA:			return ASPIERR_HA;
		case SS_NO_DEVICE:			return ASPIERR_NODEVICE;
		case SS_INVALID_SRB:		return ASPIERR_SRB;
		case SS_BUFFER_ALIGN:		return ASPIERR_ALIGN;
		case SS_SECURITY_VIOLATION:	return ASPIERR_SECURE;
		case SS_FAILED_INIT:		return ASPIERR_INIT;
		case SS_BUFFER_TO_BIG:		return ASPIERR_SIZE;
	}
	TRACE ("WARNING: no error-description found at all\n");
	return ASPIERR_UNKNOWN;
}

/*\
 *<------------ Copy ------------>
 @m copy a tape 
 *--> I N <-- @p
 * BYTE src_adapter_id - host adapter id
 * BYTE src_id - source device id
 * BYTE src_lun - source lun id 
 * BYTE dst_id - destination device id
 * BYTE dst_lun - destination lun id
 * DWORD count - number of blocks - 0=all
 */
DWORD CASPIDriver::Copy  (	BYTE src_adapter_id,
							BYTE src_id,
							BYTE src_lun,
							BYTE dst_id,
							BYTE dst_lun,
							DWORD count)
{
	SRB_MyExecSCSICmd	exec;
	DWORD				code;
	DWORD				size;
	CPY_para_head		*head;
	CPY_segment_desc	*segd;
	unsigned char		*buffer;

	size=sizeof(CPY_para_head)+sizeof(CPY_segment_desc);
	buffer=new unsigned char [size];
	ASSERT (buffer);
	ZeroMemory (buffer,size);
	head=(CPY_para_head	*)buffer;
	segd=(CPY_segment_desc *)(buffer+sizeof(CPY_para_head));

	head->priority=0x00;		//0 - high
	head->code=0x04;			//image copy
	segd->source_lun=src_lun;	//
	segd->source_id=src_id;		//
	segd->dest_lun=dst_lun;		//
	segd->dest_id=dst_id;		//
	segd->count=count;			//0 = all !

	ZeroMemory (&exec,sizeof(SRB_MyExecSCSICmd));
	TRACE ("ASPIsnoop: copy %d file marks... ",count);
	exec.SRB_Cmd			= SC_EXEC_SCSI_CMD;
	exec.SRB_HaId			= src_adapter_id;
	exec.SRB_Target			= src_id;
	exec.SRB_Lun			= src_lun;
	exec.SRB_Flags			= SRB_DIR_OUT;
	exec.SRB_BufPointer		= (unsigned char *)buffer;
	exec.SRB_BufLen			= size;
	exec.SRB_SenseLen		= SENSE_LEN;
	exec.SRB_CDBLen			= 6;
	exec.ccb.cpy.cmd		= SCSI_COPY;
	//exec.ccb.cpy.pad		= 0;
	//exec.ccb.cpy.lun		= src_lun;
	exec.ccb.cpy.len_0		= (size & 0xff);
	exec.ccb.cpy.len_1		= ((size>>8) & 0xff);
	exec.ccb.cpy.len_2		= ((size>>16) & 0xff);
	code=RunCommand(&exec);				//send it..
	delete [] buffer;
	return code;
}

/*\
 *<------------ Reserve ------------>
 @m create a direct SCSI device interconnection 
 *--> I N <-- @p
 * BYTE adapter_id - host adapter id
 * BYTE device_id - device id
 * BYTE lun - lun id
 * BYTE dest_id - destination device id
 *<-- OUT --> @r
 * DWORD - ASPIERROR_xxx defined in AspiDriver.h
 */
DWORD CASPIDriver::Reserve  (BYTE adapter_id,BYTE device_id,BYTE lun,BYTE dest_id)
{
	SRB_MyExecSCSICmd exec;
	ZeroMemory (&exec,sizeof(SRB_MyExecSCSICmd));
	TRACE ("ASPIsnoop: reserve... ");
	exec.SRB_Cmd			= SC_EXEC_SCSI_CMD;
	exec.SRB_HaId			= adapter_id;
	exec.SRB_Target			= device_id;
	exec.SRB_Lun			= lun;
	exec.SRB_Flags			= SRB_DIR_OUT;
	exec.SRB_SenseLen		= SENSE_LEN;
	exec.SRB_CDBLen			= 6;
	exec.ccb.rsv.cmd		= SCSI_RESERVE;
	exec.ccb.rsv.lun		= lun;
	exec.ccb.rsv.third_party_id	= dest_id;
//	exec.ccb.rsv.len_0		= (size & 0xff);
//	exec.ccb.rsv.len_1		= ((size>>8) & 0xff);
	return RunCommand(&exec);				//send it..
}

⌨️ 快捷键说明

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