Skip to content

Commit 76ba871

Browse files
committed
Simplify and optimize NativePathHelpers
1 parent 612d403 commit 76ba871

20 files changed

Lines changed: 503 additions & 531 deletions

File tree

src/Core/SecureFolderFS.Core.Dokany/Callbacks/BaseDokanyCallbacks.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,13 @@ namespace SecureFolderFS.Core.Dokany.Callbacks
1818
{
1919
internal abstract class BaseDokanyCallbacks : IDokanOperationsUnsafe, IDisposable
2020
{
21+
protected readonly FileSystemSpecifics specifics;
2122
protected readonly BaseHandlesManager handlesManager;
2223
protected readonly VolumeModel volumeModel;
2324

24-
public FileSystemSpecifics Specifics { get; }
25-
2625
protected BaseDokanyCallbacks(FileSystemSpecifics specifics, BaseHandlesManager handlesManager, VolumeModel volumeModel)
2726
{
28-
Specifics = specifics;
27+
this.specifics = specifics;
2928
this.handlesManager = handlesManager;
3029
this.volumeModel = volumeModel;
3130
}
@@ -83,7 +82,7 @@ public virtual NtStatus FindFiles(string fileName, out IList<FileInformation> fi
8382
/// <inheritdoc/>
8483
public virtual NtStatus SetEndOfFile(string fileName, long length, IDokanFileInfo info)
8584
{
86-
if (Specifics.Options.IsReadOnly)
85+
if (specifics.Options.IsReadOnly)
8786
return Trace(DokanResult.AccessDenied, fileName, info);
8887

8988
if (handlesManager.GetHandle<FileHandle>(GetContextValue(info)) is not { } fileHandle)
@@ -207,7 +206,7 @@ public virtual unsafe NtStatus ReadFile(string fileName, IntPtr buffer, uint buf
207206
[MethodImpl(MethodImplOptions.Synchronized)]
208207
public virtual unsafe NtStatus WriteFile(string fileName, IntPtr buffer, uint bufferLength, out int bytesWritten, long offset, IDokanFileInfo info)
209208
{
210-
if (Specifics.Options.IsReadOnly)
209+
if (specifics.Options.IsReadOnly)
211210
{
212211
bytesWritten = 0;
213212
return Trace(DokanResult.AccessDenied, fileName, info);
@@ -349,7 +348,7 @@ protected void CloseHandle(IDokanFileInfo info)
349348
/// <inheritdoc/>
350349
public virtual void Dispose()
351350
{
352-
Specifics.Dispose();
351+
specifics.Dispose();
353352
handlesManager.Dispose();
354353
}
355354

src/Core/SecureFolderFS.Core.Dokany/Callbacks/OnDeviceDokany.cs

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public override NtStatus CreateFile(string fileName, FileAccess access, FileShar
7575

7676
case FileMode.CreateNew:
7777
{
78-
if (Specifics.Options.IsReadOnly)
78+
if (specifics.Options.IsReadOnly)
7979
throw FileSystemExceptions.FileSystemReadOnly;
8080

8181
if (Directory.Exists(ciphertextPath))
@@ -102,7 +102,7 @@ public override NtStatus CreateFile(string fileName, FileAccess access, FileShar
102102
directoryIdStream.Write(directoryId);
103103

104104
// Set DirectoryID to known IDs
105-
Specifics.DirectoryIdCache.CacheSet(directoryIdPath, new(directoryId));
105+
specifics.DirectoryIdCache.CacheSet(directoryIdPath, new(directoryId));
106106
break;
107107
}
108108
}
@@ -169,7 +169,7 @@ public override NtStatus CreateFile(string fileName, FileAccess access, FileShar
169169

170170
try
171171
{
172-
if (Specifics.Options.IsReadOnly && mode.IsWriteFlag())
172+
if (specifics.Options.IsReadOnly && mode.IsWriteFlag())
173173
throw FileSystemExceptions.FileSystemReadOnly;
174174

175175
var openAccess = readAccess ? System.IO.FileAccess.Read : System.IO.FileAccess.ReadWrite;
@@ -234,7 +234,7 @@ public override void Cleanup(string fileName, IDokanFileInfo info)
234234
InvalidateContext(info);
235235

236236
// Make sure we delete redirected items from DeleteDirectory() and DeleteFile() here.
237-
if (info.DeletePending && !Specifics.Options.IsReadOnly)
237+
if (info.DeletePending && !specifics.Options.IsReadOnly)
238238
{
239239
var ciphertextPath = GetCiphertextPath(fileName);
240240
if (ciphertextPath is null)
@@ -245,12 +245,12 @@ public override void Cleanup(string fileName, IDokanFileInfo info)
245245
if (info.IsDirectory)
246246
{
247247
var directoryIdPath = Path.Combine(ciphertextPath, FileSystem.Constants.Names.DIRECTORY_ID_FILENAME);
248-
Specifics.DirectoryIdCache.CacheRemove(directoryIdPath);
249-
NativeRecycleBinHelpers.DeleteOrRecycle(ciphertextPath, Specifics, StorableType.Folder);
248+
specifics.DirectoryIdCache.CacheRemove(directoryIdPath);
249+
NativeRecycleBinHelpers.DeleteOrRecycle(ciphertextPath, specifics, StorableType.Folder);
250250
}
251251
else
252252
{
253-
NativeRecycleBinHelpers.DeleteOrRecycle(ciphertextPath, Specifics, StorableType.File);
253+
NativeRecycleBinHelpers.DeleteOrRecycle(ciphertextPath, specifics, StorableType.File);
254254
}
255255
}
256256
catch (UnauthorizedAccessException)
@@ -283,7 +283,7 @@ public override NtStatus GetFileInformation(string fileName, out FileInformation
283283
LastAccessTime = fsInfo.LastAccessTime,
284284
LastWriteTime = fsInfo.LastWriteTime,
285285
Length = fsInfo is FileInfo fileInfo2
286-
? Specifics.Security.ContentCrypt.CalculatePlaintextSize(Math.Max(0L, fileInfo2.Length - Specifics.Security.HeaderCrypt.HeaderCiphertextSize))
286+
? specifics.Security.ContentCrypt.CalculatePlaintextSize(Math.Max(0L, fileInfo2.Length - specifics.Security.HeaderCrypt.HeaderCiphertextSize))
287287
: 0L
288288
};
289289

@@ -322,9 +322,9 @@ public override NtStatus GetDiskFreeSpace(out long freeBytesAvailable, out long
322322
if (_vaultDriveInfo is null && _vaultDriveInfoTries < Constants.Dokan.MAX_DRIVE_INFO_CALLS_UNTIL_GIVE_UP)
323323
{
324324
_vaultDriveInfoTries++;
325-
_vaultDriveInfo ??= DriveInfo.GetDrives().SingleOrDefault(di =>
325+
_vaultDriveInfo ??= DriveInfo.GetDrives().SingleOrDefault(di =>
326326
di.IsReady &&
327-
di.RootDirectory.Name.Equals(Path.GetPathRoot(Specifics.ContentFolder.Id), StringComparison.OrdinalIgnoreCase));
327+
di.RootDirectory.Name.Equals(Path.GetPathRoot(specifics.ContentFolder.Id), StringComparison.OrdinalIgnoreCase));
328328
}
329329

330330
freeBytesAvailable = _vaultDriveInfo?.TotalFreeSpace ?? 0L;
@@ -349,21 +349,18 @@ public override NtStatus FindFilesWithPattern(string fileName, string searchPatt
349349
var directory = new DirectoryInfo(ciphertextPath);
350350
List<FileInformation>? fileList = null;
351351

352-
var directoryId = AbstractPathHelpers.AllocateDirectoryId(Specifics.Security, fileName);
353-
var itemsEnumerable = Specifics.Security.NameCrypt is null ? directory.EnumerateFileSystemInfos(searchPattern) : directory.EnumerateFileSystemInfos();
354-
352+
var directoryId = AbstractPathHelpers.AllocateDirectoryId(specifics.Security, fileName);
353+
var itemsEnumerable = specifics.Security.NameCrypt is null ? directory.EnumerateFileSystemInfos(searchPattern) : directory.EnumerateFileSystemInfos();
355354
foreach (var item in itemsEnumerable)
356355
{
357356
if (PathHelpers.IsCoreName(item.Name))
358357
continue;
359358

360-
var plaintextName = NativePathHelpers.GetPlaintextPath(item.FullName, Specifics, directoryId);
361-
plaintextName = plaintextName is not null ? Path.GetFileName(plaintextName) : null;
362-
359+
var plaintextName = NativePathHelpers.DecryptName(item.Name, directory.FullName, specifics, directoryId);
363360
if (string.IsNullOrEmpty(plaintextName))
364361
continue;
365362

366-
if (Specifics.Security.NameCrypt is not null && !UnsafeNativeApis.PathMatchSpec(plaintextName, searchPattern))
363+
if (specifics.Security.NameCrypt is not null && !UnsafeNativeApis.PathMatchSpec(plaintextName, searchPattern))
367364
continue;
368365

369366
fileList ??= new();
@@ -375,7 +372,7 @@ public override NtStatus FindFilesWithPattern(string fileName, string searchPatt
375372
LastAccessTime = item.LastAccessTime,
376373
LastWriteTime = item.LastWriteTime,
377374
Length = item is FileInfo fileInfo
378-
? Specifics.Security.ContentCrypt.CalculatePlaintextSize(Math.Max(0L, fileInfo.Length - Specifics.Security.HeaderCrypt.HeaderCiphertextSize))
375+
? specifics.Security.ContentCrypt.CalculatePlaintextSize(Math.Max(0L, fileInfo.Length - specifics.Security.HeaderCrypt.HeaderCiphertextSize))
379376
: 0L
380377
});
381378
}
@@ -393,7 +390,7 @@ public override NtStatus FindFilesWithPattern(string fileName, string searchPatt
393390
/// <inheritdoc/>
394391
public override NtStatus SetFileAttributes(string fileName, FileAttributes attributes, IDokanFileInfo info)
395392
{
396-
if (Specifics.Options.IsReadOnly)
393+
if (specifics.Options.IsReadOnly)
397394
return Trace(DokanResult.AccessDenied, fileName, info);
398395

399396
try
@@ -489,7 +486,7 @@ public override NtStatus DeleteFile(string fileName, IDokanFileInfo info)
489486
{
490487
// Just check if we can delete the file - the true deletion is done in Cleanup()
491488

492-
if (Specifics.Options.IsReadOnly)
489+
if (specifics.Options.IsReadOnly)
493490
return Trace(DokanResult.AccessDenied, fileName, info);
494491

495492
// Get ciphertext path
@@ -513,7 +510,7 @@ public override NtStatus DeleteFile(string fileName, IDokanFileInfo info)
513510
/// <inheritdoc/>
514511
public override NtStatus DeleteDirectory(string fileName, IDokanFileInfo info)
515512
{
516-
if (Specifics.Options.IsReadOnly)
513+
if (specifics.Options.IsReadOnly)
517514
return Trace(DokanResult.AccessDenied, fileName, info);
518515

519516
var canDelete = true;
@@ -546,7 +543,7 @@ public override NtStatus MoveFile(string oldName, string newName, bool replace,
546543
if (oldCiphertextPath is null || newCiphertextPath is null)
547544
return Trace(NtStatus.ObjectPathInvalid, fileNameCombined, info);
548545

549-
if (Specifics.Options.IsReadOnly)
546+
if (specifics.Options.IsReadOnly)
550547
return Trace(DokanResult.AccessDenied, fileNameCombined, info);
551548

552549
CloseHandle(info);
@@ -720,7 +717,7 @@ public override NtStatus GetFileSecurity(string fileName, out FileSystemSecurity
720717
/// <inheritdoc/>
721718
public override NtStatus SetFileSecurity(string fileName, FileSystemSecurity security, AccessControlSections sections, IDokanFileInfo info)
722719
{
723-
if (Specifics.Options.IsReadOnly)
720+
if (specifics.Options.IsReadOnly)
724721
return Trace(DokanResult.AccessDenied, fileName, info);
725722

726723
try
@@ -825,7 +822,7 @@ public override NtStatus FindStreams(string fileName, out IList<FileInformation>
825822
/// <inheritdoc/>
826823
protected override string? GetCiphertextPath(string plaintextName)
827824
{
828-
return NativePathHelpers.GetCiphertextPath(plaintextName, Specifics);
825+
return NativePathHelpers.GetCiphertextPath(plaintextName, specifics);
829826
}
830827
}
831828
}

src/Core/SecureFolderFS.Core.FUSE/Callbacks/BaseFuseCallbacks.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@ namespace SecureFolderFS.Core.FUSE.Callbacks
77
{
88
internal abstract class BaseFuseCallbacks : FuseFileSystemBase
99
{
10+
protected FileSystemSpecifics specifics;
1011
protected readonly FuseHandlesManager handlesManager;
1112

12-
public FileSystemSpecifics Specifics { get; }
13-
1413
protected BaseFuseCallbacks(FileSystemSpecifics specifics, FuseHandlesManager handlesManager)
1514
{
16-
Specifics = specifics;
15+
this.specifics = specifics;
1716
this.handlesManager = handlesManager;
1817
}
1918

src/Core/SecureFolderFS.Core.FUSE/Callbacks/OnDeviceFuse.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using SecureFolderFS.Core.FUSE.UnsafeNative;
66
using System.Runtime.CompilerServices;
77
using System.Text;
8+
using SecureFolderFS.Core.FileSystem.Helpers.Paths.Abstract;
89
using Tmds.Fuse;
910
using Tmds.Linux;
1011
using static SecureFolderFS.Core.FUSE.UnsafeNative.UnsafeNativeApis;
@@ -198,7 +199,7 @@ public override unsafe int GetAttr(ReadOnlySpan<byte> path, ref stat stat, FuseF
198199
return -errno;
199200

200201
if (File.Exists(ciphertextPath))
201-
stat.st_size = Math.Max(0, Specifics.Security.ContentCrypt.CalculatePlaintextSize(stat.st_size - Specifics.Security.HeaderCrypt.HeaderCiphertextSize));
202+
stat.st_size = Math.Max(0, specifics.Security.ContentCrypt.CalculatePlaintextSize(stat.st_size - specifics.Security.HeaderCrypt.HeaderCiphertextSize));
202203

203204
return 0;
204205
}
@@ -277,7 +278,7 @@ public override unsafe int MkDir(ReadOnlySpan<byte> path, mode_t mode)
277278
directoryIdStream.Write(directoryId);
278279

279280
// Set DirectoryID to known IDs
280-
Specifics.DirectoryIdCache.CacheSet(directoryIdPath, new(directoryId));
281+
specifics.DirectoryIdCache.CacheSet(directoryIdPath, new(directoryId));
281282

282283
return 0;
283284
}
@@ -359,14 +360,15 @@ public override int ReadDir(ReadOnlySpan<byte> path, ulong offset, ReadDirFlags
359360
content.AddEntry(".");
360361
content.AddEntry("..");
361362

363+
var directoryId = AbstractPathHelpers.AllocateDirectoryId(specifics.Security);
362364
foreach (var entry in Directory.GetFileSystemEntries(ciphertextPath))
363365
{
364366
if (PathHelpers.IsCoreName(entry))
365367
continue;
366368

367-
var directoryId = new byte[FileSystem.Constants.DIRECTORY_ID_SIZE];
368-
var plaintextPath = NativePathHelpers.GetPlaintextPath(entry, Specifics, directoryId);
369-
content.AddEntry(Path.GetFileName(plaintextPath));
369+
var ciphertextName = Path.GetFileName(entry);
370+
var plaintextName = NativePathHelpers.DecryptName(ciphertextName, ciphertextPath, specifics, directoryId);
371+
content.AddEntry(plaintextName);
370372
}
371373

372374
return 0;
@@ -438,7 +440,7 @@ public override unsafe int RmDir(ReadOnlySpan<byte> path)
438440

439441
// Remove DirectoryID
440442
File.Delete(directoryIdPath);
441-
Specifics.DirectoryIdCache.CacheRemove(directoryIdPath);
443+
specifics.DirectoryIdCache.CacheRemove(directoryIdPath);
442444

443445
fixed (byte *ciphertextPathPtr = Encoding.UTF8.GetBytes(ciphertextPath))
444446
{
@@ -617,7 +619,7 @@ public override int Write(ReadOnlySpan<byte> path, ulong offset, ReadOnlySpan<by
617619
fixed (byte *plaintextNamePtr = plaintextName)
618620
{
619621
var directoryId = new byte[FileSystem.Constants.DIRECTORY_ID_SIZE];
620-
return NativePathHelpers.GetCiphertextPath(Encoding.UTF8.GetString(plaintextNamePtr, plaintextName.Length), Specifics, directoryId);
622+
return NativePathHelpers.GetCiphertextPath(Encoding.UTF8.GetString(plaintextNamePtr, plaintextName.Length), specifics, directoryId);
621623
}
622624
}
623625
}

src/Core/SecureFolderFS.Core.FileSystem/FileNames/CachingFileNameAccess.cs

Lines changed: 0 additions & 103 deletions
This file was deleted.

0 commit comments

Comments
 (0)