Esempio n. 1
0
        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));
            }
        }
Esempio n. 3
0
 public void SetHeaderFromMemStream(MemoryTributary source)
 {
     if (useTempFiles)
     {
         GenerateTempFileName("header");
         using (FileStream file = new FileStream(tmpHeaderFile, FileMode.Create, FileAccess.Write))
         {
             source.WriteTo(file);
         }
     } else
     {
         this.pHeader = source.ToArray();
     }
 }
Esempio n. 4
0
        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 + 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();
        }