Skip to content

Commit

Permalink
GetPositionInBaseStream impl for FAT and NTFS
Browse files Browse the repository at this point in the history
  • Loading branch information
LTRData committed Nov 20, 2024
1 parent 9c103e5 commit 1e35f07
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 67 deletions.
5 changes: 5 additions & 0 deletions Library/DiscUtils.Fat/ClusterReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,17 @@ public ClusterReader(Stream stream, int firstDataSector, int sectorsPerCluster,
_clusterSize = _sectorsPerCluster * _bytesPerSector;
}

public Stream BaseStream => _stream;

public int ClusterSize => _clusterSize;

public int BytesPerSector => _bytesPerSector;

public int SectorsPerCluster => _sectorsPerCluster;

public long GetBaseStreamPositionForCluster(uint cluster)
=> ((uint)((cluster - 2) * _sectorsPerCluster + _firstDataSector)) * _bytesPerSector;

public void ReadCluster(uint cluster, byte[] buffer, int offset)
{
if (offset + ClusterSize > buffer.Length)
Expand Down
18 changes: 18 additions & 0 deletions Library/DiscUtils.Fat/ClusterStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices.ComTypes;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -63,6 +64,23 @@ internal ClusterStream(FatFileSystem fileSystem, FileAccess access, uint firstCl
_clusterBuffer = new byte[_reader.ClusterSize];
}

public override long? GetPositionInBaseStream(Stream baseStream, long virtualPosition)
{
if (ReferenceEquals(baseStream, this))
{
return virtualPosition;
}

if (TryGetClusterByPosition(virtualPosition, out var cluster))
{
var volumePos = _reader.GetBaseStreamPositionForCluster(cluster);

return _reader.BaseStream.GetPositionInBaseStream(baseStream, volumePos);
}

return null;
}

public override bool CanRead => _access is FileAccess.Read or FileAccess.ReadWrite;

public override bool CanSeek => true;
Expand Down
10 changes: 10 additions & 0 deletions Library/DiscUtils.Fat/FatFileStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ public FatFileStream(FatFileSystem fileSystem, Directory dir, long fileId, FileA
_stream.FirstClusterChanged += FirstClusterAllocatedHandler;
}

public override long? GetPositionInBaseStream(Stream baseStream, long virtualPosition)
{
if (ReferenceEquals(baseStream, this))
{
return virtualPosition;
}

return _stream?.GetPositionInBaseStream(baseStream, virtualPosition);
}

public override bool CanRead => _stream.CanRead;

public override bool CanSeek => _stream.CanSeek;
Expand Down
15 changes: 15 additions & 0 deletions Library/DiscUtils.Ntfs/File.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,21 @@ public FileStream(File file, NtfsAttribute attr, FileAccess access)
_wrapped = attr.Open(access);
}

public override long? GetPositionInBaseStream(Stream baseStream, long virtualPosition)
{
if (ReferenceEquals(baseStream, this))
{
return virtualPosition;
}

if (_wrapped.GetPositionInBaseStream(baseStream, virtualPosition) is { } basePos)
{
return basePos;
}

return _attr.OffsetToAbsolutePos(virtualPosition);
}

public override bool CanRead => _wrapped.CanRead;

public override bool CanSeek => _wrapped.CanSeek;
Expand Down
10 changes: 10 additions & 0 deletions Library/DiscUtils.Ntfs/NtfsFileStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ public static SparseStream Open(File file, DirectoryEntry entry, AttributeType a
}
}

public override long? GetPositionInBaseStream(Stream baseStream, long virtualPosition)
{
if (ReferenceEquals(baseStream, this))
{
return virtualPosition;
}

return _baseStream.GetPositionInBaseStream(baseStream, virtualPosition);
}

public override bool CanRead
{
get
Expand Down
6 changes: 3 additions & 3 deletions Library/DiscUtils.Ntfs/NtfsFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1357,7 +1357,7 @@ public void SetReparsePoint(string path, ReparsePoint reparsePoint)
if (stream != null)
{
// If there's an existing reparse point, unhook it.
using Stream contentStream = stream.Value.Open(FileAccess.Read);
using var contentStream = stream.Value.Open(FileAccess.Read);
var rp = contentStream.ReadStruct<ReparsePointRecord>((int)contentStream.Length);
_context.ReparsePoints.Remove(rp.Tag, dirEntry.Reference);
}
Expand Down Expand Up @@ -1422,7 +1422,7 @@ public ReparsePoint GetReparsePoint(string path)
if (stream != null)
{

using Stream contentStream = stream.Value.Open(FileAccess.Read);
using var contentStream = stream.Value.Open(FileAccess.Read);
var rp = contentStream.ReadStruct<ReparsePointRecord>((int)contentStream.Length);
return new ReparsePoint((int)rp.Tag, rp.Content);
}
Expand Down Expand Up @@ -2362,7 +2362,7 @@ private void RemoveReparsePoint(File file)
{
var rp = new ReparsePointRecord();

using (Stream contentStream = stream.Value.Open(FileAccess.Read))
using (var contentStream = stream.Value.Open(FileAccess.Read))
{
rp.ReadFrom(contentStream, (int)contentStream.Length);
}
Expand Down
Loading

0 comments on commit 1e35f07

Please sign in to comment.