//------------------------- void readHeader(BinaryReader f) { mFileHeader = new ECFHeader(); mFileHeader.mHeaderMagic = (uint)f.ReadInt32(); mFileHeader.mHeaderSize = (uint)f.ReadInt32(); mFileHeader.mHeaderAdler32 = (uint)f.ReadInt32(); mFileHeader.mFileSize = (uint)f.ReadInt32(); mFileHeader.mNumChunks = (ushort)f.ReadInt16(); mFileHeader.mFileSize = (ushort)f.ReadInt16(); mFileHeader.mID = (uint)f.ReadInt32(); mFileHeader.mChunkExtraDataSize = (ushort)f.ReadInt16(); mFileHeader.mPad0 = (ushort)f.ReadInt16(); mFileHeader.mPad1 = (uint)f.ReadInt32(); mFileHeader.endianSwap(); }
public unsafe bool writeToFile(string filename) { if (File.Exists(filename)) { File.Delete(filename); } FileStream s = File.Open(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite); BinaryWriter f = new BinaryWriter(s); BinaryReader r = new BinaryReader(s); //open reading from our temp file.. mTempChunkFile.Position = 0; BinaryReader tbr = new BinaryReader(mTempChunkFile); //WRITE OUR HEADER mHeader = new ECFHeader(); mHeader.mHeaderMagic = cECFHeaderMagic; mHeader.mHeaderSize = (uint)sizeof(ECFHeader); //THIS IS JUST THE SIZE OF THIS HEADER f.Write(ExportTo360.StructToByteArray(mHeader)); ///////////////////////////////////////// //WRITE OUR CHUNK HEADERS (Dummies!) BECFChunkHeader[] headers = new BECFChunkHeader[mChunks.Count]; ushort padVal = 0; Int32 padVal32 = 0; BECFChunkHeader ch = new BECFChunkHeader(); for (int i = 0; i < mChunks.Count; i++) { headers[i].mID = mChunks[i].mID; headers[i].mOfs = (int)f.BaseStream.Position; headers[i].mSize = (int)mChunks[i].mLength; headers[i].mAdler32 = (int)mChunks[i].mHeaderAdler32;//THIS IS THE ADLER FOR THE ACTUAL CHUNK DATA WE REPRESENT (Post endiean converted!) headers[i].mFlags = 0; headers[i].mAlignmentLog2 = 2; headers[i].mPad0 = (short)padVal; //headers[i].endianSwap();//not yet.... f.Write(ExportTo360.StructToByteArray(headers[i])); } //////////////////////////////////////////////// //WRITE OUR CHUNK BLOCKS for (int i = 0; i < mChunks.Count; i++) { //CLM [03.13.07] ECF Changes //we need to ensure each chunk is aligned to the boundry defined by ch.mAlignmentLog2 //so check to see if our position pointer is a multiple of 4 (2^2) //if it's not, write the number of bytes required to MAKE it that multiple. long pos = f.BaseStream.Position; long modPos = pos & 3; if (modPos != 0) { long numBytesToWrite = 4 - modPos; byte[] b = new byte[numBytesToWrite]; f.Write(b); } long streampos = f.BaseStream.Length; f.Write(tbr.ReadBytes((int)mChunks[i].mLength)); //fill in our header data headers[i].mOfs = (int)streampos; //seek back to our header and update our position pointer //f.Seek(sizeof(ECFHeader) + (sizeof(BECFChunkHeader) * i) + sizeof(Int64), SeekOrigin.Begin); //f.Write(Xbox_EndianSwap.endSwapI32((int)streampos)); //f.Seek(0, SeekOrigin.End); } //REWRITE OUR HEADER WITH THE PROPER DATA //write our actual file length back to the header mHeader.mFileSize = (uint)f.BaseStream.Length; // totalheaderSize; mHeader.mNumChunks = (ushort)mChunks.Count; mHeader.mFlags = 0; // mFlags; mHeader.mID = cXTD_ECFFileID; mHeader.mChunkExtraDataSize = 0; mHeader.endianSwap(); //CLM we have to calculate the adler of the endianswapped data, then endian swap ourselves mHeader.mHeaderAdler32 = calcAdler32(ExportTo360.StructToByteArray(mHeader), (uint)(sizeof(Int32) * cECFAdler32DWORDsToSkip), (uint)(sizeof(ECFHeader) - sizeof(Int32) * cECFAdler32DWORDsToSkip)); mHeader.mHeaderAdler32 = (uint)Xbox_EndianSwap.endSwapI32((int)mHeader.mHeaderAdler32); f.Seek(0, SeekOrigin.Begin); f.Write(ExportTo360.StructToByteArray(mHeader)); // f.Seek(0, SeekOrigin.End); ///////////////////////////////////////// //WRITE OUR CHUNK HEADERS (Real!) for (int i = 0; i < mChunks.Count; i++) { headers[i].endianSwap(); f.Write(ExportTo360.StructToByteArray(headers[i])); } headers = null; f.Close(); f = null; s.Close(); s = null; tbr.Close(); tbr = null; clear(); return(true); }