📄 scsi2.cpp.bak
字号:
srbExec.CDBByte [ 2 ] = 2; //Close Session
srbExec.CDBByte [ 5 ] = 1;
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::SaveFileAs(int ID,CString path){
disk_info di;
ReadDiskInfo(&di);
track_info ti;
ReadTrackInfo(di.numsess>1?2:0,&ti);
if(di.numsess>1)
m_lba=toInt32(ti.track_start_addr)+toInt32(ti.track_size)-0x101;
else
m_lba=toInt32(ti.next_writtable_addr);
BYTE blk[block_size];
int lastVATICB_Addr=m_lba-8;
if(!SCSIRead(blk,lastVATICB_Addr,1)) return false;
fileEntry lastVATICB=*(fileEntry*)blk;
int UniqueID=(int)lastVATICB.uniqueID+1;
int VAT_addr,FEAddr;
long_ad *ad;
if(lastVATICB.icbTag.flags==3){/*Embedded VAT*/
FEAddr=*(Uint32*)((BYTE*)&lastVATICB+0xb8+ID*4);
}
else if(lastVATICB.icbTag.flags==1){
ad=(long_ad*)((BYTE*)&lastVATICB+0xb0);
VAT_addr=ad->extLocation.logicalBlockNum+(8+4*ID)/block_size;
if(!SCSIRead(blk,VAT_addr+0x223,1,0)) return false;
FEAddr=*(Uint32*)(blk+(8+4*ID)%block_size);
}
if(!SCSIRead(blk,FEAddr+0x223,1,0)) return false;
ad=(long_ad*)((BYTE*)&blk+0x10c);
int fileLen=ad->extLength;
int blocks=fileLen/block_size+(fileLen%block_size?1:0);
BYTE* buffer=new BYTE[block_size*blocks];
int offset=0;
while(blocks>0){
int thisReadBlocks=blocks>16?16:blocks;
if(!SCSIRead(buffer+offset*block_size,
ad->extLocation.logicalBlockNum+0x223+offset,
thisReadBlocks,0))
return false;
offset+=thisReadBlocks;
blocks-=thisReadBlocks;
}
CFile outFile;
if(outFile.Open(path,CFile::modeCreate | CFile::modeWrite)){
outFile.Write(buffer,fileLen);
outFile.Close();
}
delete buffer;
return true;
}
//--------------------------------------------------------------------------
CString SCSI2::ListFiles(){
disk_info di;
ReadDiskInfo(&di);
track_info ti;
ReadTrackInfo(di.numsess>1?2:0,&ti);
if(di.numsess>1)
m_lba=toInt32(ti.track_start_addr)+toInt32(ti.track_size)-0x101;
else
m_lba=toInt32(ti.next_writtable_addr);
BYTE blk[block_size];
CString result;
int lastVATICB_Addr=m_lba-8;
if(!SCSIRead(blk,lastVATICB_Addr,1)) return "";
fileEntry lastVATICB=*(fileEntry*)blk;
int UniqueID=(int)lastVATICB.uniqueID+1;
int VATLength=4;
int totalVATlen=VATLength;
int lastVAT_len,lastVAT_addr,
adExtLen,firstVAT_addr,lastFIDDICBAddr;
bool VATEmbedded,FIDDEmbedded;
long_ad *ad;
if(lastVATICB.icbTag.flags==3){/*Embedded VAT*/
VATEmbedded=1;
lastVAT_len=lastVATICB.lengthAllocDescs;
totalVATlen+=lastVATICB.lengthAllocDescs;
lastVAT_addr=lastVATICB_Addr;
}
else if(lastVATICB.icbTag.flags==1){
VATEmbedded=0;
ad=(long_ad*)((BYTE*)&lastVATICB+0xb0);
adExtLen=ad->extLength;
firstVAT_addr=ad->extLocation.logicalBlockNum;
lastVAT_addr=firstVAT_addr+adExtLen/block_size;
lastVAT_len=adExtLen;
totalVATlen+=adExtLen;
}
int fileID=(totalVATlen-VATLength-0x24)/4;/*Number of existing files*/
if(VATEmbedded) lastFIDDICBAddr=*(Uint32*)((BYTE*)&lastVATICB+0xb4);
else{
if(!SCSIRead(blk,firstVAT_addr+0x223,1,0)) return "";
lastFIDDICBAddr=*(Uint32*)(blk+4);
}
if(!SCSIRead(blk,lastFIDDICBAddr+0x223,1,0)) return "";
fileEntry lastFIDDICB=*(fileEntry*)blk;
if(lastFIDDICB.icbTag.flags==3){
//Embedded FIDD
//We can get the file list from it directly
FIDDEmbedded=true;
int total_len=lastFIDDICB.lengthAllocDescs;
fileIdentDesc* FIDD=(fileIdentDesc*)(blk+176+40);
for(;(BYTE*)FIDD<blk+176+total_len;){
CString name;
for(int j=2;j<FIDD->lengthFileIdent;j+=2){
name+=(char)(FIDD->other[j]);
}
int len=38+FIDD->lengthFileIdent;
len+=(4-(len)%4)%4;
FIDD=(fileIdentDesc*)((BYTE*)FIDD+len);
if(!name.IsEmpty()) result+=name+"\r\n";
}
}
else if(lastFIDDICB.icbTag.flags==1){
//Non-Embedded FIDD
//We have to get the locations of FIDDs,
//And get the content one by one
FIDDEmbedded=false;
int leftOver=0;
long_ad* p=(long_ad*)((BYTE*)&lastFIDDICB+0xb0);
BYTE buffer[2*block_size];
while(p->extLength){
int blocks=p->extLength/block_size+
p->extLength%block_size?1:0;
if(!SCSIRead(buffer+leftOver,p->extLocation.logicalBlockNum+0x223,blocks))
return "";
int total_len=p->extLength+leftOver;
leftOver=0;
fileIdentDesc* FIDD=(fileIdentDesc*)(buffer);
for(;(BYTE*)FIDD<buffer+total_len;){
CString name;
int len=38+FIDD->lengthFileIdent;
len+=(4-(len)%4)%4;
if((BYTE*)FIDD>buffer+total_len-len){
leftOver=buffer+total_len-(BYTE*)FIDD;
memcpy(buffer,(BYTE*)FIDD,leftOver);
break;
}
for(int j=2;j<FIDD->lengthFileIdent;j+=2){
name+=(char)(FIDD->other[j]);
}
FIDD=(fileIdentDesc*)((BYTE*)FIDD+len);
if(!name.IsEmpty()) result+=name+"\r\n";
}
p++;
}
}
return result;
}
//--------------------------------------------------------------------------
bool SCSI2::WriteFiles (CString fileName) {
timestamp t;
time_t timenow;
char* impId="*Adaptec DirectCD"; //Pretend it's created by DirectCD
char* idSuffix="\x050\x001\x006";
regid*id;
time( &timenow );
udf_time_to_stamp(&t, timenow, 0);
CStringList* list=chopFileNames(fileName);
int filesCount=list->GetCount();
int totalDataBlocks=0,totalBlocks=0;
Uint64 totalVATlen,totalFIDDlen,fileID;
Uint32 FIDDLength=0;
for(int j=0;j<filesCount;j++){
CString name=list->GetAt(list->FindIndex(j));
CFile file(name,CFile::modeRead);
if(name.ReverseFind('\\')>=0) name=name.Mid(name.ReverseFind('\\')+1);
totalDataBlocks+=(int)ceil(file.GetLength()/(double)block_size);
int len=39+2*name.GetLength();
FIDDLength+=len+(4-len%4)%4;
}
int VATLength=4*filesCount;
Uint32 lastFIDD_len,lastVAT_len;
Uint32 lastFIDD_addr,lastVAT_addr;
bool FIDDEmbedded,VATEmbedded;
int newFIDDBlocks,newVATBlocks,existingVATBlocks,firstVAT_addr;
BYTE blk[block_size];
memset(blk,0,block_size);
track_info ti;
ReadTrackInfo(0,&ti);
int lastLeadOut=toInt32(ti.track_start_addr)+toInt32(ti.track_size);
m_lba=toInt32(ti.next_writtable_addr);
int lastVATICB_Addr=m_lba-8;
SCSIRead(blk,lastVATICB_Addr,1);
fileEntry lastVATICB=*(fileEntry*)blk;
int UniqueID=(int)lastVATICB.uniqueID+1;
totalVATlen=VATLength;
if(lastVATICB.icbTag.flags==3){//Embedded VAT
VATEmbedded=true;
lastVAT_len=lastVATICB.lengthAllocDescs;
totalVATlen+=lastVATICB.lengthAllocDescs;
lastVAT_addr=lastVATICB_Addr;
existingVATBlocks=1;
if(0xb0+lastVAT_len+VATLength<=block_size) newVATBlocks=0; /*Use old embedded VAT*/
else newVATBlocks=1;/*Add new VAT(s) not embedded*/
}
else if(lastVATICB.icbTag.flags==1){
VATEmbedded=false;
long_ad* p=(long_ad*)((BYTE*)&lastVATICB+0xb0);
firstVAT_addr=p->extLocation.logicalBlockNum;
lastVAT_addr=firstVAT_addr+p->extLength/block_size;
lastVAT_len=p->extLength;
totalVATlen+=p->extLength;
existingVATBlocks=p->extLength/block_size+(p->extLength%block_size?1:0);
newVATBlocks=totalVATlen/block_size+(totalVATlen%block_size?1:0);
/*Add new VAT(s) not embedded*/
}
fileID=(totalVATlen-VATLength-0x24)/4;
Uint32 lastFIDDICBAddr;
if(VATEmbedded) lastFIDDICBAddr=*(Uint32*)((BYTE*)&lastVATICB+0xb4);
else{
if(SCSIRead(blk,firstVAT_addr+0x223,1,0)) return false;
lastFIDDICBAddr=*(Uint32*)(blk+4);
}
if(!SCSIRead(blk,lastFIDDICBAddr+0x223,1)) return false;
fileEntry lastFIDDICB=*(fileEntry*)blk;
totalFIDDlen=FIDDLength;
if(lastFIDDICB.icbTag.flags==3){//Embedded FIDD
FIDDEmbedded=true;
lastFIDD_len=lastFIDDICB.lengthAllocDescs;
totalFIDDlen+=lastFIDD_len;
lastFIDD_addr=lastFIDDICBAddr;
newFIDDBlocks=0xb0+lastFIDD_len+FIDDLength<block_size?0: //Use old embedded FIDD
(int)ceil((double)(lastFIDD_len+FIDDLength)/block_size);//Add new FIDD(s) not embedded
}
else if(lastFIDDICB.icbTag.flags==1){
FIDDEmbedded=false;
long_ad* p=(long_ad*)((BYTE*)&lastFIDDICB+0xb0);
while(p->extLength){
lastFIDD_addr=p->extLocation.logicalBlockNum+p->extLength/block_size;
lastFIDD_len=p->extLength%block_size;
totalFIDDlen+=p->extLength;
p++;
}
newFIDDBlocks=(int)ceil((double)(lastFIDD_len+FIDDLength)/block_size);
//Add new FIDD(s) not embedded
}
totalBlocks=totalDataBlocks+list->GetCount()+2+newFIDDBlocks+newVATBlocks;
BYTE* buffer=new BYTE[block_size*totalBlocks];
if(m_lba+totalBlocks+7>lastLeadOut){
AfxMessageBox("Disk Full!");
return false;
}
memset(buffer,0,block_size*totalBlocks);
int offset=0;
for(j=0;j<filesCount;j++){
CString name=list->GetAt(list->FindIndex(j));
CFile file(name,CFile::modeRead);
int len=file.Read(buffer+offset,file.GetLength());
offset+=len+(block_size-len%block_size)%block_size;
}
int firstNonDataBlock=offset/block_size;
int firstEntrySector=m_lba+totalDataBlocks-0x223+newFIDDBlocks+newVATBlocks;
//ADD NEW FIDD BLOCKS HERE
//ECMA167 4/20,4/11
if(newFIDDBlocks){
if(FIDDEmbedded){
//Copy the old part first
memcpy(buffer+offset,(BYTE*)&lastFIDDICB+0xb0,lastFIDD_len);
//Write the new part
fileIdentDesc FIDD;
memset(&FIDD,0,sizeof(fileIdentDesc));
for(int j=0;j<filesCount;j++){
CString name=list->GetAt(list->FindIndex(j));
if(name.ReverseFind('\\')>=0) name=name.Mid(name.ReverseFind('\\')+1);
int len=39+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;//Virtual
FIDD.descTag=fillTag(TAG_IDENT_FID,(BYTE*)&FIDD+0x10,len+(4-len%4)%4-0x10,
m_lba+offset/block_size-0x223);//Need to change tagLoc at different blocks
memcpy(buffer+offset+lastFIDD_len,(BYTE*)&FIDD,len+(4-len%4)%4);
offset+=len+(4-len%4)%4;
}
}
else{
//Copy the old part first
if(!SCSIRead(buffer+offset,lastFIDD_addr+0x223,1)) return false;
//Write the new part
fileIdentDesc FIDD;
memset(&FIDD,0,sizeof(fileIdentDesc));
for(int j=0;j<filesCount;j++){
CString name=list->GetAt(list->FindIndex(j));
if(name.ReverseFind('\\')>=0) name=name.Mid(name.ReverseFind('\\')+1);
int len=39+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;//Virtual
FIDD.descTag=fillTag(TAG_IDENT_FID,(BYTE*)&FIDD+0x10,len+(4-len%4)%4-0x10,
m_lba+offset/block_size-0x223);//Need to change tagLoc at different blocks
memcpy(buffer+offset+lastFIDD_len,(BYTE*)&FIDD,len+(4-len%4)%4);
offset+=len+(4-len%4)%4;
}
}
}
offset+=(block_size-offset%block_size)%block_size;
//ADD NEW VAT BLOCKS HERE
//UNIVERSAL DISK FORMAT SPECIFICATIN Rev2.01 P33
if(newVATBlocks){
if(VATEmbedded){
memcpy(buffer+offset,(BYTE*)&lastVATICB+0xb0,lastVAT_len);
}
else{
if(SCSIRead(buffer+offset,firstVAT_addr+0x223,existingVATBlocks,0))
return false;
}
//MODIFY ROOT FILEENTRY VA FIRST
*(Uint32*)(buffer+offset+4)=firstEntrySector;
offset+=lastVAT_len-0x24;
memset(buffer+offset,0,existingVATBlocks*block_size-lastVAT_len);
//Write the new part
*(Uint32*)(buffer+offset)=firstEntrySector+1;
id=(regid*)(buffer+offset+4);
id->flags=0;
memcpy(id->identSuffix,idSuffix,3);
char* str=UDF_ID_ALLOC;
for(BYTE i=0;i<strlen(str);i++) id->ident[i]=str[i];
offset+=VATLength+0x24;
}
offset+=(block_size-offset%block_size)%block_size;
//WRITE THE FIDD ICB or FIDD(EMBEDDED)
//ECMA167 4/20,4/11
fileEntry FE;
memset(&FE,0,sizeof(fileEntry));
FE.icbTag.strategyType=4;
FE.icbTag.numEntries=1;
FE.icbTag.fileType=4;
FE.uid=0xffffffff;
FE.gid=0xffffffff;
FE.permissions=0x7fff;
FE.fileLinkCount=1;
FE.modificationTime=t;
FE.uniqueID=lastFIDDICB.uniqueID;
FE.impIdent.flags=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -