コード例 #1
0
        public bool ExpandTo(string workPath, string listingName)
        {
            if (mEraFile == null)
            {
                return(false);
            }

            if (!System.IO.Directory.Exists(workPath))
            {
                System.IO.Directory.CreateDirectory(workPath);
            }

            bool result = true;

            if (ProgressOutput != null)
            {
                ProgressOutput.WriteLine("Outputting listing...");
            }

            try { SaveListing(workPath, listingName); }
            catch (Exception ex)
            {
                if (VerboseOutput != null)
                {
                    VerboseOutput.WriteLine("\tEncountered an error while outputting listing: {0}", ex);
                }
                result = false;
            }

            if (result && !ExpanderOptions.Test(EraFileExpanderOptions.OnlyDumpListing))
            {
                if (ProgressOutput != null)
                {
                    ProgressOutput.WriteLine("Expanding archive to {0}...", workPath);
                }

                try { mEraFile.ExpandTo(mEraStream, workPath); }
                catch (Exception ex)
                {
                    if (VerboseOutput != null)
                    {
                        VerboseOutput.WriteLine("\tEncountered an error while expanding archive: {0}", ex);
                    }
                    result = false;
                }

                if (ProgressOutput != null)
                {
                    ProgressOutput.WriteLine("Done");
                }
            }

            mEraStream.Close();

            return(result);
        }
コード例 #2
0
        public bool Read()
        {
            bool result = true;

            try { result &= ReadEcfFromFile(); }
            catch (Exception ex)
            {
                if (VerboseOutput != null)
                {
                    VerboseOutput.WriteLine("\tEncountered an error while trying to read the ECF: {0}", ex);
                }
                result = false;
            }

            return(result);
        }
コード例 #3
0
        public bool Read()         // read the listing definition
        {
            bool result = true;

            try { result &= ReadInternal(); }
            catch (Exception ex)
            {
                if (VerboseOutput != null)
                {
                    VerboseOutput.WriteLine("\tEncountered an error while trying to read listing: {0}", ex);
                }
                result = false;
            }

            return(result);
        }
コード例 #4
0
        static IOutput DetermineOutput(Options options, IConsole console)
        {
            IOutput output = new VerboseOutput(console);

            if (options.Silent)
            {
                output = new SilentOutput();
            }
            if (options.Progress)
            {
                output = new ProgressOutput(console);
            }
            if (options.NoColor)
            {
                return(output);
            }

            return(new ColorOutput(output));
        }
コード例 #5
0
        bool ReadEcfFromStream()
        {
            bool result = true;

            result = EcfHeader.VerifyIsEcf(mEcfStream.Reader);
            if (!result)
            {
                if (VerboseOutput != null)
                {
                    VerboseOutput.WriteLine("\tFailed: File is either not even an ECF-based file, or corrupt");
                }
            }
            else
            {
                mEcfFile = new EcfFile();
                mEcfFile.Serialize(mEcfStream);
            }

            return(result);
        }
コード例 #6
0
        bool ReadPkgFromStream()
        {
            bool result = true;

            result = CaPackageFile.VerifyIsPkg(mPkgStream.Reader);
            if (!result)
            {
                if (VerboseOutput != null)
                {
                    VerboseOutput.WriteLine("\tFailed: File is either not even an PKG file, or corrupt");
                }
            }
            else
            {
                mPkgFile = new CaPackageFile();
                mPkgFile.Serialize(mPkgStream);
            }

            return(result);
        }
コード例 #7
0
        bool ReadInternal()
        {
            bool result = true;

            if (ProgressOutput != null)
            {
                ProgressOutput.WriteLine("Trying to read source listing {0}...", mSourceFile);
            }

            if (!File.Exists(mSourceFile))
            {
                result = false;
            }
            else
            {
                using (var xml = new IO.XmlElementStream(mSourceFile, FA.Read, this))
                {
                    xml.InitializeAtRootElement();
                    EcfDefinition.Serialize(xml);
                }

                EcfDefinition.CullChunksPossiblyWithoutFileData((chunkIndex, chunk) =>
                {
                    if (VerboseOutput != null)
                    {
                        VerboseOutput.WriteLine("\t\tCulling chunk #{0} since it has no associated file data",
                                                chunkIndex);
                    }
                });
            }

            if (result == false)
            {
                if (ProgressOutput != null)
                {
                    ProgressOutput.WriteLine("\tFailed!");
                }
            }

            return(result);
        }
