Compare commits

..

47 Commits

Author SHA1 Message Date
Michael Scire
7557b7eb92 util: prevent optimizer from removing endian-swapped writes 2022-05-08 15:32:59 -07:00
Michael Scire
187745abd5 ams: address some warnings when building with gcc-12 2022-05-07 17:09:22 -07:00
Michael Scire
4db485083b strat: update for code changes found in boot (closes #1797) 2022-05-05 17:45:55 -07:00
Michael Scire
e96972c939 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "b91294d3b"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "b91294d3b"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2022-04-29 16:15:06 -07:00
Michael Scire
3545c0aac2 ams: fs accuracy fixes, bump to 1.3.2 2022-04-29 16:14:01 -07:00
Michael Scire
d85875b910 os: fix various regressions since 1.3.1 2022-04-29 15:46:55 -07:00
Michael Scire
b1367942a2 os: fix minor bug (and simplify) MapProcessCodeMemory 2022-04-18 01:43:49 -07:00
Michael Scire
c2c0a2e169 ro/os: use os primitives for MapProcessCodeMemory 2022-04-18 01:39:22 -07:00
Michael Scire
f5052b4bca loader: update for changes in 14.0.0 2022-04-17 20:11:05 -07:00
Michael Scire
70d67bb115 loader: use os apis for interacting with process memory 2022-04-17 18:51:36 -07:00
Michael Scire
9056e0b05f strat: fix linux clang build 2022-04-17 14:01:03 -07:00
Michael Scire
895b6d0470 optional: add c++23 monadic interface 2022-04-17 12:17:25 -07:00
Michael Scire
dfba595cdc fs: fix null check in AesXtsStorageExternal 2022-04-16 12:28:40 -07:00
Michael Scire
175a34da43 os: silence a maybe-uninit warning 2022-04-16 12:28:21 -07:00
Michael Scire
02b126c2be os: refactor multi wait apis to better match Nintendo's latest implementation 2022-04-12 16:47:36 -07:00
Michael Scire
b45671fd35 fs: QueryEntry uses NonSecure buffers 2022-04-08 11:23:39 -07:00
Michael Scire
106599895d fs: fix memory leak when path is reallocated (closes #1842) 2022-04-08 11:02:17 -07:00
Michael Scire
80154b0a54 os: broadcast, not signal, on release more than 1 sema 2022-04-07 12:17:13 -07:00
Michael Scire
62eb4d6989 docs: add changelog for 1.3.1 2022-04-04 17:48:18 -07:00
Michael Scire
b52e44e798 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "590cdaf02"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "590cdaf02"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2022-04-04 17:47:56 -07:00
Michael Scire
72baa4ff18 ams: add enum recognition for 14.1.0 2022-04-04 17:44:56 -07:00
Michael Scire
442656899f util: update some bit utility logic 2022-04-03 10:51:46 -07:00
Michael Scire
d7f89a0c31 fs: update signature for VerifySign1 2022-04-01 21:06:26 -07:00
Michael Scire
2e6223d9d0 fssystem: add unique lock apis 2022-03-28 14:29:22 -07:00
Michael Scire
28f11a86fd fs: update romfs types 2022-03-28 13:57:06 -07:00
Michael Scire
a8b52dc123 fs: remove dead code 2022-03-28 08:37:08 -07:00
Michael Scire
9b47ddf01f fs: update LocalFileSystem 2022-03-28 01:33:40 -07:00
Michael Scire
0fbf007bcf fs: fixup all OperateRange implementations 2022-03-28 00:54:10 -07:00
Michael Scire
4ad8dad416 os: add DetachIoRegionHandle 2022-03-28 00:00:36 -07:00
Michael Scire
8e258bde9d util: LockFreeAtomicType (for time) 2022-03-27 20:15:10 -07:00
Michael Scire
c0d5140ef0 strat: add windows socket api, linux/macos TODO 2022-03-27 14:36:31 -07:00
Michael Scire
1bef1b58d4 fs: also update comment, for locking 2022-03-26 15:29:38 -07:00
Michael Scire
07cd682460 fs: fix inverted optional-lock condition 2022-03-26 15:28:40 -07:00
Michael Scire
e5c3d264ec fs: implement new 14.0.0 spl-ctr dispatch semantics 2022-03-26 15:21:12 -07:00
Michael Scire
bbf22b4c60 ams: globally prefer R_RETURN to return for ams::Result 2022-03-26 14:48:33 -07:00
Michael Scire
dd78ede99f ams: use R_SUCCEED, R_THROW globally 2022-03-26 00:14:36 -07:00
Michael Scire
e5b1739f65 fatal: yield our lbl session unless needed 2022-03-25 23:47:20 -07:00
Michael Scire
a4a2cc2218 fs: update IStorage::Check functions for 14.0.0 2022-03-25 23:29:36 -07:00
Michael Scire
5ffbed1bee fs: update a few loose missed results 2022-03-25 10:02:55 -07:00
Michael Scire
ec44eaa263 fs: update nca drivers (and dependents/callees) for 14.0.0 changes 2022-03-25 09:48:24 -07:00
Michael Scire
20e53fcd82 fs: update HashGeneratorFactorySelector to reflect 14.0.0 2022-03-24 21:57:37 -07:00
SciresM
64c6ef2de7 fs: reduce path size 0x28 -> 0x18
This implements two optimizations on fs::Path, which N added in 12.0.0.

The current structure looks like: 

```cpp
struct Path {
    const char *m_str; // Points to the read-only path string
    char *m_write_buffer_buffer; // Part of std::unique_ptr<char[], ams::fs::impl::Deleter>
    ams::fs::impl::Deleter m_write_buffer_deleter; // Parse of std::unique_ptr<char[], ams::fs::impl::Deleter>, stores the size of the buffer.
    size_t m_write_buffer_length; // Copy of the write buffer's size accessible to the Path() structure.
    bool m_is_normalized; // Whether the path buffer is normalized
};
```

This is pretty wasteful. The write buffer size is stored twice, wasting 8 bytes, because one copy of the size isn't accessible to the path.

In addition, due to alignment, the bool wastes 7 padding bytes.

This commit:

* Encodes normalized in the low bit of the write buffer length, saving 8 bytes.
* Use a custom WriteBuffer class rather than generic unique_ptr, to avoid needing to store the WriteBuffer twice.


These each save 8 bytes, for a final size of 0x18 rather than 0x28.
2022-03-24 20:22:47 -07:00
Michael Scire
817ad8f98d util: pointer traits only if <memory>/stratosphere 2022-03-24 18:24:19 -07:00
Michael Scire
dfa475a769 util: add pointer utils, use to constrain fs pointers 2022-03-24 16:21:03 -07:00
Michael Scire
141ae5c7ab fs: fix removed include 2022-03-24 13:31:49 -07:00
Michael Scire
4646581e93 fs: for my sanity, begin tracking version where code was last checked for accuracy 2022-03-24 08:43:40 -07:00
Michael Scire
b69fa13576 fatal: fix usage of removed bpc api in 14.0.0 2022-03-23 19:11:37 -07:00
694 changed files with 10324 additions and 6666 deletions

View File

@@ -1,4 +1,17 @@
# Changelog
## 1.3.2
+ Support was improved for 14.0.0+.
+ `loader` was updated to reflect the latest official behaviors.
+ `ro` was updated to reflect the latest official behaviors.
+ A number of minor issues were fixed and improvements were made, including:
+ A memory leak was fixed in filesystem path management; this could cause a crash when launching games ~100 times, or when deleting/re-downloading games.
+ A bug was fixed that could cause threads to not see a newly signaled semaphore.
+ A number of minor inaccuracies were fixed in the updated FileSystem APIs.
+ General system stability improvements to enhance the user's experience.
## 1.3.1
+ Support was added for 14.1.0.
+ A number of minor under the hood improvements to accuracy were made to better reflect latest official system module behavior, particularly around FS apis.
+ General system stability improvements to enhance the user's experience.
## 1.3.0
+ Support was added for 14.0.0.
+ `mesosphère` was updated to reflect the latest official kernel behavior.

View File

@@ -62,7 +62,7 @@ namespace ams::secmon::fatal {
/* Write the context to the file. */
R_TRY(fs::WriteFile(file, 0, ctx, sizeof(*ctx), fs::WriteOption::Flush));
return ResultSuccess();
R_SUCCEED();
}
}

View File

@@ -48,11 +48,11 @@ namespace ams::secmon::fatal {
//sdmmc::Deactivate(Port);
R_TRY(sdmmc::Activate(Port));
return ResultSuccess();
R_SUCCEED();
}
Result CheckSdCardConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
return sdmmc::CheckSdCardConnection(out_sm, out_bw, Port);
R_RETURN(sdmmc::CheckSdCardConnection(out_sm, out_bw, Port));
}
Result ReadSdCard(void *dst, size_t size, size_t sector_index, size_t sector_count) {
@@ -78,7 +78,7 @@ namespace ams::secmon::fatal {
sector_count -= cur_sectors;
}
return ResultSuccess();
R_SUCCEED();
}
Result WriteSdCard(size_t sector_index, size_t sector_count, const void *src, size_t size) {
@@ -104,7 +104,7 @@ namespace ams::secmon::fatal {
sector_count -= cur_sectors;
}
return ResultSuccess();
R_SUCCEED();
}
}

View File

