public static void Pack(string smdFile, string templateFile) { FileStream output = new FileStream(smdFile, FileMode.Create, FileAccess.ReadWrite); FileStream input; XDocument template = XDocument.Load(templateFile); if (template.Root.Name != "smd-tool") { throw new Exception("Invalid template file"); } XElement slist = template.Root.Element(XName.Get("template")); if (slist == null) { throw new Exception("Invalid template file"); } BinaryWriter bw = new BinaryWriter(output); //Write header XElement header = slist.Element(XName.Get("header")); if (header == null) { throw new Exception("Header is missing"); } input = new FileStream(header.Attribute(XName.Get("file")).Value, FileMode.Open, FileAccess.Read); FileIO.StreamCopy(input, output, 0, 0x50); input.Close(); FileIO.WriteZeroes(output, 0x50, DATA_START - 0x50); output.Position = 0x200; List <Section> sections = new List <Section>(); uint fileOffset = (uint)DATA_START; foreach (XElement xsection in slist.Elements(XName.Get("section"))) { Section section = new Section(); section.IsPresent = true; section.FileOffset = fileOffset; section.Name = xsection.Attribute(XName.Get("name")).Value; section.FileName = xsection.Attribute(XName.Get("file")).Value; section.ROMOffset = Convert.ToUInt32(xsection.Attribute(XName.Get("offset")).Value, 16); FileStream stream = new FileStream(section.FileName, FileMode.Open, FileAccess.Read); section.FileLength = (uint)stream.Length; BinaryReader br = new BinaryReader(stream); if (br.ReadUInt64() != DiscreteImage.IS_PACKED_SIGNATURE) { section.ROMLength = section.FileLength / 512; section.FileLength += DiscreteImage.HEADER_SIZE; section.IsPacked = false; } else { DiscreteImage image = new DiscreteImage(section.FileName); section.ROMLength = (uint)image.RealSize / 512; section.IsPacked = true; } fileOffset += section.FileLength; br.Close(); sections.Add(section); } for (int i = 0; i < sections.Count; i++) { //Write header Section sec = sections[i]; output.Position = 0x200 + (0x40 * i); if (!sec.IsPacked) { sec.IsPacked = true; //it will be packed anyway sec.WriteHeader(output); sec.IsPacked = false; //return flag back } else { sec.WriteHeader(output); } //Write data input = new FileStream(sec.FileName, FileMode.Open, FileAccess.Read); output.Position = sec.FileOffset; if (!sec.IsPacked) { //Write header bw.Write(0x7260EACCEACC9442); bw.Write(1u); //count bw.Write(0u); bw.Write(0u); //start bw.Write((uint)input.Length / 512); FileIO.WriteZeroes(output, sec.FileOffset + 24, DiscreteImage.HEADER_SIZE - 24); } FileIO.StreamCopy(input, output, 0, input.Length, 1024 * 1024); input.Close(); } //Compute MD5 output.Position = 0; MD5 hash = MD5.Create(); hash.ComputeHash(output); output.Position = 0x50; bw.Write(hash.Hash); }
static int Main(string[] args) { string binFileName = null, imgFileName = null; long binFilePos = 8, imgFilePos, partSize; binFileName = GetArg(args, "/u", null); if (binFileName != null) { imgFileName = GetArg(args, "/o", null); if (imgFileName == null) { if (binFileName.EndsWith(".bin")) { imgFileName = binFileName.Substring(0, binFileName.Length - 4) + ".img"; } else { imgFileName = binFileName + ".img"; } } DiscreteImage image = new DiscreteImage(binFileName); Console.WriteLine("Parts count: {0}", image.Sections.Count); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(" № From To Count"); Console.ResetColor(); int i = 0; foreach (DiscreteImage.Section section in image.Sections) { imgFilePos = section.Position; partSize = section.Length; Console.WriteLine("Part {0:d3} {1:X8} {2:X8} {3:X8}", i, binFilePos, imgFilePos, partSize); binFilePos += partSize; i++; } image.Extract(imgFileName); return 0; } binFileName = GetArg(args, "/p", null); if (binFileName != null) { PrintError("Not implemented yet"); return -1; } binFileName = GetArg(args, "/info", null); if (binFileName != null) { DiscreteImage image = new DiscreteImage(binFileName); Console.WriteLine("Parts count: {0}", image.Sections.Count); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(" № From To Count"); Console.ResetColor(); int i = 0; foreach(DiscreteImage.Section section in image.Sections) { imgFilePos = section.Position; partSize = section.Length; Console.WriteLine("Part {0:d3} {1:X8} {2:X8} {3:X8}", i, binFilePos, imgFilePos, partSize); binFilePos += partSize; i++; } return 0; } PrintUsage(); return -1; }