コード例 #8
0
        void ExpandChunkToFile(EcfFileChunkDefinition chunk, EcfChunk rawChunk)
        {
            string file_path = EcfDefinition.GetChunkAbsolutePath(chunk);

            if (!ExpanderOptions.Test(EcfFileExpanderOptions.DontOverwriteExistingFiles))
            {
                if (File.Exists(file_path))
                {
                    if (VerboseOutput != null)
                    {
                        VerboseOutput.WriteLine("\tSkipping chunk, output file already exists: {0}", file_path);
                    }

                    return;
                }
            }

            using (var fs = File.OpenWrite(file_path))
            {
                var chunk_bytes = rawChunk.GetBuffer(mEcfStream);
                fs.Write(chunk_bytes, 0, chunk_bytes.Length);
            }
        }
コード例 #9
0
        public bool Build(string workPath, string outputPath = null)
        {
            if (string.IsNullOrWhiteSpace(outputPath))
            {
                outputPath = workPath;
            }

            bool result = true;

            try
            {
                result = BuildInternal(workPath, outputPath);
            } catch (Exception ex)
            {
                if (VerboseOutput != null)
                {
                    VerboseOutput.WriteLine("\tEncountered an error while building the ECF: {0}", ex);
                }
                result = false;
            }

            return(result);
        }
コード例 #10
0
        void ExpandEntryToFile(string workPath, CaPackageEntry entry)
        {
            string file_path = Path.Combine(workPath, entry.Name);

            if (!ExpanderOptions.Test(CaPackageFileExpanderOptions.DontOverwriteExistingFiles))
            {
                if (File.Exists(file_path))
                {
                    if (VerboseOutput != null)
                    {
                        VerboseOutput.WriteLine("\tSkipping chunk, output file already exists: {0}", file_path);
                    }

                    return;
                }
            }

            using (var fs = File.OpenWrite(file_path))
            {
                var entry_bytes = mPkgFile.ReadEntryBytes(mPkgStream, entry);
                fs.Write(entry_bytes, 0, entry_bytes.Length);
            }
        }
コード例 #11
0
        bool ReadEraFromStream()
        {
            bool result = true;

            result = EraFileHeader.VerifyIsEraAndDecrypted(mEraStream.Reader);
            if (!result)
            {
                if (VerboseOutput != null)
                {
                    VerboseOutput.WriteLine("\tFailed: File is either not decrypted, corrupt, or not even an ERA");
                }
            }
            else
            {
                mEraStream.VirtualAddressTranslationInitialize(Shell.ProcessorSize.x32);

                mEraFile          = new EraFile();
                mEraFile.FileName = mSourceFile;
                mEraFile.Serialize(mEraStream);
                mEraFile.ReadPostprocess(mEraStream);
            }

            return(result);
        }
コード例 #12
0
        public bool ExpandTo(string workPath, string listingName)
        {
            if (mEcfFile == null)
            {
                return(false);
            }

            if (!Directory.Exists(workPath))
            {
                Directory.CreateDirectory(workPath);
            }

            bool result = true;

            if (ProgressOutput != null)
            {
                ProgressOutput.WriteLine("Outputting listing...");
            }

            try
            {
                PopulateEcfDefinitionFromEcfFile(workPath);
                SaveListing(workPath, listingName);
            }
            catch (Exception ex)
            {
                if (VerboseOutput != null)
                {
                    VerboseOutput.WriteLine("\tEncountered an error while outputting listing: {0}", ex);
                }
                result = false;
            }

            if (result && !ExpanderOptions.Test(EcfFileExpanderOptions.OnlyDumpListing) && WriteChunksToFile)
            {
                if (ProgressOutput != null)
                {
                    ProgressOutput.WriteLine("Expanding ECF to {0}...", workPath);
                }

                try
                {
                    ExpandChunksToFiles();
                }
                catch (Exception ex)
                {
                    if (VerboseOutput != null)
                    {
                        VerboseOutput.WriteLine("\tEncountered an error while expanding ECF: {0}", ex);
                    }
                    result = false;
                }

                if (ProgressOutput != null)
                {
                    ProgressOutput.WriteLine("Done");
                }
            }

            mEcfStream.Close();

            return(result);
        }
