Esempio n. 1
0
        bool ReadEraFromFile()
        {
            if (ProgressOutput != null)
            {
                ProgressOutput.WriteLine("Opening and reading ERA file {0}...",
                                         mSourceFile);
            }

            if (ExpanderOptions.Test(EraFileExpanderOptions.DontLoadEntireEraIntoMemory))
            {
                mEraBaseStream = System.IO.File.OpenRead(mSourceFile);
            }
            else
            {
                byte[] era_bytes = System.IO.File.ReadAllBytes(mSourceFile);
                if (ExpanderOptions.Test(EraFileExpanderOptions.Decrypt))
                {
                    if (ProgressOutput != null)
                    {
                        ProgressOutput.WriteLine("Decrypting...");
                    }

                    DecryptFileBytes(era_bytes);
                }

                mEraBaseStream = new System.IO.MemoryStream(era_bytes, writable: false);
            }

            mEraStream            = new IO.EndianStream(mEraBaseStream, Shell.EndianFormat.Big, this, permissions: FA.Read);
            mEraStream.StreamMode = FA.Read;

            return(ReadEraFromStream());
        }
        bool ReadEcfFromFile()
        {
            if (ProgressOutput != null)
            {
                ProgressOutput.WriteLine("Opening and reading ECF file {0}...",
                                         mSourceFile);
            }

            if (ExpanderOptions.Test(EcfFileExpanderOptions.DontLoadEntireEcfIntoMemory))
            {
                mEcfBaseStream = File.OpenRead(mSourceFile);
            }
            else
            {
                byte[] ecf_bytes = File.ReadAllBytes(mSourceFile);

                mEcfBaseStream = new MemoryStream(ecf_bytes, writable: false);
            }

            mEcfStream            = new IO.EndianStream(mEcfBaseStream, Shell.EndianFormat.Big, this, permissions: FileAccess.Read);
            mEcfStream.StreamMode = FileAccess.Read;

            return(ReadEcfFromStream());
        }
        public string GetCreatorToolCommandLine(string xmlFileName)
        {
            var sb = new System.Text.StringBuilder();

            sb.AppendFormat("XMLCOMP -file {0}",
                            xmlFileName);
            sb.Append(BuilderOptions.Test(XmbFileBuilderOptions.LittleEndian) == false ? "" :
                      " -littleEndian");
            sb.Append(ForceStringVariants == false ? "" :
                      " -disableNumerics");
            sb.Append(ForceUnicode == false ? "" :
                      " -forceUnicode");

            return(sb.ToString());
        }
        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);
        }
Esempio n. 5
0
        bool BuildInternal(string workPath, string eraName, string outputPath)
        {
            string era_filename = Path.Combine(outputPath, eraName);

            if (!BuilderOptions.Test(EraFileBuilderOptions.Encrypt))
            {
                era_filename += EraFileExpander.kNameExtension;
            }
            else
            {
                era_filename += EraFileBuilder.kExtensionEncrypted;
            }

            mEraFile.FileName = era_filename;

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

            if (BuilderOptions.Test(EraFileBuilderOptions.AlwaysUseXmlOverXmb))
            {
                if (ProgressOutput != null)
                {
                    ProgressOutput.WriteLine("Finding XML files to use over XMB references...");
                }

                mEraFile.TryToReferenceXmlOverXmbFies(workPath, VerboseOutput);
            }

            const FA  k_mode = FA.Write;
            const int k_initial_buffer_size = 24 * IntegerMath.kMega;             // 24MB

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

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

            using (var ms = new MemoryStream(k_initial_buffer_size))
                using (var era_memory = new IO.EndianStream(ms, Shell.EndianFormat.Big, this, permissions: k_mode))
                {
                    era_memory.StreamMode = k_mode;
                    // we can use our custom VAT system to generate relative-offset (to a given chunk) information which ECFs use
                    era_memory.VirtualAddressTranslationInitialize(Shell.ProcessorSize.x32);

                    // 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 = mEraFile.CalculateHeaderAndFileChunksSize();
                    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 &= mEraFile.Build(era_memory, workPath);

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

                        // seek back to the start of the ERA and write out the finalized header and file chunk descriptors
                        ms.Seek(0, SeekOrigin.Begin);
                        mEraFile.Serialize(era_memory);

                        // Right now we don't actually perform any file removing (eg, duplicates) until EraFile.Build so
                        // we also allow the written size to be LESS THAN the assumed preamble size
                        Contract.Assert(era_memory.BaseStream.Position <= preamble_size,
                                        "Written ERA header size is greater than what we calculated");

                        // finally, bake the ERA memory stream into a file
                        if (BuilderOptions.Test(EraFileBuilderOptions.Encrypt))
                        {
                            if (ProgressOutput != null)
                            {
                                ProgressOutput.WriteLine("\tEncrypting...");
                            }

                            var era_bytes = ms.GetBuffer();
                            EncryptFileBytes(era_bytes, (int)ms.Length);
                        }
                        else                 // not encrypted
                        {
                        }

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