public AllocationTableStream(Stream data, AllocationTable table, int blockSize, int initialBlock, long length)
 {
     Data          = data;
     BlockSize     = blockSize;
     Length        = length;
     Iterator      = new AllocationTableIterator(table, initialBlock);
     Data.Position = Iterator.PhysicalBlock * BlockSize;
 }
Exemple #2
0
 public AllocationTableIterator(AllocationTable table, int initialBlock)
 {
     Fat = table;
     if (!BeginIteration(initialBlock))
     {
         throw new ArgumentException($"Attempted to start FAT iteration from an invalid block. ({initialBlock}");
     }
 }
Exemple #3
0
        public Savefile(Keyset keyset, Stream file, bool enableIntegrityChecks)
        {
            SavefileSource = new SharedStreamSource(file);

            using (var reader = new BinaryReader(SavefileSource.CreateStream(), Encoding.Default, true))
            {
                Header = new Header(keyset, reader);
                FsLayout layout = Header.Layout;

                FileRemap = new RemapStream(
                    SavefileSource.CreateStream(layout.FileMapDataOffset, layout.FileMapDataSize),
                    Header.FileMapEntries, Header.FileRemap.MapSegmentCount);

                FileRemapSource = new SharedStreamSource(FileRemap);

                var duplexLayers = new DuplexFsLayerInfo[3];

                duplexLayers[0] = new DuplexFsLayerInfo
                {
                    DataA = new MemoryStream(Header.DuplexMasterA),
                    DataB = new MemoryStream(Header.DuplexMasterB),
                    Info  = Header.Duplex.Layers[0]
                };

                duplexLayers[1] = new DuplexFsLayerInfo
                {
                    DataA = FileRemapSource.CreateStream(layout.DuplexL1OffsetA, layout.DuplexL1Size),
                    DataB = FileRemapSource.CreateStream(layout.DuplexL1OffsetB, layout.DuplexL1Size),
                    Info  = Header.Duplex.Layers[1]
                };

                duplexLayers[2] = new DuplexFsLayerInfo
                {
                    DataA = FileRemapSource.CreateStream(layout.DuplexDataOffsetA, layout.DuplexDataSize),
                    DataB = FileRemapSource.CreateStream(layout.DuplexDataOffsetB, layout.DuplexDataSize),
                    Info  = Header.Duplex.Layers[2]
                };

                DuplexL1A   = FileRemapSource.CreateStream(layout.DuplexL1OffsetA, layout.DuplexL1Size);
                DuplexL1B   = FileRemapSource.CreateStream(layout.DuplexL1OffsetB, layout.DuplexL1Size);
                DuplexDataA = FileRemapSource.CreateStream(layout.DuplexDataOffsetA, layout.DuplexDataSize);
                DuplexDataB = FileRemapSource.CreateStream(layout.DuplexDataOffsetB, layout.DuplexDataSize);
                JournalData = FileRemapSource.CreateStream(layout.JournalDataOffset, layout.JournalDataSizeB + layout.SizeReservedArea);

                DuplexData      = new LayeredDuplexFs(duplexLayers, Header.Layout.DuplexIndex == 1);
                MetaRemap       = new RemapStream(DuplexData, Header.MetaMapEntries, Header.MetaRemap.MapSegmentCount);
                MetaRemapSource = new SharedStreamSource(MetaRemap);

                JournalTable = MetaRemapSource.CreateStream(layout.JournalTableOffset, layout.JournalTableSize);
                JournalBitmapUpdatedPhysical = MetaRemapSource.CreateStream(layout.JournalBitmapUpdatedPhysicalOffset, layout.JournalBitmapUpdatedPhysicalSize);
                JournalBitmapUpdatedVirtual  = MetaRemapSource.CreateStream(layout.JournalBitmapUpdatedVirtualOffset, layout.JournalBitmapUpdatedVirtualSize);
                JournalBitmapUnassigned      = MetaRemapSource.CreateStream(layout.JournalBitmapUnassignedOffset, layout.JournalBitmapUnassignedSize);
                JournalLayer1Hash            = MetaRemapSource.CreateStream(layout.IvfcL1Offset, layout.IvfcL1Size);
                JournalLayer2Hash            = MetaRemapSource.CreateStream(layout.IvfcL2Offset, layout.IvfcL2Size);
                JournalLayer3Hash            = MetaRemapSource.CreateStream(layout.IvfcL3Offset, layout.IvfcL3Size);
                JournalFat      = MetaRemapSource.CreateStream(layout.FatOffset, layout.FatSize);
                AllocationTable = new AllocationTable(JournalFat);

                MappingEntry[] journalMap = JournalStream.ReadMappingEntries(JournalTable, Header.Journal.MainDataBlockCount);

                SharedStream journalData = FileRemapSource.CreateStream(layout.JournalDataOffset,
                                                                        layout.JournalDataSizeB + layout.SizeReservedArea);
                JournalStream       = new JournalStream(journalData, journalMap, (int)Header.Journal.BlockSize);
                JournalStreamSource = new SharedStreamSource(JournalStream);

                IvfcStream       = InitIvfcStream(enableIntegrityChecks);
                IvfcStreamSource = new SharedStreamSource(IvfcStream);

                ReadFileInfo();
                var dictionary = new Dictionary <string, FileEntry>();
                foreach (FileEntry entry in Files)
                {
                    dictionary[entry.FullPath] = entry;
                }

                FileDict = dictionary;
            }
        }