コード例 #13
0
        bool BuildInternal(string workPath, string pkgName, string outputPath)
        {
            string pkg_filename = Path.Combine(outputPath, pkgName);

            if (File.Exists(pkg_filename))
            {
                var attrs = File.GetAttributes(pkg_filename);
                if (attrs.HasFlag(FileAttributes.ReadOnly))
                {
                    throw new IOException("PKG file is readonly, can't build: " + pkg_filename);
                }
            }

            {
                string sanitizedWorkPath = CaPackageFileDefinition.SanitizeWorkingEnvironmentPath(workPath);
                if (sanitizedWorkPath != workPath && VerboseOutput != null)
                {
                    VerboseOutput.WriteLine("Sanitized work path:");
                    VerboseOutput.WriteLine("\t{0} =>", workPath);
                    VerboseOutput.WriteLine("\t{0}", sanitizedWorkPath);
                    workPath = sanitizedWorkPath;
                }
            }

            if (ProgressOutput != null)
            {
                ProgressOutput.WriteLine("Apply changes to PKG listing for work environment...");
            }
            if (PkgDefinition.RedefineForWorkingEnvironment(workPath
                                                            , BuilderOptions.Test(CaPackageFileBuilderOptions.AlwaysUseXmlOverXmb)
                                                            , VerboseOutput))
            {
            }

            mPkgFile = new CaPackageFile();
            mPkgFile.SetupHeaderAndEntries(PkgDefinition);

            const int k_initial_buffer_size = 16 * IntegerMath.kMega;             // 16MB

            if (ProgressOutput != null)
            {
                ProgressOutput.WriteLine("Building {0} to {1}...", pkgName, outputPath);
            }

            if (ProgressOutput != null)
            {
                ProgressOutput.WriteLine("\tAllocating memory...");
            }
            bool result = true;

            using (var ms = new MemoryStream(k_initial_buffer_size))
                using (var pkg_memory = new IO.EndianStream(ms, Shell.EndianFormat.Little, this, permissions: FileAccess.Write))
                {
                    pkg_memory.StreamMode = FileAccess.Write;

                    // #TODO:

                    // create null bytes for the header and embedded file chunk descriptors
                    // previously just used Seek to do this, but it doesn't update Length.
                    long preamble_size = mPkgFile.CalculateHeaderAndFileChunksSize((CaPackageVersion)CaPackageFile.kCurrentVersion);
                    ms.SetLength(preamble_size);
                    ms.Seek(preamble_size, SeekOrigin.Begin);

                    // now we can start embedding the files
                    if (ProgressOutput != null)
                    {
                        ProgressOutput.WriteLine("\tPacking files...");
                    }
                    result = false;            //result && mPkgFile.Build(pkg_memory, workPath);

                    if (result)
                    {
                        if (ProgressOutput != null)
                        {
                            ProgressOutput.WriteLine("\tFinializing...");
                        }

                        // seek back to the start of the PKG and write out the finalized header and file entries
                        ms.Seek(0, SeekOrigin.Begin);
                        mPkgFile.Serialize(pkg_memory);

                        Contract.Assert(pkg_memory.BaseStream.Position == preamble_size,
                                        "Written PKG header size is greater than what we calculated");

                        using (var fs = new FileStream(pkg_filename, FileMode.Create, FileAccess.Write))
                            ms.WriteTo(fs);
                    }
                }
            return(result);
        }