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

📄 scsi2.cpp.bak

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