Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
070d2786c6 | ||
|
|
efa4a346af | ||
|
|
d75f9bbedf | ||
|
|
ea7f51a279 | ||
|
|
a65b6df8d2 | ||
|
|
4e112de223 | ||
|
|
20d200471d | ||
|
|
5f2d713fe4 | ||
|
|
114d2598da | ||
|
|
36bdb83cfc | ||
|
|
a975689c59 | ||
|
|
a809e23320 | ||
|
|
4db485083b | ||
|
|
e96972c939 | ||
|
|
3545c0aac2 | ||
|
|
d85875b910 | ||
|
|
b1367942a2 | ||
|
|
c2c0a2e169 | ||
|
|
f5052b4bca | ||
|
|
70d67bb115 | ||
|
|
9056e0b05f | ||
|
|
895b6d0470 | ||
|
|
dfba595cdc | ||
|
|
175a34da43 | ||
|
|
02b126c2be | ||
|
|
b45671fd35 | ||
|
|
106599895d | ||
|
|
80154b0a54 | ||
|
|
62eb4d6989 | ||
|
|
b52e44e798 | ||
|
|
72baa4ff18 | ||
|
|
442656899f | ||
|
|
d7f89a0c31 | ||
|
|
2e6223d9d0 | ||
|
|
28f11a86fd | ||
|
|
a8b52dc123 | ||
|
|
9b47ddf01f | ||
|
|
0fbf007bcf | ||
|
|
4ad8dad416 | ||
|
|
8e258bde9d | ||
|
|
c0d5140ef0 | ||
|
|
1bef1b58d4 | ||
|
|
07cd682460 | ||
|
|
e5c3d264ec | ||
|
|
bbf22b4c60 | ||
|
|
dd78ede99f | ||
|
|
e5b1739f65 | ||
|
|
a4a2cc2218 | ||
|
|
5ffbed1bee | ||
|
|
ec44eaa263 | ||
|
|
20e53fcd82 | ||
|
|
64c6ef2de7 | ||
|
|
817ad8f98d | ||
|
|
dfa475a769 | ||
|
|
141ae5c7ab | ||
|
|
4646581e93 | ||
|
|
b69fa13576 |
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace ams::kern {
|
||||
s32 new_value;
|
||||
if (count <= 0) {
|
||||
if ((it != m_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
||||
new_value = value - 2;
|
||||
new_value = value - 1;
|
||||
} else {
|
||||
new_value = value + 1;
|
||||
}
|
||||
@@ -132,7 +132,7 @@ namespace ams::kern {
|
||||
auto tmp_it = it;
|
||||
s32 tmp_num_waiters = 0;
|
||||
while ((++tmp_it != m_tree.end()) && (tmp_it->GetAddressArbiterKey() == addr)) {
|
||||
if ((tmp_num_waiters++) >= count) {
|
||||
if ((++tmp_num_waiters) >= count) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||
class DirectoryPathParser {
|
||||
NON_COPYABLE(DirectoryPathParser);
|
||||
NON_MOVEABLE(DirectoryPathParser);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
enum AccessLogMode : u32 {
|
||||
AccessLogMode_None = 0,
|
||||
AccessLogMode_Log = 1,
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
void InitializeForSystem();
|
||||
void InitializeWithMultiSessionForSystem();
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
Result MountApplicationPackage(const char *name, const char *common_path);
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
enum class BisPartitionId {
|
||||
/* Boot0 */
|
||||
BootPartition1Root = 0,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
struct Int64 {
|
||||
u32 low;
|
||||
u32 high;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum ContentType {
|
||||
ContentType_Meta = 0,
|
||||
ContentType_Control = 1,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum class ContentStorageId : u32 {
|
||||
System = 0,
|
||||
User = 1,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
constexpr inline size_t EntryNameLengthMax = 0x300;
|
||||
|
||||
struct DirectoryEntry {
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace ams::fs {
|
||||
|
||||
namespace fsa {
|
||||
|
||||
class IFile;
|
||||
class IFileSystem;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
struct FileTimeStamp {
|
||||
time::PosixTime create;
|
||||
time::PosixTime modify;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum class GameCardPartition {
|
||||
Update = 0,
|
||||
Normal = 1,
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum MountHostOptionFlag : u32 {
|
||||
MountHostOptionFlag_None = (0 << 0),
|
||||
MountHostOptionFlag_PseudoCaseSensitive = (1 << 0),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum class ImageDirectoryId {
|
||||
Nand = 0,
|
||||
SdCard = 1,
|
||||
|
||||
@@ -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>;
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum class OperationId : s64 {
|
||||
FillZero = 0,
|
||||
DestroySignature = 1,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum Priority {
|
||||
Priority_Realtime = 0,
|
||||
Priority_Normal = 1,
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
struct ProgramIndexMapInfo {
|
||||
ncm::ProgramId program_id;
|
||||
ncm::ProgramId base_program_id;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
struct QueryRangeInfo {
|
||||
s32 aes_ctr_key_type;
|
||||
s32 speed_emulation_type;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
void SetEnabledAutoAbort(bool enabled);
|
||||
void SetResultHandledByApplication(bool application);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
union RightsId {
|
||||
u8 data[0x10];
|
||||
u64 data64[2];
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class RomFsFileSystem : public fsa::IFileSystem, public impl::Newable {
|
||||
NON_COPYABLE(RomFsFileSystem);
|
||||
public:
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
Result DeleteSaveData(SaveDataId id);
|
||||
Result DeleteSaveData(SaveDataSpaceId space_id, SaveDataId id);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
Result CommitSaveData(const char *path);
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
using SaveDataId = u64;
|
||||
using SystemSaveDataId = u64;
|
||||
using SystemBcatSaveDataId = SystemSaveDataId;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class IEventNotifier;
|
||||
|
||||
struct EncryptionSeed {
|
||||
|
||||
@@ -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(); }
|
||||
};
|
||||
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
bool IsSignedSystemPartitionOnSdCardValid(const char *system_root_path);
|
||||
bool IsSignedSystemPartitionOnSdCardValidDeprecated();
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum class SpeedEmulationMode {
|
||||
None = 0,
|
||||
Faster = 1,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum StorageType : s32 {
|
||||
StorageType_SaveData = 0,
|
||||
StorageType_RomFs = 1,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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>;
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class ICommonMountNameGenerator {
|
||||
public:
|
||||
virtual ~ICommonMountNameGenerator() { /* ... */ }
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum AccessLogTarget : u32 {
|
||||
AccessLogTarget_None = (0 << 0),
|
||||
AccessLogTarget_Application = (1 << 0),
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
/* Delimiting of mount names. */
|
||||
constexpr inline const char ReservedMountNamePrefixCharacter = '@';
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum FileSystemProxyType {
|
||||
FileSystemProxyType_Code = 0,
|
||||
FileSystemProxyType_Rom = 1,
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
constexpr inline u8 TlsIoPriorityMask = 0x7;
|
||||
constexpr inline u8 TlsIoRecursiveCallMask = 0x8;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
fssystem::IHash256GeneratorFactorySelector *GetNcaHashGeneratorFactorySelector();
|
||||
fssystem::IHash256GeneratorFactorySelector *GetSaveDataHashGeneratorFactorySelector();
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
bool IsAbortNeeded(Result result);
|
||||
void LogErrorMessage(Result result, const char *function);
|
||||
|
||||
|
||||
@@ -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 {
|
||||
@@ -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);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
namespace ams::fssrv::fscreator {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class PartitionFileSystemCreator : public IPartitionFileSystemCreator {
|
||||
NON_COPYABLE(PartitionFileSystemCreator);
|
||||
NON_MOVEABLE(PartitionFileSystemCreator);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
namespace ams::fssrv::fscreator {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class RomFileSystemCreator : public IRomFileSystemCreator {
|
||||
NON_COPYABLE(RomFileSystemCreator);
|
||||
NON_MOVEABLE(RomFileSystemCreator);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace ams::mem {
|
||||
|
||||
namespace ams::fssrv {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class MemoryResourceFromStandardAllocator : public ams::MemoryResource {
|
||||
private:
|
||||
mem::StandardAllocator *m_allocator;
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace ams::fssrv {
|
||||
|
||||
}
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class NcaFileSystemServiceImpl {
|
||||
public:
|
||||
struct Configuration {
|
||||
|
||||
@@ -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>);
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace ams::fssrv {
|
||||
|
||||
}
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class ProgramRegistryServiceImpl {
|
||||
public:
|
||||
struct Configuration {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user