Esempio n. 1
0
        /// <summary>
        /// Takes a directory and a root node, and recursively makes a filesystem tree.
        /// </summary>
        /// <param name="proj">GP4 Project</param>
        /// <param name="projDir">Directory of GP4 file</param>
        /// <returns>Root directory of the image</returns>
        public static FSDir BuildFSTree(GP4.Gp4Project proj, string projDir)
        {
            void AddDirs(FSDir parent, List <GP4.Dir> imgDir)
            {
                foreach (var d in imgDir)
                {
                    FSDir dir;
                    parent.Dirs.Add(dir = new FSDir {
                        name = d.TargetName, Parent = parent
                    });
                    AddDirs(dir, d.Children);
                }
            }

            var root = new FSDir();

            AddDirs(root, proj.RootDir);

            foreach (var f in proj.files.Items)
            {
                var lastSlash = f.TargetPath.LastIndexOf('/') + 1;
                var name      = f.TargetPath.Substring(lastSlash);
                var source    = Path.Combine(projDir, f.OrigPath);
                var parent    = lastSlash == 0 ? root : FindDir(f.TargetPath.Substring(0, lastSlash - 1), root);
                parent.Files.Add(new FSFile(source)
                {
                    Parent = parent,
                    name   = name,
                });
            }
            return(root);
        }
Esempio n. 2
0
        static void AddFile(FSDir root, string path, string name, byte[] data)
        {
            var dir = FindDir(path, root);

            dir.Files.Add(new FSFile(s => s.Write(data, 0, data.Length), name, data.Length)
            {
                Parent = dir
            });
        }
Esempio n. 3
0
        /// <summary>
        /// Creates inodes and dirents for superroot, flat_path_table, and uroot.
        /// Also, creates the root node for the FS tree.
        /// </summary>
        void SetupRootStructure()
        {
            inodes.Add(super_root_ino = MakeInode(
                           Mode: InodeMode.dir | InodeMode.rx_only,
                           Blocks: 1,
                           Size: 65536,
                           SizeCompressed: 65536,
                           Nlink: 1,
                           Number: 0,
                           Flags: InodeFlags.@internal | InodeFlags.@readonly
                           ));
            inodes.Add(fpt_ino = MakeInode(
                           Mode: InodeMode.file | InodeMode.rx_only,
                           Blocks: 1,
                           Number: 1,
                           Flags: InodeFlags.@internal | InodeFlags.@readonly
                           ));
            var uroot_ino = MakeInode(
                Mode: InodeMode.dir | InodeMode.rx_only,
                Number: 2,
                Size: 65536,
                SizeCompressed: 65536,
                Blocks: 1,
                Flags: InodeFlags.@readonly,
                Nlink: 3
                );

            super_root_dirents = new List <PfsDirent>
            {
                new PfsDirent {
                    InodeNumber = 1, Name = "flat_path_table", Type = DirentType.File
                },
                new PfsDirent {
                    InodeNumber = 2, Name = "uroot", Type = DirentType.Directory
                }
            };

            root         = properties.root;
            root.name    = "uroot";
            root.ino     = uroot_ino;
            root.Dirents = new List <PfsDirent>
            {
                new PfsDirent {
                    Name = ".", Type = DirentType.Dot, InodeNumber = 2
                },
                new PfsDirent {
                    Name = "..", Type = DirentType.DotDot, InodeNumber = 2
                }
            };
            if (properties.Sign) // HACK: Outer PFS lacks readonly flags
            {
                super_root_ino.Flags &= ~InodeFlags.@readonly;
                fpt_ino.Flags        &= ~InodeFlags.@readonly;
                uroot_ino.Flags      &= ~InodeFlags.@readonly;
            }
        }
Esempio n. 4
0
        static FSDir FindDir(string name, FSDir root)
        {
            FSDir dir         = root;
            var   breadcrumbs = name.Split('/');

            foreach (var crumb in breadcrumbs)
            {
                dir = dir.Dirs.Where(d => d.name == crumb).First();
            }
            return(dir);
        }
Esempio n. 5
0
        /// <summary>
        /// Creates inodes and dirents for superroot, flat_path_table, and uroot.
        /// Also, creates the root node for the FS tree.
        /// </summary>
        void SetupRootStructure()
        {
            inodes.Add(super_root_ino = new PfsDinode32
            {
                Mode           = InodeMode.dir | InodeMode.rx_only,
                Blocks         = 1,
                Size           = 65536,
                SizeCompressed = 65536,
                Nlink          = 1,
                Number         = 0,
                Flags          = InodeFlags.@internal
            });
            inodes.Add(fpt_ino = new PfsDinode32
            {
                Mode   = InodeMode.file | InodeMode.rwx,
                Blocks = 1,
                Number = 1,
                Flags  = InodeFlags.@internal
            });
            var uroot_ino = new PfsDinode32 {
                Mode = InodeMode.dir | InodeMode.rwx, Number = 2, Size = 65536, SizeCompressed = 65536, Blocks = 1
            };

            super_root_dirents = new List <PfsDirent>
            {
                new PfsDirent {
                    InodeNumber = 1, Name = "flat_path_table", Type = 2
                },
                new PfsDirent {
                    InodeNumber = 2, Name = "uroot", Type = 3
                }
            };

            root = new FSDir
            {
                name    = "uroot",
                ino     = uroot_ino,
                Dirents = new List <PfsDirent>
                {
                    new PfsDirent {
                        Name = ".", Type = 4, InodeNumber = 2
                    },
                    new PfsDirent {
                        Name = "..", Type = 5, InodeNumber = 2
                    }
                }
            };
        }
