Beispiel #1
0
        public void InsertVariableLengthFile(string path, string source)
        {
            uint entryIndex = RomFsNameTable.GetFatEntryIndex(_underlyingStreamReader, _nameTableStartOffset, path);
            var  originalInsertDestinationEntry = RomFsFileAllocationTable.GetEntry(_underlyingStreamReader, _fatStartOffset, entryIndex);

            byte[] sourceData     = File.ReadAllBytes(source);
            var    oldEntryLength = originalInsertDestinationEntry.GetLength();

            if (oldEntryLength == sourceData.Length)
            {
                // Is still the same length so just process as fixed length file.
                _underlyingStreamReader.BaseStream.Position = originalInsertDestinationEntry.Start;
                _underlyingStreamReader.BaseStream.Write(sourceData, 0, oldEntryLength);
                return;
            }

            // Create new entry
            var newInsertDestinationEntry = new Fat32.Entry(originalInsertDestinationEntry.Start, originalInsertDestinationEntry.Start + (uint)sourceData.Length);
            int change = newInsertDestinationEntry.GetLength() - oldEntryLength;

            // Update entry value
            RomFsFileAllocationTable.SetEntry(_underlyingStreamWriter, _fatStartOffset, entryIndex, newInsertDestinationEntry);

            // Update entry values after changed one with change
            var currentEntryId = entryIndex + 1;
            var previousEntry  = newInsertDestinationEntry;
            var currentEntry   = RomFsFileAllocationTable.GetEntry(_underlyingStreamReader, _fatStartOffset, currentEntryId);

            while (!currentEntry.IsDefault)
            {
                uint newStart = (uint)(currentEntry.Start + change);
                uint newEnd   = (uint)(currentEntry.End + change);
                RomFsFileAllocationTable.SetEntry(_underlyingStreamWriter, _fatStartOffset, currentEntryId++, new Fat32.Entry(newStart, newEnd));
                previousEntry = currentEntry;
                currentEntry  = RomFsFileAllocationTable.GetEntry(_underlyingStreamReader, _fatStartOffset, currentEntryId);
            }

            // Shift data

            // last edited entry is the final non-default entry which will store the end of the data
            byte[] buffer = new byte[previousEntry.End - originalInsertDestinationEntry.End];

            // read the data from the original position
            _underlyingStream.Position = originalInsertDestinationEntry.End;
            _underlyingStream.Read(buffer, 0, buffer.Length);

            // write the data into the new position
            _underlyingStream.Position = newInsertDestinationEntry.End;
            _underlyingStream.Write(buffer, 0, buffer.Length);

            // Write file data in newly created space
            _underlyingStream.Position = newInsertDestinationEntry.Start;
            _underlyingStream.Write(sourceData, 0, sourceData.Length);
        }
Beispiel #2
0
        private void ExtractCopyOfDirectoryContentsUsingAllocation(RomFsNameTable.FolderAllocation alloc, string destinationFolder)
        {
            Directory.CreateDirectory(destinationFolder);
            uint count = alloc.FatTopFileId;

            foreach (var item in RomFsNameTable.GetContents(_underlyingStreamReader, _nameTableStartOffset, alloc))
            {
                string itemName = Encoding.UTF8.GetString(item.Name);
                if (item.IsFolder)
                {
                    ExtractCopyOfDirectoryContentsUsingAllocation(
                        RomFsNameTable.GetAllocationData(_underlyingStreamReader, _nameTableStartOffset, item.ContentsIndexIfFolder),
                        Path.Combine(destinationFolder, itemName)
                        );
                }
                else
                {
                    var entry = RomFsFileAllocationTable.GetEntry(_underlyingStreamReader, _fatStartOffset, count);
                    ExtractCopyOfFileFromEntry(entry, Path.Combine(destinationFolder, itemName));
                }
                count++;
            }
        }
Beispiel #3
0
        private Fat32.Entry GetEntryFromPath(string path)
        {
            uint entryIndex = RomFsNameTable.GetFatEntryIndex(_underlyingStreamReader, _nameTableStartOffset, path);

            return(RomFsFileAllocationTable.GetEntry(_underlyingStreamReader, _fatStartOffset, entryIndex));
        }