private void ReadImports(MemoryTributary fs) { DebugOutput.PrintLn("Reading Imports..."); Imports = new List<ME2ImportEntry>(); fs.Seek(ImportOffset, SeekOrigin.Begin); for (int i = 0; i < ImportCount; i++) { ME2ImportEntry import = new ME2ImportEntry(); import.Package = Names[fs.ReadValueS32()]; fs.Seek(12, SeekOrigin.Current); import.link = fs.ReadValueS32(); import.Name = Names[fs.ReadValueS32()]; fs.Seek(-24, SeekOrigin.Current); import.raw = fs.ReadBytes(28); Imports.Add(import); } }
private void ReadExports(MemoryTributary fs) { DebugOutput.PrintLn("Reading Exports..."); fs.Seek(ExportOffset, SeekOrigin.Begin); Exports = new List<ME2ExportEntry>(); for (int i = 0; i < ExportCount; i++) { long start = fs.Position; ME2ExportEntry exp = new ME2ExportEntry(); exp.pccRef = this; exp.infoOffset = (int)start; fs.Seek(40, SeekOrigin.Current); int count = fs.ReadValueS32(); fs.Seek(4 + count * 12, SeekOrigin.Current); count = fs.ReadValueS32(); fs.Seek(4 + count * 4, SeekOrigin.Current); fs.Seek(16, SeekOrigin.Current); long end = fs.Position; fs.Seek(start, SeekOrigin.Begin); exp.info = fs.ReadBytes((int)(end - start)); Exports.Add(exp); fs.Seek(end, SeekOrigin.Begin); if (LastExport == null || exp.DataOffset > LastExport.DataOffset) LastExport = exp; } }
private void ReadNames(MemoryTributary fs) { DebugOutput.PrintLn("Reading Names..."); fs.Seek(NameOffset, SeekOrigin.Begin); Names = new List<string>(); for (int i = 0; i < NameCount; i++) { int len = fs.ReadValueS32(); string s = fs.ReadString((uint)(len - 1)); fs.Seek(5, SeekOrigin.Current); Names.Add(s); } }
private void LoadHelper(MemoryTributary tempStream) { tempStream.Seek(12, SeekOrigin.Begin); int tempNameSize = tempStream.ReadValueS32(); tempStream.Seek(64 + tempNameSize, SeekOrigin.Begin); int tempGenerator = tempStream.ReadValueS32(); tempStream.Seek(36 + tempGenerator * 12, SeekOrigin.Current); int tempPos = (int)tempStream.Position; NumChunks = tempStream.ReadValueS32(); tempStream.Seek(0, SeekOrigin.Begin); header = tempStream.ReadBytes(tempPos); tempStream.Seek(0, SeekOrigin.Begin); if (magic != ZBlock.magic && magic.Swap() != ZBlock.magic) { DebugOutput.PrintLn("Magic number incorrect: " + magic); throw new FormatException("This is not a pcc file. The magic number is incorrect."); } if (bCompressed) { DebugOutput.PrintLn("File is compressed"); { listsStream = lzo.DecompressPCC(tempStream, this); //Correct the header bCompressed = false; listsStream.Seek(0, SeekOrigin.Begin); listsStream.WriteBytes(header); //Set numblocks to zero listsStream.WriteValueS32(0); //Write the magic number listsStream.WriteValueS32(1026281201); //Write 8 bytes of 0 listsStream.WriteValueS32(0); listsStream.WriteValueS32(0); } } else { DebugOutput.PrintLn("File already decompressed. Reading decompressed data."); listsStream = tempStream; } ReadNames(listsStream); ReadImports(listsStream); ReadExports(listsStream); LoadExports(); }
private void ReadNames(MemoryTributary fs) { DebugOutput.PrintLn("Reading Names..."); fs.Seek(NameOffset, SeekOrigin.Begin); Names = new List<string>(); for (int i = 0; i < NameCount; i++) { int len = fs.ReadValueS32(); string s = ""; if (len > 0) { s = fs.ReadString((uint)(len - 1)); fs.Seek(9, SeekOrigin.Current); } else { len *= -1; for (int j = 0; j < len - 1; j++) { s += (char)fs.ReadByte(); fs.ReadByte(); } fs.Seek(10, SeekOrigin.Current); } Names.Add(s); } }
public PCCObject(String path) { lzo = new SaltLZOHelper(); fullname = path; BitConverter.IsLittleEndian = true; DebugOutput.PrintLn("Load file : " + path); pccFileName = Path.GetFullPath(path); MemoryTributary tempStream = new MemoryTributary(); if (!File.Exists(pccFileName)) throw new FileNotFoundException("PCC file not found"); using (FileStream fs = new FileStream(pccFileName, FileMode.Open, FileAccess.Read)) { FileInfo tempInfo = new FileInfo(pccFileName); tempStream.WriteFromStream(fs, tempInfo.Length); if (tempStream.Length != tempInfo.Length) { throw new FileLoadException("File not fully read in. Try again later"); } } tempStream.Seek(12, SeekOrigin.Begin); int tempNameSize = tempStream.ReadValueS32(); tempStream.Seek(64 + tempNameSize, SeekOrigin.Begin); int tempGenerator = tempStream.ReadValueS32(); tempStream.Seek(36 + tempGenerator * 12, SeekOrigin.Current); int tempPos = (int)tempStream.Position + 4; tempStream.Seek(0, SeekOrigin.Begin); header = tempStream.ReadBytes(tempPos); tempStream.Seek(0, SeekOrigin.Begin); if (magic != ZBlock.magic && magic.Swap() != ZBlock.magic) { DebugOutput.PrintLn("Magic number incorrect: " + magic); throw new FormatException("This is not a pcc file. The magic number is incorrect."); } if (bCompressed) { DebugOutput.PrintLn("File is compressed"); listsStream = lzo.DecompressPCC(tempStream, this); //Correct the header bCompressed = false; listsStream.Seek(0, SeekOrigin.Begin); listsStream.WriteBytes(header); // Set numblocks to zero listsStream.WriteValueS32(0); //Write the magic number listsStream.WriteBytes(new byte[] { 0xF2, 0x56, 0x1B, 0x4E }); // Write 4 bytes of 0 listsStream.WriteValueS32(0); } else { DebugOutput.PrintLn("File already decompressed. Reading decompressed data."); //listsStream = tempStream; listsStream = new MemoryTributary(); tempStream.WriteTo(listsStream); } tempStream.Dispose(); ReadNames(listsStream); ReadImports(listsStream); ReadExports(listsStream); LoadExports(); }
public void ME3PCCObjectHelper(MemoryTributary tempStream, string filePath, bool TablesOnly) { tempStream.Seek(0, SeekOrigin.Begin); DataStream = new MemoryTributary(); tempStream.WriteTo(DataStream); Names = new List<string>(); Imports = new List<ME3ImportEntry>(); Exports = new List<ME3ExportEntry>(); header = tempStream.ReadBytes(headerSize); if (magic != ZBlock.magic && magic.Swap() != ZBlock.magic) throw new FormatException(filePath + " is not a pcc file"); if (lowVers != 684 && highVers != 194) throw new FormatException("unsupported version"); if (bCompressed) { // seeks the blocks info position tempStream.Seek(idxOffsets + 60, SeekOrigin.Begin); int generator = tempStream.ReadValueS32(); tempStream.Seek((generator * 12) + 20, SeekOrigin.Current); int blockCount = tempStream.ReadValueS32(); blockList = new List<Block>(); // creating the Block list for (int i = 0; i < blockCount; i++) { Block temp = new Block(); temp.uncOffset = tempStream.ReadValueS32(); temp.uncSize = tempStream.ReadValueS32(); temp.cprOffset = tempStream.ReadValueS32(); temp.cprSize = tempStream.ReadValueS32(); blockList.Add(temp); } // correcting the header, in case there's need to be saved Buffer.BlockCopy(BitConverter.GetBytes((int)0), 0, header, header.Length - 12, sizeof(int)); tempStream.Read(header, header.Length - 8, 8); headerEnd = (int)tempStream.Position; // copying the extraNamesList int extraNamesLenght = blockList[0].cprOffset - headerEnd; if (extraNamesLenght > 0) { extraNamesList = new byte[extraNamesLenght]; tempStream.Read(extraNamesList, 0, extraNamesLenght); //FileStream fileStream = File.Create(Path.GetDirectoryName(pccFileName) + "\\temp.bin"); //fileStream.Write(extraNamesList, 0, extraNamesLenght); //MessageBox.Show("posizione: " + pccStream.Position.ToString("X8")); } int dataStart = 0; using (MemoryStream he = new MemoryStream(header)) { he.Seek(0, SeekOrigin.Begin); he.ReadValueS32(); he.ReadValueS32(); dataStart = he.ReadValueS32(); } if (TablesOnly) { int TableStart = 0; for (int m = 0; m < blockList.Count; m++) { if (blockList[m].uncOffset + blockList[m].uncSize > dataStart) { TableStart = m; break; } } listsStream = new MemoryTributary(); tempStream.Seek(blockList[TableStart].cprOffset, SeekOrigin.Begin); listsStream.Seek(blockList[TableStart].uncOffset, SeekOrigin.Begin); listsStream.WriteBytes(ZBlock.Decompress(tempStream, blockList[TableStart].cprSize)); DataStream = new MemoryTributary(); tempStream.WriteTo(DataStream); bCompressed = true; } else { //Decompress ALL blocks listsStream = new MemoryTributary(); for (int i = 0; i < blockCount; i++) { tempStream.Seek(blockList[i].cprOffset, SeekOrigin.Begin); listsStream.Seek(blockList[i].uncOffset, SeekOrigin.Begin); listsStream.WriteBytes(ZBlock.Decompress(tempStream, blockList[i].cprSize)); } } bCompressed = false; } else { listsStream = new MemoryTributary(); listsStream.WriteBytes(tempStream.ToArray()); } tempStream.Dispose(); //Fill name list listsStream.Seek(NameOffset, SeekOrigin.Begin); for (int i = 0; i < NameCount; i++) { int strLength = listsStream.ReadValueS32(); Names.Add(listsStream.ReadString(strLength * -2, true, Encoding.Unicode)); } // fill import list listsStream.Seek(ImportOffset, SeekOrigin.Begin); byte[] buffer = new byte[ME3ImportEntry.byteSize]; for (int i = 0; i < ImportCount; i++) { Imports.Add(new ME3ImportEntry(this, listsStream)); } //fill export list listsStream.Seek(ExportOffset, SeekOrigin.Begin); for (int i = 0; i < ExportCount; i++) { uint expInfoOffset = (uint)listsStream.Position; listsStream.Seek(44, SeekOrigin.Current); int count = listsStream.ReadValueS32(); listsStream.Seek(-48, SeekOrigin.Current); int expInfoSize = 68 + (count * 4); buffer = new byte[expInfoSize]; listsStream.Read(buffer, 0, buffer.Length); Exports.Add(new ME3ExportEntry(this, buffer, expInfoOffset)); } }