public static Result SetGlobalAccessLogMode(this FileSystemClient fs, GlobalAccessLogMode mode) { using ReferenceCountedDisposable <IFileSystemProxy> fsProxy = fs.Impl.GetFileSystemProxyServiceObject(); Result rc = fsProxy.Target.SetGlobalAccessLogMode(mode); fs.Impl.AbortIfNeeded(rc); return(rc); }
internal static bool IsEnabledFileSystemAccessorAccessLog(this FileSystemClient fs, string mountName) { if (fs.MountTable.Find(mountName, out FileSystemAccessor accessor).IsFailure()) { return(true); } return(accessor.IsAccessLogEnabled); }
private static Result ExtendSaveDataIfNeeded(FileSystemClient fs, out long requiredSize, SaveDataSpaceId spaceId, ulong saveDataId, long requiredDataSize, long requiredJournalSize) { // Checks the current save data size and extends it if needed. // If there is not enough space to do the extension, the amount of space // the extension requires will be written to requiredSize. requiredSize = 0; return(Result.Success); }
public void Initialize(FileSystemClient fsClient, HorizonClient horizonClient) { Hos = horizonClient; InitMutex = new object(); AccessLog.Initialize(fsClient); UserMountTable.Initialize(fsClient); FsContextHandler.Initialize(fsClient); PathUtility.Initialize(fsClient); DirectorySaveDataFileSystem.Initialize(fsClient); }
public static Result TryCreateCacheStorage(this FileSystemClient fs, out long requiredSize, SaveDataSpaceId spaceId, Ncm.ApplicationId applicationId, ulong saveDataOwnerId, short index, long dataSize, long journalSize, bool allowExisting) { requiredSize = default; long requiredSizeLocal = 0; var filter = new SaveDataFilter(); filter.SetProgramId(applicationId); filter.SetIndex(index); filter.SetSaveDataType(SaveDataType.Cache); Result rc = fs.FindSaveDataWithFilter(out SaveDataInfo info, spaceId, ref filter); if (rc.IsFailure()) { if (!ResultFs.TargetNotFound.Includes(rc)) { return(rc); } Result CreateCacheFunc() => fs.CreateCacheStorage(applicationId, spaceId, saveDataOwnerId, index, dataSize, journalSize, SaveDataFlags.None); rc = CreateSaveData(fs, CreateCacheFunc, ref requiredSizeLocal, 0x4000, dataSize, journalSize); if (rc.IsFailure()) { return(rc); } requiredSize = requiredSizeLocal; return(Result.Success); } if (!allowExisting) { return(ResultFs.SaveDataPathAlreadyExists.Log()); } rc = ExtendSaveDataIfNeeded(fs, out requiredSizeLocal, spaceId, info.SaveDataId, dataSize, journalSize); if (rc.IsSuccess() || ResultFs.InsufficientFreeSpace.Includes(rc)) { requiredSize = requiredSizeLocal; return(Result.Success); } if (ResultFs.SaveDataIsExtending.Includes(rc)) { return(ResultFs.SaveDataCorrupted.LogConverted(rc)); } return(rc); }
public static void CreateOrOverwriteFile(this FileSystemClient fs, string path, long size, CreateFileOptions options) { path = PathTools.Normalize(path); if (fs.FileExists(path)) { fs.DeleteFile(path); } fs.CreateFile(path, size, CreateFileOptions.None); }
private static void SetLocalAccessLogImpl(FileSystemClient fs, bool enabled) { if (enabled) { fs.Globals.AccessLog.LocalAccessLogTarget |= AccessLogTarget.Application; } else { fs.Globals.AccessLog.LocalAccessLogTarget &= ~AccessLogTarget.Application; } }
public static void SetLocalSystemAccessLogForDebug(this FileSystemClient fs, bool enabled) { if (enabled) { fs.Globals.AccessLog.LocalAccessLogTarget |= AccessLogTarget.All; } else { fs.Globals.AccessLog.LocalAccessLogTarget &= ~AccessLogTarget.All; } }
internal static AbortSpecifier DefaultResultHandler(FileSystemClient fs, Result result) { if (fs.Globals.FsContextHandler.IsAutoAbortEnabled) { return(AbortSpecifier.Default); } else { return(AbortSpecifier.Return); } }
public static Result EnsureApplicationCacheStorage(this FileSystemClient fs, out long requiredSize, out CacheStorageTargetMedia target, Ncm.ApplicationId applicationId, ref ApplicationControlProperty nacp) { if (nacp.CacheStorageSize <= 0) { requiredSize = default; target = default; return(Result.Success); } return(EnsureApplicationCacheStorageImpl(fs, out requiredSize, out target, applicationId, nacp.SaveDataOwnerId.Value, 0, nacp.CacheStorageSize, nacp.CacheStorageJournalSize, true)); }
public static Result CopyDirectory(this FileSystemClient fs, string sourcePath, string destPath, CreateFileOptions options = CreateFileOptions.None, IProgressReport logger = null) { Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath.ToU8Span(), OpenDirectoryMode.All); if (rc.IsFailure()) { return(rc); } try { foreach (DirectoryEntryEx entry in fs.EnumerateEntries(sourcePath, "*", SearchOptions.Default)) { string subSrcPath = PathTools.Normalize(PathTools.Combine(sourcePath, entry.Name)); string subDstPath = PathTools.Normalize(PathTools.Combine(destPath, entry.Name)); if (entry.Type == DirectoryEntryType.Directory) { fs.EnsureDirectoryExists(subDstPath); rc = fs.CopyDirectory(subSrcPath, subDstPath, options, logger); if (rc.IsFailure()) { return(rc); } } if (entry.Type == DirectoryEntryType.File) { logger?.LogMessage(subSrcPath); fs.CreateOrOverwriteFile(subDstPath, entry.Size, options); rc = fs.CopyFile(subSrcPath, subDstPath, logger); if (rc.IsFailure()) { return(rc); } } } } finally { if (sourceHandle.IsValid) { fs.CloseDirectory(sourceHandle); } } return(Result.Success); }
public static IEnumerable <DirectoryEntryEx> EnumerateEntries(this FileSystemClient fs, string path, string searchPattern, SearchOptions searchOptions) { bool ignoreCase = searchOptions.HasFlag(SearchOptions.CaseInsensitive); bool recurse = searchOptions.HasFlag(SearchOptions.RecurseSubdirectories); fs.OpenDirectory(out DirectoryHandle sourceHandle, path.ToU8Span(), OpenDirectoryMode.All).ThrowIfFailure(); try { while (true) { DirectoryEntry dirEntry = default; fs.ReadDirectory(out long entriesRead, SpanHelpers.AsSpan(ref dirEntry), sourceHandle); if (entriesRead == 0) { break; } DirectoryEntryEx entry = FileSystemExtensions.GetDirectoryEntryEx(ref dirEntry, path); if (PathTools.MatchesPattern(searchPattern, entry.Name, ignoreCase)) { yield return(entry); } if (entry.Type != DirectoryEntryType.Directory || !recurse) { continue; } IEnumerable <DirectoryEntryEx> subEntries = fs.EnumerateEntries(PathTools.Combine(path, entry.Name), searchPattern, searchOptions); foreach (DirectoryEntryEx subEntry in subEntries) { yield return(subEntry); } } } finally { if (sourceHandle.IsValid) { fs.CloseDirectory(sourceHandle); } } }
public static Result CreateOrOverwriteFile(this FileSystemClient fs, string path, long size, CreateFileOptions options) { path = PathTools.Normalize(path); var u8Path = path.ToU8Span(); if (fs.FileExists(path)) { Result rc = fs.DeleteFile(u8Path); if (rc.IsFailure()) { return(rc); } } return(fs.CreateFile(u8Path, size, CreateFileOptions.None)); }
public static void EnsureDirectoryExists(this FileSystemClient fs, string path) { path = PathTools.Normalize(path); if (fs.DirectoryExists(path)) { return; } PathTools.GetMountNameLength(path, out int mountNameLength).ThrowIfFailure(); // Find the first subdirectory in the path that doesn't exist int i; for (i = path.Length - 1; i > mountNameLength + 2; i--) { if (path[i] == '/') { string subPath = path.Substring(0, i); if (fs.DirectoryExists(subPath)) { break; } } } // path[i] will be a '/', so skip that character i++; // loop until `path.Length - 1` so CreateDirectory won't be called multiple // times on path if the last character in the path is a '/' for (; i < path.Length - 1; i++) { if (path[i] == '/') { string subPath = path.Substring(0, i); fs.CreateDirectory(subPath.ToU8Span()); } } fs.CreateDirectory(path.ToU8Span()); }
private static Result GetCacheStorageTargetMediaImpl(this FileSystemClient fs, out CacheStorageTargetMedia target, Ncm.ApplicationId applicationId) { target = CacheStorageTargetMedia.None; var filter = new SaveDataFilter(); filter.SetProgramId(applicationId); filter.SetSaveDataType(SaveDataType.Cache); if (fs.IsSdCardAccessible()) { Result rc = fs.FindSaveDataWithFilter(out _, SaveDataSpaceId.SdCache, ref filter); if (rc.IsFailure() && !ResultFs.TargetNotFound.Includes(rc)) { return(rc); } if (rc.IsSuccess()) { target = CacheStorageTargetMedia.SdCard; } } // Not on the SD card. Check it it's in NAND if (target == CacheStorageTargetMedia.None) { Result rc = fs.FindSaveDataWithFilter(out _, SaveDataSpaceId.User, ref filter); if (rc.IsFailure() && !ResultFs.TargetNotFound.Includes(rc)) { return(rc); } if (rc.IsSuccess()) { target = CacheStorageTargetMedia.Nand; } } return(Result.Success); }
public static Result CreateApplicationCacheStorage(this FileSystemClient fs, out long requiredSize, out CacheStorageTargetMedia target, Ncm.ApplicationId applicationId, ref ApplicationControlProperty nacp, ushort index, long dataSize, long journalSize) { UnsafeHelpers.SkipParamInit(out requiredSize, out target); if (index > nacp.CacheStorageMaxIndex) { return(ResultFs.CacheStorageIndexTooLarge.Log()); } if (dataSize + journalSize > nacp.CacheStorageMaxSizeAndMaxJournalSize) { return(ResultFs.CacheStorageSizeTooLarge.Log()); } Result rc = fs.EnsureApplicationCacheStorage(out requiredSize, out target, applicationId, nacp.SaveDataOwnerId.Value, index, dataSize, journalSize, false); fs.Impl.AbortIfNeeded(rc); return(rc); }
public static Result CreateOrOverwriteFile(this FileSystemClient fs, string path, long size) { return(fs.CreateOrOverwriteFile(path, size, CreateFileOptions.None)); }
public static Result GetCacheStorageTargetMedia(this FileSystemClient fs, out CacheStorageTargetMedia target, Ncm.ApplicationId applicationId) { return(GetCacheStorageTargetMediaImpl(fs, out target, applicationId)); }
public static Result EnsureApplicationBcatDeliveryCacheStorage(this FileSystemClient fs, out long requiredSize, Ncm.ApplicationId applicationId, ref ApplicationControlProperty nacp) { return(EnsureApplicationBcatDeliveryCacheStorageImpl(fs, out requiredSize, applicationId, ref nacp)); }
public static Result EnsureApplicationCacheStorage(this FileSystemClient fs, out long requiredSize, Ncm.ApplicationId applicationId, ref ApplicationControlProperty nacp) { return(EnsureApplicationCacheStorageImpl(fs, out requiredSize, out _, applicationId, nacp.SaveDataOwnerId.Value, 0, nacp.CacheStorageSize, nacp.CacheStorageJournalSize, true)); }
internal FileSystemClientImpl(FileSystemClient parentClient) => Fs = parentClient;
public static IEnumerable <DirectoryEntryEx> EnumerateEntries(this FileSystemClient fs, string path) { return(fs.EnumerateEntries(path, "*")); }
private static Result EnsureApplicationCacheStorageImpl(this FileSystemClient fs, out long requiredSize, out CacheStorageTargetMedia target, Ncm.ApplicationId applicationId, ulong saveDataOwnerId, short index, long dataSize, long journalSize, bool allowExisting) { requiredSize = default; target = CacheStorageTargetMedia.SdCard; Result rc = fs.GetCacheStorageTargetMediaImpl(out CacheStorageTargetMedia targetMedia, applicationId); if (rc.IsFailure()) { return(rc); } long requiredSizeLocal = 0; if (targetMedia == CacheStorageTargetMedia.Nand) { rc = TryCreateCacheStorage(fs, out requiredSizeLocal, SaveDataSpaceId.User, applicationId, saveDataOwnerId, index, dataSize, journalSize, allowExisting); if (rc.IsFailure()) { return(rc); } } else if (targetMedia == CacheStorageTargetMedia.SdCard) { rc = TryCreateCacheStorage(fs, out requiredSizeLocal, SaveDataSpaceId.SdCache, applicationId, saveDataOwnerId, index, dataSize, journalSize, allowExisting); if (rc.IsFailure()) { return(rc); } } // Savedata doesn't exist. Try to create a new one. else { // Try to create the savedata on the SD card first if (fs.IsSdCardAccessible()) { target = CacheStorageTargetMedia.SdCard; Result CreateFuncSdCard() => fs.CreateCacheStorage(applicationId, SaveDataSpaceId.SdCache, saveDataOwnerId, index, dataSize, journalSize, SaveDataFlags.None); rc = CreateSaveData(fs, CreateFuncSdCard, ref requiredSizeLocal, 0x4000, dataSize, journalSize); if (rc.IsFailure()) { return(rc); } if (requiredSizeLocal == 0) { requiredSize = 0; return(Result.Success); } } // If the save can't be created on the SD card, try creating it on the User BIS partition requiredSizeLocal = 0; target = CacheStorageTargetMedia.Nand; Result CreateFuncNand() => fs.CreateCacheStorage(applicationId, SaveDataSpaceId.User, saveDataOwnerId, index, dataSize, journalSize, SaveDataFlags.None); rc = CreateSaveData(fs, CreateFuncNand, ref requiredSizeLocal, 0x4000, dataSize, journalSize); if (rc.IsFailure()) { return(rc); } if (requiredSizeLocal != 0) { target = CacheStorageTargetMedia.None; requiredSize = requiredSizeLocal; return(ResultFs.InsufficientFreeSpace.Log()); } } requiredSize = 0; return(Result.Success); }
public static void SetResultHandledByApplication(this FileSystemClient fs, bool isHandledByApplication) { fs.Globals.ResultHandlingUtility.IsResultHandledByApplication = isHandledByApplication; }
public static Result EnsureApplicationSaveData(FileSystemClient fs, out long requiredSize, Ncm.ApplicationId applicationId, ref ApplicationControlProperty nacp, ref Uid uid) { requiredSize = default; long requiredSizeSum = 0; // Create local variable for use in closures ProgramId saveDataOwnerId = nacp.SaveDataOwnerId; // Ensure the user account save exists if (uid != Uid.Zero && nacp.UserAccountSaveDataSize > 0) { // More local variables for use in closures Uid uidLocal = uid; long accountSaveDataSize = nacp.UserAccountSaveDataSize; long accountSaveJournalSize = nacp.UserAccountSaveDataJournalSize; Result CreateAccountSaveFunc() { UserId userId = ConvertAccountUidToFsUserId(uidLocal); return(fs.CreateSaveData(applicationId, userId, saveDataOwnerId.Value, accountSaveDataSize, accountSaveJournalSize, SaveDataFlags.None)); } var filter = new SaveDataFilter(); filter.SetProgramId(applicationId); filter.SetSaveDataType(SaveDataType.Account); filter.SetUserId(new UserId(uid.Id.High, uid.Id.Low)); // The 0x4c000 includes the save meta and other stuff Result rc = EnsureAndExtendSaveData(fs, CreateAccountSaveFunc, ref requiredSizeSum, ref filter, 0x4c000, accountSaveDataSize, accountSaveJournalSize); if (rc.IsFailure()) { return(rc); } } // Ensure the device save exists if (nacp.DeviceSaveDataSize > 0) { long deviceSaveDataSize = nacp.DeviceSaveDataSize; long deviceSaveJournalSize = nacp.DeviceSaveDataJournalSize; Result CreateDeviceSaveFunc() => fs.CreateDeviceSaveData(applicationId, saveDataOwnerId.Value, deviceSaveDataSize, deviceSaveJournalSize, 0); var filter = new SaveDataFilter(); filter.SetProgramId(applicationId); filter.SetSaveDataType(SaveDataType.Device); Result rc = EnsureAndExtendSaveData(fs, CreateDeviceSaveFunc, ref requiredSizeSum, ref filter, 0x4000, deviceSaveDataSize, deviceSaveJournalSize); if (rc.IsFailure()) { return(rc); } } Result bcatRc = EnsureApplicationBcatDeliveryCacheStorageImpl(fs, out long requiredSizeBcat, applicationId, ref nacp); if (bcatRc.IsFailure()) { if (!ResultFs.InsufficientFreeSpace.Includes(bcatRc)) { return(bcatRc); } requiredSizeSum += requiredSizeBcat; } if (nacp.TemporaryStorageSize > 0) { if (requiredSizeSum > 0) { // If there was already insufficient space to create the previous saves, check if the temp // save already exists instead of trying to create a new one. var filter = new SaveDataFilter(); filter.SetProgramId(applicationId); filter.SetSaveDataType(SaveDataType.Temporary); Result rc = fs.FindSaveDataWithFilter(out _, SaveDataSpaceId.Temporary, ref filter); if (rc.IsFailure()) { if (!ResultFs.TargetNotFound.Includes(rc)) { return(rc); } Result queryRc = fs.QuerySaveDataTotalSize(out long tempSaveTotalSize, nacp.TemporaryStorageSize, 0); if (queryRc.IsFailure()) { return(queryRc); } requiredSizeSum += Utilities.AlignUp(tempSaveTotalSize, 0x4000) + 0x4000; } } else { Result createRc = fs.CreateTemporaryStorage(applicationId, nacp.SaveDataOwnerId.Value, nacp.TemporaryStorageSize, 0); if (createRc.IsFailure()) { if (ResultFs.InsufficientFreeSpace.Includes(createRc)) { Result queryRc = fs.QuerySaveDataTotalSize(out long tempSaveTotalSize, nacp.TemporaryStorageSize, 0); if (queryRc.IsFailure()) { return(queryRc); } requiredSizeSum += Utilities.AlignUp(tempSaveTotalSize, 0x4000) + 0x4000; } else if (ResultFs.PathAlreadyExists.Includes(createRc)) { requiredSizeSum += 0; } else { return(createRc); } } } } requiredSize = requiredSizeSum; return(requiredSize == 0 ? Result.Success : ResultFs.InsufficientFreeSpace.Log()); }
private static Result EnsureApplicationBcatDeliveryCacheStorageImpl(FileSystemClient fs, out long requiredSize, TitleId applicationId, ref ApplicationControlProperty nacp) { const long bcatDeliveryCacheJournalSize = 0x200000; requiredSize = default; if (nacp.BcatDeliveryCacheStorageSize <= 0) { requiredSize = 0; return(Result.Success); } var filter = new SaveDataFilter(); filter.SetTitleId(applicationId); filter.SetSaveDataType(SaveDataType.BcatDeliveryCacheStorage); Result rc = fs.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter); if (rc.IsSuccess()) { rc = ExtendSaveDataIfNeeded(fs, out long requiredSizeBcat, SaveDataSpaceId.User, saveDataInfo.SaveDataId, nacp.DeviceSaveDataSize, bcatDeliveryCacheJournalSize); if (rc.IsFailure()) { if (!ResultRangeFs.InsufficientFreeSpace.Contains(rc)) { return(rc); } requiredSize = requiredSizeBcat; } } else if (rc != ResultFs.TargetNotFound) { return(rc); } else { Result createRc = fs.CreateBcatSaveData(applicationId, nacp.BcatDeliveryCacheStorageSize); if (createRc.IsFailure()) { if (ResultRangeFs.InsufficientFreeSpace.Contains(createRc)) { // todo: Call QuerySaveDataTotalSize and assign the value to requiredSize requiredSize = 0; } else if (createRc == ResultFs.PathAlreadyExists) { requiredSize = 0; } else { return(createRc); } } } return(requiredSize > 0 ? ResultFs.InsufficientFreeSpace.Log() : Result.Success); }
public static Result EnsureApplicationSaveData(FileSystemClient fs, out long requiredSize, TitleId applicationId, ref ApplicationControlProperty nacp, ref Uid uid) { requiredSize = default; long requiredSizeSum = 0; if (uid != Uid.Zero && nacp.UserAccountSaveDataSize > 0) { var filter = new SaveDataFilter(); filter.SetTitleId(applicationId); filter.SetSaveDataType(SaveDataType.SaveData); filter.SetUserId(new UserId(uid.Id.High, uid.Id.Low)); Result rc = fs.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter); if (rc.IsSuccess()) { rc = ExtendSaveDataIfNeeded(fs, out long requiredSizeUser, SaveDataSpaceId.User, saveDataInfo.SaveDataId, nacp.UserAccountSaveDataSize, nacp.UserAccountSaveDataJournalSize); if (rc.IsFailure()) { if (!ResultRangeFs.InsufficientFreeSpace.Contains(rc)) { return(rc); } requiredSizeSum = requiredSizeUser; } } else if (rc != ResultFs.TargetNotFound) { return(rc); } else { UserId userId = ConvertAccountUidToFsUserId(uid); Result createRc = fs.CreateSaveData(applicationId, userId, nacp.SaveDataOwnerId, nacp.UserAccountSaveDataSize, nacp.UserAccountSaveDataJournalSize, 0); if (createRc.IsFailure()) { if (ResultRangeFs.InsufficientFreeSpace.Contains(createRc)) { // todo: Call QuerySaveDataTotalSize and assign the value to requiredSizeSum requiredSizeSum = 0; } else if (createRc == ResultFs.PathAlreadyExists) { requiredSizeSum = 0; } else { return(createRc); } } } } if (nacp.DeviceSaveDataSize > 0) { var filter = new SaveDataFilter(); filter.SetTitleId(applicationId); filter.SetSaveDataType(SaveDataType.DeviceSaveData); Result rc = fs.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter); if (rc.IsSuccess()) { rc = ExtendSaveDataIfNeeded(fs, out long requiredSizeDevice, SaveDataSpaceId.User, saveDataInfo.SaveDataId, nacp.DeviceSaveDataSize, nacp.DeviceSaveDataJournalSize); if (rc.IsFailure()) { if (!ResultRangeFs.InsufficientFreeSpace.Contains(rc)) { return(rc); } requiredSizeSum += requiredSizeDevice; } } else if (rc != ResultFs.TargetNotFound) { return(rc); } else { Result createRc = fs.CreateDeviceSaveData(applicationId, nacp.SaveDataOwnerId, nacp.DeviceSaveDataSize, nacp.DeviceSaveDataJournalSize, 0); if (createRc.IsFailure()) { if (ResultRangeFs.InsufficientFreeSpace.Contains(createRc)) { // todo: Call QuerySaveDataTotalSize and add the value to requiredSizeSum requiredSizeSum += 0; } else if (createRc == ResultFs.PathAlreadyExists) { requiredSizeSum += 0; } else { return(createRc); } } } } Result bcatRc = EnsureApplicationBcatDeliveryCacheStorageImpl(fs, out long requiredSizeBcat, applicationId, ref nacp); if (bcatRc.IsFailure()) { if (!ResultRangeFs.InsufficientFreeSpace.Contains(bcatRc)) { return(bcatRc); } requiredSizeSum += requiredSizeBcat; } // Don't actually do this yet because the temp save indexer hasn't been implemented // todo: Flip the operator when it is if (nacp.TemporaryStorageSize < 0) { if (requiredSizeSum > 0) { var filter = new SaveDataFilter(); filter.SetTitleId(applicationId); filter.SetSaveDataType(SaveDataType.TemporaryStorage); Result rc = fs.FindSaveDataWithFilter(out _, SaveDataSpaceId.User, ref filter); if (rc.IsFailure()) { if (rc != ResultFs.TargetNotFound) { return(rc); } // todo: Call QuerySaveDataTotalSize and add the value to requiredSizeSum requiredSizeSum += 0; } } else { Result createRc = fs.CreateTemporaryStorage(applicationId, nacp.SaveDataOwnerId, nacp.TemporaryStorageSize, 0); if (createRc.IsFailure()) { if (ResultRangeFs.InsufficientFreeSpace.Contains(createRc)) { // todo: Call QuerySaveDataTotalSize and assign the value to requiredSizeSum requiredSizeSum += 0; } else if (createRc == ResultFs.PathAlreadyExists) { requiredSizeSum += 0; } else { return(createRc); } } } } requiredSize = requiredSizeSum; return(requiredSize == 0 ? Result.Success : ResultFs.InsufficientFreeSpace.Log()); }
public static Result CopyFile(this FileSystemClient fs, string sourcePath, string destPath, IProgressReport logger = null) { Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath.ToU8Span(), OpenMode.Read); if (rc.IsFailure()) { return(rc); } using (sourceHandle) { rc = fs.OpenFile(out FileHandle destHandle, destPath.ToU8Span(), OpenMode.Write | OpenMode.AllowAppend); if (rc.IsFailure()) { return(rc); } using (destHandle) { const int maxBufferSize = 0x10000; rc = fs.GetFileSize(out long fileSize, sourceHandle); if (rc.IsFailure()) { return(rc); } int bufferSize = (int)Math.Min(maxBufferSize, fileSize); logger?.SetTotal(fileSize); byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize); try { for (long offset = 0; offset < fileSize; offset += bufferSize) { int toRead = (int)Math.Min(fileSize - offset, bufferSize); Span <byte> buf = buffer.AsSpan(0, toRead); rc = fs.ReadFile(out long _, sourceHandle, offset, buf); if (rc.IsFailure()) { return(rc); } rc = fs.WriteFile(destHandle, offset, buf); if (rc.IsFailure()) { return(rc); } logger?.ReportAdd(toRead); } } finally { ArrayPool <byte> .Shared.Return(buffer); logger?.SetTotal(0); } rc = fs.FlushFile(destHandle); if (rc.IsFailure()) { return(rc); } } } return(Result.Success); }
public static IEnumerable <DirectoryEntryEx> EnumerateEntries(this FileSystemClient fs, string path, string searchPattern) { return(fs.EnumerateEntries(path, searchPattern, SearchOptions.RecurseSubdirectories)); }
public static bool FileExists(this FileSystemClient fs, string path) { Result rc = fs.GetEntryType(out DirectoryEntryType type, path.ToU8Span()); return(rc.IsSuccess() && type == DirectoryEntryType.File); }