mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-04-22 04:24:48 +00:00
fs: implement user fs wrappers
This commit is contained in:
parent
32f6660b7a
commit
6514fb75a8
14 changed files with 594 additions and 1 deletions
|
@ -25,6 +25,7 @@
|
|||
#include "fs/fs_remote_storage.hpp"
|
||||
#include "fs/fs_file_storage.hpp"
|
||||
#include "fs/fs_query_range.hpp"
|
||||
#include "fs/impl/fs_common_mount_name.hpp"
|
||||
#include "fs/fs_mount.hpp"
|
||||
#include "fs/fs_path_tool.hpp"
|
||||
#include "fs/fs_path_utils.hpp"
|
||||
|
|
|
@ -22,4 +22,12 @@ namespace ams::fs {
|
|||
|
||||
using DirectoryEntry = ::FsDirectoryEntry;
|
||||
|
||||
struct DirectoryHandle {
|
||||
void *handle;
|
||||
};
|
||||
|
||||
Result ReadDirectory(s64 *out_count, DirectoryEntry *out_entries, DirectoryHandle handle, s64 max_entries);
|
||||
Result GetDirectoryEntryCount(s64 *out, DirectoryHandle handle);
|
||||
void CloseDirectory(DirectoryHandle handle);
|
||||
|
||||
}
|
||||
|
|
|
@ -60,4 +60,19 @@ namespace ams::fs {
|
|||
|
||||
static_assert(std::is_pod<WriteOption>::value && sizeof(WriteOption) == sizeof(u32));
|
||||
|
||||
struct FileHandle {
|
||||
void *handle;
|
||||
};
|
||||
|
||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option);
|
||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size);
|
||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option);
|
||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size);
|
||||
Result GetFileSize(s64 *out, FileHandle handle);
|
||||
Result FlushFile(FileHandle handle);
|
||||
Result WriteFile(FileHandle handle, s64 offset, const void *buffer, size_t size, const fs::WriteOption &option);
|
||||
Result SetFileSize(FileHandle handle, s64 size);
|
||||
int GetFileOpenMode(FileHandle handle);
|
||||
void CloseFile(FileHandle handle);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,12 @@
|
|||
|
||||
namespace ams::fs {
|
||||
|
||||
namespace fsa {
|
||||
|
||||
class IFile;
|
||||
|
||||
}
|
||||
|
||||
enum OpenMode {
|
||||
OpenMode_Read = ::FsOpenMode_Read,
|
||||
OpenMode_Write = ::FsOpenMode_Write,
|
||||
|
@ -49,4 +55,27 @@ namespace ams::fs {
|
|||
|
||||
using FileTimeStampRaw = ::FsTimeStampRaw;
|
||||
|
||||
struct FileHandle;
|
||||
struct DirectoryHandle;
|
||||
|
||||
Result CreateFile(const char *path, s64 size);
|
||||
Result CreateFile(const char* path, s64 size, int option);
|
||||
Result DeleteFile(const char *path);
|
||||
Result CreateDirectory(const char *path);
|
||||
Result DeleteDirectory(const char *path);
|
||||
Result DeleteDirectoryRecursively(const char *path);
|
||||
Result RenameFile(const char *old_path, const char *new_path);
|
||||
Result RenameDirectory(const char *old_path, const char *new_path);
|
||||
Result GetEntryType(DirectoryEntryType *out, const char *path);
|
||||
Result OpenFile(FileHandle *out_file, const char *path, int mode);
|
||||
Result OpenDirectory(DirectoryHandle *out_dir, const char *path, int mode);
|
||||
Result CleanDirectoryRecursively(const char *path);
|
||||
Result GetFreeSpaceSize(s64 *out, const char *path);
|
||||
Result GetTotalSpaceSize(s64 *out, const char *path);
|
||||
|
||||
Result SetConcatenationFileAttribute(const char *path);
|
||||
Result GetFileTimeStampRaw(FileTimeStampRaw *out, const char *path);
|
||||
|
||||
Result OpenFile(FileHandle *out, std::unique_ptr<fsa::IFile> &&file, int mode);
|
||||
|
||||
}
|
||||
|
|
|
@ -26,12 +26,17 @@ namespace ams::fs {
|
|||
constexpr inline char Dot = '.';
|
||||
constexpr inline char NullTerminator = '\x00';
|
||||
|
||||
constexpr inline char UnsupportedDirectorySeparator = '/';
|
||||
}
|
||||
|
||||
class PathTool {
|
||||
public:
|
||||
static constexpr const char RootPath[] = "/";
|
||||
public:
|
||||
static constexpr inline bool IsUnsupportedSeparator(char c) {
|
||||
return c == StringTraits::UnsupportedDirectorySeparator;
|
||||
}
|
||||
|
||||
static constexpr inline bool IsSeparator(char c) {
|
||||
return c == StringTraits::DirectorySeparator;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
#include "fs_file.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
|
@ -42,4 +43,6 @@ namespace ams::fs {
|
|||
using FileQueryRangeInfo = QueryRangeInfo;
|
||||
using StorageQueryRangeInfo = QueryRangeInfo;
|
||||
|
||||
Result QueryRange(QueryRangeInfo *out, FileHandle handle, s64 offset, s64 size);
|
||||
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace ams::fs {
|
|||
}
|
||||
};
|
||||
|
||||
class RemoteFileSystem : public fsa::IFileSystem {
|
||||
class RemoteFileSystem : public fsa::IFileSystem, public impl::Newable {
|
||||
private:
|
||||
std::unique_ptr<::FsFileSystem, impl::Deleter> base_fs;
|
||||
public:
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* Delimiting of mount names. */
|
||||
constexpr inline const char ReservedMountNamePrefixCharacter = '@';
|
||||
constexpr inline const char *MountNameDelimiter = ":/";
|
||||
|
||||
/* Filesystem names. */
|
||||
constexpr inline const char *HostRootFileSystemMountName = "@Host";
|
||||
constexpr inline const char *SdCardFileSystemMountName = "@Sdcard";
|
||||
constexpr inline const char *GameCardFileSystemMountName = "@Gc";
|
||||
|
||||
constexpr inline size_t GameCardFileSystemMountNameSuffixLength = 1;
|
||||
constexpr inline const char *GameCardFileSystemMountNameUpdateSuffix = "U";
|
||||
constexpr inline const char *GameCardFileSystemMountNameNormalSuffix = "N";
|
||||
constexpr inline const char *GameCardFileSystemMountNameSecureSuffix = "S";
|
||||
|
||||
/* Built-in storage names. */
|
||||
constexpr inline const char *BisCalibrationFilePartitionMountName = "@CalibFile";
|
||||
constexpr inline const char *BisSafeModePartitionMountName = "@Safe";
|
||||
constexpr inline const char *BisUserPartitionMountName = "@User";
|
||||
constexpr inline const char *BisSystemPartitionMountName = "@System";
|
||||
|
||||
/* Registered update partition. */
|
||||
constexpr inline const char *RegisteredUpdatePartitionMountName = "@RegUpdate";
|
||||
|
||||
}
|
168
libraries/libstratosphere/source/fs/fsa/fs_mount_utils.cpp
Normal file
168
libraries/libstratosphere/source/fs/fsa/fs_mount_utils.cpp
Normal file
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "fs_filesystem_accessor.hpp"
|
||||
#include "fs_mount_utils.hpp"
|
||||
#include "fs_user_mount_table.hpp"
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
namespace {
|
||||
|
||||
const char *FindMountNameDriveSeparator(const char *path) {
|
||||
for (const char *cur = path; cur < path + MountNameLengthMax + 1; cur++) {
|
||||
if (PathTool::IsDriveSeparator(*cur)) {
|
||||
return cur;
|
||||
} else if (PathTool::IsNullTerminator(*cur)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Result GetMountNameImpl(MountName &out, const char *path) {
|
||||
const char *drive_separator = FindMountNameDriveSeparator(path);
|
||||
R_UNLESS(drive_separator != nullptr, fs::ResultInvalidMountName());
|
||||
|
||||
const size_t len = drive_separator - path;
|
||||
R_UNLESS(len + 1 <= sizeof(MountName), fs::ResultInvalidMountName());
|
||||
|
||||
std::memcpy(out.str, path, len);
|
||||
out.str[len] = StringTraits::NullTerminator;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MountName GetMountName(const char *path) {
|
||||
MountName mount_name;
|
||||
|
||||
if (IsWindowsDrive(path)) {
|
||||
std::strncpy(mount_name.str, HostRootFileSystemMountName, MountNameLengthMax);
|
||||
mount_name.str[MountNameLengthMax] = StringTraits::NullTerminator;
|
||||
} else {
|
||||
R_ABORT_UNLESS(GetMountNameImpl(mount_name, path));
|
||||
}
|
||||
|
||||
return mount_name;
|
||||
}
|
||||
|
||||
const char *GetSubPath(const char *path) {
|
||||
if (IsWindowsDrive(path)) {
|
||||
return path;
|
||||
}
|
||||
|
||||
const char *sub_path = path;
|
||||
while (!PathTool::IsDriveSeparator(*sub_path)) {
|
||||
sub_path++;
|
||||
}
|
||||
|
||||
AMS_ABORT_UNLESS(PathTool::IsSeparator(sub_path[1]) || PathTool::IsUnsupportedSeparator(sub_path[1]));
|
||||
return sub_path + 1;
|
||||
}
|
||||
|
||||
bool IsValidMountName(const char *name) {
|
||||
if (PathTool::IsNullTerminator(*name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PathTool::IsWindowsDriveCharacter(name[0]) && PathTool::IsNullTerminator(name[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t len = 0;
|
||||
for (const char *cur = name; !PathTool::IsNullTerminator(*cur); cur++) {
|
||||
if (PathTool::IsDriveSeparator(*cur) || PathTool::IsSeparator(*cur)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((++len) > MountNameLengthMax) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: N validates that the mount name decodes via utf-8 here. */
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsWindowsDrive(const char *name) {
|
||||
return PathTool::IsWindowsAbsolutePath(name);
|
||||
}
|
||||
|
||||
bool IsReservedMountName(const char *name) {
|
||||
return name[0] != ReservedMountNamePrefixCharacter;
|
||||
}
|
||||
|
||||
Result CheckMountName(const char *name) {
|
||||
R_TRY(CheckMountNameAllowingReserved(name));
|
||||
R_UNLESS(!impl::IsReservedMountName(name), fs::ResultInvalidMountName());
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result CheckMountNameAllowingReserved(const char *name) {
|
||||
R_UNLESS(name != nullptr, fs::ResultInvalidMountName());
|
||||
R_UNLESS(impl::IsValidMountName(name), fs::ResultInvalidMountName());
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FindFileSystem(FileSystemAccessor **out, const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
|
||||
R_UNLESS(strncmp(path, HostRootFileSystemMountName, strnlen(HostRootFileSystemMountName, sizeof(MountName))) != 0, fs::ResultInvalidPathFormat());
|
||||
|
||||
return impl::Find(out, GetMountName(path).str);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
namespace {
|
||||
|
||||
Result UnmountImpl(const char *name) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::Find(std::addressof(accessor), name));
|
||||
|
||||
if (accessor->IsFileDataCacheAttachable()) {
|
||||
/* TODO: Data cache purge */
|
||||
}
|
||||
|
||||
impl::Unregister(name);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Result ConvertToFsCommonPath(char *dst, size_t dst_size, const char *src) {
|
||||
/* Get the mount name for the path. */
|
||||
MountName mount_name = impl::GetMountName(src);
|
||||
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::Find(std::addressof(accessor), mount_name.str));
|
||||
R_TRY(accessor->GetCommonMountName(dst, dst_size));
|
||||
|
||||
const auto mount_name_len = strnlen(dst, dst_size);
|
||||
const auto common_path_len = std::snprintf(dst + mount_name_len, dst_size - mount_name_len, "%s", impl::GetSubPath(src));
|
||||
|
||||
R_UNLESS(static_cast<size_t>(common_path_len) < dst_size - mount_name_len, fs::ResultTooLongPath());
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void Unmount(const char *mount_name) {
|
||||
R_ABORT_UNLESS(UnmountImpl(mount_name));
|
||||
}
|
||||
|
||||
}
|
31
libraries/libstratosphere/source/fs/fsa/fs_mount_utils.hpp
Normal file
31
libraries/libstratosphere/source/fs/fsa/fs_mount_utils.hpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
class FileSystemAccessor;
|
||||
|
||||
Result FindFileSystem(FileSystemAccessor **out, const char *path);
|
||||
|
||||
const char *GetSubPath(const char *path);
|
||||
bool IsWindowsDrive(const char *name);
|
||||
bool IsReservedMountName(const char *name);
|
||||
Result CheckMountName(const char *name);
|
||||
Result CheckMountNameAllowingReserved(const char *name);
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "fs_directory_accessor.hpp"
|
||||
#include "fs_filesystem_accessor.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
namespace {
|
||||
|
||||
ALWAYS_INLINE impl::DirectoryAccessor *Get(DirectoryHandle handle) {
|
||||
return reinterpret_cast<impl::DirectoryAccessor *>(handle.handle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Result ReadDirectory(s64 *out_count, DirectoryEntry *out_entries, DirectoryHandle handle, s64 max_entries) {
|
||||
return Get(handle)->Read(out_count, out_entries, max_entries);
|
||||
}
|
||||
|
||||
Result GetDirectoryEntryCount(s64 *out, DirectoryHandle handle) {
|
||||
return Get(handle)->GetEntryCount(out);
|
||||
}
|
||||
|
||||
void CloseDirectory(DirectoryHandle handle) {
|
||||
delete Get(handle);
|
||||
}
|
||||
|
||||
}
|
77
libraries/libstratosphere/source/fs/fsa/fs_user_file.cpp
Normal file
77
libraries/libstratosphere/source/fs/fsa/fs_user_file.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "fs_file_accessor.hpp"
|
||||
#include "fs_filesystem_accessor.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
namespace {
|
||||
|
||||
ALWAYS_INLINE impl::FileAccessor *Get(FileHandle handle) {
|
||||
return reinterpret_cast<impl::FileAccessor *>(handle.handle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
||||
size_t read_size;
|
||||
R_TRY(ReadFile(std::addressof(size), handle, offset, buffer, size, option));
|
||||
R_UNLESS(read_size == size, fs::ResultOutOfRange());
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||
return ReadFile(handle, offset, buffer, size, ReadOption());
|
||||
}
|
||||
|
||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
||||
return Get(handle)->Read(out, offset, buffer, size, option);
|
||||
}
|
||||
|
||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||
return ReadFile(out, handle, offset, buffer, size, ReadOption());
|
||||
}
|
||||
|
||||
Result GetFileSize(s64 *out, FileHandle handle) {
|
||||
return Get(handle)->GetSize(out);
|
||||
}
|
||||
|
||||
Result FlushFile(FileHandle handle) {
|
||||
return Get(handle)->Flush();
|
||||
}
|
||||
|
||||
Result WriteFile(FileHandle handle, s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) {
|
||||
return Get(handle)->Write(offset, buffer, size, option);
|
||||
}
|
||||
|
||||
Result SetFileSize(FileHandle handle, s64 size) {
|
||||
return Get(handle)->SetSize(size);
|
||||
}
|
||||
|
||||
int GetFileOpenMode(FileHandle handle) {
|
||||
return Get(handle)->GetOpenMode();
|
||||
}
|
||||
|
||||
void CloseFile(FileHandle handle) {
|
||||
delete Get(handle);
|
||||
}
|
||||
|
||||
Result QueryRange(QueryRangeInfo *out, FileHandle handle, s64 offset, s64 size) {
|
||||
return Get(handle)->OperateRange(out, sizeof(*out), OperationId::QueryRange, offset, size, nullptr, 0);
|
||||
}
|
||||
|
||||
}
|
170
libraries/libstratosphere/source/fs/fsa/fs_user_filesystem.cpp
Normal file
170
libraries/libstratosphere/source/fs/fsa/fs_user_filesystem.cpp
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software {
|
||||
|
||||
}
|
||||
you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY {
|
||||
|
||||
}
|
||||
without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "fs_filesystem_accessor.hpp"
|
||||
#include "fs_file_accessor.hpp"
|
||||
#include "fs_directory_accessor.hpp"
|
||||
#include "fs_mount_utils.hpp"
|
||||
#include "fs_user_mount_table.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
Result CreateFile(const char *path, s64 size) {
|
||||
return CreateFile(path, size, 0);
|
||||
}
|
||||
|
||||
Result CreateFile(const char* path, s64 size, int option) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), path));
|
||||
|
||||
return accessor->CreateFile(impl::GetSubPath(path), size, option);
|
||||
}
|
||||
|
||||
Result DeleteFile(const char *path) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), path));
|
||||
|
||||
return accessor->DeleteFile(impl::GetSubPath(path));
|
||||
}
|
||||
|
||||
Result CreateDirectory(const char *path) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), path));
|
||||
|
||||
return accessor->CreateDirectory(impl::GetSubPath(path));
|
||||
}
|
||||
|
||||
Result DeleteDirectory(const char *path) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), path));
|
||||
|
||||
return accessor->DeleteDirectory(impl::GetSubPath(path));
|
||||
}
|
||||
|
||||
Result DeleteDirectoryRecursively(const char *path) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), path));
|
||||
|
||||
return accessor->DeleteDirectoryRecursively(impl::GetSubPath(path));
|
||||
}
|
||||
|
||||
Result RenameFile(const char *old_path, const char *new_path) {
|
||||
impl::FileSystemAccessor *old_accessor;
|
||||
impl::FileSystemAccessor *new_accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(old_accessor), old_path));
|
||||
R_TRY(impl::FindFileSystem(std::addressof(new_accessor), new_path));
|
||||
|
||||
R_UNLESS(old_accessor == new_accessor, fs::ResultRenameToOtherFileSystem());
|
||||
return old_accessor->RenameFile(impl::GetSubPath(old_path), impl::GetSubPath(new_path));
|
||||
}
|
||||
|
||||
Result RenameDirectory(const char *old_path, const char *new_path) {
|
||||
impl::FileSystemAccessor *old_accessor;
|
||||
impl::FileSystemAccessor *new_accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(old_accessor), old_path));
|
||||
R_TRY(impl::FindFileSystem(std::addressof(new_accessor), new_path));
|
||||
|
||||
R_UNLESS(old_accessor == new_accessor, fs::ResultRenameToOtherFileSystem());
|
||||
return old_accessor->RenameDirectory(impl::GetSubPath(old_path), impl::GetSubPath(new_path));
|
||||
}
|
||||
|
||||
Result GetEntryType(DirectoryEntryType *out, const char *path) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), path));
|
||||
|
||||
return accessor->GetEntryType(out, impl::GetSubPath(path));
|
||||
}
|
||||
|
||||
Result OpenFile(FileHandle *out_file, const char *path, int mode) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), path));
|
||||
|
||||
R_UNLESS(out_file != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
std::unique_ptr<impl::FileAccessor> file_accessor;
|
||||
R_TRY(accessor->OpenFile(std::addressof(file_accessor), impl::GetSubPath(path), static_cast<OpenMode>(mode)));
|
||||
|
||||
out_file->handle = file_accessor.release();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result OpenDirectory(DirectoryHandle *out_dir, const char *path, int mode) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), path));
|
||||
|
||||
R_UNLESS(out_dir != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
std::unique_ptr<impl::DirectoryAccessor> dir_accessor;
|
||||
R_TRY(accessor->OpenDirectory(std::addressof(dir_accessor), impl::GetSubPath(path), static_cast<OpenDirectoryMode>(mode)));
|
||||
|
||||
out_dir->handle = dir_accessor.release();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result CleanDirectoryRecursively(const char *path) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), path));
|
||||
|
||||
return accessor->CleanDirectoryRecursively(impl::GetSubPath(path));
|
||||
}
|
||||
|
||||
Result GetFreeSpaceSize(s64 *out, const char *path) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), path));
|
||||
|
||||
return accessor->GetFreeSpaceSize(out, impl::GetSubPath(path));
|
||||
}
|
||||
|
||||
Result GetTotalSpaceSize(s64 *out, const char *path) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), path));
|
||||
|
||||
return accessor->GetTotalSpaceSize(out, impl::GetSubPath(path));
|
||||
}
|
||||
|
||||
|
||||
Result SetConcatenationFileAttribute(const char *path) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), path));
|
||||
|
||||
return accessor->QueryEntry(nullptr, 0, nullptr, 0, fsa::QueryId::SetConcatenationFileAttribute, impl::GetSubPath(path));
|
||||
}
|
||||
|
||||
Result GetFileTimeStampRaw(FileTimeStampRaw *out, const char *path) {
|
||||
impl::FileSystemAccessor *accessor;
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), path));
|
||||
|
||||
return accessor->GetFileTimeStampRaw(out, impl::GetSubPath(path));
|
||||
}
|
||||
|
||||
Result OpenFile(FileHandle *out, std::unique_ptr<fsa::IFile> &&file, int mode) {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
std::unique_ptr<impl::FileAccessor> file_accessor(new impl::FileAccessor(std::move(file), nullptr, static_cast<OpenMode>(mode)));
|
||||
R_UNLESS(file_accessor != nullptr, fs::ResultAllocationFailureInUserFileSystem());
|
||||
out->handle = file_accessor.release();
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -56,6 +56,7 @@ namespace ams::fs {
|
|||
R_DEFINE_ERROR_RESULT(AllocationFailureInRegisterB, 3366);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailureInPathNormalizer, 3367);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemInterfaceAdapter, 3407);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailureInUserFileSystem, 3420);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(MmcAccessFailed, 3500, 3999);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue