diff --git a/src/LibHac/Fs/ConcatenationDirectory.cs b/src/LibHac/Fs/ConcatenationDirectory.cs index 140f165f..4f53f5b0 100644 --- a/src/LibHac/Fs/ConcatenationDirectory.cs +++ b/src/LibHac/Fs/ConcatenationDirectory.cs @@ -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 + } } } diff --git a/src/LibHac/Fs/ConcatenationFileSystem.cs b/src/LibHac/Fs/ConcatenationFileSystem.cs index 409485d9..0cc8dd90 100644 --- a/src/LibHac/Fs/ConcatenationFileSystem.cs +++ b/src/LibHac/Fs/ConcatenationFileSystem.cs @@ -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;