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

📄 scsi2.cpp.bak

📁 一个UDF系统的SCSI的CDROM刻录软件.
💻 BAK
📖 第 1 页 / 共 5 页
字号:
	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 + -