/// <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.proj, p.projDir); 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)); { var stream = p.output; 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); } } }
void Setup() { // 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 // This doesn't seem to really matter when verifying a PKG so use all zeroes for now var seed = new byte[16]; // Insert header digest to be calculated with the rest of the digests sig_order.Push(new BlockSigInfo(0, 0x380, 0x5A0)); hdr = new PfsHeader { BlockSize = properties.BlockSize, ReadOnly = 1, Mode = (properties.Sign ? PfsMode.Signed : 0) | (properties.Encrypt ? PfsMode.Encrypted : 0) | PfsMode.UnknownFlagAlwaysSet, UnknownIndex = 1, Seed = properties.Encrypt || properties.Sign ? seed : null }; inodes = new List <inode>(); Log("Setting up root structure..."); SetupRootStructure(); allDirs = root.GetAllChildrenDirs(); allFiles = root.GetAllChildrenFiles(); allNodes = new List <FSNode>(allDirs); allNodes.AddRange(allFiles); Log(string.Format("Creating directory inodes ({0})...", allDirs.Count)); addDirInodes(); Log(string.Format("Creating file inodes ({0})...", allFiles.Count)); addFileInodes(); Log("Creating flat_path_table..."); fpt = new FlatPathTable(allNodes); Log("Calculating data block layout..."); allNodes.Insert(0, root); CalculateDataBlockLayout(); }
/// <summary> /// This gets called by the constructor. /// </summary> void Setup() { // 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 // This doesn't seem to really matter when verifying a PKG so use all zeroes for now var seed = new byte[16]; // Insert header digest to be calculated with the rest of the digests final_sigs.Push(new BlockSigInfo(0, 0x380, 0x5A0)); hdr = new PfsHeader { BlockSize = properties.BlockSize, ReadOnly = 1, Mode = (properties.Sign ? PfsMode.Signed : 0) | (properties.Encrypt ? PfsMode.Encrypted : 0) | PfsMode.UnknownFlagAlwaysSet, UnknownIndex = 1, Seed = properties.Encrypt || properties.Sign ? seed : null }; inodes = new List <inode>(); Log("Setting up filesystem structure..."); SetupRootStructure(); allDirs = root.GetAllChildrenDirs(); allFiles = root.GetAllChildrenFiles().Where(f => f.Parent?.name != "sce_sys" || !PKG.EntryNames.NameToId.ContainsKey(f.name)).ToList(); allNodes = new List <FSNode>(allDirs); allNodes.AddRange(allFiles); Log($"Creating inodes ({allDirs.Count} dirs and {allFiles.Count} files)..."); addDirInodes(); addFileInodes(); fpt = new FlatPathTable(allNodes); Log("Calculating data block layout..."); allNodes.Insert(0, root); CalculateDataBlockLayout(); }
/// <summary> /// This gets called by the constructor. /// </summary> void Setup() { // 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 // Insert header digest to be calculated with the rest of the digests final_sigs.Push(new BlockSigInfo(0, 0x380, 0x5A0)); hdr = new PfsHeader { BlockSize = properties.BlockSize, ReadOnly = 1, Mode = (properties.Sign ? PfsMode.Signed : 0) | (properties.Encrypt ? PfsMode.Encrypted : 0) | PfsMode.UnknownFlagAlwaysSet, UnknownIndex = 1, Seed = properties.Encrypt || properties.Sign ? properties.Seed : null }; inodes = new List <inode>(); Log("Setting up filesystem structure..."); allDirs = properties.root.GetAllChildrenDirs(); allFiles = properties.root.GetAllChildrenFiles().Where(f => f.Parent?.name != "sce_sys" || !PKG.EntryNames.NameToId.ContainsKey(f.name)).ToList(); allNodes = new List <FSNode>(allDirs.OrderBy(d => d.FullPath()).ToList()); allNodes.AddRange(allFiles); SetupRootStructure(FlatPathTable.HasCollision(allNodes)); Log($"Creating inodes ({allDirs.Count} dirs and {allFiles.Count} files)..."); addDirInodes(); addFileInodes(); (fpt, colResolver) = FlatPathTable.Create(allNodes); Log("Calculating data block layout..."); allNodes.Insert(0, properties.root); CalculateDataBlockLayout(); }