/// <summary> /// Builds and saves a PFS image. /// </summary> /// <param name="p"></param> public void BuildPfs(PfsProperties p) { // TODO: Combine the superroot-specific stuff with the rest of the data block writing. // I think this is as simple as adding superroot and flat_path_table to allNodes hdr = new PfsHeader { BlockSize = p.BlockSize }; inodes = new List <PfsDinode32>(); dirents = new List <List <PfsDirent> >(); Console.WriteLine("Setting up root structure..."); SetupRootStructure(); BuildFSTree(root, p.RootDirectory); allDirs = root.GetAllChildrenDirs(); allFiles = root.GetAllChildrenFiles(); allNodes = new List <FSNode>(allDirs); allNodes.AddRange(allFiles); Console.WriteLine("Creating directory inodes ({0})...", allDirs.Count); addDirInodes(); Console.WriteLine("Creating file inodes ({0})...", allFiles.Count); addFileInodes(); Console.WriteLine("Creating flat_path_table..."); fpt = new FlatPathTable(allNodes); Console.WriteLine("Calculating data block layout..."); allNodes.Insert(0, root); CalculateDataBlockLayout(); Console.WriteLine("Writing image file..."); hdr.Ndblock = allFiles.Sum((f) => CeilDiv(f.Size, hdr.BlockSize)); using (var stream = File.Create(p.ImageFilename)) { Console.WriteLine("Writing header..."); hdr.WriteToStream(stream); Console.WriteLine("Writing inodes..."); WriteInodes(stream); Console.WriteLine("Writing superroot dirents"); WriteSuperrootDirents(stream); Console.WriteLine("Writing flat_path_table"); stream.Position = fpt_ino.db[0] * hdr.BlockSize; fpt.WriteToStream(stream); Console.WriteLine("Writing data blocks..."); for (var x = 0; x < allNodes.Count; x++) { var f = allNodes[x]; stream.Position = f.ino.db[0] * hdr.BlockSize; WriteFSNode(stream, f); } } }
static PfsProperties ParseArgs(string[] args) { var p = new PfsProperties() { BlockSize = 0x10000, RootDirectory = null }; for (var i = 0; i < args.Length; i++) { switch (args[i]) { case "-r": p.RootDirectory = args[++i]; break; case "-b": p.BlockSize = uint.Parse(args[++i]); break; case "-o": p.ImageFilename = args[++i]; break; default: Console.WriteLine("Unknown argument " + args[i]); throw new ArgumentException(); } } if (!Directory.Exists(p.RootDirectory)) { throw new ArgumentException(); } return(p); }