Workaround the inability to access FAT attributes in Linux

This commit is contained in:
Alex Barney 2019-07-07 23:45:02 -05:00
parent 6f1596ae5f
commit 74a3929eb9
2 changed files with 54 additions and 2 deletions

View file

@ -1,5 +1,9 @@
using System.Collections.Generic;
#if NETCOREAPP
using System.Runtime.InteropServices;
#endif
namespace LibHac.Fs
{
public class ConcatenationDirectory : IDirectory
@ -23,7 +27,7 @@ namespace LibHac.Fs
{
foreach (DirectoryEntry entry in ParentDirectory.Read())
{
bool isSplit = ConcatenationFileSystem.HasConcatenationFileAttribute(entry.Attributes);
bool isSplit = IsConcatenationFile(entry);
if (!CanReturnEntry(entry, isSplit)) continue;
@ -44,7 +48,7 @@ namespace LibHac.Fs
foreach (DirectoryEntry entry in ParentDirectory.Read())
{
bool isSplit = ConcatenationFileSystem.HasConcatenationFileAttribute(entry.Attributes);
bool isSplit = IsConcatenationFile(entry);
if (CanReturnEntry(entry, isSplit)) count++;
}
@ -57,5 +61,21 @@ namespace LibHac.Fs
return Mode.HasFlag(OpenDirectoryMode.Files) && (entry.Type == DirectoryEntryType.File || isSplit) ||
Mode.HasFlag(OpenDirectoryMode.Directories) && entry.Type == DirectoryEntryType.Directory && !isSplit;
}
private bool IsConcatenationFile(DirectoryEntry entry)
{
#if NETCOREAPP
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return ConcatenationFileSystem.HasConcatenationFileAttribute(entry.Attributes);
}
else
{
return ParentFileSystem.IsConcatenationFile(entry.FullPath);
}
#else
return ConcatenationFileSystem.HasConcatenationFileAttribute(entry.Attributes);
#endif
}
}
}

View file

@ -1,6 +1,10 @@
using System;
using System.Collections.Generic;
#if NETCOREAPP
using System.Runtime.InteropServices;
#endif
namespace LibHac.Fs
{
public class ConcatenationFileSystem : IFileSystem
@ -17,11 +21,39 @@ namespace LibHac.Fs
SubFileSize = subFileSize;
}
// .NET Core on platforms other than Windows doesn't support getting the
// archive flag in FAT file systems. Try to work around that for now for reading,
// but writing still won't work properly on those platforms
internal bool IsConcatenationFile(string path)
{
#if NETCOREAPP
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return HasConcatenationFileAttribute(BaseFileSystem.GetFileAttributes(path));
}
else
{
return IsConcatenationFileHeuristic(path);
}
#else
return HasConcatenationFileAttribute(BaseFileSystem.GetFileAttributes(path));
#endif
}
#if NETCOREAPP
private bool IsConcatenationFileHeuristic(string path)
{
if (BaseFileSystem.GetEntryType(path) != DirectoryEntryType.Directory) return false;
if (BaseFileSystem.GetEntryType(PathTools.Combine(path, "00")) != DirectoryEntryType.File) return false;
if (BaseFileSystem.OpenDirectory(path, OpenDirectoryMode.Directories).GetEntryCount() > 0) return false;
// Should be enough checks to avoid most false positives. Maybe
return true;
}
#endif
internal static bool HasConcatenationFileAttribute(NxFileAttributes attributes)
{
return (attributes & NxFileAttributes.Directory) != 0 && (attributes & NxFileAttributes.Archive) != 0;