@@ -34,45 +34,45 @@ namespace ams::fs {
Result TranslateFatFsError(FRESULT res) {
switch (res) {
case FR_OK:
return ResultSuccess();
R_SUCCEED();
case FR_DISK_ERR:
return fs::ResultMmcAccessFailed();
R_THROW(fs::ResultMmcAccessFailed());
case FR_INT_ERR:
return fs::ResultPreconditionViolation();
R_THROW(fs::ResultPreconditionViolation());
case FR_NOT_READY:
return fs::ResultMmcAccessFailed();
R_THROW(fs::ResultMmcAccessFailed());
case FR_NO_FILE:
return fs::ResultPathNotFound();
R_THROW(fs::ResultPathNotFound());
case FR_NO_PATH:
return fs::ResultPathNotFound();
R_THROW(fs::ResultPathNotFound());
case FR_INVALID_NAME:
return fs::ResultInvalidPath();
R_THROW(fs::ResultInvalidPath());
case FR_DENIED:
return fs::ResultPermissionDenied();
R_THROW(fs::ResultPermissionDenied());
case FR_EXIST:
return fs::ResultPathAlreadyExists();
R_THROW(fs::ResultPathAlreadyExists());
case FR_INVALID_OBJECT:
return fs::ResultInvalidArgument();
R_THROW(fs::ResultInvalidArgument());
case FR_WRITE_PROTECTED:
return fs::ResultWriteNotPermitted();
R_THROW(fs::ResultWriteNotPermitted());
case FR_INVALID_DRIVE:
return fs::ResultInvalidMountName();
R_THROW(fs::ResultInvalidMountName());
case FR_NOT_ENABLED:
return fs::ResultInvalidMountName(); /* BAD/TODO */
R_THROW(fs::ResultInvalidMountName()); /* BAD/TODO */
case FR_NO_FILESYSTEM:
return fs::ResultInvalidMountName(); /* BAD/TODO */
R_THROW(fs::ResultInvalidMountName()); /* BAD/TODO */
case FR_TIMEOUT:
return fs::ResultTargetLocked(); /* BAD/TODO */
R_THROW(fs::ResultTargetLocked()); /* BAD/TODO */
case FR_LOCKED:
return fs::ResultTargetLocked();
R_THROW(fs::ResultTargetLocked());
case FR_NOT_ENOUGH_CORE:
return fs::ResultPreconditionViolation(); /* BAD/TODO */
R_THROW(fs::ResultPreconditionViolation()); /* BAD/TODO */
case FR_TOO_MANY_OPEN_FILES:
return fs::ResultPreconditionViolation(); /* BAD/TODO */
R_THROW(fs::ResultPreconditionViolation()); /* BAD/TODO */
case FR_INVALID_PARAMETER:
return fs::ResultInvalidArgument();
R_THROW(fs::ResultInvalidArgument());
default:
return fs::ResultInternal();
R_THROW(fs::ResultInternal());
}
}
@@ -125,11 +125,11 @@ namespace ams::fs {
/* Expand the file. */
R_TRY(TranslateFatFsError(f_expand(std::addressof(fp), size, 1)));
return ResultSuccess();
R_SUCCEED();
}
Result CreateDirectory(const char *path) {
return TranslateFatFsError(f_mkdir(path));
R_RETURN(TranslateFatFsError(f_mkdir(path)));
}
Result OpenFile(FileHandle *out_file, const char *path, int mode) {
@@ -144,10 +144,10 @@ namespace ams::fs {
out_file->_handle = fp;
g_files_opened[i] = true;
g_open_modes[i] = mode;
return ResultSuccess();
R_SUCCEED();
}
}
return fs::ResultOpenCountLimit();
R_THROW(fs::ResultOpenCountLimit());
}
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
@@ -164,11 +164,11 @@ namespace ams::fs {
/* Check that we read the correct amount. */
R_UNLESS(br == size, fs::ResultOutOfRange());
return ResultSuccess();
R_SUCCEED();
}
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size) {
return ReadFile(handle, offset, buffer, size, fs::ReadOption::None);
R_RETURN(ReadFile(handle, offset, buffer, size, fs::ReadOption::None));
}
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
@@ -185,21 +185,21 @@ namespace ams::fs {
/* Set the output size. */
*out = br;
return ResultSuccess();
R_SUCCEED();
}
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) {
return ReadFile(out, handle, offset, buffer, size, fs::ReadOption::None);
R_RETURN(ReadFile(out, handle, offset, buffer, size, fs::ReadOption::None));
}
Result GetFileSize(s64 *out, FileHandle handle) {
FIL *fp = GetInternalFile(handle);
*out = f_size(fp);
return ResultSuccess();
R_SUCCEED();
}
Result FlushFile(FileHandle handle) {
return TranslateFatFsError(f_sync(GetInternalFile(handle)));
R_RETURN(TranslateFatFsError(f_sync(GetInternalFile(handle))));
}
Result WriteFile(FileHandle handle, s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) {
@@ -218,7 +218,7 @@ namespace ams::fs {
R_TRY(FlushFile(handle));
}
return ResultSuccess();
R_SUCCEED();
}
Result SetFileSize(FileHandle handle, s64 size) {
@@ -242,7 +242,7 @@ namespace ams::fs {
/* Check that our expansion succeeded. */
AMS_ASSERT(f_size(fp) == static_cast<FSIZE_t>(size));
return ResultSuccess();
R_SUCCEED();
}
int GetFileOpenMode(FileHandle handle) {

View File

@@ -39,45 +39,45 @@ namespace ams::fs {
Result TranslateFatFsError(FRESULT res) {
switch (res) {
case FR_OK:
return ResultSuccess();
R_SUCCEED();
case FR_DISK_ERR:
return fs::ResultMmcAccessFailed();
R_THROW(fs::ResultMmcAccessFailed());
case FR_INT_ERR:
return fs::ResultPreconditionViolation();
R_THROW(fs::ResultPreconditionViolation());
case FR_NOT_READY:
return fs::ResultMmcAccessFailed();
R_THROW(fs::ResultMmcAccessFailed());
case FR_NO_FILE:
return fs::ResultPathNotFound();
R_THROW(fs::ResultPathNotFound());
case FR_NO_PATH:
return fs::ResultPathNotFound();
R_THROW(fs::ResultPathNotFound());
case FR_INVALID_NAME:
return fs::ResultInvalidPath();
R_THROW(fs::ResultInvalidPath());
case FR_DENIED:
return fs::ResultPermissionDenied();
R_THROW(fs::ResultPermissionDenied());
case FR_EXIST:
return fs::ResultPathAlreadyExists();
R_THROW(fs::ResultPathAlreadyExists());
case FR_INVALID_OBJECT:
return fs::ResultInvalidArgument();
R_THROW(fs::ResultInvalidArgument());
case FR_WRITE_PROTECTED:
return fs::ResultWriteNotPermitted();
R_THROW(fs::ResultWriteNotPermitted());
case FR_INVALID_DRIVE:
return fs::ResultInvalidMountName();
R_THROW(fs::ResultInvalidMountName());
case FR_NOT_ENABLED:
return fs::ResultInvalidMountName(); /* BAD/TODO */
R_THROW(fs::ResultInvalidMountName()); /* BAD/TODO */
case FR_NO_FILESYSTEM:
return fs::ResultInvalidMountName(); /* BAD/TODO */
R_THROW(fs::ResultInvalidMountName()); /* BAD/TODO */
case FR_TIMEOUT:
return fs::ResultTargetLocked(); /* BAD/TODO */
R_THROW(fs::ResultTargetLocked()); /* BAD/TODO */
case FR_LOCKED:
return fs::ResultTargetLocked();
R_THROW(fs::ResultTargetLocked());
case FR_NOT_ENOUGH_CORE:
return fs::ResultPreconditionViolation(); /* BAD/TODO */
R_THROW(fs::ResultPreconditionViolation()); /* BAD/TODO */
case FR_TOO_MANY_OPEN_FILES:
return fs::ResultPreconditionViolation(); /* BAD/TODO */
R_THROW(fs::ResultPreconditionViolation()); /* BAD/TODO */
case FR_INVALID_PARAMETER:
return fs::ResultInvalidArgument();
R_THROW(fs::ResultInvalidArgument());
default:
return fs::ResultInternal();
R_THROW(fs::ResultInternal());
}
}
@@ -138,7 +138,7 @@ namespace ams::fs {
*out_entry_type = (info.fattrib & AM_DIR) ? DirectoryEntryType_Directory : DirectoryEntryType_File;
*out_archive = (info.fattrib & AM_ARC);
return ResultSuccess();
R_SUCCEED();
}
Result CreateFile(const char *path, s64 size) {
@@ -152,11 +152,11 @@ namespace ams::fs {
/* Expand the file. */
R_TRY(TranslateFatFsError(f_expand(std::addressof(fp), size, 1)));
return ResultSuccess();
R_SUCCEED();
}
Result CreateDirectory(const char *path) {
return TranslateFatFsError(f_mkdir(path));
R_RETURN(TranslateFatFsError(f_mkdir(path)));
}
Result OpenFile(FileHandle *out_file, const char *path, int mode) {
@@ -171,10 +171,10 @@ namespace ams::fs {
out_file->_handle = fp;
g_files_opened[i] = true;
g_open_modes[i] = mode;
return ResultSuccess();
R_SUCCEED();
}
}
return fs::ResultOpenCountLimit();
R_THROW(fs::ResultOpenCountLimit());
}
Result OpenDirectory(DirectoryHandle *out_dir, const char *path) {
@@ -188,10 +188,10 @@ namespace ams::fs {
/* Set the output. */
out_dir->_handle = dp;
g_dirs_opened[i] = true;
return ResultSuccess();
R_SUCCEED();
}
}
return fs::ResultOpenCountLimit();
R_THROW(fs::ResultOpenCountLimit());
}
Result ReadDirectory(s64 *out_count, DirectoryEntry *out_entries, DirectoryHandle handle, s64 max_entries) {
@@ -209,7 +209,7 @@ namespace ams::fs {
}
*out_count = count;
return ResultSuccess();
R_SUCCEED();
}
void CloseDirectory(DirectoryHandle handle) {
@@ -232,11 +232,11 @@ namespace ams::fs {
/* Check that we read the correct amount. */
R_UNLESS(br == size, fs::ResultOutOfRange());
return ResultSuccess();
R_SUCCEED();
}
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size) {
return ReadFile(handle, offset, buffer, size, fs::ReadOption::None);
R_RETURN(ReadFile(handle, offset, buffer, size, fs::ReadOption::None));
}
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
@@ -253,21 +253,21 @@ namespace ams::fs {
/* Set the output size. */
*out = br;
return ResultSuccess();
R_SUCCEED();
}
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) {
return ReadFile(out, handle, offset, buffer, size, fs::ReadOption::None);
R_RETURN(ReadFile(out, handle, offset, buffer, size, fs::ReadOption::None));
}
Result GetFileSize(s64 *out, FileHandle handle) {
FIL *fp = GetInternalFile(handle);
*out = f_size(fp);
return ResultSuccess();
R_SUCCEED();
}
Result FlushFile(FileHandle handle) {
return TranslateFatFsError(f_sync(GetInternalFile(handle)));
R_RETURN(TranslateFatFsError(f_sync(GetInternalFile(handle))));
}
Result WriteFile(FileHandle handle, s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) {
@@ -286,7 +286,7 @@ namespace ams::fs {
R_TRY(FlushFile(handle));
}
return ResultSuccess();
R_SUCCEED();
}
Result SetFileSize(FileHandle handle, s64 size) {
@@ -310,7 +310,7 @@ namespace ams::fs {
/* Check that our expansion succeeded. */
AMS_ASSERT(f_size(fp) == static_cast<FSIZE_t>(size));
return ResultSuccess();
R_SUCCEED();
}
int GetFileOpenMode(FileHandle handle) {

View File

@@ -20,7 +20,7 @@ namespace ams::fs {
Result FileHandleStorage::UpdateSize() {
R_SUCCEED_IF(m_size != InvalidSize);
return GetFileSize(std::addressof(m_size), m_handle);
R_RETURN(GetFileSize(std::addressof(m_size), m_handle));
}
Result FileHandleStorage::Read(s64 offset, void *buffer, size_t size) {
@@ -34,9 +34,9 @@ namespace ams::fs {
R_TRY(this->UpdateSize());
/* Ensure our access is valid. */
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
return ReadFile(m_handle, offset, buffer, size, fs::ReadOption());
R_RETURN(ReadFile(m_handle, offset, buffer, size, fs::ReadOption()));
}
Result FileHandleStorage::Write(s64 offset, const void *buffer, size_t size) {
@@ -50,24 +50,24 @@ namespace ams::fs {
R_TRY(this->UpdateSize());
/* Ensure our access is valid. */
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
return WriteFile(m_handle, offset, buffer, size, fs::WriteOption());
R_RETURN(WriteFile(m_handle, offset, buffer, size, fs::WriteOption()));
}
Result FileHandleStorage::Flush() {
return FlushFile(m_handle);
R_RETURN(FlushFile(m_handle));
}
Result FileHandleStorage::GetSize(s64 *out_size) {
R_TRY(this->UpdateSize());
*out_size = m_size;
return ResultSuccess();
R_SUCCEED();
}
Result FileHandleStorage::SetSize(s64 size) {
m_size = InvalidSize;
return SetFileSize(m_handle, size);
R_RETURN(SetFileSize(m_handle, size));
}
}

View File

@@ -31,25 +31,38 @@ namespace ams::fs {
virtual Result GetSize(s64 *out) = 0;
public:
static inline bool CheckAccessRange(s64 offset, s64 size, s64 total_size) {
return offset >= 0 &&
size >= 0 &&
size <= total_size &&
offset <= (total_size - size);
static inline Result CheckAccessRange(s64 offset, s64 size, s64 total_size) {
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
R_UNLESS(size >= 0, fs::ResultInvalidSize());
R_UNLESS(util::CanAddWithoutOverflow<s64>(offset, size), fs::ResultOutOfRange());
R_UNLESS(offset + size <= total_size, fs::ResultOutOfRange());
R_SUCCEED();
}
static inline bool CheckAccessRange(s64 offset, size_t size, s64 total_size) {
return CheckAccessRange(offset, static_cast<s64>(size), total_size);
static ALWAYS_INLINE Result CheckAccessRange(s64 offset, size_t size, s64 total_size) {
R_RETURN(CheckAccessRange(offset, static_cast<s64>(size), total_size));
}
static inline bool CheckOffsetAndSize(s64 offset, s64 size) {
return offset >= 0 &&
size >= 0 &&
offset <= (offset + size);
static inline Result CheckOffsetAndSize(s64 offset, s64 size) {
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
R_UNLESS(size >= 0, fs::ResultInvalidSize());
R_UNLESS(util::CanAddWithoutOverflow<s64>(offset, size), fs::ResultOutOfRange());
R_SUCCEED();
}
static inline bool CheckOffsetAndSize(s64 offset, size_t size) {
return CheckOffsetAndSize(offset, static_cast<s64>(size));
static ALWAYS_INLINE Result CheckOffsetAndSize(s64 offset, size_t size) {
R_RETURN(CheckOffsetAndSize(offset, static_cast<s64>(size)));
}
static inline Result CheckOffsetAndSizeWithResult(s64 offset, s64 size, Result fail_result) {
R_TRY_CATCH(CheckOffsetAndSize(offset, size)) {
R_CONVERT_ALL(fail_result);
} R_END_TRY_CATCH;
R_SUCCEED();
}
static ALWAYS_INLINE Result CheckOffsetAndSizeWithResult(s64 offset, size_t size, Result fail_result) {
R_RETURN(CheckOffsetAndSizeWithResult(offset, static_cast<s64>(size), fail_result));
}
};
@@ -60,23 +73,23 @@ namespace ams::fs {
ReadOnlyStorageAdapter(IStorage &s) : m_storage(s) { /* ... */ }
virtual Result Read(s64 offset, void *buffer, size_t size) override {
return m_storage.Read(offset, buffer, size);
R_RETURN(m_storage.Read(offset, buffer, size));
}
virtual Result Flush() override {
return m_storage.Flush();
R_RETURN(m_storage.Flush());
}
virtual Result GetSize(s64 *out) override {
return m_storage.GetSize(out);
R_RETURN(m_storage.GetSize(out));
}
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
return fs::ResultUnsupportedOperation();
R_THROW(fs::ResultUnsupportedOperation());
}
virtual Result SetSize(s64 size) override {
return fs::ResultUnsupportedOperation();
R_THROW(fs::ResultUnsupportedOperation());
}
};
@@ -93,9 +106,9 @@ namespace ams::fs {
R_SUCCEED_IF(size == 0);
/* Validate arguments and read. */
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
return m_storage.Read(m_offset + offset, buffer, size);
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
R_RETURN(m_storage.Read(m_offset + offset, buffer, size));
}
virtual Result Write(s64 offset, const void *buffer, size_t size) override{
@@ -103,22 +116,22 @@ namespace ams::fs {
R_SUCCEED_IF(size == 0);
/* Validate arguments and write. */
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
return m_storage.Write(m_offset + offset, buffer, size);
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
R_RETURN(m_storage.Write(m_offset + offset, buffer, size));
}
virtual Result Flush() override {
return m_storage.Flush();
R_RETURN(m_storage.Flush());
}
virtual Result GetSize(s64 *out) override {
*out = m_size;
return ResultSuccess();
R_SUCCEED();
}
virtual Result SetSize(s64 size) override {
return fs::ResultUnsupportedSetSizeForNotResizableSubStorage();
R_THROW(fs::ResultUnsupportedSetSizeForNotResizableSubStorage());
}
};

View File

@@ -33,11 +33,11 @@ namespace ams::nxboot {
ShowFatalError("SdCard: unaligned access to %" PRIx64 ", size=%" PRIx64"\n", static_cast<u64>(offset), static_cast<u64>(size));
}
return ReadSdCard(buffer, size, offset / sdmmc::SectorSize, size / sdmmc::SectorSize);
R_RETURN(ReadSdCard(buffer, size, offset / sdmmc::SectorSize, size / sdmmc::SectorSize));
}
virtual Result Flush() override {
return ResultSuccess();
R_SUCCEED();
}
virtual Result GetSize(s64 *out) override {
@@ -45,15 +45,15 @@ namespace ams::nxboot {
R_TRY(GetSdCardMemoryCapacity(std::addressof(num_sectors)));
*out = static_cast<s64>(num_sectors) * static_cast<s64>(sdmmc::SectorSize);
return ResultSuccess();
R_SUCCEED();
}
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
return fs::ResultUnsupportedOperation();
R_THROW(fs::ResultUnsupportedOperation());
}
virtual Result SetSize(s64 size) override {
return fs::ResultUnsupportedOperation();
R_THROW(fs::ResultUnsupportedOperation());
}
};
@@ -67,11 +67,11 @@ namespace ams::nxboot {
ShowFatalError("SdCard: unaligned access to %" PRIx64 ", size=%" PRIx64"\n", static_cast<u64>(offset), static_cast<u64>(size));
}
return ReadMmc(buffer, size, Partition, offset / sdmmc::SectorSize, size / sdmmc::SectorSize);
R_RETURN(ReadMmc(buffer, size, Partition, offset / sdmmc::SectorSize, size / sdmmc::SectorSize));
}
virtual Result Flush() override {
return ResultSuccess();
R_SUCCEED();
}
virtual Result GetSize(s64 *out) override {
@@ -79,15 +79,15 @@ namespace ams::nxboot {
R_TRY(GetMmcMemoryCapacity(std::addressof(num_sectors), Partition));
*out = num_sectors * sdmmc::SectorSize;
return ResultSuccess();
R_SUCCEED();
}
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
return fs::ResultUnsupportedOperation();
R_THROW(fs::ResultUnsupportedOperation());
}
virtual Result SetSize(s64 size) override {
return fs::ResultUnsupportedOperation();
R_THROW(fs::ResultUnsupportedOperation());
}
};
@@ -153,23 +153,23 @@ namespace ams::nxboot {
subofs = 0;
}
return ResultSuccess();
R_SUCCEED();
}
virtual Result Flush() override {
return fs::ResultUnsupportedOperation();
R_THROW(fs::ResultUnsupportedOperation());
}
virtual Result GetSize(s64 *out) override {
return fs::ResultUnsupportedOperation();
R_THROW(fs::ResultUnsupportedOperation());
}
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
return fs::ResultUnsupportedOperation();
R_THROW(fs::ResultUnsupportedOperation());
}
virtual Result SetSize(s64 size) override {
return fs::ResultUnsupportedOperation();
R_THROW(fs::ResultUnsupportedOperation());
}
};
@@ -349,11 +349,11 @@ namespace ams::nxboot {
}
Result ReadBoot0(s64 offset, void *dst, size_t size) {
return g_boot0_storage->Read(offset, dst, size);
R_RETURN(g_boot0_storage->Read(offset, dst, size));
}
Result ReadPackage2(s64 offset, void *dst, size_t size) {
return g_package2_storage->Read(offset, dst, size);
R_RETURN(g_package2_storage->Read(offset, dst, size));
}
}

View File

@@ -45,7 +45,7 @@ namespace ams::nxboot {
/* Write the context to the file. */
R_TRY(fs::WriteFile(file, 0, ctx, sizeof(*ctx), fs::WriteOption::Flush));
return ResultSuccess();
R_SUCCEED();
}
}

View File

@@ -34,7 +34,7 @@ namespace ams::nxboot {
g_mmc_partition = partition;
}
return ResultSuccess();
R_SUCCEED();
}
}
@@ -47,29 +47,29 @@ namespace ams::nxboot {
sdmmc::SetMmcWorkBuffer(MmcPort, g_mmc_work_buffer, sizeof(g_mmc_work_buffer));
/* Activate the mmc. */
return sdmmc::Activate(MmcPort);
R_RETURN(sdmmc::Activate(MmcPort));
}
Result CheckMmcConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
return sdmmc::CheckMmcConnection(out_sm, out_bw, MmcPort);
R_RETURN(sdmmc::CheckMmcConnection(out_sm, out_bw, MmcPort));
}
Result GetMmcMemoryCapacity(u32 *out_num_sectors, sdmmc::MmcPartition partition) {
if (partition == sdmmc::MmcPartition_UserData) {
return sdmmc::GetDeviceMemoryCapacity(out_num_sectors, MmcPort);
R_RETURN(sdmmc::GetDeviceMemoryCapacity(out_num_sectors, MmcPort));
} else {
return sdmmc::GetMmcBootPartitionCapacity(out_num_sectors, MmcPort);
R_RETURN(sdmmc::GetMmcBootPartitionCapacity(out_num_sectors, MmcPort));
}
}
Result ReadMmc(void *dst, size_t size, sdmmc::MmcPartition partition, size_t sector_index, size_t sector_count) {
R_TRY(SelectMmcPartition(partition));
return sdmmc::Read(dst, size, MmcPort, sector_index, sector_count);
R_RETURN(sdmmc::Read(dst, size, MmcPort, sector_index, sector_count));
}
Result WriteMmc(sdmmc::MmcPartition partition, size_t sector_index, size_t sector_count, const void *src, size_t size) {
R_TRY(SelectMmcPartition(partition));
return sdmmc::Write(MmcPort, sector_index, sector_count, src, size);
R_RETURN(sdmmc::Write(MmcPort, sector_index, sector_count, src, size));
}
}

View File

@@ -78,7 +78,7 @@ namespace ams::nxboot {
sdmmc::SetSdCardWorkBuffer(SdCardPort, g_sd_work_buffer, sizeof(g_sd_work_buffer));
/* Activate the SD card. */
return sdmmc::Activate(SdCardPort);
R_RETURN(sdmmc::Activate(SdCardPort));
}
void FinalizeSdCard() {
@@ -90,19 +90,19 @@ namespace ams::nxboot {
}
Result CheckSdCardConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
return sdmmc::CheckSdCardConnection(out_sm, out_bw, SdCardPort);
R_RETURN(sdmmc::CheckSdCardConnection(out_sm, out_bw, SdCardPort));
}
Result GetSdCardMemoryCapacity(u32 *out_num_sectors) {
return sdmmc::GetDeviceMemoryCapacity(out_num_sectors, SdCardPort);
R_RETURN(sdmmc::GetDeviceMemoryCapacity(out_num_sectors, SdCardPort));
}
Result ReadSdCard(void *dst, size_t size, size_t sector_index, size_t sector_count) {
return sdmmc::Read(dst, size, SdCardPort, sector_index, sector_count);
R_RETURN(sdmmc::Read(dst, size, SdCardPort, sector_index, sector_count));
}
Result WriteSdCard(size_t sector_index, size_t sector_count, const void *src, size_t size) {
return sdmmc::Write(SdCardPort, sector_index, sector_count, src, size);
R_RETURN(sdmmc::Write(SdCardPort, sector_index, sector_count, src, size));
}
}

View File

@@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
branch = master
commit = 726a7efddf8d2950e1b12848cecb66f17fbdde37
parent = 44d553d12ebac4051f2a1adbc12aeff5b3d905d9
commit = b91294d3b9960eafef6d5d80b08870d427324bc9
parent = 3545c0aac2cdfc1f6f897e8c669a8e33358b3ece
method = merge
cmdver = 0.4.1

View File

