📄 scsi2.cpp.bak
字号:
// SCSI2.cpp: implementation of the SCSI2 class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CDR.h"
#include "SCSI2.h"
#include "scsireg.h"
#include "osta_udf.h"
#include "ecma_167.h"
#include <math.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#pragma pack(1)
extern timestamp *
udf_time_to_stamp(timestamp *dest, time_t tv_sec, long tv_usec);
extern Uint16
udf_crc(Uchar *data, Uint32 size);
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
SCSI2::SCSI2()
{
hEventSRB=NULL;
m_HA=1;
m_ID=0;
m_LUN=0;
m_silence=false;
}
//----------------------------------------------------------------------------
SCSI2::~SCSI2()
{
FreeLibrary(hinstWNASPI32);
}
//----------------------------------------------------------------------------
void SCSI2::SCSISelectDevice(BYTE HA_num, BYTE SCSI_Id, BYTE SCSI_Lun)
{
m_HA=HA_num;
m_ID=SCSI_Id;
m_LUN=SCSI_Lun;
}
//----------------------------------------------------------------------------
bool SCSI2::ASPIStart ( void ) {
// load WNASPI32.DLL
hinstWNASPI32 = LoadLibrary( "WNASPI32" );
if( !hinstWNASPI32 )
{
MessageBox ( NULL, "LoadLibrary:\nWNASPI32.DLL not found.",
"Error FS 002", MB_ICONSTOP );
return false;
}
pfnGetASPI32Buffer = (int(_cdecl*)(PASPI32BUFF))GetProcAddress( hinstWNASPI32, "GetASPI32Buffer" );
pfnFreeASPI32Buffer = (int(_cdecl*)(PASPI32BUFF))GetProcAddress( hinstWNASPI32, "FreeASPI32Buffer" );
pfnTranslateASPI32Address = (int(_cdecl*)(PDWORD, PDWORD))GetProcAddress( hinstWNASPI32,"TranslateASPI32Address" );
// load the address of GetASPI32SupportInfo
pfnGetASPI32SupportInfo = (DWORD(_cdecl*)(void))GetProcAddress( hinstWNASPI32, "GetASPI32SupportInfo" );
if ( pfnGetASPI32SupportInfo == NULL )
{
MessageBox ( NULL, "GetProcAddress:\nGetASPI32SupportInfo not fount.",
"Error FS 003", MB_ICONSTOP );
return false;
}
// load the address of SendASPI32Command
pfnSendASPI32Command = (DWORD (_cdecl*)( LPSRB ))GetProcAddress( hinstWNASPI32, "SendASPI32Command" );
if ( pfnSendASPI32Command == NULL )
{
MessageBox ( NULL, "GetProcAddress:\npfnSendASPI32Command not found.",
"Error FS 004", MB_ICONSTOP );
return false;
}
// call GetASPI32SupportInfo
DWORD dwSupportInfo = pfnGetASPI32SupportInfo ( );
BYTE byHaCount;
BYTE byASPIStatus;
byHaCount = LOBYTE ( LOWORD ( dwSupportInfo ) );
byASPIStatus = HIBYTE ( LOWORD ( dwSupportInfo ) );
switch ( byASPIStatus )
{
case SS_COMP: // ASPI support OK, now create the event object
hEventSRB = CreateEvent ( NULL, true, false, NULL );
if ( !hEventSRB )
{
MessageBox ( NULL, "Could not create the event object.",
"Error FS 005", MB_ICONEXCLAMATION );
return false;
}
return true; // true = everything OK !!!
case SS_NO_ADAPTERS:
AfxMessageBox("No SCSI2 device found.");
return false;
case SS_NO_ASPI:
MessageBox ( NULL, "Could not find the ASPI manager.",
"GetASPISupportInfo:", MB_ICONSTOP );
return false;
case SS_ILLEGAL_MODE:
MessageBox ( NULL, "ASPI for Windows does not support real mode.",
"GetASPISupportInfo:", MB_ICONSTOP );
return false;
case SS_OLD_MANAGER:
MessageBox ( NULL, "Old ASPI manager.",
"GetASPISupportInfo:", MB_ICONSTOP );
return false;
default:
MessageBox ( NULL, "Error initializing ASPI.",
"GetASPISupportInfo:", MB_ICONSTOP );
return false;
}
}
//----------------------------------------------------------------------------
void SCSI2::ASPIStop ( void ) {
// release the event object
if(hEventSRB!=NULL) CloseHandle ( hEventSRB );
// unload WNASPI32.DLL
FreeLibrary ( hinstWNASPI32 );
return;
}
//--------------------------------------------------------------------------
bool SCSI2::ASPIReset () {
CString szReturnString;
unsigned char szBuffer[40];
SRB_ExecSCSICmd srbExec;
memset ( &srbExec, 0, sizeof ( SRB_ExecSCSICmd ) );
srbExec.SRB_Cmd = SC_RESET_DEV;
srbExec.SRB_HaId = m_HA;
srbExec.SRB_Flags = SRB_DIR_IN;
srbExec.SRB_Target = m_ID;
srbExec.SRB_Lun = m_LUN;
srbExec.SRB_BufLen = 36;
srbExec.SRB_BufPointer = szBuffer;
srbExec.SRB_SenseLen = SENSE_LEN;
srbExec.SRB_CDBLen = 0;
pfnSendASPI32Command ( ( LPSRB ) &srbExec );
while ( srbExec.SRB_Status == SS_PENDING );
return srbExec.SRB_Status == SS_COMP;
}
//----------------------------------------------------------------------------
int SCSI2::SCSIBusScan ( DRIVEINFO* Info,BYTE type,bool silent ) {
// PHASE 1: determine how many host adapters are installed and the
// name and version of the ASPI manager
// initialize the SRB for the first inquiry
SRB_HAInquiry srbHAInquiry;
memset ( &srbHAInquiry, 0, sizeof ( SRB_HAInquiry ) );
srbHAInquiry . SRB_Cmd = SC_HA_INQUIRY;
srbHAInquiry . SRB_HaId = 0;
// get the number of host adapters installed
pfnSendASPI32Command ( (LPSRB)&srbHAInquiry );
if ( srbHAInquiry.SRB_Status != SS_COMP ){
MessageBox ( NULL, "Host adapter inquiry failed.",
"Error FS 006:", MB_ICONSTOP );
return 0;
}
BYTE HA_Count = srbHAInquiry . HA_Count;
int HA=m_HA;
int ID=m_ID;
int LUN=m_LUN;
int count=0;
// for each host adapter...
for ( m_HA = 0; m_HA < HA_Count; m_HA++ )
{
memset ( &srbHAInquiry, 0, sizeof ( SRB_HAInquiry ) );
srbHAInquiry . SRB_Cmd = SC_HA_INQUIRY;
srbHAInquiry . SRB_HaId = m_HA;
pfnSendASPI32Command ( ( LPSRB ) &srbHAInquiry );
if ( srbHAInquiry . SRB_Status != SS_COMP )
{
CString s;
s.Format("Host adapter %d inquiry failed.",m_HA);
AfxMessageBox ( s );
}
else
{
// for each SCSI id...
for ( m_ID = 0; m_ID < 8; m_ID++ )
{
// for each logical unit...
for ( m_LUN = 0; m_LUN < 8; m_LUN++ )
{
CString szDevice = "Unknown device type.";
SRB_GDEVBlock srbGDEVBlock;
memset ( &srbGDEVBlock, 0, sizeof ( srbGDEVBlock ) );
srbGDEVBlock.SRB_Cmd = SC_GET_DEV_TYPE;
srbGDEVBlock.SRB_HaId = m_HA;
srbGDEVBlock.SRB_Target = m_ID;
srbGDEVBlock.SRB_Lun = m_LUN;
pfnSendASPI32Command ( ( LPSRB ) &srbGDEVBlock );
if ( srbGDEVBlock.SRB_Status != SS_COMP ) continue;
BYTE devType=srbGDEVBlock.SRB_DeviceType;
switch(devType){
case DTYPE_DASD:
szDevice= "Direct access storage device" ;
break;
case DTYPE_SEQD:
szDevice= "Sequntial access storage device";
break;
case DTYPE_PRNT:
szDevice= "Printer device" ;
break;
case DTYPE_PROC:
szDevice= "Processor device" ;
break;
case DTYPE_WORM:
szDevice= "WORM device" ;
break;
case DTYPE_CDROM:
szDevice= "CD-ROM device" ;
break;
case DTYPE_SCAN:
szDevice= "Scanner device" ;
break;
case DTYPE_OPTI:
szDevice= "Optical memory device" ;
break;
case DTYPE_JUKE:
szDevice= "Medium changer device" ;
break;
case DTYPE_COMM:
szDevice= "Communication device" ;
break;
}
CString inq=SCSIInquiry(false);
if(type!=0xff&&type!=devType) continue;
if(!silent){
CString szMsg ;
szMsg.Format("Host adapter:%d\nSCSI ID:%d\nLogical Unit:%d\n%s\r\n%s",
m_HA,m_ID,m_LUN,szDevice,inq);
AfxMessageBox ( szMsg );
}
Info[count].m_HA=m_HA;
Info[count].m_ID=m_ID;
Info[count].m_LUN=m_LUN;
Info[count].m_name=inq;
count++;
}
}
}
}
SCSISelectDevice(HA,ID,LUN);
return count;
}
//--------------------------------------------------------------------------
CString SCSI2::SCSIInquiry (bool multiline) {
CString s,temp;
unsigned char szBuffer[40];
SRB_ExecSCSICmd srbExec;
memset ( &srbExec, 0, sizeof ( SRB_ExecSCSICmd ) );
srbExec.SRB_Cmd = SC_EXEC_SCSI_CMD;
srbExec.SRB_HaId = m_HA;
srbExec.SRB_Flags = SRB_DIR_IN;
srbExec.SRB_Target = m_ID;
srbExec.SRB_Lun = m_LUN;
srbExec.SRB_BufLen = 36;
srbExec.SRB_BufPointer = szBuffer;
srbExec.SRB_SenseLen = SENSE_LEN;
srbExec.SRB_CDBLen = 6;
srbExec.CDBByte [ 0 ] = SCSI_INQUIRY;
srbExec.CDBByte [ 4 ] = 36; // allocation length per szBuffer [ ]
pfnSendASPI32Command ( ( LPSRB ) &srbExec );
while ( srbExec.SRB_Status == SS_PENDING );
scsi_inquiry* result=(scsi_inquiry*)szBuffer;
if ( srbExec.SRB_Status != SS_COMP )
s="Inquiry error.";
else{
if(multiline)
s="Vendor:\t"+CString(result->vendor_info).Left(8)+
"\nProduct :\t"+CString(result->prod_ident).Left(16)+
"\nVersion :\t"+CString(result->prod_revision).Left(4);
else{
temp=CString(result->vendor_info).Left(8);
temp.TrimRight();
if(!temp.IsEmpty()) s=temp+" ";
temp=CString(result->prod_ident).Left(16);
temp.TrimRight();
s+=temp+" (Ver ";
temp=CString(result->prod_revision).Left(4);
temp.TrimRight();
s+=temp+")";
}
}
return s;
}
//--------------------------------------------------------------------------
bool SCSI2::CloseSession () {
CString szReturnString;
unsigned char szBuffer[40];
SRB_ExecSCSICmd srbExec;
BYTE buffer[block_size*0x168];
//Anchor Volume Descriptor Pointer
//ECMA167 3/14
anchorVolDescPtr AVDP;
memset(&AVDP,0,sizeof(anchorVolDescPtr));
AVDP.mainVolDescSeqExt.extLocation=0x201;
AVDP.mainVolDescSeqExt.extLength=0x8000;
AVDP.reserveVolDescSeqExt.extLocation=0x211;
AVDP.reserveVolDescSeqExt.extLength=0x8000;
//Volume Identifiers
//ECMA167 2/4
memset(buffer,0,block_size*0x168);
sprintf((char*)buffer+0x10*block_size+1,"BEA01\1");
sprintf((char*)buffer+0x11*block_size+1,"NSR02\1");
sprintf((char*)buffer+0x12*block_size+1,"TEA01\1");
AVDP.descTag=fillTag(TAG_IDENT_AVDP,(BYTE*)&AVDP+0x10,0x1f0,0x100);
*(anchorVolDescPtr*)(buffer+0x100*block_size)=AVDP;
while( TestUnitReady() );
if(!SetWriteParameters(1,10,4,0x20)) return false;
if(!WritePacket(buffer,0,0x168,false)) return false;
//Write End of Session Data, which includes VAT ICB and AVDPs
//UNIVERSAL DISK FORMAT SPECIFICATION REV2.01 P133
while( TestUnitReady() );
memset(buffer,0,block_size*0x168);
track_info p1;
ReadTrackInfo(0,&p1);
int lastICB=toInt32(p1.next_writtable_addr)-8;
SCSIRead(buffer,lastICB,1);
fileEntry lastVAT=*(fileEntry*)buffer;
lastVAT.descTag=fillTag(TAG_IDENT_FE,(BYTE*)&lastVAT+0x10,
lastVAT.descTag.descCRCLength,lastICB-0x223+0x108);
memset(buffer,0,block_size*0x168);
AVDP.descTag=fillTag(TAG_IDENT_AVDP,(BYTE*)&AVDP+0x10,0x1f0,lastICB+8);
for(int j=0;j<0x100;j++)
*(anchorVolDescPtr*)(buffer+j*block_size)=AVDP;
memcpy(buffer+0x100*block_size,&lastVAT,lastVAT.descTag.descCRCLength+0x10);
while( TestUnitReady() );
if(!SetWriteParameters(0,10,5,0x20)) return false;
if(!WritePacket(buffer,lastICB+8,0x101)) return false;
//Close Track
while( TestUnitReady() );
memset ( &srbExec, 0, sizeof ( SRB_ExecSCSICmd ) );
srbExec.SRB_Cmd = SC_EXEC_SCSI_CMD;
srbExec.SRB_HaId = m_HA;
srbExec.SRB_Flags = SRB_DIR_IN;
srbExec.SRB_Target = m_ID;
srbExec.SRB_Lun = m_LUN;
srbExec.SRB_BufLen = 36;
srbExec.SRB_BufPointer = szBuffer;
srbExec.SRB_SenseLen = SENSE_LEN;
srbExec.SRB_CDBLen = 10;
srbExec.CDBByte [ 0 ] = 0x5b;
srbExec.CDBByte [ 1 ] = 1; //Immediate
srbExec.CDBByte [ 2 ] = 1; //Close Track
srbExec.CDBByte [ 5 ] = 2;
pfnSendASPI32Command ( ( LPSRB ) &srbExec );
while ( srbExec.SRB_Status == SS_PENDING );
if(checkError(srbExec.SRB_Status)!="SUCCESS"&&!m_silence){
m_sense=*(scsi_sense*)srbExec.SenseArea;
AfxMessageBox(checkSense());
return false;
}
//Close Session
while( TestUnitReady() );
memset ( &srbExec, 0, sizeof ( SRB_ExecSCSICmd ) );
srbExec.SRB_Cmd = SC_EXEC_SCSI_CMD;
srbExec.SRB_HaId = m_HA;
srbExec.SRB_Flags = SRB_DIR_IN;
srbExec.SRB_Target = m_ID;
srbExec.SRB_Lun = m_LUN;
srbExec.SRB_BufLen = 36;
srbExec.SRB_BufPointer = szBuffer;
srbExec.SRB_SenseLen = SENSE_LEN;
srbExec.SRB_CDBLen = 10;
srbExec.CDBByte [ 0 ] = 0x5b;
srbExec.CDBByte [ 1 ] = 1; //Immediate
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -