예제 #1
0
        private bool TryPackFileFromDisk(IO.EndianStream blockStream, string workPath,
                                         EraFileEntryChunk file)
        {
            string path = Path.Combine(workPath, file.FileName);

            if (!File.Exists(path))
            {
                Debug.Trace.Resource.TraceInformation("Couldn't pack file into {0}, file does not exist: {1}",
                                                      FileName, file.FileName);
                return(false);
            }

            try
            {
                file.FileDateTime = GetMostRecentTimeStamp(path);

                byte[] file_bytes = File.ReadAllBytes(path);
                using (var ms = new MemoryStream(file_bytes, false))
                {
                    PackFileData(blockStream, ms, file);
                }
            } catch (Exception ex)
            {
                Debug.Trace.Resource.TraceData(System.Diagnostics.TraceEventType.Error, TypeExtensions.kNone,
                                               string.Format("Couldn't pack file into {0}, encountered exception dealing with {1}", FileName, file.FileName),
                                               ex);
                return(false);
            }

            return(true);
        }
예제 #2
0
        static EraFileEntryChunk GenerateFileNamesTableEntryChunk()
        {
            var chunk = new EraFileEntryChunk();

            chunk.CompressionType = ECF.EcfCompressionType.DeflateStream;

            return(chunk);
        }
예제 #3
0
        private bool TryPack(IO.EndianStream blockStream, string workPath,
                             EraFileEntryChunk file)
        {
            if (mLocalFiles.ContainsKey(file.FileName))
            {
                return(TryPackLocalFile(blockStream, file));
            }

            return(TryPackFileFromDisk(blockStream, workPath, file));
        }
예제 #4
0
        private void ReadChunks(IO.XmlElementStream s)
        {
            foreach (var n in s.ElementsByName(ECF.EcfChunk.kXmlElementStreamName))
            {
                var f = new EraFileEntryChunk();
                using (s.EnterCursorBookmark(n))
                {
                    f.Read(s, false);
                }

                mFiles.Add(f);
            }
        }
예제 #5
0
        private void AddVersionFile()
        {
            var file = new EraFileEntryChunk();

            file.CompressionType = ECF.EcfCompressionType.Stored;
            var assembly = System.Reflection.Assembly.GetExecutingAssembly();

            file.FileName     = "version.txt";
            file.FileDateTime = BuildModeDefaultTimestamp;
            string version = string.Format("{0}\n{1}\n{2}",
                                           assembly.FullName,
                                           assembly.GetName().Version,
                                           System.Reflection.Assembly.GetEntryAssembly().FullName);

            mLocalFiles[file.FileName] = version;
            mFiles.Add(file);
        }
예제 #6
0
        private void ValidateAdler32(EraFileEntryChunk fileEntry, IO.EndianStream blockStream)
        {
            var actual_adler = fileEntry.ComputeAdler32(blockStream);

            if (actual_adler != fileEntry.Adler32)
            {
                string chunk_name = !string.IsNullOrEmpty(fileEntry.FileName)
                                        ? fileEntry.FileName
                                        : "FileNames";//fileEntry.EntryId.ToString("X16");

                throw new System.IO.InvalidDataException(string.Format(
                                                             "Invalid chunk adler32 for '{0}' offset={1} size={2} " +
                                                             "expected {3} but got {4}",
                                                             chunk_name, fileEntry.DataOffset, fileEntry.DataSize.ToString("X8"),
                                                             fileEntry.Adler32.ToString("X8"),
                                                             actual_adler.ToString("X8")
                                                             ));
            }
        }
예제 #7
0
        private bool TryPackLocalFile(IO.EndianStream blockStream,
                                      EraFileEntryChunk file)
        {
            string file_data;

            if (!mLocalFiles.TryGetValue(file.FileName, out file_data))
            {
                Debug.Trace.Resource.TraceInformation("Couldn't pack local-file into {0}, local-file does not exist: {1}",
                                                      FileName, file.FileName);
                return(false);
            }

            byte[] file_bytes = System.Text.Encoding.ASCII.GetBytes(file_data);
            using (var ms = new MemoryStream(file_bytes, false))
            {
                PackFileData(blockStream, ms, file);
            }

            return(true);
        }
예제 #8
0
        private void ValidateHashes(EraFileEntryChunk fileEntry, IO.EndianStream blockStream)
        {
            fileEntry.ComputeHash(blockStream, TigerHasher);

            if (!fileEntry.CompressedDataTiger128.EqualsArray(TigerHasher.Hash))
            {
                string chunk_name = !string.IsNullOrEmpty(fileEntry.FileName)
                                        ? fileEntry.FileName
                                        : "FileNames";//fileEntry.EntryId.ToString("X16");

                throw new System.IO.InvalidDataException(string.Format(
                                                             "Invalid chunk hash for '{0}' offset={1} size={2} " +
                                                             "expected {3} but got {4}",
                                                             chunk_name, fileEntry.DataOffset, fileEntry.DataSize.ToString("X8"),
                                                             Text.Util.ByteArrayToString(fileEntry.CompressedDataTiger128),
                                                             Text.Util.ByteArrayToString(TigerHasher.Hash, 0, EraFileEntryChunk.kCompresssedDataTigerHashSize)
                                                             ));
            }

            if (fileEntry.CompressionType == ECF.EcfCompressionType.Stored)
            {
                ulong tiger64;
                TigerHasher.TryGetAsTiger64(out tiger64);

                if (fileEntry.DecompressedDataTiger64 != tiger64)
                {
                    string chunk_name = !string.IsNullOrEmpty(fileEntry.FileName)
                                                ? fileEntry.FileName
                                                : "FileNames";//fileEntry.EntryId.ToString("X16");

                    throw new System.IO.InvalidDataException(string.Format(
                                                                 "Chunk id mismatch for '{0}' offset={1} size={2} " +
                                                                 "expected {3} but got {4}",
                                                                 chunk_name, fileEntry.DataOffset, fileEntry.DataSize.ToString("X8"),
                                                                 fileEntry.DecompressedDataTiger64.ToString("X16"),
                                                                 Text.Util.ByteArrayToString(TigerHasher.Hash, 0, sizeof(ulong))
                                                                 ));
                }
            }
        }