@@ -67,7 +67,7 @@ endif
ifeq ($(ATMOSPHERE_BOARD),nx-hac-001)
export LDFLAGS = -specs=$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/stratosphere.specs -specs=$(DEVKITPRO)/libnx/switch.specs $(CXXFLAGS) $(CXXWRAPS) $(CXXREQUIRED) -Wl,-Map,$(notdir $*.map)
else ifeq ($(ATMOSPHERE_COMPILER_NAME),clang)
else ifeq ($(ATMOSPHERE_OS_NAME),macos)
export LDFLAGS = $(CXXFLAGS) $(CXXWRAPS) $(CXXREQUIRED) -Wl,-map,$(notdir $@.map)
else
export LDFLAGS = $(CXXFLAGS) $(CXXWRAPS) $(CXXREQUIRED) -Wl,-Map,$(notdir $@.map)

View File

@@ -55,7 +55,7 @@ namespace ams::ddsf {
/* Attach the session. */
m_session_list.push_back(*session);
return ResultSuccess();
R_SUCCEED();
}
void DetachSession(ISession *session) {
@@ -113,12 +113,12 @@ namespace ams::ddsf {
template<typename F>
Result ForEachSession(F f, bool return_on_fail) {
return impl::ForEach(m_session_list_lock, m_session_list, f, return_on_fail);
R_RETURN(impl::ForEach(m_session_list_lock, m_session_list, f, return_on_fail));
}
template<typename F>
Result ForEachSession(F f, bool return_on_fail) const {
return impl::ForEach(m_session_list_lock, m_session_list, f, return_on_fail);
R_RETURN(impl::ForEach(m_session_list_lock, m_session_list, f, return_on_fail));
}
template<typename F>

View File

@@ -76,12 +76,12 @@ namespace ams::ddsf {
template<typename F>
Result ForEachDevice(F f, bool return_on_fail) {
return impl::ForEach(m_device_list_lock, m_device_list, f, return_on_fail);
R_RETURN(impl::ForEach(m_device_list_lock, m_device_list, f, return_on_fail));
}
template<typename F>
Result ForEachDevice(F f, bool return_on_fail) const {
return impl::ForEach(m_device_list_lock, m_device_list, f, return_on_fail);
R_RETURN(impl::ForEach(m_device_list_lock, m_device_list, f, return_on_fail));
}
template<typename F>

View File

@@ -26,13 +26,13 @@ namespace ams::ddsf::impl {
for (auto && it : list) {
if (const auto cur_result = f(std::addressof(it)); R_FAILED(cur_result)) {
if (return_on_fail) {
return cur_result;
R_RETURN(cur_result);
} else if (R_SUCCEEDED(result)) {
result = cur_result;
}
}
}
return result;
R_RETURN(result);
}
template<typename List, typename F, typename Lock>

View File

@@ -30,7 +30,6 @@
#include <stratosphere/fs/fsa/fs_registrar.hpp>
#include <stratosphere/fs/fs_remote_filesystem.hpp>
#include <stratosphere/fs/fs_read_only_filesystem.hpp>
#include <stratosphere/fs/fs_shared_filesystem_holder.hpp>
#include <stratosphere/fs/fs_istorage.hpp>
#include <stratosphere/fs/fs_i_event_notifier.hpp>
#include <stratosphere/fs/fs_substorage.hpp>
@@ -66,4 +65,5 @@
#include <stratosphere/fs/fs_program_index_map_info.hpp>
#include <stratosphere/fs/impl/fs_access_log_impl.hpp>
#include <stratosphere/fs/impl/fs_hash_generator_factory_selector.hpp>
#include <stratosphere/fs/impl/fs_storage_service_object_adapter.hpp>
#include <stratosphere/fs/fs_api.hpp>

View File

@@ -20,9 +20,11 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: 14.3.0.0 */
class HierarchicalRomFileTable {
public:
using Position = u32;
using Position = u32;
using StorageSizeType = u32;
struct FindPosition {
Position next_dir;
@@ -30,8 +32,7 @@ namespace ams::fs {
};
static_assert(util::is_pod<FindPosition>::value);
using DirectoryInfo = RomDirectoryInfo;
using FileInfo = RomFileInfo;
using FileInfo = RomFileInfo;
static constexpr RomFileId PositionToFileId(Position pos) {
return static_cast<RomFileId>(pos);
@@ -80,23 +81,23 @@ namespace ams::fs {
using Base = KeyValueRomStorageTemplate<ImplKeyType, ValueType, MaxKeyLength>;
public:
Result Add(Position *out, const ClientKeyType &key, const Value &value) {
return Base::AddInternal(out, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar), value);
R_RETURN(Base::AddInternal(out, key.key, key.Hash(), key.name.begin(), key.name.length(), value));
}
Result Get(Position *out_pos, Value *out_val, const ClientKeyType &key) {
return Base::GetInternal(out_pos, out_val, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar));
R_RETURN(Base::GetInternal(out_pos, out_val, key.key, key.Hash(), key.name.begin(), key.name.length()));
}
Result GetByPosition(ImplKey *out_key, Value *out_val, Position pos) {
return Base::GetByPosition(out_key, out_val, pos);
R_RETURN(Base::GetByPosition(out_key, out_val, pos));
}
Result GetByPosition(ImplKey *out_key, Value *out_val, void *out_aux, size_t *out_aux_size, Position pos) {
return Base::GetByPosition(out_key, out_val, out_aux, out_aux_size, pos);
R_RETURN(Base::GetByPosition(out_key, out_val, out_aux, out_aux_size, pos));
}
Result SetByPosition(Position pos, const Value &value) {
return Base::SetByPosition(pos, value);
R_RETURN(Base::SetByPosition(pos, value));
}
};
@@ -121,16 +122,15 @@ namespace ams::fs {
constexpr u32 Hash() const {
u32 hash = this->key.parent ^ 123456789;
const RomPathChar * name = this->name.path;
const RomPathChar * const end = name + this->name.length;
while (name < end) {
const u32 cur = static_cast<u32>(static_cast<std::make_unsigned<RomPathChar>::type>(*(name++)));
hash = ((hash >> 5) | (hash << 27)) ^ cur;
const RomPathChar * cur = this->name.begin();
const RomPathChar * const end = this->name.end();
while (cur < end) {
const u32 c = static_cast<u32>(static_cast<std::make_unsigned<RomPathChar>::type>(*(cur++)));
hash = ((hash >> 5) | (hash << 27)) ^ c;
}
return hash;
}
};
static_assert(util::is_pod<EntryKey>::value);
using DirectoryEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomDirectoryEntry>;
using FileEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomFileEntry>;
@@ -138,35 +138,24 @@ namespace ams::fs {
DirectoryEntryMapTable m_dir_table;
FileEntryMapTable m_file_table;
public:
static s64 QueryDirectoryEntryBucketStorageSize(s64 count);
static size_t QueryDirectoryEntrySize(size_t aux_size);
static s64 QueryFileEntryBucketStorageSize(s64 count);
static size_t QueryFileEntrySize(size_t aux_size);
static s64 QueryDirectoryEntryBucketStorageSize(StorageSizeType count);
static s64 QueryDirectoryEntrySize(StorageSizeType aux_size);
static s64 QueryFileEntryBucketStorageSize(StorageSizeType count);
static s64 QueryFileEntrySize(StorageSizeType aux_size);
static Result Format(SubStorage dir_bucket, SubStorage file_bucket);
public:
HierarchicalRomFileTable();
constexpr u32 GetDirectoryEntryCount() const {
return m_dir_table.GetEntryCount();
}
constexpr u32 GetFileEntryCount() const {
return m_file_table.GetEntryCount();
}
Result Initialize(SubStorage dir_bucket, SubStorage dir_entry, SubStorage file_bucket, SubStorage file_entry);
void Finalize();
Result CreateRootDirectory();
Result CreateDirectory(RomDirectoryId *out, const RomPathChar *path, const DirectoryInfo &info);
Result CreateDirectory(RomDirectoryId *out, const RomPathChar *path);
Result CreateFile(RomFileId *out, const RomPathChar *path, const FileInfo &info);
Result ConvertPathToDirectoryId(RomDirectoryId *out, const RomPathChar *path);
Result ConvertPathToFileId(RomFileId *out, const RomPathChar *path);
Result GetDirectoryInformation(DirectoryInfo *out, const RomPathChar *path);
Result GetDirectoryInformation(DirectoryInfo *out, RomDirectoryId id);
Result OpenFile(FileInfo *out, const RomPathChar *path);
Result OpenFile(FileInfo *out, RomFileId id);
@@ -178,7 +167,7 @@ namespace ams::fs {
Result QueryRomFileSystemSize(s64 *out_dir_entry_size, s64 *out_file_entry_size);
private:
Result GetGrandParent(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, Position pos, RomPathTool::RomEntryName name, const RomPathChar *path);
Result GetParent(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, Position pos, RomPathTool::RomEntryName name, const RomPathChar *path);
Result FindParentDirectoryRecursive(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, RomPathTool::PathParser *parser, const RomPathChar *path);
@@ -194,8 +183,6 @@ namespace ams::fs {
Result GetFileEntry(Position *out_pos, RomFileEntry *out_entry, const EntryKey &key);
Result GetFileEntry(RomFileEntry *out_entry, RomFileId id);
Result GetDirectoryInformation(DirectoryInfo *out, const EntryKey &key);
Result OpenFile(FileInfo *out, const EntryKey &key);
Result FindOpen(FindPosition *out, const EntryKey &key);

View File

@@ -19,6 +19,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: 14.3.0.0 */
template<typename KeyType, typename ValueType, size_t MaxAuxiliarySize>
class KeyValueRomStorageTemplate {
public:
@@ -27,6 +28,8 @@ namespace ams::fs {
using Position = u32;
using BucketIndex = s64;
using StorageSizeType = u32;
struct FindIndex {
BucketIndex ind;
Position pos;
@@ -39,7 +42,7 @@ namespace ams::fs {
Key key;
Value value;
Position next;
u32 size;
StorageSizeType size;
};
static_assert(util::is_pod<Element>::value);
private:
@@ -53,53 +56,41 @@ namespace ams::fs {
return num * sizeof(Position);
}
static constexpr s64 QueryBucketCount(s64 size) {
static constexpr s64 QueryBucketCount(StorageSizeType size) {
return size / sizeof(Position);
}
static constexpr size_t QueryEntrySize(size_t aux_size) {
return util::AlignUp(sizeof(Element) + aux_size, alignof(Element));
static constexpr size_t QueryEntrySize(StorageSizeType aux_size) {
return util::AlignUp<size_t>(sizeof(Element) + aux_size, alignof(Element));
}
static Result Format(SubStorage bucket, s64 count) {
static Result Format(SubStorage bucket, StorageSizeType count) {
const Position pos = InvalidPosition;
for (s64 i = 0; i < count; i++) {
for (auto i = 0u; i < count; i++) {
R_TRY(bucket.Write(i * sizeof(pos), std::addressof(pos), sizeof(pos)));
}
return ResultSuccess();
R_SUCCEED();
}
public:
KeyValueRomStorageTemplate() : m_bucket_count(), m_bucket_storage(), m_kv_storage(), m_total_entry_size(), m_entry_count() { /* ... */ }
constexpr KeyValueRomStorageTemplate() : m_bucket_count(), m_bucket_storage(), m_kv_storage(), m_total_entry_size(), m_entry_count() { /* ... */ }
Result Initialize(const SubStorage &bucket, s64 count, const SubStorage &kv) {
AMS_ASSERT(count > 0);
m_bucket_storage = bucket;
m_bucket_count = count;
m_kv_storage = kv;
return ResultSuccess();
R_SUCCEED();
}
void Finalize() {
m_bucket_storage = SubStorage();
m_kv_storage = SubStorage();
m_bucket_count = 0;
m_kv_storage = SubStorage();
}
s64 GetTotalEntrySize() const {
return m_total_entry_size;
}
Result GetFreeSize(s64 *out) {
AMS_ASSERT(out != nullptr);
s64 kv_size = 0;
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
*out = kv_size - m_total_entry_size;
return ResultSuccess();
}
constexpr u32 GetEntryCount() const {
return m_entry_count;
}
protected:
Result AddInternal(Position *out, const Key &key, u32 hash_key, const void *aux, size_t aux_size, const Value &value) {
AMS_ASSERT(out != nullptr);
@@ -116,18 +107,18 @@ namespace ams::fs {
}
Position pos;
R_TRY(this->AllocateEntry(std::addressof(pos), aux_size));
R_TRY(this->AllocateEntry(std::addressof(pos), static_cast<StorageSizeType>(aux_size)));
Position next_pos;
R_TRY(this->LinkEntry(std::addressof(next_pos), pos, hash_key));
const Element elem = { key, value, next_pos, static_cast<u32>(aux_size) };
const Element elem = { key, value, next_pos, static_cast<StorageSizeType>(aux_size) };
R_TRY(this->WriteKeyValue(std::addressof(elem), pos, aux, aux_size));
*out = pos;
m_entry_count++;
return ResultSuccess();
R_SUCCEED();
}
Result GetInternal(Position *out_pos, Value *out_val, const Key &key, u32 hash_key, const void *aux, size_t aux_size) {
@@ -141,7 +132,7 @@ namespace ams::fs {
*out_pos = pos;
*out_val = elem.value;
return ResultSuccess();
R_SUCCEED();
}
Result GetByPosition(Key *out_key, Value *out_val, Position pos) {
@@ -153,7 +144,7 @@ namespace ams::fs {
*out_key = elem.key;
*out_val = elem.value;
return ResultSuccess();
R_SUCCEED();
}
Result GetByPosition(Key *out_key, Value *out_val, void *out_aux, size_t *out_aux_size, Position pos) {
@@ -167,14 +158,14 @@ namespace ams::fs {
*out_key = elem.key;
*out_val = elem.value;
return ResultSuccess();
R_SUCCEED();
}
Result SetByPosition(Position pos, const Value &value) {
Element elem;
R_TRY(this->ReadKeyValue(std::addressof(elem), pos));
elem.value = value;
return this->WriteKeyValue(std::addressof(elem), pos, nullptr, 0);
R_RETURN(this->WriteKeyValue(std::addressof(elem), pos, nullptr, 0));
}
private:
BucketIndex HashToBucket(u32 hash_key) const {
@@ -202,17 +193,16 @@ namespace ams::fs {
R_UNLESS(cur != InvalidPosition, fs::ResultDbmKeyNotFound());
u8 *buf = static_cast<u8 *>(::ams::fs::impl::Allocate(MaxAuxiliarySize));
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedInDbmRomKeyValueStorage());
ON_SCOPE_EXIT { ::ams::fs::impl::Deallocate(buf, MaxAuxiliarySize); };
auto buf = ::ams::fs::impl::MakeUnique<u8[]>(MaxAuxiliarySize);
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
while (true) {
size_t cur_aux_size;
R_TRY(this->ReadKeyValue(out_elem, buf, std::addressof(cur_aux_size), cur));
R_TRY(this->ReadKeyValue(out_elem, buf.get(), std::addressof(cur_aux_size), cur));
if (key.IsEqual(out_elem->key, aux, aux_size, buf, cur_aux_size)) {
if (key.IsEqual(out_elem->key, aux, aux_size, buf.get(), cur_aux_size)) {
*out_pos = cur;
return ResultSuccess();
R_SUCCEED();
}
*out_prev = cur;
@@ -221,18 +211,18 @@ namespace ams::fs {
}
}
Result AllocateEntry(Position *out, size_t aux_size) {
Result AllocateEntry(Position *out, StorageSizeType aux_size) {
AMS_ASSERT(out != nullptr);
s64 kv_size;
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
const size_t end_pos = m_total_entry_size + sizeof(Element) + aux_size;
const size_t end_pos = m_total_entry_size + sizeof(Element) + static_cast<size_t>(aux_size);
R_UNLESS(end_pos <= static_cast<size_t>(kv_size), fs::ResultDbmKeyFull());
*out = static_cast<Position>(m_total_entry_size);
m_total_entry_size = util::AlignUp(static_cast<s64>(end_pos), alignof(Position));
return ResultSuccess();
m_total_entry_size = util::AlignUp<s64>(static_cast<s64>(end_pos), alignof(Position));
R_SUCCEED();
}
Result LinkEntry(Position *out, Position pos, u32 hash_key) {
@@ -250,7 +240,7 @@ namespace ams::fs {
R_TRY(this->WriteBucket(pos, ind));
*out = next;
return ResultSuccess();
R_SUCCEED();
}
Result ReadBucket(Position *out, BucketIndex ind) {
@@ -258,14 +248,14 @@ namespace ams::fs {
AMS_ASSERT(ind < m_bucket_count);
const s64 offset = ind * sizeof(Position);
return m_bucket_storage.Read(offset, out, sizeof(*out));
R_RETURN(m_bucket_storage.Read(offset, out, sizeof(*out)));
}
Result WriteBucket(Position pos, BucketIndex ind) {
AMS_ASSERT(ind < m_bucket_count);
const s64 offset = ind * sizeof(Position);
return m_bucket_storage.Write(offset, std::addressof(pos), sizeof(pos));
R_RETURN(m_bucket_storage.Write(offset, std::addressof(pos), sizeof(pos)));
}
Result ReadKeyValue(Element *out, Position pos) {
@@ -275,7 +265,7 @@ namespace ams::fs {
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
AMS_ASSERT(pos < kv_size);
return m_kv_storage.Read(pos, out, sizeof(*out));
R_RETURN(m_kv_storage.Read(pos, out, sizeof(*out)));
}
Result ReadKeyValue(Element *out, void *out_aux, size_t *out_aux_size, Position pos) {
@@ -290,7 +280,7 @@ namespace ams::fs {
R_TRY(m_kv_storage.Read(pos + sizeof(*out), out_aux, out->size));
}
return ResultSuccess();
R_SUCCEED();
}
Result WriteKeyValue(const Element *elem, Position pos, const void *aux, size_t aux_size) {
@@ -307,7 +297,7 @@ namespace ams::fs {
R_TRY(m_kv_storage.Write(pos + sizeof(*elem), aux, aux_size));
}
return ResultSuccess();
R_SUCCEED();
}
};

View File

@@ -18,34 +18,60 @@
namespace ams::fs::RomPathTool {
/* ACCURATE_TO_VERSION: 14.3.0.0 */
constexpr inline u32 MaxPathLength = 0x300;
struct RomEntryName {
size_t length;
const RomPathChar *path;
};
static_assert(util::is_pod<RomEntryName>::value);
constexpr void InitEntryName(RomEntryName *entry) {
AMS_ASSERT(entry != nullptr);
entry->length = 0;
}
constexpr inline bool IsSeparator(RomPathChar c) {
constexpr ALWAYS_INLINE bool IsSeparator(RomPathChar c) {
return c == RomStringTraits::DirectorySeparator;
}
constexpr inline bool IsNullTerminator(RomPathChar c) {
constexpr ALWAYS_INLINE bool IsNullTerminator(RomPathChar c) {
return c == RomStringTraits::NullTerminator;
}
constexpr inline bool IsDot(RomPathChar c) {
constexpr ALWAYS_INLINE bool IsDot(RomPathChar c) {
return c == RomStringTraits::Dot;
}
constexpr inline bool IsCurrentDirectory(const RomEntryName &name) {
return name.length == 1 && IsDot(name.path[0]);
}
class RomEntryName {
private:
const RomPathChar *m_path;
size_t m_length;
public:
constexpr RomEntryName() : m_path(nullptr), m_length(0) {
/* ... */
}
constexpr void Initialize(const RomPathChar *p, size_t len) {
m_path = p;
m_length = len;
}
constexpr bool IsCurrentDirectory() const {
return m_length == 1 && IsDot(m_path[0]);
}
constexpr bool IsParentDirectory() const {
return m_length == 2 && IsDot(m_path[0]) && IsDot(m_path[1]);
}
constexpr bool IsRootDirectory() const {
return m_length == 0;
}
constexpr const RomPathChar *begin() const {
return m_path;
}
constexpr const RomPathChar *end() const {
return m_path + m_length;
}
constexpr size_t length() const {
return m_length;
}
};
constexpr inline bool IsCurrentDirectory(const RomPathChar *p, size_t length) {
AMS_ASSERT(p != nullptr);
@@ -57,10 +83,6 @@ namespace ams::fs::RomPathTool {
return IsDot(p[0]) && IsNullTerminator(p[1]);
}
constexpr inline bool IsParentDirectory(const RomEntryName &name) {
return name.length == 2 && IsDot(name.path[0]) && IsDot(name.path[1]);
}
constexpr inline bool IsParentDirectory(const RomPathChar *p) {
AMS_ASSERT(p != nullptr);
return IsDot(p[0]) && IsDot(p[1]) && IsNullTerminator(p[2]);

View File

@@ -18,9 +18,10 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: 14.3.0.0 */
using RomPathChar = char;
using RomFileId = s32;
using RomDirectoryId = s32;
using RomFileId = u32;
using RomDirectoryId = u32;
struct RomFileSystemInformation {
s64 size;
@@ -37,11 +38,6 @@ namespace ams::fs {
static_assert(util::is_pod<RomFileSystemInformation>::value);
static_assert(sizeof(RomFileSystemInformation) == 0x50);
struct RomDirectoryInfo {
/* ... */
};
static_assert(util::is_pod<RomDirectoryInfo>::value);
struct RomFileInfo {
Int64 offset;
Int64 size;

View File

@@ -19,6 +19,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: 13.4.0.0 */
class DirectoryPathParser {
NON_COPYABLE(DirectoryPathParser);
NON_MOVEABLE(DirectoryPathParser);

View File

@@ -22,6 +22,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
class FileStorage : public IStorage, public impl::Newable {
NON_COPYABLE(FileStorage);
NON_MOVEABLE(FileStorage);
@@ -74,6 +75,7 @@ namespace ams::fs {
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override;
};
/* ACCURATE_TO_VERSION: Unknown */
class FileStorageBasedFileSystem : public FileStorage {
NON_COPYABLE(FileStorageBasedFileSystem);
NON_MOVEABLE(FileStorageBasedFileSystem);

View File

@@ -18,6 +18,8 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
enum AccessLogMode : u32 {
AccessLogMode_None = 0,
AccessLogMode_Log = 1,

View File

@@ -18,6 +18,8 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
void InitializeForSystem();
void InitializeWithMultiSessionForSystem();

View File

@@ -18,6 +18,8 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
Result MountApplicationPackage(const char *name, const char *common_path);
}

View File

@@ -19,6 +19,8 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
enum class BisPartitionId {
/* Boot0 */
BootPartition1Root = 0,

View File

@@ -20,6 +20,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: 13.4.0.0 */
Result MountCode(CodeVerificationData *out, const char *name, const char *path, ncm::ProgramId program_id);
Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, ncm::ProgramId program_id, bool is_hbl, bool is_specific);

View File

@@ -19,6 +19,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: 13.4.0.0 */
struct CodeVerificationData : public ams::sf::LargeData {
u8 signature[crypto::Rsa2048PssSha256Verifier::SignatureSize];
u8 target_hash[crypto::Rsa2048PssSha256Verifier::HashSize];

View File

@@ -21,6 +21,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
struct Int64 {
u32 low;
u32 high;

View File

@@ -19,6 +19,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
enum ContentType {
ContentType_Meta = 0,
ContentType_Control = 1,

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
enum class ContentStorageId : u32 {
System = 0,
User = 1,

View File

@@ -19,6 +19,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
Result MountDeviceSaveData(const char *name);
Result MountDeviceSaveData(const char *name, const ncm::ApplicationId application_id);

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
constexpr inline size_t EntryNameLengthMax = 0x300;
struct DirectoryEntry {

View File

@@ -20,7 +20,7 @@ namespace ams::fs {
namespace fsa {
class IFile;
class IFileSystem;
}

View File

@@ -20,6 +20,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
struct FileTimeStamp {
time::PosixTime create;
time::PosixTime modify;

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
enum class GameCardPartition {
Update = 0,
Normal = 1,

View File

@@ -20,6 +20,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
enum MountHostOptionFlag : u32 {
MountHostOptionFlag_None = (0 << 0),
MountHostOptionFlag_PseudoCaseSensitive = (1 << 0),

View File

@@ -18,13 +18,14 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
class IEventNotifier {
public:
virtual ~IEventNotifier() { /* ... */ }
Result BindEvent(os::SystemEventType *out, os::EventClearMode clear_mode) {
AMS_ASSERT(out != nullptr);
return this->DoBindEvent(out, clear_mode);
R_RETURN(this->DoBindEvent(out, clear_mode));
}
private:
virtual Result DoBindEvent(os::SystemEventType *out, os::EventClearMode clear_mode) = 0;

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
enum class ImageDirectoryId {
Nand = 0,
SdCard = 1,

View File

@@ -20,6 +20,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: 14.3.0.0 */
class IStorage {
public:
virtual ~IStorage() { /* ... */ }
@@ -37,28 +38,41 @@ namespace ams::fs {
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) = 0;
virtual Result OperateRange(OperationId op_id, s64 offset, s64 size) {
return this->OperateRange(nullptr, 0, op_id, offset, size, nullptr, 0);
R_RETURN(this->OperateRange(nullptr, 0, op_id, offset, size, nullptr, 0));
}
public:
static inline bool CheckAccessRange(s64 offset, s64 size, s64 total_size) {
return offset >= 0 &&
size >= 0 &&
size <= total_size &&
offset <= (total_size - size);
static inline Result CheckAccessRange(s64 offset, s64 size, s64 total_size) {
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
R_UNLESS(size >= 0, fs::ResultInvalidSize());
R_UNLESS(util::CanAddWithoutOverflow<s64>(offset, size), fs::ResultOutOfRange());
R_UNLESS(offset + size <= total_size, fs::ResultOutOfRange());
R_SUCCEED();
}
static inline bool CheckAccessRange(s64 offset, size_t size, s64 total_size) {
return CheckAccessRange(offset, static_cast<s64>(size), total_size);
static ALWAYS_INLINE Result CheckAccessRange(s64 offset, size_t size, s64 total_size) {
R_RETURN(CheckAccessRange(offset, static_cast<s64>(size), total_size));
}
static inline bool CheckOffsetAndSize(s64 offset, s64 size) {
return offset >= 0 &&
size >= 0 &&
offset <= (offset + size);
static inline Result CheckOffsetAndSize(s64 offset, s64 size) {
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
R_UNLESS(size >= 0, fs::ResultInvalidSize());
R_UNLESS(util::CanAddWithoutOverflow<s64>(offset, size), fs::ResultOutOfRange());
R_SUCCEED();
}
static inline bool CheckOffsetAndSize(s64 offset, size_t size) {
return CheckOffsetAndSize(offset, static_cast<s64>(size));
static ALWAYS_INLINE Result CheckOffsetAndSize(s64 offset, size_t size) {
R_RETURN(CheckOffsetAndSize(offset, static_cast<s64>(size)));
}
static inline Result CheckOffsetAndSizeWithResult(s64 offset, s64 size, Result fail_result) {
R_TRY_CATCH(CheckOffsetAndSize(offset, size)) {
R_CONVERT_ALL(fail_result);
} R_END_TRY_CATCH;
R_SUCCEED();
}
static ALWAYS_INLINE Result CheckOffsetAndSizeWithResult(s64 offset, size_t size, Result fail_result) {
R_RETURN(CheckOffsetAndSizeWithResult(offset, static_cast<s64>(size), fail_result));
}
};
@@ -81,32 +95,35 @@ namespace ams::fs {
virtual ~ReadOnlyStorageAdapter() { /* ... */ }
public:
virtual Result Read(s64 offset, void *buffer, size_t size) override {
return m_storage->Read(offset, buffer, size);
R_RETURN(m_storage->Read(offset, buffer, size));
}
virtual Result Flush() override {
return m_storage->Flush();
R_RETURN(m_storage->Flush());
}
virtual Result GetSize(s64 *out) override {
return m_storage->GetSize(out);
R_RETURN(m_storage->GetSize(out));
}
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
return m_storage->OperateRange(dst, dst_size, op_id, offset, size, src, src_size);
R_RETURN(m_storage->OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
}
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
/* TODO: Better result? Is it possible to get a more specific one? */
AMS_UNUSED(offset, buffer, size);
return fs::ResultUnsupportedOperation();
R_THROW(fs::ResultUnsupportedOperation());
}
virtual Result SetSize(s64 size) override {
/* TODO: Better result? Is it possible to get a more specific one? */
AMS_UNUSED(size);
return fs::ResultUnsupportedOperation();
R_THROW(fs::ResultUnsupportedOperation());
}
};
template<typename T>
concept PointerToStorage = ::ams::util::RawOrSmartPointerTo<T, ::ams::fs::IStorage>;
}

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
using AllocateFunction = void *(*)(size_t);
using DeallocateFunction = void (*)(void *, size_t);
@@ -25,6 +26,8 @@ namespace ams::fs {
namespace impl {
class Newable;
void *Allocate(size_t size);
void Deallocate(void *ptr, size_t size);
@@ -129,20 +132,27 @@ namespace ams::fs {
};
template<typename T>
std::unique_ptr<T, Deleter> MakeUnique() {
static_assert(util::is_pod<T>::value);
auto MakeUnique() {
/* Check that we're not using MakeUnique unnecessarily. */
static_assert(!std::derived_from<T, ::ams::fs::impl::Newable>);
return std::unique_ptr<T, Deleter>(static_cast<T *>(::ams::fs::impl::Allocate(sizeof(T))), Deleter(sizeof(T)));
}
template<typename ArrayT>
std::unique_ptr<ArrayT, Deleter> MakeUnique(size_t size) {
auto MakeUnique(size_t size) {
using T = typename std::remove_extent<ArrayT>::type;
static_assert(util::is_pod<ArrayT>::value);
static_assert(std::is_array<ArrayT>::value);
/* Check that we're not using MakeUnique unnecessarily. */
static_assert(!std::derived_from<T, ::ams::fs::impl::Newable>);
using ReturnType = std::unique_ptr<ArrayT, Deleter>;
const size_t alloc_size = sizeof(T) * size;
return std::unique_ptr<ArrayT, Deleter>(static_cast<T *>(::ams::fs::impl::Allocate(alloc_size)), Deleter(alloc_size));
return ReturnType(static_cast<T *>(::ams::fs::impl::Allocate(alloc_size)), Deleter(alloc_size));
}
}

View File

@@ -20,6 +20,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
class MemoryStorage : public ::ams::fs::IStorage, public ::ams::fs::impl::Newable {
private:
u8 * const m_buf;
@@ -33,11 +34,11 @@ namespace ams::fs {
/* Validate arguments. */
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
/* Copy from memory. */
std::memcpy(buffer, m_buf + offset, size);
return ResultSuccess();
R_SUCCEED();
}
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
@@ -46,25 +47,25 @@ namespace ams::fs {
/* Validate arguments. */
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
/* Copy to memory. */
std::memcpy(m_buf + offset, buffer, size);
return ResultSuccess();
R_SUCCEED();
}
virtual Result Flush() override {
return ResultSuccess();
R_SUCCEED();
}
virtual Result GetSize(s64 *out) override {
*out = m_size;
return ResultSuccess();
R_SUCCEED();
}
virtual Result SetSize(s64 size) override {
AMS_UNUSED(size);
return fs::ResultUnsupportedSetSizeForMemoryStorage();
R_THROW(fs::ResultUnsupportedSetSizeForMemoryStorage());
}
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
@@ -72,14 +73,14 @@ namespace ams::fs {
switch (op_id) {
case OperationId::Invalidate:
return ResultSuccess();
R_SUCCEED();
case OperationId::QueryRange:
R_UNLESS(dst != nullptr, fs::ResultNullptrArgument());
R_UNLESS(dst_size == sizeof(QueryRangeInfo), fs::ResultInvalidSize());
reinterpret_cast<QueryRangeInfo *>(dst)->Clear();
return ResultSuccess();
R_SUCCEED();
default:
return fs::ResultUnsupportedOperateRangeForMemoryStorage();
R_THROW(fs::ResultUnsupportedOperateRangeForMemoryStorage());
}
}
};

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
constexpr inline size_t MountNameLengthMax = 15;
Result ConvertToFsCommonPath(char *dst, size_t dst_size, const char *src);

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
enum class OperationId : s64 {
FillZero = 0,
DestroySignature = 1,

View File

@@ -23,6 +23,8 @@ namespace ams::fs {
class DirectoryPathParser;
/* ACCURATE_TO_VERSION: 13.4.0.0 */
/* NOTE: Intentional inaccuracy in custom WriteBuffer class, to save 0x10 bytes (0x28 -> 0x18) over Nintendo's implementation. */
class Path {
NON_COPYABLE(Path);
NON_MOVEABLE(Path);
@@ -31,43 +33,115 @@ namespace ams::fs {
static constexpr size_t WriteBufferAlignmentLength = 8;
private:
friend class DirectoryPathParser;
private:
using WriteBuffer = std::unique_ptr<char[], ::ams::fs::impl::Deleter>;
public:
class WriteBuffer {
NON_COPYABLE(WriteBuffer);
private:
char *m_buffer;
size_t m_length_and_is_normalized;
public:
constexpr WriteBuffer() : m_buffer(nullptr), m_length_and_is_normalized(0) { /* ... */ }
constexpr ~WriteBuffer() {
if (m_buffer != nullptr) {
::ams::fs::impl::Deallocate(m_buffer, this->GetLength());
this->ResetBuffer();
}
}
constexpr WriteBuffer(WriteBuffer &&rhs) : m_buffer(rhs.m_buffer), m_length_and_is_normalized(rhs.m_length_and_is_normalized) {
rhs.ResetBuffer();
}
constexpr WriteBuffer &operator=(WriteBuffer &&rhs) {
if (m_buffer != nullptr) {
::ams::fs::impl::Deallocate(m_buffer, this->GetLength());
}
m_buffer = rhs.m_buffer;
m_length_and_is_normalized = rhs.m_length_and_is_normalized;
rhs.ResetBuffer();
return *this;
}
std::unique_ptr<char[], ::ams::fs::impl::Deleter> ReleaseBuffer() {
auto released = std::unique_ptr<char[], ::ams::fs::impl::Deleter>(m_buffer, ::ams::fs::impl::Deleter(this->GetLength()));
this->ResetBuffer();
return released;
}
constexpr ALWAYS_INLINE void ResetBuffer() {
m_buffer = nullptr;
this->SetLength(0);
}
constexpr ALWAYS_INLINE char *Get() const {
return m_buffer;
}
constexpr ALWAYS_INLINE size_t GetLength() const {
return m_length_and_is_normalized >> 1;
}
constexpr ALWAYS_INLINE bool IsNormalized() const {
return static_cast<bool>(m_length_and_is_normalized & 1);
}
constexpr ALWAYS_INLINE void SetNormalized() {
m_length_and_is_normalized |= static_cast<size_t>(1);
}
constexpr ALWAYS_INLINE void SetNotNormalized() {
m_length_and_is_normalized &= ~static_cast<size_t>(1);
}
private:
constexpr ALWAYS_INLINE WriteBuffer(char *buffer, size_t length) : m_buffer(buffer), m_length_and_is_normalized(0) {
this->SetLength(length);
}
public:
static WriteBuffer Make(size_t length) {
if (void *alloc = ::ams::fs::impl::Allocate(length); alloc != nullptr) {
return WriteBuffer(static_cast<char *>(alloc), length);
} else {
return WriteBuffer();
}
}
private:
constexpr ALWAYS_INLINE void SetLength(size_t size) {
m_length_and_is_normalized = (m_length_and_is_normalized & 1) | (size << 1);
}
};
private:
const char *m_str;
util::TypedStorage<WriteBuffer> m_write_buffer;
size_t m_write_buffer_length;
bool m_is_normalized;
WriteBuffer m_write_buffer;
public:
Path() : m_str(EmptyPath), m_write_buffer_length(0), m_is_normalized(false) {
util::ConstructAt(m_write_buffer, nullptr);
}
constexpr Path(const char *s, util::ConstantInitializeTag) : m_str(s), m_write_buffer(), m_write_buffer_length(0), m_is_normalized(true) {
constexpr Path() : m_str(EmptyPath), m_write_buffer() {
/* ... */
}
constexpr ~Path() {
if (!std::is_constant_evaluated()) {
util::DestroyAt(m_write_buffer);
}
constexpr Path(const char *s, util::ConstantInitializeTag) : m_str(s), m_write_buffer() {
m_write_buffer.SetNormalized();
}
WriteBuffer ReleaseBuffer() {
constexpr ~Path() { /* ... */ }
std::unique_ptr<char[], ::ams::fs::impl::Deleter> ReleaseBuffer() {
/* Check pre-conditions. */
AMS_ASSERT(util::GetReference(m_write_buffer) != nullptr);
AMS_ASSERT(m_write_buffer.Get() != nullptr);
/* Reset. */
m_str = EmptyPath;
m_write_buffer_length = 0;
m_str = EmptyPath;
/* Return our write buffer. */
return std::move(util::GetReference(m_write_buffer));
/* Release our write buffer. */
return m_write_buffer.ReleaseBuffer();
}
constexpr Result SetShallowBuffer(const char *buffer) {
/* Check pre-conditions. */
AMS_ASSERT(m_write_buffer_length == 0);
AMS_ASSERT(m_write_buffer.GetLength() == 0);
/* Check the buffer is valid. */
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
@@ -76,44 +150,49 @@ namespace ams::fs {
this->SetReadOnlyBuffer(buffer);
/* Note that we're normalized. */
m_is_normalized = true;
this->SetNormalized();
R_SUCCEED();
}
const char *GetString() const {
constexpr const char *GetString() const {
/* Check pre-conditions. */
AMS_ASSERT(m_is_normalized);
AMS_ASSERT(this->IsNormalized());
return m_str;
}
size_t GetLength() const {
return std::strlen(this->GetString());
constexpr size_t GetLength() const {
if (std::is_constant_evaluated()) {
return util::Strlen(this->GetString());
} else {
return std::strlen(this->GetString());
}
}
bool IsEmpty() const {
constexpr bool IsEmpty() const {
return *m_str == '\x00';
}
bool IsMatchHead(const char *p, size_t len) const {
constexpr bool IsMatchHead(const char *p, size_t len) const {
return util::Strncmp(this->GetString(), p, len) == 0;
}
Result Initialize(const Path &rhs) {
/* Check the other path is normalized. */
R_UNLESS(rhs.m_is_normalized, fs::ResultNotNormalized());
const bool normalized = rhs.IsNormalized();
R_UNLESS(normalized, fs::ResultNotNormalized());
/* Allocate buffer for our path. */
const auto len = rhs.GetLength();
R_TRY(this->Preallocate(len + 1));
/* Copy the path. */
const size_t copied = util::Strlcpy<char>(util::GetReference(m_write_buffer).get(), rhs.GetString(), len + 1);
const size_t copied = util::Strlcpy<char>(m_write_buffer.Get(), rhs.GetString(), len + 1);
R_UNLESS(copied == len, fs::ResultUnexpectedInPathA());
/* Set normalized. */
m_is_normalized = rhs.m_is_normalized;
this->SetNormalized();
R_SUCCEED();
}
@@ -125,7 +204,7 @@ namespace ams::fs {
R_TRY(this->InitializeImpl(path, len));
/* Set not normalized. */
m_is_normalized = false;
this->SetNotNormalized();
R_SUCCEED();
}
@@ -134,7 +213,7 @@ namespace ams::fs {
/* Check the path is valid. */
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
return this->Initialize(path, std::strlen(path));
R_RETURN(this->Initialize(path, std::strlen(path)));
}
Result InitializeWithFormat(const char *fmt, ...) __attribute__((format (printf, 2, 3))) {
@@ -153,7 +232,7 @@ namespace ams::fs {
R_TRY(this->Preallocate(len + 1));
/* Format our path into our new buffer. */
const auto real_len = util::VSNPrintf(util::GetReference(m_write_buffer).get(), m_write_buffer_length, fmt, vl);
const auto real_len = util::VSNPrintf(m_write_buffer.Get(), m_write_buffer.GetLength(), fmt, vl);
AMS_ASSERT(real_len == len);
AMS_UNUSED(real_len);
@@ -161,7 +240,7 @@ namespace ams::fs {
va_end(vl);
/* Set not normalized. */
m_is_normalized = false;
this->SetNotNormalized();
R_SUCCEED();
}
@@ -174,12 +253,12 @@ namespace ams::fs {
R_TRY(this->InitializeImpl(path, std::strlen(path)));
/* Replace slashes as desired. */
if (m_write_buffer_length > 1) {
fs::Replace(this->GetWriteBuffer(), m_write_buffer_length - 1, '\\', '/');
if (const auto write_buffer_length = m_write_buffer.GetLength(); write_buffer_length > 1) {
fs::Replace(m_write_buffer.Get(), write_buffer_length - 1, '\\', '/');
}
/* Set not normalized. */
m_is_normalized = false;
this->SetNotNormalized();
R_SUCCEED();
}
@@ -192,15 +271,15 @@ namespace ams::fs {
R_TRY(this->InitializeImpl(path, std::strlen(path)));
/* Replace slashes as desired. */
if (m_write_buffer_length > 1) {
if (auto *p = this->GetWriteBuffer(); p[0] == '/' && p[1] == '/') {
if (m_write_buffer.GetLength() > 1) {
if (auto *p = m_write_buffer.Get(); p[0] == '/' && p[1] == '/') {
p[0] = '\\';
p[1] = '\\';
}
}
/* Set not normalized. */
m_is_normalized = false;
this->SetNotNormalized();
R_SUCCEED();
}
@@ -213,11 +292,11 @@ namespace ams::fs {
R_TRY(this->InitializeImpl(path, std::strlen(path)));
/* Set not normalized. */
m_is_normalized = false;
this->SetNotNormalized();
/* Replace unc as desired. */
if (m_str[0]) {
auto *p = this->GetWriteBuffer();
auto *p = m_write_buffer.Get();
/* Replace :/// -> \\ as needed. */
if (auto *sep = std::strstr(p, ":///"); sep != nullptr) {
@@ -250,7 +329,7 @@ namespace ams::fs {
R_TRY(this->InitializeImpl(path, size));
/* Set not normalized. */
m_is_normalized = false;
this->SetNotNormalized();
/* Perform normalization. */
fs::PathFlags path_flags;
@@ -262,16 +341,17 @@ namespace ams::fs {
/* NOTE: In this case, Nintendo checks is normalized, then sets is normalized, then returns success. */
/* This seems like a bug. */
size_t dummy;
R_TRY(PathFormatter::IsNormalized(std::addressof(m_is_normalized), std::addressof(dummy), m_str));
bool normalized;
R_TRY(PathFormatter::IsNormalized(std::addressof(normalized), std::addressof(dummy), m_str));
m_is_normalized = true;
this->SetNormalized();
R_SUCCEED();
}
/* Normalize. */
R_TRY(this->Normalize(path_flags));
m_is_normalized = true;
this->SetNormalized();
R_SUCCEED();
}
@@ -287,7 +367,7 @@ namespace ams::fs {
this->ClearBuffer();
/* Set normalized. */
m_is_normalized = true;
this->SetNormalized();
R_SUCCEED();
}
@@ -323,8 +403,8 @@ namespace ams::fs {
/* Reset our write buffer. */
WriteBuffer old_write_buffer;
if (util::GetReference(m_write_buffer) != nullptr) {
old_write_buffer = std::move(util::GetReference(m_write_buffer));
if (m_write_buffer.Get() != nullptr) {
old_write_buffer = std::move(m_write_buffer);
this->ClearBuffer();
}
@@ -332,9 +412,9 @@ namespace ams::fs {
R_TRY(this->Preallocate(cur_len + 1 + child_len + 1));
/* Get our write buffer. */
auto *dst = this->GetWriteBuffer();
if (old_write_buffer != nullptr && cur_len > 0) {
util::Strlcpy<char>(dst, old_write_buffer.get(), cur_len + 1);
auto *dst = m_write_buffer.Get();
if (old_write_buffer.Get() != nullptr && cur_len > 0) {
util::Strlcpy<char>(dst, old_write_buffer.Get(), cur_len + 1);
}
/* Add separator. */
@@ -375,15 +455,15 @@ namespace ams::fs {
Result RemoveChild() {
/* If we don't have a write-buffer, ensure that we have one. */
if (util::GetReference(m_write_buffer) == nullptr) {
if (m_write_buffer.Get() == nullptr) {
if (const auto len = std::strlen(m_str); len > 0) {
R_TRY(this->Preallocate(len));
util::Strlcpy<char>(util::GetReference(m_write_buffer).get(), m_str, len + 1);
util::Strlcpy<char>(m_write_buffer.Get(), m_str, len + 1);
}
}
/* Check that it's possible for us to remove a child. */
auto *p = this->GetWriteBuffer();
auto *p = m_write_buffer.Get();
s32 len = std::strlen(p);
R_UNLESS(len != 1 || (p[0] != '/' && p[0] != '.'), fs::ResultNotImplemented());
@@ -413,7 +493,7 @@ namespace ams::fs {
Result Normalize(const PathFlags &flags) {
/* If we're already normalized, nothing to do. */
R_SUCCEED_IF(m_is_normalized);
R_SUCCEED_IF(this->IsNormalized());
/* Check if we're normalized. */
bool normalized;
@@ -423,7 +503,7 @@ namespace ams::fs {
/* If we're not normalized, normalize. */
if (!normalized) {
/* Determine necessary buffer length. */
auto len = m_write_buffer_length;
auto len = m_write_buffer.GetLength();
if (flags.IsRelativePathAllowed() && fs::IsPathRelative(m_str)) {
len += 2;
}
@@ -433,57 +513,59 @@ namespace ams::fs {
/* Allocate a new buffer. */
const size_t size = util::AlignUp(len, WriteBufferAlignmentLength);
auto buf = fs::impl::MakeUnique<char[]>(size);
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
auto buf = WriteBuffer::Make(size);
R_UNLESS(buf.Get() != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
/* Normalize into it. */
R_TRY(PathFormatter::Normalize(buf.get(), size, util::GetReference(m_write_buffer).get(), m_write_buffer_length, flags));
R_TRY(PathFormatter::Normalize(buf.Get(), size, m_write_buffer.Get(), m_write_buffer.GetLength(), flags));
/* Set the normalized buffer as our buffer. */
this->SetModifiableBuffer(std::move(buf), size);
this->SetModifiableBuffer(std::move(buf));
}
/* Set normalized. */
m_is_normalized = true;
this->SetNormalized();
R_SUCCEED();
}
private:
void ClearBuffer() {
util::GetReference(m_write_buffer).reset();
m_write_buffer_length = 0;
m_write_buffer.ResetBuffer();
m_str = EmptyPath;
}
void SetModifiableBuffer(WriteBuffer &&buffer, size_t size) {
void SetModifiableBuffer(WriteBuffer &&buffer) {
/* Check pre-conditions. */
AMS_ASSERT(buffer.get() != nullptr);
AMS_ASSERT(size > 0);
AMS_ASSERT(util::IsAligned(size, WriteBufferAlignmentLength));
AMS_ASSERT(buffer.Get() != nullptr);
AMS_ASSERT(buffer.GetLength() > 0);
AMS_ASSERT(util::IsAligned(buffer.GetLength(), WriteBufferAlignmentLength));
/* Get whether we're normalized. */
if (m_write_buffer.IsNormalized()) {
buffer.SetNormalized();
} else {
buffer.SetNotNormalized();
}
/* Set write buffer. */
util::GetReference(m_write_buffer) = std::move(buffer);
m_write_buffer_length = size;
m_str = util::GetReference(m_write_buffer).get();
m_write_buffer = std::move(buffer);
m_str = m_write_buffer.Get();
}
constexpr void SetReadOnlyBuffer(const char *buffer) {
m_str = buffer;
if (!std::is_constant_evaluated()) {
util::GetReference(m_write_buffer) = nullptr;
m_write_buffer_length = 0;
}
m_write_buffer.ResetBuffer();
}
Result Preallocate(size_t length) {
/* Allocate additional space, if needed. */
if (length > m_write_buffer_length) {
if (length > m_write_buffer.GetLength()) {
/* Allocate buffer. */
const size_t size = util::AlignUp(length, WriteBufferAlignmentLength);
auto buf = fs::impl::MakeUnique<char[]>(size);
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
auto buf = WriteBuffer::Make(size);
R_UNLESS(buf.Get() != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
/* Set write buffer. */
this->SetModifiableBuffer(std::move(buf), size);
this->SetModifiableBuffer(std::move(buf));
}
R_SUCCEED();
@@ -495,7 +577,7 @@ namespace ams::fs {
R_TRY(this->Preallocate(size + 1));
/* Copy the path. */
const size_t copied = util::Strlcpy<char>(this->GetWriteBuffer(), path, size + 1);
const size_t copied = util::Strlcpy<char>(m_write_buffer.Get(), path, size + 1);
R_UNLESS(copied >= size, fs::ResultUnexpectedInPathA());
} else {
/* We can just clear the buffer. */
@@ -505,14 +587,20 @@ namespace ams::fs {
R_SUCCEED();
}
char *GetWriteBuffer() {
AMS_ASSERT(util::GetReference(m_write_buffer) != nullptr);
return util::GetReference(m_write_buffer).get();
constexpr char *GetWriteBuffer() {
AMS_ASSERT(m_write_buffer.Get() != nullptr);
return m_write_buffer.Get();
}
size_t GetWriteBufferLength() const {
return m_write_buffer_length;
constexpr ALWAYS_INLINE size_t GetWriteBufferLength() const {
return m_write_buffer.GetLength();
}
constexpr ALWAYS_INLINE bool IsNormalized() const { return m_write_buffer.IsNormalized(); }
constexpr ALWAYS_INLINE void SetNormalized() { m_write_buffer.SetNormalized(); }
constexpr ALWAYS_INLINE void SetNotNormalized() { m_write_buffer.SetNotNormalized(); }
public:
ALWAYS_INLINE bool operator==(const fs::Path &rhs) const { return std::strcmp(this->GetString(), rhs.GetString()) == 0; }
ALWAYS_INLINE bool operator!=(const fs::Path &rhs) const { return !(*this == rhs); }
@@ -579,4 +667,9 @@ namespace ams::fs {
R_RETURN(SetUpFixedPath(out, buf));
}
constexpr inline bool IsWindowsDriveRootPath(const fs::Path &path) {
const char * const str = path.GetString();
return fs::IsWindowsDrive(str) && (str[2] == StringTraits::DirectorySeparator || str[2] == StringTraits::AlternateDirectorySeparator) && str[3] == StringTraits::NullTerminator;
}
}

View File

@@ -19,6 +19,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: 13.4.0.0 */
namespace StringTraits {
constexpr inline char DirectorySeparator = '/';
@@ -618,7 +619,7 @@ namespace ams::fs {
}
static constexpr ALWAYS_INLINE Result SkipMountName(const char **out, size_t *out_len, const char *path) {
return ParseMountName(out, out_len, nullptr, 0, path);
R_RETURN(ParseMountName(out, out_len, nullptr, 0, path));
}
static constexpr Result ParseMountName(const char **out, size_t *out_len, char *out_mount_name, size_t out_mount_name_buffer_size, const char *path) {
@@ -683,7 +684,7 @@ namespace ams::fs {
}
static constexpr ALWAYS_INLINE Result SkipRelativeDotPath(const char **out, size_t *out_len, const char *path) {
return ParseRelativeDotPath(out, out_len, nullptr, 0, path);
R_RETURN(ParseRelativeDotPath(out, out_len, nullptr, 0, path));
}
static constexpr Result ParseRelativeDotPath(const char **out, size_t *out_len, char *out_relative, size_t out_relative_buffer_size, const char *path) {

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
enum Priority {
Priority_Realtime = 0,
Priority_Normal = 1,

View File

@@ -19,6 +19,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
struct ProgramIndexMapInfo {
ncm::ProgramId program_id;
ncm::ProgramId base_program_id;

View File

@@ -19,6 +19,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
struct QueryRangeInfo {
s32 aes_ctr_key_type;
s32 speed_emulation_type;

View File

@@ -22,6 +22,8 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
namespace {
class ReadOnlyFile : public fsa::IFile, public impl::Newable {
@@ -34,15 +36,15 @@ namespace ams::fs {
virtual ~ReadOnlyFile() { /* ... */ }
private:
virtual Result DoRead(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) override final {
return m_base_file->Read(out, offset, buffer, size, option);
R_RETURN(m_base_file->Read(out, offset, buffer, size, option));
}
virtual Result DoGetSize(s64 *out) override final {
return m_base_file->GetSize(out);
R_RETURN(m_base_file->GetSize(out));
}
virtual Result DoFlush() override final {
return ResultSuccess();
R_SUCCEED();
}
virtual Result DoWrite(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) override final {
@@ -52,21 +54,21 @@ namespace ams::fs {
AMS_ASSERT(!need_append);
AMS_UNUSED(buffer);
return fs::ResultUnsupportedWriteForReadOnlyFile();
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFile());
}
virtual Result DoSetSize(s64 size) override final {
R_TRY(this->DrySetSize(size, fs::OpenMode_Read));
return fs::ResultUnsupportedWriteForReadOnlyFile();
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFile());
}
virtual Result DoOperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override final {
switch (op_id) {
case OperationId::Invalidate:
case OperationId::QueryRange:
return m_base_file->OperateRange(dst, dst_size, op_id, offset, size, src, src_size);
R_RETURN(m_base_file->OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
default:
return fs::ResultUnsupportedOperateRangeForReadOnlyFile();
R_THROW(fs::ResultUnsupportedOperateRangeForReadOnlyFile());
}
}
public:
@@ -98,74 +100,73 @@ namespace ams::fs {
R_UNLESS(read_only_file != nullptr, fs::ResultAllocationMemoryFailedInReadOnlyFileSystemA());
*out_file = std::move(read_only_file);
return ResultSuccess();
R_SUCCEED();
}
virtual Result DoOpenDirectory(std::unique_ptr<fsa::IDirectory> *out_dir, const fs::Path &path, OpenDirectoryMode mode) override final {
return m_base_fs->OpenDirectory(out_dir, path, mode);
R_RETURN(m_base_fs->OpenDirectory(out_dir, path, mode));
}
virtual Result DoGetEntryType(DirectoryEntryType *out, const fs::Path &path) override final {
return m_base_fs->GetEntryType(out, path);
R_RETURN(m_base_fs->GetEntryType(out, path));
}
virtual Result DoCommit() override final {
return ResultSuccess();
R_SUCCEED();
}
virtual Result DoCreateFile(const fs::Path &path, s64 size, int flags) override final {
AMS_UNUSED(path, size, flags);
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
}
virtual Result DoDeleteFile(const fs::Path &path) override final {
AMS_UNUSED(path);
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
}
virtual Result DoCreateDirectory(const fs::Path &path) override final {
AMS_UNUSED(path);
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
}
virtual Result DoDeleteDirectory(const fs::Path &path) override final {
AMS_UNUSED(path);
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
}
virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) override final {
AMS_UNUSED(path);
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
}
virtual Result DoRenameFile(const fs::Path &old_path, const fs::Path &new_path) override final {
AMS_UNUSED(old_path, new_path);
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
}
virtual Result DoRenameDirectory(const fs::Path &old_path, const fs::Path &new_path) override final {
AMS_UNUSED(old_path, new_path);
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
}
virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override final {
AMS_UNUSED(path);
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
}
virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override final {
AMS_UNUSED(out, path);
return fs::ResultUnsupportedCommitProvisionallyForReadOnlyFileSystem();
R_RETURN(m_base_fs->GetFreeSpaceSize(out, path));
}
virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override final {
AMS_UNUSED(out, path);
return fs::ResultUnsupportedCommitProvisionallyForReadOnlyFileSystem();
R_THROW(fs::ResultUnsupportedGetTotalSpaceSizeForReadOnlyFileSystem());
}
virtual Result DoCommitProvisionally(s64 counter) override final {
AMS_UNUSED(counter);
return fs::ResultUnsupportedGetTotalSpaceSizeForReadOnlyFileSystem();
R_THROW(fs::ResultUnsupportedCommitProvisionallyForReadOnlyFileSystem());
}
};

View File

@@ -35,23 +35,23 @@ namespace ams::fs {
virtual ~RemoteFile() { fsFileClose(std::addressof(m_base_file)); }
public:
virtual Result DoRead(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) override final {
return fsFileRead(std::addressof(m_base_file), offset, buffer, size, option._value, out);
R_RETURN(fsFileRead(std::addressof(m_base_file), offset, buffer, size, option._value, out));
}
virtual Result DoGetSize(s64 *out) override final {
return fsFileGetSize(std::addressof(m_base_file), out);
R_RETURN(fsFileGetSize(std::addressof(m_base_file), out));
}
virtual Result DoFlush() override final {
return fsFileFlush(std::addressof(m_base_file));
R_RETURN(fsFileFlush(std::addressof(m_base_file)));
}
virtual Result DoWrite(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) override final {
return fsFileWrite(std::addressof(m_base_file), offset, buffer, size, option._value);
R_RETURN(fsFileWrite(std::addressof(m_base_file), offset, buffer, size, option._value));
}
virtual Result DoSetSize(s64 size) override final {
return fsFileSetSize(std::addressof(m_base_file), size);
R_RETURN(fsFileSetSize(std::addressof(m_base_file), size));
}
virtual Result DoOperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override final {
@@ -60,7 +60,7 @@ namespace ams::fs {
R_UNLESS(op_id == OperationId::QueryRange, fs::ResultUnsupportedOperateRangeForFileServiceObjectAdapter());
R_UNLESS(dst_size == sizeof(FileQueryRangeInfo), fs::ResultInvalidSize());
return fsFileOperateRange(std::addressof(m_base_file), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(dst));
R_RETURN(fsFileOperateRange(std::addressof(m_base_file), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(dst)));
}
public:
virtual sf::cmif::DomainObjectId GetDomainObjectId() const override final {
@@ -80,11 +80,11 @@ namespace ams::fs {
public:
virtual Result DoRead(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries) override final {
static_assert(sizeof(*out_entries) == sizeof(::FsDirectoryEntry));
return fsDirRead(std::addressof(m_base_dir), out_count, max_entries, reinterpret_cast<::FsDirectoryEntry *>(out_entries));
R_RETURN(fsDirRead(std::addressof(m_base_dir), out_count, max_entries, reinterpret_cast<::FsDirectoryEntry *>(out_entries)));
}
virtual Result DoGetEntryCount(s64 *out) override final {
return fsDirGetEntryCount(std::addressof(m_base_dir), out);
R_RETURN(fsDirGetEntryCount(std::addressof(m_base_dir), out));
}
public:
virtual sf::cmif::DomainObjectId GetDomainObjectId() const override final {
@@ -119,31 +119,31 @@ namespace ams::fs {
virtual Result DoCreateFile(const fs::Path &path, s64 size, int flags) override final {
fssrv::sf::Path sf_path;
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
return fsFsCreateFile(std::addressof(m_base_fs), sf_path.str, size, flags);
R_RETURN(fsFsCreateFile(std::addressof(m_base_fs), sf_path.str, size, flags));
}
virtual Result DoDeleteFile(const fs::Path &path) override final {
fssrv::sf::Path sf_path;
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
return fsFsDeleteFile(std::addressof(m_base_fs), sf_path.str);
R_RETURN(fsFsDeleteFile(std::addressof(m_base_fs), sf_path.str));
}
virtual Result DoCreateDirectory(const fs::Path &path) override final {
fssrv::sf::Path sf_path;
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
return fsFsCreateDirectory(std::addressof(m_base_fs), sf_path.str);
R_RETURN(fsFsCreateDirectory(std::addressof(m_base_fs), sf_path.str));
}
virtual Result DoDeleteDirectory(const fs::Path &path) override final {
fssrv::sf::Path sf_path;
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
return fsFsDeleteDirectory(std::addressof(m_base_fs), sf_path.str);
R_RETURN(fsFsDeleteDirectory(std::addressof(m_base_fs), sf_path.str));
}
virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) override final {
fssrv::sf::Path sf_path;
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
return fsFsDeleteDirectoryRecursively(std::addressof(m_base_fs), sf_path.str);
R_RETURN(fsFsDeleteDirectoryRecursively(std::addressof(m_base_fs), sf_path.str));
}
virtual Result DoRenameFile(const fs::Path &old_path, const fs::Path &new_path) override final {
@@ -151,7 +151,7 @@ namespace ams::fs {
fssrv::sf::Path new_sf_path;
R_TRY(GetPathForServiceObject(std::addressof(old_sf_path), old_path));
R_TRY(GetPathForServiceObject(std::addressof(new_sf_path), new_path));
return fsFsRenameFile(std::addressof(m_base_fs), old_sf_path.str, new_sf_path.str);
R_RETURN(fsFsRenameFile(std::addressof(m_base_fs), old_sf_path.str, new_sf_path.str));
}
virtual Result DoRenameDirectory(const fs::Path &old_path, const fs::Path &new_path) override final {
@@ -159,7 +159,7 @@ namespace ams::fs {
fssrv::sf::Path new_sf_path;
R_TRY(GetPathForServiceObject(std::addressof(old_sf_path), old_path));
R_TRY(GetPathForServiceObject(std::addressof(new_sf_path), new_path));
return fsFsRenameDirectory(std::addressof(m_base_fs), old_sf_path.str, new_sf_path.str);
R_RETURN(fsFsRenameDirectory(std::addressof(m_base_fs), old_sf_path.str, new_sf_path.str));
}
virtual Result DoGetEntryType(DirectoryEntryType *out, const fs::Path &path) override final {
@@ -167,7 +167,7 @@ namespace ams::fs {
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
static_assert(sizeof(::FsDirEntryType) == sizeof(DirectoryEntryType));
return fsFsGetEntryType(std::addressof(m_base_fs), sf_path.str, reinterpret_cast<::FsDirEntryType *>(out));
R_RETURN(fsFsGetEntryType(std::addressof(m_base_fs), sf_path.str, reinterpret_cast<::FsDirEntryType *>(out)));
}
virtual Result DoOpenFile(std::unique_ptr<fsa::IFile> *out_file, const fs::Path &path, OpenMode mode) override final {
@@ -181,7 +181,7 @@ namespace ams::fs {
R_UNLESS(file != nullptr, fs::ResultAllocationMemoryFailedNew());
*out_file = std::move(file);
return ResultSuccess();
R_SUCCEED();
}
virtual Result DoOpenDirectory(std::unique_ptr<fsa::IDirectory> *out_dir, const fs::Path &path, OpenDirectoryMode mode) override final {
@@ -195,42 +195,42 @@ namespace ams::fs {
R_UNLESS(dir != nullptr, fs::ResultAllocationMemoryFailedNew());
*out_dir = std::move(dir);
return ResultSuccess();
R_SUCCEED();
}
virtual Result DoCommit() override final {
return fsFsCommit(std::addressof(m_base_fs));
R_RETURN(fsFsCommit(std::addressof(m_base_fs)));
}
virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override final {
fssrv::sf::Path sf_path;
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
return fsFsGetFreeSpace(std::addressof(m_base_fs), sf_path.str, out);
R_RETURN(fsFsGetFreeSpace(std::addressof(m_base_fs), sf_path.str, out));
}
virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override final {
fssrv::sf::Path sf_path;
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
return fsFsGetTotalSpace(std::addressof(m_base_fs), sf_path.str, out);
R_RETURN(fsFsGetTotalSpace(std::addressof(m_base_fs), sf_path.str, out));
}
virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override final {
fssrv::sf::Path sf_path;
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
return fsFsCleanDirectoryRecursively(std::addressof(m_base_fs), sf_path.str);
R_RETURN(fsFsCleanDirectoryRecursively(std::addressof(m_base_fs), sf_path.str));
}
virtual Result DoGetFileTimeStampRaw(FileTimeStampRaw *out, const fs::Path &path) override final {
fssrv::sf::Path sf_path;
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
static_assert(sizeof(FileTimeStampRaw) == sizeof(::FsTimeStampRaw));
return fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), sf_path.str, reinterpret_cast<::FsTimeStampRaw *>(out));
R_RETURN(fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), sf_path.str, reinterpret_cast<::FsTimeStampRaw *>(out)));
}
virtual Result DoQueryEntry(char *dst, size_t dst_size, const char *src, size_t src_size, fsa::QueryId query, const fs::Path &path) override final {
fssrv::sf::Path sf_path;
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
return fsFsQueryEntry(std::addressof(m_base_fs), dst, dst_size, src, src_size, sf_path.str, static_cast<FsFileSystemQueryId>(query));
R_RETURN(fsFsQueryEntry(std::addressof(m_base_fs), dst, dst_size, src, src_size, sf_path.str, static_cast<FsFileSystemQueryId>(query)));
}
};
#endif

View File

@@ -32,29 +32,29 @@ namespace ams::fs {
virtual ~RemoteStorage() { fsStorageClose(std::addressof(m_base_storage)); }
public:
virtual Result Read(s64 offset, void *buffer, size_t size) override {
return fsStorageRead(std::addressof(m_base_storage), offset, buffer, size);
R_RETURN(fsStorageRead(std::addressof(m_base_storage), offset, buffer, size));
};
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
return fsStorageWrite(std::addressof(m_base_storage), offset, buffer, size);
R_RETURN(fsStorageWrite(std::addressof(m_base_storage), offset, buffer, size));
};
virtual Result Flush() override {
return fsStorageFlush(std::addressof(m_base_storage));
R_RETURN(fsStorageFlush(std::addressof(m_base_storage)));
};
virtual Result GetSize(s64 *out_size) override {
return fsStorageGetSize(std::addressof(m_base_storage), out_size);
R_RETURN(fsStorageGetSize(std::addressof(m_base_storage), out_size));
};
virtual Result SetSize(s64 size) override {
return fsStorageSetSize(std::addressof(m_base_storage), size);
R_RETURN(fsStorageSetSize(std::addressof(m_base_storage), size));
};
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
/* TODO: How to deal with this? */
AMS_UNUSED(dst, dst_size, op_id, offset, size, src, src_size);
return fs::ResultUnsupportedOperation();
R_THROW(fs::ResultUnsupportedOperation());
};
};
#endif

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
void SetEnabledAutoAbort(bool enabled);
void SetResultHandledByApplication(bool application);

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
union RightsId {
u8 data[0x10];
u64 data64[2];

View File

@@ -23,6 +23,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
class RomFsFileSystem : public fsa::IFileSystem, public impl::Newable {
NON_COPYABLE(RomFsFileSystem);
public:

View File

@@ -19,6 +19,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
Result DeleteSaveData(SaveDataId id);
Result DeleteSaveData(SaveDataSpaceId space_id, SaveDataId id);

View File

@@ -19,6 +19,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
Result CommitSaveData(const char *path);
}

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
using SaveDataId = u64;
using SystemSaveDataId = u64;
using SystemBcatSaveDataId = SystemSaveDataId;

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
class IEventNotifier;
struct EncryptionSeed {

View File

@@ -1,54 +0,0 @@
/*
* Copyright (c) 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/fs/fs_common.hpp>
#include <stratosphere/fs/impl/fs_newable.hpp>
#include <stratosphere/fs/fsa/fs_ifile.hpp>
#include <stratosphere/fs/fsa/fs_idirectory.hpp>
#include <stratosphere/fs/fsa/fs_ifilesystem.hpp>
namespace ams::fs {
class SharedFileSystemHolder : public fsa::IFileSystem, public impl::Newable {
NON_COPYABLE(SharedFileSystemHolder);
NON_MOVEABLE(SharedFileSystemHolder);
private:
std::shared_ptr<fsa::IFileSystem> m_fs;
public:
SharedFileSystemHolder(std::shared_ptr<fsa::IFileSystem> f) : m_fs(std::move(f)) { /* ... */ }
public:
virtual Result DoCreateFile(const fs::Path &path, s64 size, int flags) override { return m_fs->CreateFile(path, size, flags); }
virtual Result DoDeleteFile(const fs::Path &path) override { return m_fs->DeleteFile(path); }
virtual Result DoCreateDirectory(const fs::Path &path) override { return m_fs->CreateDirectory(path); }
virtual Result DoDeleteDirectory(const fs::Path &path) override { return m_fs->DeleteDirectory(path); }
virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) override { return m_fs->DeleteDirectoryRecursively(path); }
virtual Result DoRenameFile(const fs::Path &old_path, const fs::Path &new_path) override { return m_fs->RenameFile(old_path, new_path); }
virtual Result DoRenameDirectory(const fs::Path &old_path, const fs::Path &new_path) override { return m_fs->RenameDirectory(old_path, new_path); }
virtual Result DoGetEntryType(fs::DirectoryEntryType *out, const fs::Path &path) override { return m_fs->GetEntryType(out, path); }
virtual Result DoOpenFile(std::unique_ptr<fs::fsa::IFile> *out_file, const fs::Path &path, fs::OpenMode mode) override { return m_fs->OpenFile(out_file, path, mode); }
virtual Result DoOpenDirectory(std::unique_ptr<fs::fsa::IDirectory> *out_dir, const fs::Path &path, fs::OpenDirectoryMode mode) override { return m_fs->OpenDirectory(out_dir, path, mode); }
virtual Result DoCommit() override { return m_fs->Commit(); }
virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override { return m_fs->GetFreeSpaceSize(out, path); }
virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override { return m_fs->GetTotalSpaceSize(out, path); }
virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override { return m_fs->CleanDirectoryRecursively(path); }
/* These aren't accessible as commands. */
virtual Result DoCommitProvisionally(s64 counter) override { return m_fs->CommitProvisionally(counter); }
virtual Result DoRollback() override { return m_fs->Rollback(); }
virtual Result DoFlush() override { return m_fs->Flush(); }
};
}

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
bool IsSignedSystemPartitionOnSdCardValid(const char *system_root_path);
bool IsSignedSystemPartitionOnSdCardValidDeprecated();

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
enum class SpeedEmulationMode {
None = 0,
Faster = 1,

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
enum StorageType : s32 {
StorageType_SaveData = 0,
StorageType_RomFs = 1,

View File

@@ -19,6 +19,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
class SubStorage : public ::ams::fs::IStorage, public ::ams::fs::impl::Newable {
private:
std::shared_ptr<IStorage> m_shared_base_storage;
@@ -74,41 +75,42 @@ namespace ams::fs {
public:
virtual Result Read(s64 offset, void *buffer, size_t size) override {
/* Ensure we're initialized. */
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
/* Succeed immediately on zero-sized operation. */
R_SUCCEED_IF(size == 0);
/* Validate arguments and read. */
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
return m_base_storage->Read(m_offset + offset, buffer, size);
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
R_RETURN(m_base_storage->Read(m_offset + offset, buffer, size));
}
virtual Result Write(s64 offset, const void *buffer, size_t size) override{
/* Ensure we're initialized. */
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
/* Succeed immediately on zero-sized operation. */
R_SUCCEED_IF(size == 0);
/* Validate arguments and write. */
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
return m_base_storage->Write(m_offset + offset, buffer, size);
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
R_RETURN(m_base_storage->Write(m_offset + offset, buffer, size));
}
virtual Result Flush() override {
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
return m_base_storage->Flush();
R_RETURN(m_base_storage->Flush());
}
virtual Result SetSize(s64 size) override {
/* Ensure we're initialized and validate arguments. */
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
R_UNLESS(m_resizable, fs::ResultUnsupportedSetSizeForNotResizableSubStorage());
R_UNLESS(IStorage::CheckOffsetAndSize(m_offset, size), fs::ResultInvalidSize());
R_TRY(IStorage::CheckOffsetAndSize(m_offset, size));
/* Ensure that we're allowed to set size. */
s64 cur_size;
@@ -119,7 +121,7 @@ namespace ams::fs {
R_TRY(m_base_storage->SetSize(m_offset + size));
m_size = size;
return ResultSuccess();
R_SUCCEED();
}
virtual Result GetSize(s64 *out) override {
@@ -127,19 +129,24 @@ namespace ams::fs {
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
*out = m_size;
return ResultSuccess();
R_SUCCEED();
}
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
/* Ensure we're initialized. */
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
/* Succeed immediately on zero-sized operation. */
R_SUCCEED_IF(size == 0);
/* If we're not invalidating, sanity check arguments. */
if (op_id != fs::OperationId::Invalidate) {
/* Succeed immediately on zero-sized operation other than invalidate. */
R_SUCCEED_IF(size == 0);
/* Validate arguments and operate. */
R_UNLESS(IStorage::CheckOffsetAndSize(offset, size), fs::ResultOutOfRange());
return m_base_storage->OperateRange(dst, dst_size, op_id, m_offset + offset, size, src, src_size);
/* Check access extents. */
R_TRY(IStorage::CheckOffsetAndSize(offset, size));
}
/* Perform the operation. */
R_RETURN(m_base_storage->OperateRange(dst, dst_size, op_id, m_offset + offset, size, src, src_size));
}
using IStorage::OperateRange;

View File

@@ -18,6 +18,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
Result QueryMountSystemDataCacheSize(size_t *out, ncm::SystemDataId data_id);
Result MountSystemData(const char *name, ncm::SystemDataId data_id);

View File

@@ -19,6 +19,7 @@
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
void DisableAutoSaveDataCreation();
Result CreateSystemSaveData(SystemSaveDataId save_id, s64 size, s64 journal_size, u32 flags);

View File

@@ -20,6 +20,7 @@
namespace ams::fs::fsa {
/* ACCURATE_TO_VERSION: Unknown */
class IDirectory {
public:
virtual ~IDirectory() { /* ... */ }
@@ -28,7 +29,7 @@ namespace ams::fs::fsa {
R_UNLESS(out_count != nullptr, fs::ResultNullptrArgument());
if (max_entries == 0) {
*out_count = 0;
return ResultSuccess();
R_SUCCEED();
}
R_UNLESS(out_entries != nullptr, fs::ResultNullptrArgument());
R_UNLESS(max_entries > 0, fs::ResultInvalidArgument());

View File

@@ -22,6 +22,7 @@
namespace ams::fs::fsa {
/* ACCURATE_TO_VERSION: Unknown */
class IFile;
class IDirectory;
@@ -180,4 +181,7 @@ namespace ams::fs::fsa {
}
};
template<typename T>
concept PointerToFileSystem = ::ams::util::RawOrSmartPointerTo<T, ::ams::fs::fsa::IFileSystem>;
}

View File

@@ -19,6 +19,7 @@
namespace ams::fs::fsa {
/* ACCURATE_TO_VERSION: Unknown */
class ICommonMountNameGenerator {
public:
virtual ~ICommonMountNameGenerator() { /* ... */ }

View File

@@ -23,6 +23,7 @@
namespace ams::fs::impl {
/* ACCURATE_TO_VERSION: Unknown */
enum AccessLogTarget : u32 {
AccessLogTarget_None = (0 << 0),
AccessLogTarget_Application = (1 << 0),

View File

@@ -17,6 +17,8 @@
namespace ams::fs::impl {
/* ACCURATE_TO_VERSION: Unknown */
/* Delimiting of mount names. */
constexpr inline const char ReservedMountNamePrefixCharacter = '@';

View File

@@ -18,6 +18,7 @@
namespace ams::fs::impl {
/* ACCURATE_TO_VERSION: Unknown */
Result QueryMountDataCacheSize(size_t *out, ncm::DataId data_id, ncm::StorageId storage_id);
Result MountData(const char *name, ncm::DataId data_id, ncm::StorageId storage_id);

View File

@@ -18,6 +18,7 @@
namespace ams::fs::impl {
/* ACCURATE_TO_VERSION: Unknown */
enum FileSystemProxyType {
FileSystemProxyType_Code = 0,
FileSystemProxyType_Rom = 1,

View File

@@ -19,6 +19,7 @@
namespace ams::fs::impl {
/* ACCURATE_TO_VERSION: Unknown */
constexpr inline u8 TlsIoPriorityMask = 0x7;
constexpr inline u8 TlsIoRecursiveCallMask = 0x8;

View File

@@ -18,6 +18,7 @@
namespace ams::fs::impl {
/* ACCURATE_TO_VERSION: Unknown */
fssystem::IHash256GeneratorFactorySelector *GetNcaHashGeneratorFactorySelector();
fssystem::IHash256GeneratorFactorySelector *GetSaveDataHashGeneratorFactorySelector();

View File

@@ -18,6 +18,7 @@
namespace ams::fs::impl {
/* ACCURATE_TO_VERSION: Unknown */
class Newable {
public:
static ALWAYS_INLINE void *operator new(size_t size) noexcept {

View File

@@ -20,6 +20,7 @@
namespace ams::fs::impl {
/* ACCURATE_TO_VERSION: Unknown */
enum TlsIoPriority : u8 {
TlsIoPriority_Normal = 0,
TlsIoPriority_Realtime = 1,
@@ -43,10 +44,10 @@ namespace ams::fs::impl {
case PriorityRaw_Realtime: *out = TlsIoPriority_Realtime; break;
case PriorityRaw_Low: *out = TlsIoPriority_Low; break;
case PriorityRaw_Background: *out = TlsIoPriority_Background; break;
default: return fs::ResultInvalidArgument();
default: R_THROW(fs::ResultInvalidArgument());
}
return ResultSuccess();
R_SUCCEED();
}
constexpr inline Result ConvertTlsIoPriorityToFsPriority(PriorityRaw *out, u8 tls_io) {
@@ -57,10 +58,10 @@ namespace ams::fs::impl {
case TlsIoPriority_Realtime: *out = PriorityRaw_Realtime; break;
case TlsIoPriority_Low: *out = PriorityRaw_Low; break;
case TlsIoPriority_Background: *out = PriorityRaw_Background; break;
default: return fs::ResultInvalidArgument();
default: R_THROW(fs::ResultInvalidArgument());
}
return ResultSuccess();
R_SUCCEED();
}
inline u8 GetTlsIoPriority(os::ThreadType *thread) {

View File

@@ -18,6 +18,7 @@
namespace ams::fs::impl {
/* ACCURATE_TO_VERSION: Unknown */
bool IsAbortNeeded(Result result);
void LogErrorMessage(Result result, const char *function);

View File

@@ -14,17 +14,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere.hpp>
#include <stratosphere/fs/fs_common.hpp>
#include <stratosphere/fs/fs_istorage.hpp>
#include <stratosphere/fs/impl/fs_newable.hpp>
namespace ams::fs::impl {
template<typename StorageInterface>
class StorageServiceObjectAdapter : public ::ams::fs::impl::Newable, public ::ams::fs::IStorage {
NON_COPYABLE(StorageServiceObjectAdapter);
NON_MOVEABLE(StorageServiceObjectAdapter);
private:
sf::SharedPointer<fssrv::sf::IStorage> m_x;
sf::SharedPointer<StorageInterface> m_x;
public:
explicit StorageServiceObjectAdapter(sf::SharedPointer<fssrv::sf::IStorage> &&o) : m_x(o) { /* ... */}
explicit StorageServiceObjectAdapter(sf::SharedPointer<StorageInterface> &&o) : m_x(o) { /* ... */}
virtual ~StorageServiceObjectAdapter() { /* ... */ }
public:
virtual Result Read(s64 offset, void *buffer, size_t size) override final {

View File

@@ -19,6 +19,7 @@
namespace ams::fssrv::fscreator {
/* ACCURATE_TO_VERSION: 13.4.0.0 */
class LocalFileSystemCreator final : public ILocalFileSystemCreator {
NON_COPYABLE(LocalFileSystemCreator);
NON_MOVEABLE(LocalFileSystemCreator);

View File

@@ -19,6 +19,7 @@
namespace ams::fssrv::fscreator {
/* ACCURATE_TO_VERSION: Unknown */
class PartitionFileSystemCreator : public IPartitionFileSystemCreator {
NON_COPYABLE(PartitionFileSystemCreator);
NON_MOVEABLE(PartitionFileSystemCreator);

View File

@@ -19,6 +19,7 @@
namespace ams::fssrv::fscreator {
/* ACCURATE_TO_VERSION: Unknown */
class RomFileSystemCreator : public IRomFileSystemCreator {
NON_COPYABLE(RomFileSystemCreator);
NON_MOVEABLE(RomFileSystemCreator);

View File

@@ -19,6 +19,7 @@
namespace ams::fssrv::fscreator {
/* ACCURATE_TO_VERSION: 13.4.0.0 */
class SubDirectoryFileSystemCreator final : public ISubDirectoryFileSystemCreator {
NON_COPYABLE(SubDirectoryFileSystemCreator);
NON_MOVEABLE(SubDirectoryFileSystemCreator);

View File

@@ -35,6 +35,7 @@ namespace ams::fssrv {
class AccessLogServiceImpl;
class DebugConfigurationServiceImpl;
/* ACCURATE_TO_VERSION: Unknown */
struct FileSystemProxyConfiguration {
fscreator::FileSystemCreatorInterfaces *m_fs_creator_interfaces;
BaseStorageServiceImpl *m_base_storage_service_impl;

View File

@@ -30,6 +30,7 @@ namespace ams::fssrv {
class NcaFileSystemService;
class SaveDataFileSystemService;
/* ACCURATE_TO_VERSION: Unknown */
class FileSystemProxyImpl {
NON_COPYABLE(FileSystemProxyImpl);
NON_MOVEABLE(FileSystemProxyImpl);
@@ -147,26 +148,27 @@ namespace ams::fssrv {
static_assert(sf::IsIFileSystemProxy<FileSystemProxyImpl>);
static_assert(sf::IsIFileSystemProxyForLoader<FileSystemProxyImpl>);
/* ACCURATE_TO_VERSION: Unknown */
class InvalidFileSystemProxyImplForLoader {
public:
Result OpenCodeFileSystemDeprecated(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id) {
AMS_UNUSED(out_fs, path, program_id);
return fs::ResultPortAcceptableCountLimited();
R_THROW(fs::ResultPortAcceptableCountLimited());
}
Result OpenCodeFileSystem(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id) {
AMS_UNUSED(out_fs, out_verif, path, program_id);
return fs::ResultPortAcceptableCountLimited();
R_THROW(fs::ResultPortAcceptableCountLimited());
}
Result IsArchivedProgram(ams::sf::Out<bool> out, u64 process_id) {
AMS_UNUSED(out, process_id);
return fs::ResultPortAcceptableCountLimited();
R_THROW(fs::ResultPortAcceptableCountLimited());
}
Result SetCurrentProcess(const ams::sf::ClientProcessId &client_pid) {
AMS_UNUSED(client_pid);
return fs::ResultPortAcceptableCountLimited();
R_THROW(fs::ResultPortAcceptableCountLimited());
}
};
static_assert(sf::IsIFileSystemProxyForLoader<FileSystemProxyImpl>);

View File

@@ -49,18 +49,21 @@ namespace ams::fssystem {
namespace ams::fssrv::fscreator {
/* ACCURATE_TO_VERSION: Unknown */
class IRomFileSystemCreator {
public:
virtual ~IRomFileSystemCreator() { /* ... */ }
virtual Result Create(std::shared_ptr<fs::fsa::IFileSystem> *out, std::shared_ptr<fs::IStorage> storage) = 0;
};
/* ACCURATE_TO_VERSION: Unknown */
class IPartitionFileSystemCreator {
public:
virtual ~IPartitionFileSystemCreator() { /* ... */ }
virtual Result Create(std::shared_ptr<fs::fsa::IFileSystem> *out, std::shared_ptr<fs::IStorage> storage) = 0;
};
/* ACCURATE_TO_VERSION: Unknown */
class IStorageOnNcaCreator {
public:
virtual ~IStorageOnNcaCreator() { /* ... */ }
@@ -69,6 +72,7 @@ namespace ams::fssrv::fscreator {
virtual Result CreateNcaReader(std::shared_ptr<fssystem::NcaReader> *out, std::shared_ptr<fs::IStorage> storage) = 0;
};
/* ACCURATE_TO_VERSION: Unknown */
class ILocalFileSystemCreator {
public:
virtual Result Create(std::shared_ptr<fs::fsa::IFileSystem> *out, const fs::Path &path, bool case_sensitive, bool ensure_root, Result on_path_not_found) = 0;
@@ -78,11 +82,13 @@ namespace ams::fssrv::fscreator {
}
};
/* ACCURATE_TO_VERSION: Unknown */
class ISubDirectoryFileSystemCreator {
public:
virtual Result Create(std::shared_ptr<fs::fsa::IFileSystem> *out, std::shared_ptr<fs::fsa::IFileSystem> base_fs, const fs::Path &path) = 0;
};
/* ACCURATE_TO_VERSION: Unknown */
struct FileSystemCreatorInterfaces {
ILocalFileSystemCreator *local_fs_creator;
ISubDirectoryFileSystemCreator *subdir_fs_creator;

View File

@@ -20,6 +20,7 @@
namespace ams::fssrv {
/* ACCURATE_TO_VERSION: Unknown */
class MemoryResourceFromExpHeap : public ams::MemoryResource {
private:
lmem::HeapHandle m_heap_handle;
@@ -41,6 +42,7 @@ namespace ams::fssrv {
}
};
/* ACCURATE_TO_VERSION: Unknown */
class PeakCheckableMemoryResourceFromExpHeap : public ams::MemoryResource {
private:
lmem::HeapHandle m_heap_handle;

View File

@@ -25,6 +25,7 @@ namespace ams::mem {
namespace ams::fssrv {
/* ACCURATE_TO_VERSION: Unknown */
class MemoryResourceFromStandardAllocator : public ams::MemoryResource {
private:
mem::StandardAllocator *m_allocator;

View File

@@ -47,6 +47,7 @@ namespace ams::fssrv {
}
/* ACCURATE_TO_VERSION: Unknown */
class NcaFileSystemServiceImpl {
public:
struct Configuration {

View File

@@ -27,6 +27,7 @@ namespace ams::fssrv {
}
/* ACCURATE_TO_VERSION: Unknown */
class ProgramRegistryImpl {
NON_COPYABLE(ProgramRegistryImpl);
NON_MOVEABLE(ProgramRegistryImpl);
@@ -45,26 +46,27 @@ namespace ams::fssrv {
};
static_assert(sf::IsIProgramRegistry<ProgramRegistryImpl>);
/* ACCURATE_TO_VERSION: Unknown */
class InvalidProgramRegistryImpl {
public:
Result RegisterProgram(u64 process_id, u64 program_id, u8 storage_id, const ams::sf::InBuffer &data, s64 data_size, const ams::sf::InBuffer &desc, s64 desc_size) {
AMS_UNUSED(process_id, program_id, storage_id, data, data_size, desc, desc_size);
return fs::ResultPortAcceptableCountLimited();
R_THROW(fs::ResultPortAcceptableCountLimited());
}
Result UnregisterProgram(u64 process_id) {
AMS_UNUSED(process_id);
return fs::ResultPortAcceptableCountLimited();
R_THROW(fs::ResultPortAcceptableCountLimited());
}
Result SetCurrentProcess(const ams::sf::ClientProcessId &client_pid) {
AMS_UNUSED(client_pid);
return fs::ResultPortAcceptableCountLimited();
R_THROW(fs::ResultPortAcceptableCountLimited());
}
Result SetEnabledProgramVerification(bool en) {
AMS_UNUSED(en);
return fs::ResultPortAcceptableCountLimited();
R_THROW(fs::ResultPortAcceptableCountLimited());
}
};
static_assert(sf::IsIProgramRegistry<InvalidProgramRegistryImpl>);

View File

@@ -27,6 +27,7 @@ namespace ams::fssrv {
}
/* ACCURATE_TO_VERSION: Unknown */
class ProgramRegistryServiceImpl {
public:
struct Configuration {

View File

@@ -28,6 +28,7 @@ namespace ams::fssrv {
namespace ams::fssrv::impl {
/* ACCURATE_TO_VERSION: 13.4.0.0 */
struct Accessibility {
u8 value;
@@ -60,6 +61,7 @@ namespace ams::fssrv::impl {
Accessibility GetAccessibility() const { return m_accessibility; }
};
/* ACCURATE_TO_VERSION: 13.4.0.0 */
class AccessControl {
public:
enum class AccessibilityType : u32 {

View File

@@ -21,6 +21,7 @@
namespace ams::fssrv::impl {
/* ACCURATE_TO_VERSION: 13.4.0.0 */
#define AMS_FSSRV_FOR_EACH_ACCESS_CONTROL_CAPABILITY(HANDLER, _NS_) \
HANDLER(CanAbandonAccessFailure, _NS_::AccessFailureResolution) \
HANDLER(CanChallengeCardExistence, _NS_::GameCard) \
@@ -179,6 +180,7 @@ namespace ams::fssrv::impl {
HANDLER(CanWriteSaveDataFileSystemExtraDataFlags, _NS_::SaveDataTransferVersion2, _NS_::SystemSaveDataManagement, _NS_::SaveDataBackUp) \
HANDLER(CanWriteSaveDataFileSystemExtraDataTimeStamp, _NS_::SaveDataBackUp)
/* ACCURATE_TO_VERSION: 13.4.0.0 */
class AccessControlBits {
public:
enum class Bits : u64 {

View File

@@ -22,6 +22,7 @@
namespace ams::fssrv::impl {
/* ACCURATE_TO_VERSION: 13.4.0.0 */
class ExternalKeyEntry : public util::IntrusiveListBaseNode<ExternalKeyEntry>, public ::ams::fs::impl::Newable {
private:
fs::RightsId m_rights_id;
@@ -48,6 +49,7 @@ namespace ams::fssrv::impl {
}
};
/* ACCURATE_TO_VERSION: 13.4.0.0 */
class ExternalKeyManager {
NON_COPYABLE(ExternalKeyManager);
NON_MOVEABLE(ExternalKeyManager);

View File

@@ -22,6 +22,7 @@
namespace ams::fssrv::impl {
/* ACCURATE_TO_VERSION: 13.4.0.0 */
ams::sf::EmplacedRef<fssrv::sf::IFileSystemProxy, fssrv::FileSystemProxyImpl> GetFileSystemProxyServiceObject();
ams::sf::SharedPointer<fssrv::sf::IProgramRegistry> GetProgramRegistryServiceObject();

View File

@@ -22,12 +22,14 @@
namespace ams::fssrv::impl {
/* ACCURATE_TO_VERSION: 13.4.0.0 */
struct ProgramIndexMapInfoEntry : public ::ams::util::IntrusiveListBaseNode<ProgramIndexMapInfoEntry>, public ::ams::fs::impl::Newable {
ncm::ProgramId program_id;
ncm::ProgramId base_program_id;
u8 program_index;
};
/* ACCURATE_TO_VERSION: 13.4.0.0 */
class ProgramIndexMapInfoManager {
NON_COPYABLE(ProgramIndexMapInfoManager);
NON_MOVEABLE(ProgramIndexMapInfoManager);

View File

@@ -37,6 +37,7 @@ namespace ams::fssrv::impl {
class FileSystemInterfaceAdapter;
/* ACCURATE_TO_VERSION: 13.4.0.0 */
class FileInterfaceAdapter {
NON_COPYABLE(FileInterfaceAdapter);
NON_MOVEABLE(FileInterfaceAdapter);
@@ -60,6 +61,7 @@ namespace ams::fssrv::impl {
};
static_assert(fssrv::sf::IsIFile<FileInterfaceAdapter>);
/* ACCURATE_TO_VERSION: 13.4.0.0 */
class DirectoryInterfaceAdapter {
NON_COPYABLE(DirectoryInterfaceAdapter);
NON_MOVEABLE(DirectoryInterfaceAdapter);
@@ -76,6 +78,7 @@ namespace ams::fssrv::impl {
};
static_assert(fssrv::sf::IsIDirectory<DirectoryInterfaceAdapter>);
/* ACCURATE_TO_VERSION: 13.4.0.0 */
class FileSystemInterfaceAdapter : public ams::sf::ISharedObject {
NON_COPYABLE(FileSystemInterfaceAdapter);
NON_MOVEABLE(FileSystemInterfaceAdapter);
@@ -117,7 +120,7 @@ namespace ams::fssrv::impl {
Result CleanDirectoryRecursively(const fssrv::sf::Path &path);
Result GetFileTimeStampRaw(ams::sf::Out<fs::FileTimeStampRaw> out, const fssrv::sf::Path &path);
Result QueryEntry(const ams::sf::OutBuffer &out_buf, const ams::sf::InBuffer &in_buf, s32 query_id, const fssrv::sf::Path &path);
Result QueryEntry(const ams::sf::OutNonSecureBuffer &out_buf, const ams::sf::InNonSecureBuffer &in_buf, s32 query_id, const fssrv::sf::Path &path);
};
#if defined(ATMOSPHERE_OS_HORIZON)
@@ -132,28 +135,28 @@ namespace ams::fssrv::impl {
virtual ~RemoteFile() { fsFileClose(std::addressof(m_base_file)); }
public:
Result Read(ams::sf::Out<s64> out, s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size, fs::ReadOption option) {
return fsFileRead(std::addressof(m_base_file), offset, buffer.GetPointer(), size, option._value, reinterpret_cast<u64 *>(out.GetPointer()));
R_RETURN(fsFileRead(std::addressof(m_base_file), offset, buffer.GetPointer(), size, option._value, reinterpret_cast<u64 *>(out.GetPointer())));
}
Result Write(s64 offset, const ams::sf::InNonSecureBuffer &buffer, s64 size, fs::WriteOption option) {
return fsFileWrite(std::addressof(m_base_file), offset, buffer.GetPointer(), size, option._value);
R_RETURN(fsFileWrite(std::addressof(m_base_file), offset, buffer.GetPointer(), size, option._value));
}
Result Flush(){
return fsFileFlush(std::addressof(m_base_file));
R_RETURN(fsFileFlush(std::addressof(m_base_file)));
}
Result SetSize(s64 size) {
return fsFileSetSize(std::addressof(m_base_file), size);
R_RETURN(fsFileSetSize(std::addressof(m_base_file), size));
}
Result GetSize(ams::sf::Out<s64> out) {
return fsFileGetSize(std::addressof(m_base_file), out.GetPointer());
R_RETURN(fsFileGetSize(std::addressof(m_base_file), out.GetPointer()));
}
Result OperateRange(ams::sf::Out<fs::FileQueryRangeInfo> out, s32 op_id, s64 offset, s64 size) {
static_assert(sizeof(::FsRangeInfo) == sizeof(fs::FileQueryRangeInfo));
return fsFileOperateRange(std::addressof(m_base_file), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(out.GetPointer()));
R_RETURN(fsFileOperateRange(std::addressof(m_base_file), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(out.GetPointer())));
}
Result OperateRangeWithBuffer(const ams::sf::OutNonSecureBuffer &out_buf, const ams::sf::InNonSecureBuffer &in_buf, s32 op_id, s64 offset, s64 size) {
@@ -175,11 +178,11 @@ namespace ams::fssrv::impl {
public:
Result Read(ams::sf::Out<s64> out, const ams::sf::OutBuffer &out_entries) {
static_assert(sizeof(::FsDirectoryEntry) == sizeof(fs::DirectoryEntry));
return fsDirRead(std::addressof(m_base_dir), out.GetPointer(), out_entries.GetSize() / sizeof(fs::DirectoryEntry), reinterpret_cast<::FsDirectoryEntry *>(out_entries.GetPointer()));
R_RETURN(fsDirRead(std::addressof(m_base_dir), out.GetPointer(), out_entries.GetSize() / sizeof(fs::DirectoryEntry), reinterpret_cast<::FsDirectoryEntry *>(out_entries.GetPointer())));
}
Result GetEntryCount(ams::sf::Out<s64> out) {
return fsDirGetEntryCount(std::addressof(m_base_dir), out.GetPointer());
R_RETURN(fsDirGetEntryCount(std::addressof(m_base_dir), out.GetPointer()));
}
};
static_assert(fssrv::sf::IsIDirectory<RemoteDirectory>);
@@ -196,61 +199,61 @@ namespace ams::fssrv::impl {
public:
/* Command API. */
Result CreateFile(const fssrv::sf::Path &path, s64 size, s32 option) {
return fsFsCreateFile(std::addressof(m_base_fs), path.str, size, option);
R_RETURN(fsFsCreateFile(std::addressof(m_base_fs), path.str, size, option));
}
Result DeleteFile(const fssrv::sf::Path &path) {
return fsFsDeleteFile(std::addressof(m_base_fs), path.str);
R_RETURN(fsFsDeleteFile(std::addressof(m_base_fs), path.str));
}
Result CreateDirectory(const fssrv::sf::Path &path) {
return fsFsCreateDirectory(std::addressof(m_base_fs), path.str);
R_RETURN(fsFsCreateDirectory(std::addressof(m_base_fs), path.str));
}
Result DeleteDirectory(const fssrv::sf::Path &path) {
return fsFsDeleteDirectory(std::addressof(m_base_fs), path.str);
R_RETURN(fsFsDeleteDirectory(std::addressof(m_base_fs), path.str));
}
Result DeleteDirectoryRecursively(const fssrv::sf::Path &path) {
return fsFsDeleteDirectoryRecursively(std::addressof(m_base_fs), path.str);
R_RETURN(fsFsDeleteDirectoryRecursively(std::addressof(m_base_fs), path.str));
}
Result RenameFile(const fssrv::sf::Path &old_path, const fssrv::sf::Path &new_path) {
return fsFsRenameFile(std::addressof(m_base_fs), old_path.str, new_path.str);
R_RETURN(fsFsRenameFile(std::addressof(m_base_fs), old_path.str, new_path.str));
}
Result RenameDirectory(const fssrv::sf::Path &old_path, const fssrv::sf::Path &new_path) {
return fsFsRenameDirectory(std::addressof(m_base_fs), old_path.str, new_path.str);
R_RETURN(fsFsRenameDirectory(std::addressof(m_base_fs), old_path.str, new_path.str));
}
Result GetEntryType(ams::sf::Out<u32> out, const fssrv::sf::Path &path) {
static_assert(sizeof(::FsDirEntryType) == sizeof(u32));
return fsFsGetEntryType(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsDirEntryType *>(out.GetPointer()));
R_RETURN(fsFsGetEntryType(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsDirEntryType *>(out.GetPointer())));
}
Result Commit() {
return fsFsCommit(std::addressof(m_base_fs));
R_RETURN(fsFsCommit(std::addressof(m_base_fs)));
}
Result GetFreeSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path) {
return fsFsGetFreeSpace(std::addressof(m_base_fs), path.str, out.GetPointer());
R_RETURN(fsFsGetFreeSpace(std::addressof(m_base_fs), path.str, out.GetPointer()));
}
Result GetTotalSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path) {
return fsFsGetTotalSpace(std::addressof(m_base_fs), path.str, out.GetPointer());
R_RETURN(fsFsGetTotalSpace(std::addressof(m_base_fs), path.str, out.GetPointer()));
}
Result CleanDirectoryRecursively(const fssrv::sf::Path &path) {
return fsFsCleanDirectoryRecursively(std::addressof(m_base_fs), path.str);
R_RETURN(fsFsCleanDirectoryRecursively(std::addressof(m_base_fs), path.str));
}
Result GetFileTimeStampRaw(ams::sf::Out<fs::FileTimeStampRaw> out, const fssrv::sf::Path &path) {
static_assert(sizeof(fs::FileTimeStampRaw) == sizeof(::FsTimeStampRaw));
return fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsTimeStampRaw *>(out.GetPointer()));
R_RETURN(fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsTimeStampRaw *>(out.GetPointer())));
}
Result QueryEntry(const ams::sf::OutBuffer &out_buf, const ams::sf::InBuffer &in_buf, s32 query_id, const fssrv::sf::Path &path) {
return fsFsQueryEntry(std::addressof(m_base_fs), out_buf.GetPointer(), out_buf.GetSize(), in_buf.GetPointer(), in_buf.GetSize(), path.str, static_cast<FsFileSystemQueryId>(query_id));
Result QueryEntry(const ams::sf::OutNonSecureBuffer &out_buf, const ams::sf::InNonSecureBuffer &in_buf, s32 query_id, const fssrv::sf::Path &path) {
R_RETURN(fsFsQueryEntry(std::addressof(m_base_fs), out_buf.GetPointer(), out_buf.GetSize(), in_buf.GetPointer(), in_buf.GetSize(), path.str, static_cast<FsFileSystemQueryId>(query_id)));
}
Result OpenFile(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFile>> out, const fssrv::sf::Path &path, u32 mode);

View File

@@ -27,6 +27,7 @@ namespace ams::fs {
namespace ams::fssrv::impl {
/* ACCURATE_TO_VERSION: 13.4.0.0 */
class StorageInterfaceAdapter {
NON_COPYABLE(StorageInterfaceAdapter);
private:
@@ -56,28 +57,28 @@ namespace ams::fssrv::impl {
virtual ~RemoteStorage() { fsStorageClose(std::addressof(m_base_storage)); }
public:
Result Read(s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size) {
return fsStorageRead(std::addressof(m_base_storage), offset, buffer.GetPointer(), size);
R_RETURN(fsStorageRead(std::addressof(m_base_storage), offset, buffer.GetPointer(), size));
}
Result Write(s64 offset, const ams::sf::InNonSecureBuffer &buffer, s64 size) {
return fsStorageWrite(std::addressof(m_base_storage), offset, buffer.GetPointer(), size);
R_RETURN(fsStorageWrite(std::addressof(m_base_storage), offset, buffer.GetPointer(), size));
}
Result Flush(){
return fsStorageFlush(std::addressof(m_base_storage));
R_RETURN(fsStorageFlush(std::addressof(m_base_storage)));
}
Result SetSize(s64 size) {
return fsStorageSetSize(std::addressof(m_base_storage), size);
R_RETURN(fsStorageSetSize(std::addressof(m_base_storage), size));
}
Result GetSize(ams::sf::Out<s64> out) {
return fsStorageGetSize(std::addressof(m_base_storage), out.GetPointer());
R_RETURN(fsStorageGetSize(std::addressof(m_base_storage), out.GetPointer()));
}
Result OperateRange(ams::sf::Out<fs::StorageQueryRangeInfo> out, s32 op_id, s64 offset, s64 size) {
static_assert(sizeof(::FsRangeInfo) == sizeof(fs::StorageQueryRangeInfo));
return fsStorageOperateRange(std::addressof(m_base_storage), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(out.GetPointer()));
R_RETURN(fsStorageOperateRange(std::addressof(m_base_storage), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(out.GetPointer())));
}
};
static_assert(fssrv::sf::IsIStorage<RemoteStorage>);

View File

@@ -18,6 +18,7 @@
#include <stratosphere/sf.hpp>
/* TODO */
/* ACCURATE_TO_VERSION: 13.4.0.0 */
#define AMS_FSSRV_I_DEVICE_OPERATOR_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 0, Result, IsSdCardInserted, (ams::sf::Out<bool> out), (out)) \
AMS_SF_METHOD_INFO(C, H, 200, Result, IsGameCardInserted, (ams::sf::Out<bool> out), (out)) \

Some files were not shown because too many files have changed in this diff Show More