📄 scsi2.cpp
字号:
for(BYTE i=0;i<strlen(impId);i++) FE.impIdent.ident[i]=impId[i];
FE.impIdent.identSuffix[0]=6;
FE.impIdent.identSuffix[6]=5;
FE.informationLength=totalFIDDlen;
if(FIDDEmbedded&&newFIDDBlocks==0)
{//USE THE OLD EMBEDDED FIDD
FE.icbTag.flags=0x3;
FE.lengthAllocDescs=(Uint32)totalFIDDlen;
int FIDD_Offset=0xB0;
//COPY THE OLD PART FIRST
memcpy((BYTE*)&FE+FIDD_Offset,(BYTE*)&lastFIDDICB+FIDD_Offset,lastFIDD_len);
FIDD_Offset+=lastFIDD_len;
fileIdentDesc FIDD;
memset(&FIDD,0,sizeof(fileIdentDesc));
for(int j=0;j<filesCount;j++){
//ADD NEW ENTRY FOR EACH NEW FILE
CString name=list->GetAt(list->FindIndex(j));
if(name.ReverseFind('\\')>=0) name=name.Mid(name.ReverseFind('\\')+1);
int len=40+2*name.GetLength();
char* uniname=(char*)((BYTE*)&FIDD+38);
memset(uniname,0,2*name.GetLength()+1);
uniname[0]=0x10;
for(int i=0;i<name.GetLength();i++)
uniname[2*(i+1)]=name[i];
FIDD.fileVersionNum=1;
FIDD.fileCharacteristics=0;
FIDD.lengthFileIdent=2*name.GetLength()+1;
FIDD.icb.extLength=0x800;
FIDD.icb.extLocation.logicalBlockNum=(Uint32)fileID+j;
FIDD.icb.extLocation.partitionReferenceNum=1;
FIDD.descTag=fillTag(TAG_IDENT_FID,(BYTE*)&FIDD+0x10,len+(4-len%4)%4-0x10,1);
memcpy((BYTE*)&FE+FIDD_Offset,(BYTE*)&FIDD,len+(4-len%4)%4);
FIDD_Offset+=len+(4-len%4)%4;
}
FE.descTag=fillTag(TAG_IDENT_FE,(BYTE*)&FE+0x10,0xa0+lastFIDD_len+FIDDLength,1);
}
else if(FIDDEmbedded){
//THE FIDD IS NO LONGER EMBEDDED,THE FIDD ICB HAS TO BE REWRITTEN HERE
//THE FIDD ITSELF IS ALREADY WRITTEN AT THE BEGINNING OF THIS FUNCTION
FE.icbTag.flags=0x1;
FE.lengthAllocDescs=0x750;
long_ad* p=(long_ad*)((BYTE*)&FE+0xb0);
p->extLength=(Uint32)(FIDDLength+lastFIDD_len);
p->extLocation.logicalBlockNum=m_lba-0x223+totalDataBlocks;
p->extLocation.partitionReferenceNum=0; //Physical Partition
FE.descTag=fillTag(TAG_IDENT_FE,(BYTE*)&FE+0x10,0x7f0,1);
}
else{
memcpy(&FE,&lastFIDDICB,block_size);
FE.informationLength=totalFIDDlen;
long_ad* p=(long_ad*)((BYTE*)&FE+0xb0);
while(p->extLength) p++;
p--;//Last FIDD must be rewritten
if(p->extLength>0x800){
p->extLength-=p->extLength%block_size;
p++;
}
p->extLength=(Uint32)(FIDDLength+lastFIDD_len);
p->extLocation.logicalBlockNum=m_lba-0x223+totalDataBlocks;
p->extLocation.partitionReferenceNum=0; //Physical Partition
FE.descTag=fillTag(TAG_IDENT_FE,(BYTE*)&FE+0x10,0x7f0,1);
}
*(fileEntry*)(buffer+offset)=FE;
offset+=block_size;
memset(&FE,0,sizeof(fileEntry));
FE.icbTag.strategyType=4;
FE.icbTag.numEntries=1;
FE.icbTag.fileType=5;
FE.icbTag.flags=0x1;
FE.uid=0xffffffff;
FE.gid=0xffffffff;
FE.permissions=0x7BDE;
FE.fileLinkCount=1;
FE.modificationTime=t;
for(i=0;i<strlen(impId);i++) FE.impIdent.ident[i]=impId[i];
FE.impIdent.identSuffix[0]=6;
FE.impIdent.identSuffix[6]=5;
FE.uniqueID=UniqueID++;
FE.lengthExtendedAttr=0x5c;
FE.lengthAllocDescs=0x6f0;
Uint32 fileLocation=m_lba-0x223;
for(j=0;j<filesCount;j++){
//ADD ONE FILE ENTRY FOR EACH FILE
//ECMA-167 4/28
CString name=list->GetAt(list->FindIndex(j));
CFile file(name,CFile::modeRead);
int len=file.GetLength();
int blocks=(int)ceil(len/(double)block_size);
FE.informationLength=len;
FE.logicalBlocksRecorded=blocks;
FE.uniqueID=UniqueID++;
BYTE* other=&FE.other[0];
*(Uint32*)(other+0x10)=0xffffffff;
*(Uint32*)(other+0x14)=0xffffffff;
fileTimesExtAttr* FTEA=(fileTimesExtAttr*)(other+0x18);
FTEA->attrType=5;
FTEA->attrSubtype=1;
FTEA->attrLength=0x5c;
FTEA->dataLength=0x0c;
FTEA->fileTimeExistence=1;
FTEA->fileTimes=t;
short_ad* ad=(short_ad*)(other+0x5c);
ad->extLength=len;
ad->extPosition=fileLocation;
fileLocation+=blocks;
*(tag*)other=fillTag(0x106,(BYTE*)other+0xc0,0x4c,j+2);
FE.descTag=fillTag(TAG_IDENT_FE,(BYTE*)&FE+0x10,0x7ec,(Uint32)fileID+j);
*(fileEntry*)(buffer+offset)=FE;
offset+=block_size;
}
//VAT ICB or VAT(EMBEDDED)
//UNIVERSAL DISK FORMAT SPECIFICATIN Rev2.01 P33
memset(&FE,0,sizeof(fileEntry));
FE.icbTag.strategyType=4;
FE.icbTag.numEntries=1;
FE.uid=0xffffffff;
FE.gid=0xffffffff;
FE.permissions=0x7fff;
FE.modificationTime=t;
for(i=0;i<strlen(impId);i++) FE.impIdent.ident[i]=impId[i];
FE.impIdent.identSuffix[0]=6;
FE.impIdent.identSuffix[6]=5;
FE.uniqueID=UniqueID++;
FE.informationLength=totalVATlen;
if(VATEmbedded&&newVATBlocks==0)
{
//USE OLD EMBEDDED VAT
FE.icbTag.flags=0x3;
FE.lengthAllocDescs=(Uint32)totalVATlen;
//COPY THE OLD VAT
memcpy((BYTE*)&FE+0xb0,(BYTE*)&lastVATICB+0xb0,lastVATICB.lengthAllocDescs-0x24);
//MODIFY THE ROOT FILE ENTRY OF VAT TO NEW FIDD ADDRESS
*(Uint32*)((BYTE*)&FE+0xB4)=firstEntrySector;
//ADD NEW ENTRIES FOR THE EMBEDDED VAT
BYTE* newVATEntryAddr=(BYTE*)&FE+0xB0+lastVATICB.lengthAllocDescs-0x24;
for(i=0;i<filesCount;i++){
//Add one entry for each file
*(Uint32*)(newVATEntryAddr+i*4)=firstEntrySector+1+i;
}
//OTHER STUFF TO FILL
regid* id=(regid*)(newVATEntryAddr+4*filesCount);
id->flags=0;
id->identSuffix[0]=0x50;
id->identSuffix[1]=0x01;
id->identSuffix[2]=0x06;
char* str=UDF_ID_ALLOC;
for(i=0;i<strlen(str);i++) id->ident[i]=str[i];
*(Uint32*)(newVATEntryAddr+4*filesCount+0x20)=lastVATICB_Addr-0x223;
FE.descTag=fillTag(TAG_IDENT_FE,(BYTE*)&FE+0x10,0xa0+lastVATICB.lengthAllocDescs+4*filesCount,
firstEntrySector+1+filesCount);
}
else if(VATEmbedded){
//THE VAT IS NO LONGER EMBEDDED,THE VAT ICB HAS TO BE REWRITTEN HERE
//THE VAT ITSELF IS ALREADY WRITTEN AT THE BEGINNING OF THIS FUNCTION
FE.icbTag.flags=0x1;
FE.lengthAllocDescs=0x750;
//LOCATION OF THE VAT
long_ad* p=(long_ad*)((BYTE*)&FE+0xb0);
p->extLength=(Uint32)(VATLength+lastVAT_len);
p->extLocation.logicalBlockNum=m_lba-0x223+totalDataBlocks+newFIDDBlocks;
p->extLocation.partitionReferenceNum=0; //Physical Partition
FE.descTag=fillTag(TAG_IDENT_FE,(BYTE*)&FE+0x10,0x7f0,firstEntrySector+1+filesCount);
}
else{
//ONLY NEED TO CHANGE THE LAST VAT ENTRY IN THE VAT ICB
memcpy(&FE,&lastFIDDICB,block_size);
FE.informationLength=totalVATlen;
long_ad* p=(long_ad*)((BYTE*)&FE+0xb0);
while(p->extLength) p++;
p--;//Last VAT must be rewritten
if(p->extLength>0x800){
p->extLength-=p->extLength%block_size;
p++;
}
p->extLength=(Uint32)(VATLength+lastVAT_len);
p->extLocation.logicalBlockNum=m_lba-0x223+totalDataBlocks+newFIDDBlocks;
p->extLocation.partitionReferenceNum=0; //Physical Partition
FE.descTag=fillTag(TAG_IDENT_FE,(BYTE*)&FE+0x10,0x7f0,firstEntrySector+1+filesCount);
}
*(fileEntry*)(buffer+offset)=FE;
if(!SetWriteParameters(0,10,5,0x20)) return false;
bool result=WritePacket(buffer,m_lba,totalBlocks);
delete buffer;
delete list;
return result;
}
//--------------------------------------------------------------------------
bool SCSI2::WritePacket(long len) {
BYTE* buffer=new BYTE[block_size*len];
memset(buffer,0,block_size*len);
bool res= WritePacket (buffer,m_lba,len);
delete buffer;
return res;
}
//--------------------------------------------------------------------------
bool SCSI2::WritePacket (unsigned char* buffer,long len) {
return WritePacket (buffer,m_lba,len);
}
//--------------------------------------------------------------------------
bool SCSI2::WritePacket (unsigned char* buffer,long addr,long len,bool packet) {
while(TestUnitReady());
m_lba=addr;
SRB_ExecSCSICmd srbExec;
memset ( &srbExec, 0, sizeof ( SRB_ExecSCSICmd ) );
for(int i=0;len-i*0x10>0;i++){
int thisLen=len-i*0x10<0x10?len-i*0x10:0x10;
memset ( &srbExec, 0, sizeof ( SRB_ExecSCSICmd ) );
srbExec.SRB_Cmd = SC_EXEC_SCSI_CMD;
srbExec.SRB_HaId = m_HA;
srbExec.SRB_Target = m_ID;
srbExec.SRB_Lun = m_LUN;
srbExec.SRB_Flags = SRB_DIR_OUT;
srbExec.SRB_BufLen = block_size*thisLen;
srbExec.SRB_BufPointer = buffer+i*0x10*block_size;
srbExec.SRB_SenseLen = SENSE_LEN;
srbExec.SRB_CDBLen = 10;
srbExec.CDBByte [ 0 ] = SCSI_WRITE10;
srbExec.CDBByte [ 1 ] = 0x00; //0x08=FUA
srbExec.CDBByte [ 2 ] = (m_lba>>24)&0xff;
srbExec.CDBByte [ 3 ] = (m_lba>>16)&0xff;
srbExec.CDBByte [ 4 ] = (m_lba>>8)&0xff;
srbExec.CDBByte [ 5 ] = m_lba&0xff;
srbExec.CDBByte [ 7 ] = (thisLen>>8)&0xff;
srbExec.CDBByte [ 8 ] = thisLen&0xff;
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());
break;
}
if(srbExec.SRB_Status == SS_COMP) m_lba+=thisLen;
}
if(srbExec.SRB_Status == SS_COMP&&packet){
m_lba+=7;
srbExec.SRB_BufLen = 0;
srbExec.SRB_BufPointer=0;
srbExec.CDBByte [ 2 ] = (m_lba>>24)&0xff;
srbExec.CDBByte [ 3 ] = (m_lba>>16)&0xff;
srbExec.CDBByte [ 4 ] = (m_lba>>8)&0xff;
srbExec.CDBByte [ 5 ] = m_lba&0xff;
srbExec.CDBByte [ 7 ] = 0;
srbExec.CDBByte [ 8 ] = 0;
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 srbExec.SRB_Status == SS_COMP;
}
//--------------------------------------------------------------------------
bool SCSI2::ReserveTrack(int size){
BYTE *buffer=new BYTE[block_size];
memset(buffer,0,block_size);
while(TestUnitReady());
SRB_ExecSCSICmd srbExec;
memset ( &srbExec, 0, sizeof ( SRB_ExecSCSICmd ) );
srbExec.SRB_Cmd = SC_EXEC_SCSI_CMD;
srbExec.SRB_HaId = m_HA;
srbExec.SRB_Target = m_ID;
srbExec.SRB_Lun = m_LUN;
srbExec.SRB_Flags = SRB_DIR_IN;
srbExec.SRB_BufLen = block_size;
srbExec.SRB_BufPointer = buffer;
srbExec.SRB_SenseLen = SENSE_LEN;
srbExec.SRB_CDBLen = 10;
srbExec.CDBByte [ 0 ] = 0x53; //Reserve Track
srbExec.CDBByte [ 7 ] = (size>>8)&0xff;
srbExec.CDBByte [ 8 ] = size&0xff;
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());
}
delete buffer;
return srbExec.SRB_Status == SS_COMP;
}
//--------------------------------------------------------------------------
bool SCSI2::FormatDisc (const char* label) {
//Set write mode to TAO
if(!SetWriteParameters(1,10,4,0x20)) return false;
//Reserve Track of length 0x168, which will be used
//closing the session
if(!ReserveTrack(0x168)) return false;
//Set write mode back to variable packet
if(!SetWriteParameters(0,10,5,0x20)) return false;
int HEADER_SIZE=0x26;
int FIRST_VRS=0x201;
int SECOND_VRS=0x211;
BYTE *buffer=new BYTE[block_size*HEADER_SIZE];
char* str;
char* impId="*Adaptec DirectCD";
char* volID=new char[32];
memset(volID,0,32);
volID[0]=0x10; //16bits per character
for(BYTE i=0;i<strlen(label);i++) volID[2*(i+1)]=label[i]; //Unicode
memset(buffer,0,block_size*HEADER_SIZE);
anchorVolDescPtr AVDP;
memset(&AVDP,0,sizeof(anchorVolDescPtr));
AVDP.mainVolDescSeqExt.extLocation=FIRST_VRS;
AVDP.mainVolDescSeqExt.extLength=0x8000;
AVDP.reserveVolDescSeqExt.extLocation=SECOND_VRS;
AVDP.reserveVolDescSeqExt.extLength=0x8000;
AVDP.descTag=fillTag(TAG_IDENT_AVDP,(BYTE*)&AVDP+0x10,0x1f0,0x200);
*(anchorVolDescPtr*)buffer=AVDP;
timestamp t;
time_t timenow;
time( &timenow );
udf_time_to_stamp(&t, timenow, 0);
int offset=block_size;
for(int repeat=0;repeat<2;repeat++){
int base=repeat?SECOND_VRS:FIRST_VRS;
offset=repeat?0x11*block_size:block_size;
//Write PVD
primaryVolDesc PVD;
memset(&PVD,0,sizeof(primaryVolDesc));
PVD.volDescSeqNum=1;
for(i=0;i<32;i++) PVD.volIdent[i]=volID[i];
PVD.volIdent[31]=2*strlen(label)+1; //Length of dstring
PVD.volSeqNum=1;
PVD.maxVolSeqNum=1;
PVD.interchangeLvl=2;
PVD.maxInterchangeLvl=3;
PVD.charSetList=1;
PVD.maxCharSetList=1;
PVD.volSetIdent[0]=0x08;
PVD.volSetIdent[1]='0';
PVD.volSetIdent[2]='C';
PVD.volSetIdent[3]='F';
PVD.volSetIdent[4]='E';
PVD.volSetIdent[5]='9';
PVD.volSetIdent[6]='0';
PVD.volSetIdent[7]='C';
PVD.volSetIdent[8]='B';
PVD.volSetIdent[127]=0x09; //Length of dstring
PVD.descCharSet.charSetType=UDF_CHAR_SET_TYPE;
PVD.explanatoryCharSet.charSetType=UDF_CHAR_SET_TYPE;
str=UDF_CHAR_SET_INFO;
for(i=0;i<strlen(str);i++){
PVD.descCharSet.charSetInfo[i]=str[i];
PVD.explanatoryCharSet.charSetInfo[i]=str[i];
}
PVD.recordingDateAndTime=t;
PVD.impIdent.flags=0;
for(i=0;i<strlen(impId);i++) PVD.impIdent.ident[i]=impId[i];
PVD.impIdent.identSuffix[0]=6;
PVD.impIdent.identSuffix[6]=5;
PVD.descTag=fillTag(TAG_IDENT_PVD,(BYTE*)&PVD+0x10,0x1f0,base);
*(primaryVolDesc*)(buffer+offset)=PVD;
//Write LVD
logicalVolDesc LVD;
memset(&LVD,0,sizeof(logicalVolDesc));
LVD.volDescSeqNum=2;
LVD.descCharSet.charSetType=0;
str=UDF_CHAR_SET_INFO;
for(i=0;i<strlen(str);i++) LVD.descCharSet.charSetInfo[i]=str[i];
for(i=0;i<32;i++) LVD.logicalVolIdent[i]=volID[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -