Exemple #1
0
        private void WriteData(Stream stream)
        {
            Log("Writing data...");
            hdr.WriteToStream(stream);
            WriteInodes(stream);
            WriteSuperrootDirents(stream);

            allNodes.Insert(0, new FSFile(s => fpt.WriteToStream(s), "flat_path_table", fpt.Size)
            {
                ino = fpt_ino
            });
            if (colResolver != null)
            {
                allNodes.Insert(1, new FSFile(s => colResolver.WriteToStream(s), "collision_resolver", colResolver.Size)
                {
                    ino = cr_ino
                });
            }

            for (var x = 0; x < allNodes.Count; x++)
            {
                var f = allNodes[x];
                stream.Position = f.ino.StartBlock * hdr.BlockSize;
                WriteFSNode(stream, f);
            }
        }
Exemple #2
0
        /// <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);
                }
            }
        }
Exemple #3
0
        private void WriteData(Stream stream)
        {
            Log("Writing data...");
            hdr.WriteToStream(stream);
            WriteInodes(stream);
            WriteSuperrootDirents(stream);

            var fpt_file = new FSFile(s => fpt.WriteToStream(s), "flat_path_table", fpt.Size);

            fpt_file.ino = fpt_ino;
            allNodes.Insert(0, fpt_file);

            for (var x = 0; x < allNodes.Count; x++)
            {
                var f = allNodes[x];
                stream.Position = f.ino.StartBlock * hdr.BlockSize;
                WriteFSNode(stream, f);
            }
        }
Exemple #4
0
        public void WriteImage(Stream stream)
        {
            Log("Writing header...");
            hdr.WriteToStream(stream);
            Log("Writing inodes...");
            WriteInodes(stream);
            Log("Writing superroot dirents");
            WriteSuperrootDirents(stream);

            var fpt_file = new FSFile(s => fpt.WriteToStream(s), "flat_path_table", fpt.Size);

            fpt_file.ino = fpt_ino;
            allNodes.Insert(0, fpt_file);

            Log("Writing data blocks...");
            for (var x = 0; x < allNodes.Count; x++)
            {
                var f = allNodes[x];
                stream.Position = f.ino.StartBlock * hdr.BlockSize;
                WriteFSNode(stream, f);
            }
            stream.SetLength(hdr.Ndblock * hdr.BlockSize);

            if (hdr.Mode.HasFlag(PfsMode.Signed))
            {
                Log("Signing...");
                var signKey = Crypto.PfsGenSignKey(properties.EKPFS, hdr.Seed);
                foreach (var sig in sig_order)
                {
                    var sig_buffer = new byte[sig.Size];
                    stream.Position = sig.Block * properties.BlockSize;
                    stream.Read(sig_buffer, 0, sig.Size);
                    stream.Position = sig.SigOffset;
                    stream.Write(Crypto.HmacSha256(signKey, sig_buffer), 0, 32);
                    stream.WriteLE((int)sig.Block);
                }
            }

            if (hdr.Mode.HasFlag(PfsMode.Encrypted))
            {
                Log("Encrypting...");
                var encKey   = Crypto.PfsGenEncKey(properties.EKPFS, hdr.Seed);
                var dataKey  = new byte[16];
                var tweakKey = new byte[16];
                Buffer.BlockCopy(encKey, 0, tweakKey, 0, 16);
                Buffer.BlockCopy(encKey, 16, dataKey, 0, 16);
                stream.Position = hdr.BlockSize;
                var       transformer  = new XtsBlockTransform(dataKey, tweakKey);
                const int sectorSize   = 0x1000;
                long      xtsSector    = 16;
                long      totalSectors = (stream.Length + 0xFFF) / sectorSize;
                byte[]    sectorBuffer = new byte[sectorSize];
                while (xtsSector < totalSectors)
                {
                    if (xtsSector / 0x10 == emptyBlock)
                    {
                        xtsSector += 16;
                    }
                    stream.Position = xtsSector * sectorSize;
                    stream.Read(sectorBuffer, 0, sectorSize);
                    transformer.EncryptSector(sectorBuffer, (ulong)xtsSector);
                    stream.Position = xtsSector * sectorSize;
                    stream.Write(sectorBuffer, 0, sectorSize);
                    xtsSector += 1;
                }
            }
        }