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); }
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); }