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); }
private void ExtractCopyOfFileFromEntry(Fat32.Entry entry, string destinationFile) { _underlyingStreamReader.BaseStream.Position = entry.Start; byte[] bytes = _underlyingStreamReader.ReadBytes(entry.GetLength()); File.WriteAllBytes(destinationFile, bytes); }