Esempio n. 6
0
        public static PfsProperties MakeInnerPFSProps(GP4.Gp4Project proj, string projDir)
        {
            var root = new FSDir();

            BuildFSTree(root, proj, projDir);
            var timestamp = DateTime.Parse(proj.volume.TimeStamp).ToUniversalTime().Subtract(new DateTime(1970, 1, 1)).TotalSeconds;

            return(new PfsProperties()
            {
                root = root,
                BlockSize = 0x10000,
                Encrypt = false,
                Sign = false,
                FileTime = GetTimeStamp(proj),
            });
        }
Esempio n. 7
0
        /// <summary>
        /// Takes a directory and a root node, and recursively makes a filesystem tree.
        /// </summary>
        /// <param name="root">Root directory of the image</param>
        /// <param name="proj">GP4 Project</param>
        /// <param name="projDir">Directory of GP4 file</param>
        static void BuildFSTree(FSDir root, GP4.Gp4Project proj, string projDir)
        {
            void AddDirs(FSDir parent, List <GP4.Dir> imgDir)
            {
                foreach (var d in imgDir)
                {
                    FSDir dir;
                    parent.Dirs.Add(dir = new FSDir {
                        name = d.TargetName, Parent = parent
                    });
                    AddDirs(dir, d.Children);
                }
            }

            FSDir FindDir(string name)
            {
                FSDir dir         = root;
                var   breadcrumbs = name.Split('/');

                foreach (var crumb in breadcrumbs)
                {
                    dir = dir.Dirs.Where(d => d.name == crumb).First();
                }
                return(dir);
            }

            AddDirs(root, proj.RootDir);

            foreach (var f in proj.files)
            {
                var lastSlash = f.TargetPath.LastIndexOf('/') + 1;
                if (f.TargetPath == "sce_sys/param.sfo")
                {
                    continue;
                }
                var name   = f.TargetPath.Substring(lastSlash);
                var source = Path.Combine(projDir, f.OrigPath);
                var parent = lastSlash == 0 ? root : FindDir(f.TargetPath.Substring(0, lastSlash - 1));
                parent.Files.Add(new FSFile(source)
                {
                    Parent = parent,
                    name   = name,
                });
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Generates a PfsProperties object for the outer PFS image of a PKG with the given properties.
        /// </summary>
        /// <param name="props">PKG properties to convert from</param>
        /// <param name="innerPFS">Inner pfs image to use, presumably from MakeInnerPFSProps</param>
        /// <param name="EKPFS">Encryption key for PFS</param>
        /// <param name="encrypt">Set to false to make a non-encrypted PFS</param>
        /// <returns></returns>
        public static PfsProperties MakeOuterPFSProps(PKG.PkgProperties props, PfsBuilder innerPFS, byte[] EKPFS, bool encrypt = true)
        {
            var root = new FSDir();

            root.Files.Add(new FSFile(innerPFS)
            {
                Parent = root,
            });
            return(new PfsProperties()
            {
                root = root,
                BlockSize = 0x10000,
                Encrypt = encrypt,
                Sign = true,
                EKPFS = EKPFS,
                Seed = new byte[16],
                FileTime = GetTimeStamp(props),
            });
        }
Esempio n. 9
0
        /// <summary>
        /// Generates a PfsProperties object for the outer PFS image of a PKG with the given properties.
        /// </summary>
        /// <param name="props">PKG properties to convert from</param>
        /// <param name="innerPFS">Inner pfs image to use, presumably from MakeInnerPFSProps</param>
        /// <param name="EKPFS">Encryption key for PFS</param>
        /// <param name="encrypt">Set to false to make a non-encrypted PFS</param>
        /// <returns></returns>
        public static PfsProperties MakeOuterPFSProps(PKG.PkgProperties props, PfsBuilder innerPFS, byte[] EKPFS, bool encrypt = true)
        {
            var root = new FSDir();

            root.Files.Add(new FSFile(innerPFS)
            {
                Parent = root,
            });
            return(new PfsProperties()
            {
                root = root,
                BlockSize = 0x10000,
                Encrypt = encrypt,
                Sign = true,
                EKPFS = EKPFS,
                // This doesn't seem to really matter when verifying a PKG so use all zeroes for now
                Seed = new byte[16],
                FileTime = GetTimeStamp(props),
            });
        }