예제 #9
0
        public void SerializeFileEntryChunks(IO.EndianStream s)
        {
            if (s.IsReading)
            {
                mFiles.Capacity = mHeader.FileCount;

                for (int x = 0; x < mFiles.Capacity; x++)
                {
                    var file = new EraFileEntryChunk();
                    file.Serialize(s);

                    mFiles.Add(file);
                }
            }
            else if (s.IsWriting)
            {
                foreach (var f in mFiles)
                {
                    f.Serialize(s);
                }
            }
        }
예제 #10
0
 public int CalculateHeaderAndFileChunksSize()
 {
     return
         (EraFileHeader.CalculateHeaderSize() +
          EraFileEntryChunk.CalculateFileChunksSize(mFiles.Count));
 }
예제 #11
0
 private void PackFileNames(IO.EndianStream blockStream, System.IO.MemoryStream source, EraFileEntryChunk file)
 {
     file.FileDateTime = BuildModeDefaultTimestamp;
     PackFileData(blockStream, source, file);
 }
예제 #12
0
        private void PackFileData(IO.EndianStream blockStream, System.IO.Stream source, EraFileEntryChunk file)
        {
            file.BuildBuffer(blockStream, source, TigerHasher);

#if false
            ValidateAdler32(file, blockStream);
            ValidateHashes(file, blockStream);
#endif
        }
예제 #13
0
        private void UnpackToDisk(IO.EndianStream blockStream, string fullPath, EraFileExpander expander, EraFileEntryChunk file)
        {
            byte[] buffer = file.GetBuffer(blockStream);

            using (var fs = System.IO.File.Create(fullPath))
            {
                fs.Write(buffer, 0, buffer.Length);
            }

            System.IO.File.SetCreationTimeUtc(fullPath, file.FileDateTime);
            System.IO.File.SetLastWriteTimeUtc(fullPath, file.FileDateTime);

            if (ResourceUtils.IsXmbFile(fullPath))
            {
                if (!expander.ExpanderOptions.Test(EraFileExpanderOptions.DontTranslateXmbFiles))
                {
                    var va_size       = Shell.ProcessorSize.x32;
                    var builtFor64Bit = expander.Options.Test(EraFileUtilOptions.x64);
                    if (builtFor64Bit)
                    {
                        va_size = Shell.ProcessorSize.x64;
                    }

                    TransformXmbToXml(buffer, fullPath, blockStream.ByteOrder, va_size);
                }
            }
            else if (ResourceUtils.IsScaleformFile(fullPath))
            {
                if (expander.ExpanderOptions.Test(EraFileExpanderOptions.DecompressUIFiles))
                {
                    bool success = false;

                    try
                    {
                        success = DecompressUIFileToDisk(buffer, fullPath);
                    }
                    catch (Exception ex)
                    {
                        Debug.Trace.Resource.TraceEvent(System.Diagnostics.TraceEventType.Error, TypeExtensions.kNone,
                                                        "Exception during {0} of '{1}': {2}",
                                                        EraFileExpanderOptions.DecompressUIFiles, fullPath, ex);
                        success = false;
                    }

                    if (!success && expander.VerboseOutput != null)
                    {
                        expander.VerboseOutput.WriteLine("Option {0} failed on '{1}'",
                                                         EraFileExpanderOptions.DecompressUIFiles, fullPath);
                    }
                }
                if (expander.ExpanderOptions.Test(EraFileExpanderOptions.TranslateGfxFiles))
                {
                    var result = TransformGfxToSwfFileResult.Failed;

                    try
                    {
                        result = TransformGfxToSwfFile(buffer, fullPath);
                    }
                    catch (Exception ex)
                    {
                        Debug.Trace.Resource.TraceEvent(System.Diagnostics.TraceEventType.Error, TypeExtensions.kNone,
                                                        "Exception during {0} of '{1}': {2}",
                                                        EraFileExpanderOptions.TranslateGfxFiles, fullPath, ex);
                    }

                    if (expander.VerboseOutput != null)
                    {
                        if (result == TransformGfxToSwfFileResult.Failed)
                        {
                            expander.VerboseOutput.WriteLine("Option {0} failed on '{1}'",
                                                             EraFileExpanderOptions.TranslateGfxFiles, fullPath);
                        }
                        else if (result == TransformGfxToSwfFileResult.InputIsAlreadySwf)
                        {
                            expander.VerboseOutput.WriteLine("Option {0} skipped on '{1}', it is already an SWF-based file",
                                                             EraFileExpanderOptions.TranslateGfxFiles, fullPath);
                        }
                    }
                }
            }
        }
예제 #14
0
        private bool TryUnpack(IO.EndianStream blockStream, string workPath, EraFileExpander expander, EraFileEntryChunk file)
        {
            if (IsIgnoredLocalFile(file.FileName))
            {
                return(false);
            }

            string full_path = System.IO.Path.Combine(workPath, file.FileName);

            if (ResourceUtils.IsLocalScenarioFile(file.FileName))
            {
                return(false);
            }
            else if (!ShouldUnpack(expander, full_path))
            {
                return(false);
            }

            CreatePathForUnpacking(full_path);

            UnpackToDisk(blockStream, full_path, expander, file);
            return(true);
        }