Compare commits
41 Commits
revision
...
1400_suppo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
003f369238 | ||
|
|
56050a2195 | ||
|
|
e15bcc10a8 | ||
|
|
caf0be85fa | ||
|
|
8c955587f4 | ||
|
|
253ce776cb | ||
|
|
bec0c7ec2f | ||
|
|
ae09c45f6b | ||
|
|
059a005647 | ||
|
|
b7091df796 | ||
|
|
bb0be4de8e | ||
|
|
7454507467 | ||
|
|
79dbc22cb2 | ||
|
|
0896d47a92 | ||
|
|
4288b12f37 | ||
|
|
599c4ebf42 | ||
|
|
abede65264 | ||
|
|
fee7a4b774 | ||
|
|
a39448905a | ||
|
|
29a53bc572 | ||
|
|
262a066c8c | ||
|
|
de6d8d4ab4 | ||
|
|
dc7184c01f | ||
|
|
b428e77c16 | ||
|
|
30ff0254a4 | ||
|
|
c04ebf10a0 | ||
|
|
f466f9e825 | ||
|
|
7498958a06 | ||
|
|
f804793fdf | ||
|
|
0a81889967 | ||
|
|
cd83a3bd08 | ||
|
|
11e3d4a620 | ||
|
|
c593b1be89 | ||
|
|
36ab24f93a | ||
|
|
41e2c24101 | ||
|
|
b06ada6ac8 | ||
|
|
b2413b7464 | ||
|
|
fa330deeba | ||
|
|
df1b133bc7 | ||
|
|
40601cc74c | ||
|
|
9acf48ba5f |
@@ -1,17 +1,4 @@
|
||||
# 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.
|
||||
@@ -28,10 +15,9 @@
|
||||
+ If you are a developer interested in adding support for another target, please reach out to `SciresM#0524` on discord.
|
||||
+ This is intended to finally allow sanely testing Atmosphère's code, by allowing most of it to run on a PC (with access to a debugger) instead of on game console hardware.
|
||||
+ In addition, this will allow making PC tools which reuse code written for Atmosphère directly..
|
||||
+ **Please Note**: This has no relation to interacting with official software on PC whatsoever. This really allows for making tests and self-contained atmosphère-based command-line tools; the Atmosphère project continues to have zero interest in attempting to run official software of any kind.
|
||||
+ In the course of adding this support (and working on tooling using it), a number of fairly major revisions were made to stratosphere (particularly surrounding filesystem code).
|
||||
+ **Please Note**: A number of changes made for this (and ones necessary in the process of adding support for 14.0.0) are api-breaking.
|
||||
+ If you're a developer and any of this caused your code to break, please feel free to contact `SciresM#0524` for help updating your program.
|
||||
+ **Please Note**: This has no relation to interacting with official software on PC whatsoever. This does not and is not intended to enable anything with official software, it only really allows for making tests and self-contained atmosphère-based tools.
|
||||
+ In the course of adding this support (and working on tooling using it), a number of major revisions were added to stratosphere:
|
||||
+
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.2.6
|
||||
+ Support was added for 13.2.1.
|
||||
|
||||
6
emummc/.gitrepo
vendored
6
emummc/.gitrepo
vendored
@@ -4,9 +4,9 @@
|
||||
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||
;
|
||||
[subrepo]
|
||||
remote = https://github.com/m4xw/emummc
|
||||
remote = https://github.com/m4xw/emuMMC
|
||||
branch = develop
|
||||
commit = 56a2e8a2078944d9bf8daead237036254bb6e36d
|
||||
parent = 4f763b2aa401ac3e3d699ec8c866ae9b3c8fb28d
|
||||
commit = a9d56959460fc794ce2cb6405402c25a3e89c47f
|
||||
parent = ff719641396c635b735873fb2b020c910f768a04
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
|
||||
28
emummc/source/nx/cache.s
vendored
28
emummc/source/nx/cache.s
vendored
@@ -27,10 +27,6 @@ CODE_BEGIN armDCacheFlush
|
||||
bic x8, x0, x10
|
||||
mov x10, x1
|
||||
|
||||
mov w1, #1
|
||||
mrs x0, tpidrro_el0
|
||||
strb w1, [x0, #0x104]
|
||||
|
||||
armDCacheFlush_L0:
|
||||
dc civac, x8
|
||||
add x8, x8, x9
|
||||
@@ -38,9 +34,6 @@ armDCacheFlush_L0:
|
||||
bcc armDCacheFlush_L0
|
||||
|
||||
dsb sy
|
||||
|
||||
strb wzr, [x0, #0x104]
|
||||
|
||||
ret
|
||||
CODE_END
|
||||
|
||||
@@ -55,10 +48,6 @@ CODE_BEGIN armDCacheClean
|
||||
bic x8, x0, x10
|
||||
mov x10, x1
|
||||
|
||||
mov w1, #1
|
||||
mrs x0, tpidrro_el0
|
||||
strb w1, [x0, #0x104]
|
||||
|
||||
armDCacheClean_L0:
|
||||
dc cvac, x8
|
||||
add x8, x8, x9
|
||||
@@ -66,9 +55,6 @@ armDCacheClean_L0:
|
||||
bcc armDCacheClean_L0
|
||||
|
||||
dsb sy
|
||||
|
||||
strb wzr, [x0, #0x104]
|
||||
|
||||
ret
|
||||
CODE_END
|
||||
|
||||
@@ -82,10 +68,6 @@ CODE_BEGIN armICacheInvalidate
|
||||
bic x8, x0, x10
|
||||
mov x10, x1
|
||||
|
||||
mov w1, #1
|
||||
mrs x0, tpidrro_el0
|
||||
strb w1, [x0, #0x104]
|
||||
|
||||
armICacheInvalidate_L0:
|
||||
ic ivau, x8
|
||||
add x8, x8, x9
|
||||
@@ -93,9 +75,6 @@ armICacheInvalidate_L0:
|
||||
bcc armICacheInvalidate_L0
|
||||
|
||||
dsb sy
|
||||
|
||||
strb wzr, [x0, #0x104]
|
||||
|
||||
ret
|
||||
CODE_END
|
||||
|
||||
@@ -110,10 +89,6 @@ CODE_BEGIN armDCacheZero
|
||||
bic x8, x0, x10
|
||||
mov x10, x1
|
||||
|
||||
mov w1, #1
|
||||
mrs x0, tpidrro_el0
|
||||
strb w1, [x0, #0x104]
|
||||
|
||||
armDCacheZero_L0:
|
||||
dc zva, x8
|
||||
add x8, x8, x9
|
||||
@@ -121,8 +96,5 @@ armDCacheZero_L0:
|
||||
bcc armDCacheZero_L0
|
||||
|
||||
dsb sy
|
||||
|
||||
strb wzr, [x0, #0x104]
|
||||
|
||||
ret
|
||||
CODE_END
|
||||
|
||||
@@ -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));
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,11 +48,11 @@ namespace ams::secmon::fatal {
|
||||
//sdmmc::Deactivate(Port);
|
||||
R_TRY(sdmmc::Activate(Port));
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result CheckSdCardConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
|
||||
R_RETURN(sdmmc::CheckSdCardConnection(out_sm, out_bw, Port));
|
||||
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;
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,45 +34,45 @@ namespace ams::fs {
|
||||
Result TranslateFatFsError(FRESULT res) {
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
case FR_DISK_ERR:
|
||||
R_THROW(fs::ResultMmcAccessFailed());
|
||||
return fs::ResultMmcAccessFailed();
|
||||
case FR_INT_ERR:
|
||||
R_THROW(fs::ResultPreconditionViolation());
|
||||
return fs::ResultPreconditionViolation();
|
||||
case FR_NOT_READY:
|
||||
R_THROW(fs::ResultMmcAccessFailed());
|
||||
return fs::ResultMmcAccessFailed();
|
||||
case FR_NO_FILE:
|
||||
R_THROW(fs::ResultPathNotFound());
|
||||
return fs::ResultPathNotFound();
|
||||
case FR_NO_PATH:
|
||||
R_THROW(fs::ResultPathNotFound());
|
||||
return fs::ResultPathNotFound();
|
||||
case FR_INVALID_NAME:
|
||||
R_THROW(fs::ResultInvalidPath());
|
||||
return fs::ResultInvalidPath();
|
||||
case FR_DENIED:
|
||||
R_THROW(fs::ResultPermissionDenied());
|
||||
return fs::ResultPermissionDenied();
|
||||
case FR_EXIST:
|
||||
R_THROW(fs::ResultPathAlreadyExists());
|
||||
return fs::ResultPathAlreadyExists();
|
||||
case FR_INVALID_OBJECT:
|
||||
R_THROW(fs::ResultInvalidArgument());
|
||||
return fs::ResultInvalidArgument();
|
||||
case FR_WRITE_PROTECTED:
|
||||
R_THROW(fs::ResultWriteNotPermitted());
|
||||
return fs::ResultWriteNotPermitted();
|
||||
case FR_INVALID_DRIVE:
|
||||
R_THROW(fs::ResultInvalidMountName());
|
||||
return fs::ResultInvalidMountName();
|
||||
case FR_NOT_ENABLED:
|
||||
R_THROW(fs::ResultInvalidMountName()); /* BAD/TODO */
|
||||
return fs::ResultInvalidMountName(); /* BAD/TODO */
|
||||
case FR_NO_FILESYSTEM:
|
||||
R_THROW(fs::ResultInvalidMountName()); /* BAD/TODO */
|
||||
return fs::ResultInvalidMountName(); /* BAD/TODO */
|
||||
case FR_TIMEOUT:
|
||||
R_THROW(fs::ResultTargetLocked()); /* BAD/TODO */
|
||||
return fs::ResultTargetLocked(); /* BAD/TODO */
|
||||
case FR_LOCKED:
|
||||
R_THROW(fs::ResultTargetLocked());
|
||||
return fs::ResultTargetLocked();
|
||||
case FR_NOT_ENOUGH_CORE:
|
||||
R_THROW(fs::ResultPreconditionViolation()); /* BAD/TODO */
|
||||
return fs::ResultPreconditionViolation(); /* BAD/TODO */
|
||||
case FR_TOO_MANY_OPEN_FILES:
|
||||
R_THROW(fs::ResultPreconditionViolation()); /* BAD/TODO */
|
||||
return fs::ResultPreconditionViolation(); /* BAD/TODO */
|
||||
case FR_INVALID_PARAMETER:
|
||||
R_THROW(fs::ResultInvalidArgument());
|
||||
return fs::ResultInvalidArgument();
|
||||
default:
|
||||
R_THROW(fs::ResultInternal());
|
||||
return fs::ResultInternal();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,11 +125,11 @@ namespace ams::fs {
|
||||
/* Expand the file. */
|
||||
R_TRY(TranslateFatFsError(f_expand(std::addressof(fp), size, 1)));
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result CreateDirectory(const char *path) {
|
||||
R_RETURN(TranslateFatFsError(f_mkdir(path)));
|
||||
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;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
R_THROW(fs::ResultOpenCountLimit());
|
||||
return 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());
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||
R_RETURN(ReadFile(handle, offset, buffer, size, fs::ReadOption::None));
|
||||
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;
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||
R_RETURN(ReadFile(out, handle, offset, buffer, size, fs::ReadOption::None));
|
||||
return ReadFile(out, handle, offset, buffer, size, fs::ReadOption::None);
|
||||
}
|
||||
|
||||
Result GetFileSize(s64 *out, FileHandle handle) {
|
||||
FIL *fp = GetInternalFile(handle);
|
||||
*out = f_size(fp);
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FlushFile(FileHandle handle) {
|
||||
R_RETURN(TranslateFatFsError(f_sync(GetInternalFile(handle))));
|
||||
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));
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
int GetFileOpenMode(FileHandle handle) {
|
||||
|
||||
@@ -39,45 +39,45 @@ namespace ams::fs {
|
||||
Result TranslateFatFsError(FRESULT res) {
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
case FR_DISK_ERR:
|
||||
R_THROW(fs::ResultMmcAccessFailed());
|
||||
return fs::ResultMmcAccessFailed();
|
||||
case FR_INT_ERR:
|
||||
R_THROW(fs::ResultPreconditionViolation());
|
||||
return fs::ResultPreconditionViolation();
|
||||
case FR_NOT_READY:
|
||||
R_THROW(fs::ResultMmcAccessFailed());
|
||||
return fs::ResultMmcAccessFailed();
|
||||
case FR_NO_FILE:
|
||||
R_THROW(fs::ResultPathNotFound());
|
||||
return fs::ResultPathNotFound();
|
||||
case FR_NO_PATH:
|
||||
R_THROW(fs::ResultPathNotFound());
|
||||
return fs::ResultPathNotFound();
|
||||
case FR_INVALID_NAME:
|
||||
R_THROW(fs::ResultInvalidPath());
|
||||
return fs::ResultInvalidPath();
|
||||
case FR_DENIED:
|
||||
R_THROW(fs::ResultPermissionDenied());
|
||||
return fs::ResultPermissionDenied();
|
||||
case FR_EXIST:
|
||||
R_THROW(fs::ResultPathAlreadyExists());
|
||||
return fs::ResultPathAlreadyExists();
|
||||
case FR_INVALID_OBJECT:
|
||||
R_THROW(fs::ResultInvalidArgument());
|
||||
return fs::ResultInvalidArgument();
|
||||
case FR_WRITE_PROTECTED:
|
||||
R_THROW(fs::ResultWriteNotPermitted());
|
||||
return fs::ResultWriteNotPermitted();
|
||||
case FR_INVALID_DRIVE:
|
||||
R_THROW(fs::ResultInvalidMountName());
|
||||
return fs::ResultInvalidMountName();
|
||||
case FR_NOT_ENABLED:
|
||||
R_THROW(fs::ResultInvalidMountName()); /* BAD/TODO */
|
||||
return fs::ResultInvalidMountName(); /* BAD/TODO */
|
||||
case FR_NO_FILESYSTEM:
|
||||
R_THROW(fs::ResultInvalidMountName()); /* BAD/TODO */
|
||||
return fs::ResultInvalidMountName(); /* BAD/TODO */
|
||||
case FR_TIMEOUT:
|
||||
R_THROW(fs::ResultTargetLocked()); /* BAD/TODO */
|
||||
return fs::ResultTargetLocked(); /* BAD/TODO */
|
||||
case FR_LOCKED:
|
||||
R_THROW(fs::ResultTargetLocked());
|
||||
return fs::ResultTargetLocked();
|
||||
case FR_NOT_ENOUGH_CORE:
|
||||
R_THROW(fs::ResultPreconditionViolation()); /* BAD/TODO */
|
||||
return fs::ResultPreconditionViolation(); /* BAD/TODO */
|
||||
case FR_TOO_MANY_OPEN_FILES:
|
||||
R_THROW(fs::ResultPreconditionViolation()); /* BAD/TODO */
|
||||
return fs::ResultPreconditionViolation(); /* BAD/TODO */
|
||||
case FR_INVALID_PARAMETER:
|
||||
R_THROW(fs::ResultInvalidArgument());
|
||||
return fs::ResultInvalidArgument();
|
||||
default:
|
||||
R_THROW(fs::ResultInternal());
|
||||
return 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);
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
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)));
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result CreateDirectory(const char *path) {
|
||||
R_RETURN(TranslateFatFsError(f_mkdir(path)));
|
||||
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;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
R_THROW(fs::ResultOpenCountLimit());
|
||||
return 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;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
R_THROW(fs::ResultOpenCountLimit());
|
||||
return 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;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void CloseDirectory(DirectoryHandle handle) {
|
||||
@@ -232,11 +232,11 @@ namespace ams::fs {
|
||||
/* Check that we read the correct amount. */
|
||||
R_UNLESS(br == size, fs::ResultOutOfRange());
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||
R_RETURN(ReadFile(handle, offset, buffer, size, fs::ReadOption::None));
|
||||
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;
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||
R_RETURN(ReadFile(out, handle, offset, buffer, size, fs::ReadOption::None));
|
||||
return ReadFile(out, handle, offset, buffer, size, fs::ReadOption::None);
|
||||
}
|
||||
|
||||
Result GetFileSize(s64 *out, FileHandle handle) {
|
||||
FIL *fp = GetInternalFile(handle);
|
||||
*out = f_size(fp);
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FlushFile(FileHandle handle) {
|
||||
R_RETURN(TranslateFatFsError(f_sync(GetInternalFile(handle))));
|
||||
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));
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
int GetFileOpenMode(FileHandle handle) {
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace ams::fs {
|
||||
|
||||
Result FileHandleStorage::UpdateSize() {
|
||||
R_SUCCEED_IF(m_size != InvalidSize);
|
||||
R_RETURN(GetFileSize(std::addressof(m_size), m_handle));
|
||||
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_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
||||
|
||||
R_RETURN(ReadFile(m_handle, offset, buffer, size, fs::ReadOption()));
|
||||
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_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
||||
|
||||
R_RETURN(WriteFile(m_handle, offset, buffer, size, fs::WriteOption()));
|
||||
return WriteFile(m_handle, offset, buffer, size, fs::WriteOption());
|
||||
}
|
||||
|
||||
Result FileHandleStorage::Flush() {
|
||||
R_RETURN(FlushFile(m_handle));
|
||||
return FlushFile(m_handle);
|
||||
}
|
||||
|
||||
Result FileHandleStorage::GetSize(s64 *out_size) {
|
||||
R_TRY(this->UpdateSize());
|
||||
*out_size = m_size;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FileHandleStorage::SetSize(s64 size) {
|
||||
m_size = InvalidSize;
|
||||
R_RETURN(SetFileSize(m_handle, size));
|
||||
return SetFileSize(m_handle, size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,38 +31,25 @@ namespace ams::fs {
|
||||
|
||||
virtual Result GetSize(s64 *out) = 0;
|
||||
public:
|
||||
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, s64 size, s64 total_size) {
|
||||
return offset >= 0 &&
|
||||
size >= 0 &&
|
||||
size <= total_size &&
|
||||
offset <= (total_size - 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 CheckAccessRange(s64 offset, size_t size, s64 total_size) {
|
||||
return CheckAccessRange(offset, static_cast<s64>(size), total_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, s64 size) {
|
||||
return offset >= 0 &&
|
||||
size >= 0 &&
|
||||
offset <= (offset + 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));
|
||||
static inline bool CheckOffsetAndSize(s64 offset, size_t size) {
|
||||
return CheckOffsetAndSize(offset, static_cast<s64>(size));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -73,23 +60,23 @@ namespace ams::fs {
|
||||
ReadOnlyStorageAdapter(IStorage &s) : m_storage(s) { /* ... */ }
|
||||
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
R_RETURN(m_storage.Read(offset, buffer, size));
|
||||
return m_storage.Read(offset, buffer, size);
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_RETURN(m_storage.Flush());
|
||||
return m_storage.Flush();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
R_RETURN(m_storage.GetSize(out));
|
||||
return m_storage.GetSize(out);
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -106,9 +93,9 @@ namespace ams::fs {
|
||||
R_SUCCEED_IF(size == 0);
|
||||
|
||||
/* Validate arguments and read. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||
R_RETURN(m_storage.Read(m_offset + offset, buffer, size));
|
||||
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);
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override{
|
||||
@@ -116,22 +103,22 @@ namespace ams::fs {
|
||||
R_SUCCEED_IF(size == 0);
|
||||
|
||||
/* Validate arguments and write. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||
R_RETURN(m_storage.Write(m_offset + offset, buffer, size));
|
||||
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);
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_RETURN(m_storage.Flush());
|
||||
return m_storage.Flush();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
*out = m_size;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
R_THROW(fs::ResultUnsupportedSetSizeForNotResizableSubStorage());
|
||||
return 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));
|
||||
}
|
||||
|
||||
R_RETURN(ReadSdCard(buffer, size, offset / sdmmc::SectorSize, size / sdmmc::SectorSize));
|
||||
return ReadSdCard(buffer, size, offset / sdmmc::SectorSize, size / sdmmc::SectorSize);
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
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);
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
return 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));
|
||||
}
|
||||
|
||||
R_RETURN(ReadMmc(buffer, size, Partition, offset / sdmmc::SectorSize, size / sdmmc::SectorSize));
|
||||
return ReadMmc(buffer, size, Partition, offset / sdmmc::SectorSize, size / sdmmc::SectorSize);
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
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;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -153,23 +153,23 @@ namespace ams::nxboot {
|
||||
subofs = 0;
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -349,11 +349,11 @@ namespace ams::nxboot {
|
||||
}
|
||||
|
||||
Result ReadBoot0(s64 offset, void *dst, size_t size) {
|
||||
R_RETURN(g_boot0_storage->Read(offset, dst, size));
|
||||
return g_boot0_storage->Read(offset, dst, size);
|
||||
}
|
||||
|
||||
Result ReadPackage2(s64 offset, void *dst, size_t size) {
|
||||
R_RETURN(g_package2_storage->Read(offset, dst, size));
|
||||
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));
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace ams::nxboot {
|
||||
g_mmc_partition = partition;
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,29 +47,29 @@ namespace ams::nxboot {
|
||||
sdmmc::SetMmcWorkBuffer(MmcPort, g_mmc_work_buffer, sizeof(g_mmc_work_buffer));
|
||||
|
||||
/* Activate the mmc. */
|
||||
R_RETURN(sdmmc::Activate(MmcPort));
|
||||
return sdmmc::Activate(MmcPort);
|
||||
}
|
||||
|
||||
Result CheckMmcConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
|
||||
R_RETURN(sdmmc::CheckMmcConnection(out_sm, out_bw, MmcPort));
|
||||
return sdmmc::CheckMmcConnection(out_sm, out_bw, MmcPort);
|
||||
}
|
||||
|
||||
Result GetMmcMemoryCapacity(u32 *out_num_sectors, sdmmc::MmcPartition partition) {
|
||||
if (partition == sdmmc::MmcPartition_UserData) {
|
||||
R_RETURN(sdmmc::GetDeviceMemoryCapacity(out_num_sectors, MmcPort));
|
||||
return sdmmc::GetDeviceMemoryCapacity(out_num_sectors, MmcPort);
|
||||
} else {
|
||||
R_RETURN(sdmmc::GetMmcBootPartitionCapacity(out_num_sectors, MmcPort));
|
||||
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));
|
||||
R_RETURN(sdmmc::Read(dst, size, MmcPort, sector_index, sector_count));
|
||||
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));
|
||||
R_RETURN(sdmmc::Write(MmcPort, sector_index, sector_count, src, size));
|
||||
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. */
|
||||
R_RETURN(sdmmc::Activate(SdCardPort));
|
||||
return sdmmc::Activate(SdCardPort);
|
||||
}
|
||||
|
||||
void FinalizeSdCard() {
|
||||
@@ -90,19 +90,19 @@ namespace ams::nxboot {
|
||||
}
|
||||
|
||||
Result CheckSdCardConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
|
||||
R_RETURN(sdmmc::CheckSdCardConnection(out_sm, out_bw, SdCardPort));
|
||||
return sdmmc::CheckSdCardConnection(out_sm, out_bw, SdCardPort);
|
||||
}
|
||||
|
||||
Result GetSdCardMemoryCapacity(u32 *out_num_sectors) {
|
||||
R_RETURN(sdmmc::GetDeviceMemoryCapacity(out_num_sectors, SdCardPort));
|
||||
return sdmmc::GetDeviceMemoryCapacity(out_num_sectors, SdCardPort);
|
||||
}
|
||||
|
||||
Result ReadSdCard(void *dst, size_t size, size_t sector_index, size_t sector_count) {
|
||||
R_RETURN(sdmmc::Read(dst, size, SdCardPort, sector_index, sector_count));
|
||||
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) {
|
||||
R_RETURN(sdmmc::Write(SdCardPort, sector_index, sector_count, src, size));
|
||||
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 = b91294d3b9960eafef6d5d80b08870d427324bc9
|
||||
parent = 3545c0aac2cdfc1f6f897e8c669a8e33358b3ece
|
||||
commit = 0d161b8588aa6482b84f3c44dd001055b01a047f
|
||||
parent = 4efa5d7dd0bfbdf89a6261af0aef3878ca784b05
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
|
||||
@@ -67,8 +67,6 @@ 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_OS_NAME),macos)
|
||||
export LDFLAGS = $(CXXFLAGS) $(CXXWRAPS) $(CXXREQUIRED) -Wl,-map,$(notdir $@.map)
|
||||
else
|
||||
export LDFLAGS = $(CXXFLAGS) $(CXXWRAPS) $(CXXREQUIRED) -Wl,-Map,$(notdir $@.map)
|
||||
endif
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace ams::kern {
|
||||
s32 new_value;
|
||||
if (count <= 0) {
|
||||
if ((it != m_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
||||
new_value = value - 1;
|
||||
new_value = value - 2;
|
||||
} 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);
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void DetachSession(ISession *session) {
|
||||
@@ -113,12 +113,12 @@ namespace ams::ddsf {
|
||||
|
||||
template<typename F>
|
||||
Result ForEachSession(F f, bool return_on_fail) {
|
||||
R_RETURN(impl::ForEach(m_session_list_lock, m_session_list, f, return_on_fail));
|
||||
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 {
|
||||
R_RETURN(impl::ForEach(m_session_list_lock, m_session_list, f, return_on_fail));
|
||||
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) {
|
||||
R_RETURN(impl::ForEach(m_device_list_lock, m_device_list, f, return_on_fail));
|
||||
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 {
|
||||
R_RETURN(impl::ForEach(m_device_list_lock, m_device_list, f, return_on_fail));
|
||||
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) {
|
||||
R_RETURN(cur_result);
|
||||
return cur_result;
|
||||
} else if (R_SUCCEEDED(result)) {
|
||||
result = cur_result;
|
||||
}
|
||||
}
|
||||
}
|
||||
R_RETURN(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename List, typename F, typename Lock>
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#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>
|
||||
@@ -65,5 +66,4 @@
|
||||
#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,11 +20,9 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||
class HierarchicalRomFileTable {
|
||||
public:
|
||||
using Position = u32;
|
||||
using StorageSizeType = u32;
|
||||
using Position = u32;
|
||||
|
||||
struct FindPosition {
|
||||
Position next_dir;
|
||||
@@ -32,7 +30,8 @@ namespace ams::fs {
|
||||
};
|
||||
static_assert(util::is_pod<FindPosition>::value);
|
||||
|
||||
using FileInfo = RomFileInfo;
|
||||
using DirectoryInfo = RomDirectoryInfo;
|
||||
using FileInfo = RomFileInfo;
|
||||
|
||||
static constexpr RomFileId PositionToFileId(Position pos) {
|
||||
return static_cast<RomFileId>(pos);
|
||||
@@ -81,23 +80,23 @@ namespace ams::fs {
|
||||
using Base = KeyValueRomStorageTemplate<ImplKeyType, ValueType, MaxKeyLength>;
|
||||
public:
|
||||
Result Add(Position *out, const ClientKeyType &key, const Value &value) {
|
||||
R_RETURN(Base::AddInternal(out, key.key, key.Hash(), key.name.begin(), key.name.length(), value));
|
||||
return Base::AddInternal(out, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar), value);
|
||||
}
|
||||
|
||||
Result Get(Position *out_pos, Value *out_val, const ClientKeyType &key) {
|
||||
R_RETURN(Base::GetInternal(out_pos, out_val, key.key, key.Hash(), key.name.begin(), key.name.length()));
|
||||
return Base::GetInternal(out_pos, out_val, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar));
|
||||
}
|
||||
|
||||
Result GetByPosition(ImplKey *out_key, Value *out_val, Position pos) {
|
||||
R_RETURN(Base::GetByPosition(out_key, out_val, pos));
|
||||
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) {
|
||||
R_RETURN(Base::GetByPosition(out_key, out_val, out_aux, out_aux_size, pos));
|
||||
return Base::GetByPosition(out_key, out_val, out_aux, out_aux_size, pos);
|
||||
}
|
||||
|
||||
Result SetByPosition(Position pos, const Value &value) {
|
||||
R_RETURN(Base::SetByPosition(pos, value));
|
||||
return Base::SetByPosition(pos, value);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -122,15 +121,16 @@ namespace ams::fs {
|
||||
|
||||
constexpr u32 Hash() const {
|
||||
u32 hash = this->key.parent ^ 123456789;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
static_assert(util::is_pod<EntryKey>::value);
|
||||
|
||||
using DirectoryEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomDirectoryEntry>;
|
||||
using FileEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomFileEntry>;
|
||||
@@ -138,24 +138,35 @@ namespace ams::fs {
|
||||
DirectoryEntryMapTable m_dir_table;
|
||||
FileEntryMapTable m_file_table;
|
||||
public:
|
||||
static s64 QueryDirectoryEntryBucketStorageSize(StorageSizeType count);
|
||||
static s64 QueryDirectoryEntrySize(StorageSizeType aux_size);
|
||||
static s64 QueryFileEntryBucketStorageSize(StorageSizeType count);
|
||||
static s64 QueryFileEntrySize(StorageSizeType aux_size);
|
||||
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 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);
|
||||
Result CreateDirectory(RomDirectoryId *out, const RomPathChar *path, const DirectoryInfo &info);
|
||||
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);
|
||||
|
||||
@@ -167,7 +178,7 @@ namespace ams::fs {
|
||||
|
||||
Result QueryRomFileSystemSize(s64 *out_dir_entry_size, s64 *out_file_entry_size);
|
||||
private:
|
||||
Result GetParent(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, Position pos, RomPathTool::RomEntryName name, const RomPathChar *path);
|
||||
Result GetGrandParent(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);
|
||||
|
||||
@@ -183,6 +194,8 @@ 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,7 +19,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||
template<typename KeyType, typename ValueType, size_t MaxAuxiliarySize>
|
||||
class KeyValueRomStorageTemplate {
|
||||
public:
|
||||
@@ -28,8 +27,6 @@ namespace ams::fs {
|
||||
using Position = u32;
|
||||
using BucketIndex = s64;
|
||||
|
||||
using StorageSizeType = u32;
|
||||
|
||||
struct FindIndex {
|
||||
BucketIndex ind;
|
||||
Position pos;
|
||||
@@ -42,7 +39,7 @@ namespace ams::fs {
|
||||
Key key;
|
||||
Value value;
|
||||
Position next;
|
||||
StorageSizeType size;
|
||||
u32 size;
|
||||
};
|
||||
static_assert(util::is_pod<Element>::value);
|
||||
private:
|
||||
@@ -56,41 +53,53 @@ namespace ams::fs {
|
||||
return num * sizeof(Position);
|
||||
}
|
||||
|
||||
static constexpr s64 QueryBucketCount(StorageSizeType size) {
|
||||
static constexpr s64 QueryBucketCount(s64 size) {
|
||||
return size / sizeof(Position);
|
||||
}
|
||||
|
||||
static constexpr size_t QueryEntrySize(StorageSizeType aux_size) {
|
||||
return util::AlignUp<size_t>(sizeof(Element) + aux_size, alignof(Element));
|
||||
static constexpr size_t QueryEntrySize(size_t aux_size) {
|
||||
return util::AlignUp(sizeof(Element) + aux_size, alignof(Element));
|
||||
}
|
||||
|
||||
static Result Format(SubStorage bucket, StorageSizeType count) {
|
||||
static Result Format(SubStorage bucket, s64 count) {
|
||||
const Position pos = InvalidPosition;
|
||||
for (auto i = 0u; i < count; i++) {
|
||||
for (s64 i = 0; i < count; i++) {
|
||||
R_TRY(bucket.Write(i * sizeof(pos), std::addressof(pos), sizeof(pos)));
|
||||
}
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
public:
|
||||
constexpr KeyValueRomStorageTemplate() : m_bucket_count(), m_bucket_storage(), m_kv_storage(), m_total_entry_size(), m_entry_count() { /* ... */ }
|
||||
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;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void Finalize() {
|
||||
m_bucket_storage = SubStorage();
|
||||
m_bucket_count = 0;
|
||||
m_kv_storage = SubStorage();
|
||||
m_bucket_count = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -107,18 +116,18 @@ namespace ams::fs {
|
||||
}
|
||||
|
||||
Position pos;
|
||||
R_TRY(this->AllocateEntry(std::addressof(pos), static_cast<StorageSizeType>(aux_size)));
|
||||
R_TRY(this->AllocateEntry(std::addressof(pos), 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<StorageSizeType>(aux_size) };
|
||||
const Element elem = { key, value, next_pos, static_cast<u32>(aux_size) };
|
||||
R_TRY(this->WriteKeyValue(std::addressof(elem), pos, aux, aux_size));
|
||||
|
||||
*out = pos;
|
||||
m_entry_count++;
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetInternal(Position *out_pos, Value *out_val, const Key &key, u32 hash_key, const void *aux, size_t aux_size) {
|
||||
@@ -132,7 +141,7 @@ namespace ams::fs {
|
||||
|
||||
*out_pos = pos;
|
||||
*out_val = elem.value;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetByPosition(Key *out_key, Value *out_val, Position pos) {
|
||||
@@ -144,7 +153,7 @@ namespace ams::fs {
|
||||
|
||||
*out_key = elem.key;
|
||||
*out_val = elem.value;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetByPosition(Key *out_key, Value *out_val, void *out_aux, size_t *out_aux_size, Position pos) {
|
||||
@@ -158,14 +167,14 @@ namespace ams::fs {
|
||||
|
||||
*out_key = elem.key;
|
||||
*out_val = elem.value;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result SetByPosition(Position pos, const Value &value) {
|
||||
Element elem;
|
||||
R_TRY(this->ReadKeyValue(std::addressof(elem), pos));
|
||||
elem.value = value;
|
||||
R_RETURN(this->WriteKeyValue(std::addressof(elem), pos, nullptr, 0));
|
||||
return this->WriteKeyValue(std::addressof(elem), pos, nullptr, 0);
|
||||
}
|
||||
private:
|
||||
BucketIndex HashToBucket(u32 hash_key) const {
|
||||
@@ -193,16 +202,17 @@ namespace ams::fs {
|
||||
|
||||
R_UNLESS(cur != InvalidPosition, fs::ResultDbmKeyNotFound());
|
||||
|
||||
auto buf = ::ams::fs::impl::MakeUnique<u8[]>(MaxAuxiliarySize);
|
||||
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
||||
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); };
|
||||
|
||||
while (true) {
|
||||
size_t cur_aux_size;
|
||||
R_TRY(this->ReadKeyValue(out_elem, buf.get(), std::addressof(cur_aux_size), cur));
|
||||
R_TRY(this->ReadKeyValue(out_elem, buf, std::addressof(cur_aux_size), cur));
|
||||
|
||||
if (key.IsEqual(out_elem->key, aux, aux_size, buf.get(), cur_aux_size)) {
|
||||
if (key.IsEqual(out_elem->key, aux, aux_size, buf, cur_aux_size)) {
|
||||
*out_pos = cur;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
*out_prev = cur;
|
||||
@@ -211,18 +221,18 @@ namespace ams::fs {
|
||||
}
|
||||
}
|
||||
|
||||
Result AllocateEntry(Position *out, StorageSizeType aux_size) {
|
||||
Result AllocateEntry(Position *out, size_t 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) + static_cast<size_t>(aux_size);
|
||||
const size_t end_pos = m_total_entry_size + sizeof(Element) + 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<s64>(static_cast<s64>(end_pos), alignof(Position));
|
||||
R_SUCCEED();
|
||||
m_total_entry_size = util::AlignUp(static_cast<s64>(end_pos), alignof(Position));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result LinkEntry(Position *out, Position pos, u32 hash_key) {
|
||||
@@ -240,7 +250,7 @@ namespace ams::fs {
|
||||
R_TRY(this->WriteBucket(pos, ind));
|
||||
|
||||
*out = next;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ReadBucket(Position *out, BucketIndex ind) {
|
||||
@@ -248,14 +258,14 @@ namespace ams::fs {
|
||||
AMS_ASSERT(ind < m_bucket_count);
|
||||
|
||||
const s64 offset = ind * sizeof(Position);
|
||||
R_RETURN(m_bucket_storage.Read(offset, out, sizeof(*out)));
|
||||
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);
|
||||
R_RETURN(m_bucket_storage.Write(offset, std::addressof(pos), sizeof(pos)));
|
||||
return m_bucket_storage.Write(offset, std::addressof(pos), sizeof(pos));
|
||||
}
|
||||
|
||||
Result ReadKeyValue(Element *out, Position pos) {
|
||||
@@ -265,7 +275,7 @@ namespace ams::fs {
|
||||
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
|
||||
AMS_ASSERT(pos < kv_size);
|
||||
|
||||
R_RETURN(m_kv_storage.Read(pos, out, sizeof(*out)));
|
||||
return m_kv_storage.Read(pos, out, sizeof(*out));
|
||||
}
|
||||
|
||||
Result ReadKeyValue(Element *out, void *out_aux, size_t *out_aux_size, Position pos) {
|
||||
@@ -280,7 +290,7 @@ namespace ams::fs {
|
||||
R_TRY(m_kv_storage.Read(pos + sizeof(*out), out_aux, out->size));
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result WriteKeyValue(const Element *elem, Position pos, const void *aux, size_t aux_size) {
|
||||
@@ -297,7 +307,7 @@ namespace ams::fs {
|
||||
R_TRY(m_kv_storage.Write(pos + sizeof(*elem), aux, aux_size));
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -18,60 +18,34 @@
|
||||
|
||||
namespace ams::fs::RomPathTool {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||
|
||||
constexpr inline u32 MaxPathLength = 0x300;
|
||||
|
||||
constexpr ALWAYS_INLINE bool IsSeparator(RomPathChar c) {
|
||||
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) {
|
||||
return c == RomStringTraits::DirectorySeparator;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE bool IsNullTerminator(RomPathChar c) {
|
||||
constexpr inline bool IsNullTerminator(RomPathChar c) {
|
||||
return c == RomStringTraits::NullTerminator;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE bool IsDot(RomPathChar c) {
|
||||
constexpr inline bool IsDot(RomPathChar c) {
|
||||
return c == RomStringTraits::Dot;
|
||||
}
|
||||
|
||||
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 RomEntryName &name) {
|
||||
return name.length == 1 && IsDot(name.path[0]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsCurrentDirectory(const RomPathChar *p, size_t length) {
|
||||
AMS_ASSERT(p != nullptr);
|
||||
@@ -83,6 +57,10 @@ 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,10 +18,9 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||
using RomPathChar = char;
|
||||
using RomFileId = u32;
|
||||
using RomDirectoryId = u32;
|
||||
using RomFileId = s32;
|
||||
using RomDirectoryId = s32;
|
||||
|
||||
struct RomFileSystemInformation {
|
||||
s64 size;
|
||||
@@ -38,6 +37,11 @@ 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,7 +19,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||
class DirectoryPathParser {
|
||||
NON_COPYABLE(DirectoryPathParser);
|
||||
NON_MOVEABLE(DirectoryPathParser);
|
||||
@@ -102,9 +101,10 @@ namespace ams::fs {
|
||||
s32 i;
|
||||
for (i = m_position; m_buffer[i] != StringTraits::DirectorySeparator; ++i) {
|
||||
if (m_buffer[i] == StringTraits::NullTerminator) {
|
||||
char * const ret = (i != m_position) ? m_buffer + m_position : nullptr;
|
||||
m_position = -1;
|
||||
return ret;
|
||||
if (i == m_position) {
|
||||
m_position = -1;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class FileStorage : public IStorage, public impl::Newable {
|
||||
NON_COPYABLE(FileStorage);
|
||||
NON_MOVEABLE(FileStorage);
|
||||
@@ -75,7 +74,6 @@ 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,8 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
enum AccessLogMode : u32 {
|
||||
AccessLogMode_None = 0,
|
||||
AccessLogMode_Log = 1,
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
void InitializeForSystem();
|
||||
void InitializeWithMultiSessionForSystem();
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
Result MountApplicationPackage(const char *name, const char *common_path);
|
||||
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
enum class BisPartitionId {
|
||||
/* Boot0 */
|
||||
BootPartition1Root = 0,
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
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,7 +19,6 @@
|
||||
|
||||
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,7 +21,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
struct Int64 {
|
||||
u32 low;
|
||||
u32 high;
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum ContentType {
|
||||
ContentType_Meta = 0,
|
||||
ContentType_Control = 1,
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum class ContentStorageId : u32 {
|
||||
System = 0,
|
||||
User = 1,
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
Result MountDeviceSaveData(const char *name);
|
||||
Result MountDeviceSaveData(const char *name, const ncm::ApplicationId application_id);
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
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 IFileSystem;
|
||||
class IFile;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
struct FileTimeStamp {
|
||||
time::PosixTime create;
|
||||
time::PosixTime modify;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum class GameCardPartition {
|
||||
Update = 0,
|
||||
Normal = 1,
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum MountHostOptionFlag : u32 {
|
||||
MountHostOptionFlag_None = (0 << 0),
|
||||
MountHostOptionFlag_PseudoCaseSensitive = (1 << 0),
|
||||
|
||||
@@ -18,14 +18,13 @@
|
||||
|
||||
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);
|
||||
R_RETURN(this->DoBindEvent(out, clear_mode));
|
||||
return this->DoBindEvent(out, clear_mode);
|
||||
}
|
||||
private:
|
||||
virtual Result DoBindEvent(os::SystemEventType *out, os::EventClearMode clear_mode) = 0;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum class ImageDirectoryId {
|
||||
Nand = 0,
|
||||
SdCard = 1,
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||
class IStorage {
|
||||
public:
|
||||
virtual ~IStorage() { /* ... */ }
|
||||
@@ -38,41 +37,28 @@ 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) {
|
||||
R_RETURN(this->OperateRange(nullptr, 0, op_id, offset, size, nullptr, 0));
|
||||
return this->OperateRange(nullptr, 0, op_id, offset, size, nullptr, 0);
|
||||
}
|
||||
public:
|
||||
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, s64 size, s64 total_size) {
|
||||
return offset >= 0 &&
|
||||
size >= 0 &&
|
||||
size <= total_size &&
|
||||
offset <= (total_size - 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 CheckAccessRange(s64 offset, size_t size, s64 total_size) {
|
||||
return CheckAccessRange(offset, static_cast<s64>(size), total_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, s64 size) {
|
||||
return offset >= 0 &&
|
||||
size >= 0 &&
|
||||
offset <= (offset + 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));
|
||||
static inline bool CheckOffsetAndSize(s64 offset, size_t size) {
|
||||
return CheckOffsetAndSize(offset, static_cast<s64>(size));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -95,35 +81,32 @@ namespace ams::fs {
|
||||
virtual ~ReadOnlyStorageAdapter() { /* ... */ }
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
R_RETURN(m_storage->Read(offset, buffer, size));
|
||||
return m_storage->Read(offset, buffer, size);
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_RETURN(m_storage->Flush());
|
||||
return m_storage->Flush();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
R_RETURN(m_storage->GetSize(out));
|
||||
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 {
|
||||
R_RETURN(m_storage->OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
|
||||
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);
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
/* TODO: Better result? Is it possible to get a more specific one? */
|
||||
AMS_UNUSED(size);
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept PointerToStorage = ::ams::util::RawOrSmartPointerTo<T, ::ams::fs::IStorage>;
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
using AllocateFunction = void *(*)(size_t);
|
||||
using DeallocateFunction = void (*)(void *, size_t);
|
||||
|
||||
@@ -26,8 +25,6 @@ namespace ams::fs {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class Newable;
|
||||
|
||||
void *Allocate(size_t size);
|
||||
void Deallocate(void *ptr, size_t size);
|
||||
|
||||
@@ -132,27 +129,20 @@ namespace ams::fs {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto MakeUnique() {
|
||||
/* Check that we're not using MakeUnique unnecessarily. */
|
||||
static_assert(!std::derived_from<T, ::ams::fs::impl::Newable>);
|
||||
|
||||
std::unique_ptr<T, Deleter> MakeUnique() {
|
||||
static_assert(util::is_pod<T>::value);
|
||||
return std::unique_ptr<T, Deleter>(static_cast<T *>(::ams::fs::impl::Allocate(sizeof(T))), Deleter(sizeof(T)));
|
||||
}
|
||||
|
||||
template<typename ArrayT>
|
||||
auto MakeUnique(size_t size) {
|
||||
std::unique_ptr<ArrayT, Deleter> 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 ReturnType(static_cast<T *>(::ams::fs::impl::Allocate(alloc_size)), Deleter(alloc_size));
|
||||
return std::unique_ptr<ArrayT, Deleter>(static_cast<T *>(::ams::fs::impl::Allocate(alloc_size)), Deleter(alloc_size));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class MemoryStorage : public ::ams::fs::IStorage, public ::ams::fs::impl::Newable {
|
||||
private:
|
||||
u8 * const m_buf;
|
||||
@@ -34,11 +33,11 @@ namespace ams::fs {
|
||||
|
||||
/* Validate arguments. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
||||
|
||||
/* Copy from memory. */
|
||||
std::memcpy(buffer, m_buf + offset, size);
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
@@ -47,25 +46,25 @@ namespace ams::fs {
|
||||
|
||||
/* Validate arguments. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
||||
|
||||
/* Copy to memory. */
|
||||
std::memcpy(m_buf + offset, buffer, size);
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
*out = m_size;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
AMS_UNUSED(size);
|
||||
R_THROW(fs::ResultUnsupportedSetSizeForMemoryStorage());
|
||||
return 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 {
|
||||
@@ -73,14 +72,14 @@ namespace ams::fs {
|
||||
|
||||
switch (op_id) {
|
||||
case OperationId::Invalidate:
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
case OperationId::QueryRange:
|
||||
R_UNLESS(dst != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(dst_size == sizeof(QueryRangeInfo), fs::ResultInvalidSize());
|
||||
reinterpret_cast<QueryRangeInfo *>(dst)->Clear();
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
default:
|
||||
R_THROW(fs::ResultUnsupportedOperateRangeForMemoryStorage());
|
||||
return fs::ResultUnsupportedOperateRangeForMemoryStorage();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
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,7 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum class OperationId : s64 {
|
||||
FillZero = 0,
|
||||
DestroySignature = 1,
|
||||
|
||||
@@ -23,8 +23,6 @@ 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);
|
||||
@@ -33,115 +31,43 @@ namespace ams::fs {
|
||||
static constexpr size_t WriteBufferAlignmentLength = 8;
|
||||
private:
|
||||
friend class DirectoryPathParser;
|
||||
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:
|
||||
using WriteBuffer = std::unique_ptr<char[], ::ams::fs::impl::Deleter>;
|
||||
private:
|
||||
const char *m_str;
|
||||
WriteBuffer m_write_buffer;
|
||||
util::TypedStorage<WriteBuffer> m_write_buffer;
|
||||
size_t m_write_buffer_length;
|
||||
bool m_is_normalized;
|
||||
public:
|
||||
constexpr Path() : m_str(EmptyPath), m_write_buffer() {
|
||||
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(const char *s, util::ConstantInitializeTag) : m_str(s), m_write_buffer() {
|
||||
m_write_buffer.SetNormalized();
|
||||
constexpr ~Path() {
|
||||
if (!std::is_constant_evaluated()) {
|
||||
util::DestroyAt(m_write_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr ~Path() { /* ... */ }
|
||||
|
||||
std::unique_ptr<char[], ::ams::fs::impl::Deleter> ReleaseBuffer() {
|
||||
WriteBuffer ReleaseBuffer() {
|
||||
/* Check pre-conditions. */
|
||||
AMS_ASSERT(m_write_buffer.Get() != nullptr);
|
||||
AMS_ASSERT(util::GetReference(m_write_buffer) != nullptr);
|
||||
|
||||
/* Reset. */
|
||||
m_str = EmptyPath;
|
||||
m_str = EmptyPath;
|
||||
m_write_buffer_length = 0;
|
||||
|
||||
/* Release our write buffer. */
|
||||
return m_write_buffer.ReleaseBuffer();
|
||||
/* Return our write buffer. */
|
||||
return std::move(util::GetReference(m_write_buffer));
|
||||
}
|
||||
|
||||
constexpr Result SetShallowBuffer(const char *buffer) {
|
||||
/* Check pre-conditions. */
|
||||
AMS_ASSERT(m_write_buffer.GetLength() == 0);
|
||||
AMS_ASSERT(m_write_buffer_length == 0);
|
||||
|
||||
/* Check the buffer is valid. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
@@ -150,49 +76,44 @@ namespace ams::fs {
|
||||
this->SetReadOnlyBuffer(buffer);
|
||||
|
||||
/* Note that we're normalized. */
|
||||
this->SetNormalized();
|
||||
m_is_normalized = true;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
constexpr const char *GetString() const {
|
||||
const char *GetString() const {
|
||||
/* Check pre-conditions. */
|
||||
AMS_ASSERT(this->IsNormalized());
|
||||
AMS_ASSERT(m_is_normalized);
|
||||
|
||||
return m_str;
|
||||
}
|
||||
|
||||
constexpr size_t GetLength() const {
|
||||
if (std::is_constant_evaluated()) {
|
||||
return util::Strlen(this->GetString());
|
||||
} else {
|
||||
return std::strlen(this->GetString());
|
||||
}
|
||||
size_t GetLength() const {
|
||||
return std::strlen(this->GetString());
|
||||
}
|
||||
|
||||
constexpr bool IsEmpty() const {
|
||||
bool IsEmpty() const {
|
||||
return *m_str == '\x00';
|
||||
}
|
||||
|
||||
constexpr bool IsMatchHead(const char *p, size_t len) const {
|
||||
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. */
|
||||
const bool normalized = rhs.IsNormalized();
|
||||
R_UNLESS(normalized, fs::ResultNotNormalized());
|
||||
R_UNLESS(rhs.m_is_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>(m_write_buffer.Get(), rhs.GetString(), len + 1);
|
||||
const size_t copied = util::Strlcpy<char>(util::GetReference(m_write_buffer).get(), rhs.GetString(), len + 1);
|
||||
R_UNLESS(copied == len, fs::ResultUnexpectedInPathA());
|
||||
|
||||
/* Set normalized. */
|
||||
this->SetNormalized();
|
||||
m_is_normalized = rhs.m_is_normalized;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -204,7 +125,7 @@ namespace ams::fs {
|
||||
R_TRY(this->InitializeImpl(path, len));
|
||||
|
||||
/* Set not normalized. */
|
||||
this->SetNotNormalized();
|
||||
m_is_normalized = false;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -213,7 +134,7 @@ namespace ams::fs {
|
||||
/* Check the path is valid. */
|
||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
R_RETURN(this->Initialize(path, std::strlen(path)));
|
||||
return this->Initialize(path, std::strlen(path));
|
||||
}
|
||||
|
||||
Result InitializeWithFormat(const char *fmt, ...) __attribute__((format (printf, 2, 3))) {
|
||||
@@ -232,7 +153,7 @@ namespace ams::fs {
|
||||
R_TRY(this->Preallocate(len + 1));
|
||||
|
||||
/* Format our path into our new buffer. */
|
||||
const auto real_len = util::VSNPrintf(m_write_buffer.Get(), m_write_buffer.GetLength(), fmt, vl);
|
||||
const auto real_len = util::VSNPrintf(util::GetReference(m_write_buffer).get(), m_write_buffer_length, fmt, vl);
|
||||
AMS_ASSERT(real_len == len);
|
||||
AMS_UNUSED(real_len);
|
||||
|
||||
@@ -240,7 +161,7 @@ namespace ams::fs {
|
||||
va_end(vl);
|
||||
|
||||
/* Set not normalized. */
|
||||
this->SetNotNormalized();
|
||||
m_is_normalized = false;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -253,12 +174,12 @@ namespace ams::fs {
|
||||
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
||||
|
||||
/* Replace slashes as desired. */
|
||||
if (const auto write_buffer_length = m_write_buffer.GetLength(); write_buffer_length > 1) {
|
||||
fs::Replace(m_write_buffer.Get(), write_buffer_length - 1, '\\', '/');
|
||||
if (m_write_buffer_length > 1) {
|
||||
fs::Replace(this->GetWriteBuffer(), m_write_buffer_length - 1, '\\', '/');
|
||||
}
|
||||
|
||||
/* Set not normalized. */
|
||||
this->SetNotNormalized();
|
||||
m_is_normalized = false;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -271,15 +192,15 @@ namespace ams::fs {
|
||||
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
||||
|
||||
/* Replace slashes as desired. */
|
||||
if (m_write_buffer.GetLength() > 1) {
|
||||
if (auto *p = m_write_buffer.Get(); p[0] == '/' && p[1] == '/') {
|
||||
if (m_write_buffer_length > 1) {
|
||||
if (auto *p = this->GetWriteBuffer(); p[0] == '/' && p[1] == '/') {
|
||||
p[0] = '\\';
|
||||
p[1] = '\\';
|
||||
}
|
||||
}
|
||||
|
||||
/* Set not normalized. */
|
||||
this->SetNotNormalized();
|
||||
m_is_normalized = false;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -292,11 +213,11 @@ namespace ams::fs {
|
||||
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
||||
|
||||
/* Set not normalized. */
|
||||
this->SetNotNormalized();
|
||||
m_is_normalized = false;
|
||||
|
||||
/* Replace unc as desired. */
|
||||
if (m_str[0]) {
|
||||
auto *p = m_write_buffer.Get();
|
||||
auto *p = this->GetWriteBuffer();
|
||||
|
||||
/* Replace :/// -> \\ as needed. */
|
||||
if (auto *sep = std::strstr(p, ":///"); sep != nullptr) {
|
||||
@@ -329,7 +250,7 @@ namespace ams::fs {
|
||||
R_TRY(this->InitializeImpl(path, size));
|
||||
|
||||
/* Set not normalized. */
|
||||
this->SetNotNormalized();
|
||||
m_is_normalized = false;
|
||||
|
||||
/* Perform normalization. */
|
||||
fs::PathFlags path_flags;
|
||||
@@ -341,17 +262,16 @@ 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;
|
||||
bool normalized;
|
||||
R_TRY(PathFormatter::IsNormalized(std::addressof(normalized), std::addressof(dummy), m_str));
|
||||
R_TRY(PathFormatter::IsNormalized(std::addressof(m_is_normalized), std::addressof(dummy), m_str));
|
||||
|
||||
this->SetNormalized();
|
||||
m_is_normalized = true;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* Normalize. */
|
||||
R_TRY(this->Normalize(path_flags));
|
||||
|
||||
this->SetNormalized();
|
||||
m_is_normalized = true;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -367,7 +287,7 @@ namespace ams::fs {
|
||||
this->ClearBuffer();
|
||||
|
||||
/* Set normalized. */
|
||||
this->SetNormalized();
|
||||
m_is_normalized = true;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -403,8 +323,8 @@ namespace ams::fs {
|
||||
|
||||
/* Reset our write buffer. */
|
||||
WriteBuffer old_write_buffer;
|
||||
if (m_write_buffer.Get() != nullptr) {
|
||||
old_write_buffer = std::move(m_write_buffer);
|
||||
if (util::GetReference(m_write_buffer) != nullptr) {
|
||||
old_write_buffer = std::move(util::GetReference(m_write_buffer));
|
||||
this->ClearBuffer();
|
||||
}
|
||||
|
||||
@@ -412,9 +332,9 @@ namespace ams::fs {
|
||||
R_TRY(this->Preallocate(cur_len + 1 + child_len + 1));
|
||||
|
||||
/* Get our write buffer. */
|
||||
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);
|
||||
auto *dst = this->GetWriteBuffer();
|
||||
if (old_write_buffer != nullptr && cur_len > 0) {
|
||||
util::Strlcpy<char>(dst, old_write_buffer.get(), cur_len + 1);
|
||||
}
|
||||
|
||||
/* Add separator. */
|
||||
@@ -455,15 +375,15 @@ namespace ams::fs {
|
||||
|
||||
Result RemoveChild() {
|
||||
/* If we don't have a write-buffer, ensure that we have one. */
|
||||
if (m_write_buffer.Get() == nullptr) {
|
||||
if (util::GetReference(m_write_buffer) == nullptr) {
|
||||
if (const auto len = std::strlen(m_str); len > 0) {
|
||||
R_TRY(this->Preallocate(len));
|
||||
util::Strlcpy<char>(m_write_buffer.Get(), m_str, len + 1);
|
||||
util::Strlcpy<char>(util::GetReference(m_write_buffer).get(), m_str, len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that it's possible for us to remove a child. */
|
||||
auto *p = m_write_buffer.Get();
|
||||
auto *p = this->GetWriteBuffer();
|
||||
s32 len = std::strlen(p);
|
||||
R_UNLESS(len != 1 || (p[0] != '/' && p[0] != '.'), fs::ResultNotImplemented());
|
||||
|
||||
@@ -493,7 +413,7 @@ namespace ams::fs {
|
||||
|
||||
Result Normalize(const PathFlags &flags) {
|
||||
/* If we're already normalized, nothing to do. */
|
||||
R_SUCCEED_IF(this->IsNormalized());
|
||||
R_SUCCEED_IF(m_is_normalized);
|
||||
|
||||
/* Check if we're normalized. */
|
||||
bool normalized;
|
||||
@@ -503,7 +423,7 @@ namespace ams::fs {
|
||||
/* If we're not normalized, normalize. */
|
||||
if (!normalized) {
|
||||
/* Determine necessary buffer length. */
|
||||
auto len = m_write_buffer.GetLength();
|
||||
auto len = m_write_buffer_length;
|
||||
if (flags.IsRelativePathAllowed() && fs::IsPathRelative(m_str)) {
|
||||
len += 2;
|
||||
}
|
||||
@@ -513,59 +433,57 @@ namespace ams::fs {
|
||||
|
||||
/* Allocate a new buffer. */
|
||||
const size_t size = util::AlignUp(len, WriteBufferAlignmentLength);
|
||||
auto buf = WriteBuffer::Make(size);
|
||||
R_UNLESS(buf.Get() != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
||||
auto buf = fs::impl::MakeUnique<char[]>(size);
|
||||
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
||||
|
||||
/* Normalize into it. */
|
||||
R_TRY(PathFormatter::Normalize(buf.Get(), size, m_write_buffer.Get(), m_write_buffer.GetLength(), flags));
|
||||
R_TRY(PathFormatter::Normalize(buf.get(), size, util::GetReference(m_write_buffer).get(), m_write_buffer_length, flags));
|
||||
|
||||
/* Set the normalized buffer as our buffer. */
|
||||
this->SetModifiableBuffer(std::move(buf));
|
||||
this->SetModifiableBuffer(std::move(buf), size);
|
||||
}
|
||||
|
||||
/* Set normalized. */
|
||||
this->SetNormalized();
|
||||
m_is_normalized = true;
|
||||
R_SUCCEED();
|
||||
}
|
||||
private:
|
||||
void ClearBuffer() {
|
||||
m_write_buffer.ResetBuffer();
|
||||
util::GetReference(m_write_buffer).reset();
|
||||
m_write_buffer_length = 0;
|
||||
m_str = EmptyPath;
|
||||
}
|
||||
|
||||
void SetModifiableBuffer(WriteBuffer &&buffer) {
|
||||
void SetModifiableBuffer(WriteBuffer &&buffer, size_t size) {
|
||||
/* Check pre-conditions. */
|
||||
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();
|
||||
}
|
||||
AMS_ASSERT(buffer.get() != nullptr);
|
||||
AMS_ASSERT(size > 0);
|
||||
AMS_ASSERT(util::IsAligned(size, WriteBufferAlignmentLength));
|
||||
|
||||
/* Set write buffer. */
|
||||
m_write_buffer = std::move(buffer);
|
||||
m_str = m_write_buffer.Get();
|
||||
util::GetReference(m_write_buffer) = std::move(buffer);
|
||||
m_write_buffer_length = size;
|
||||
m_str = util::GetReference(m_write_buffer).get();
|
||||
}
|
||||
|
||||
constexpr void SetReadOnlyBuffer(const char *buffer) {
|
||||
m_str = buffer;
|
||||
m_write_buffer.ResetBuffer();
|
||||
if (!std::is_constant_evaluated()) {
|
||||
util::GetReference(m_write_buffer) = nullptr;
|
||||
m_write_buffer_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Result Preallocate(size_t length) {
|
||||
/* Allocate additional space, if needed. */
|
||||
if (length > m_write_buffer.GetLength()) {
|
||||
if (length > m_write_buffer_length) {
|
||||
/* Allocate buffer. */
|
||||
const size_t size = util::AlignUp(length, WriteBufferAlignmentLength);
|
||||
auto buf = WriteBuffer::Make(size);
|
||||
R_UNLESS(buf.Get() != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
||||
auto buf = fs::impl::MakeUnique<char[]>(size);
|
||||
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
||||
|
||||
/* Set write buffer. */
|
||||
this->SetModifiableBuffer(std::move(buf));
|
||||
this->SetModifiableBuffer(std::move(buf), size);
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
@@ -577,7 +495,7 @@ namespace ams::fs {
|
||||
R_TRY(this->Preallocate(size + 1));
|
||||
|
||||
/* Copy the path. */
|
||||
const size_t copied = util::Strlcpy<char>(m_write_buffer.Get(), path, size + 1);
|
||||
const size_t copied = util::Strlcpy<char>(this->GetWriteBuffer(), path, size + 1);
|
||||
R_UNLESS(copied >= size, fs::ResultUnexpectedInPathA());
|
||||
} else {
|
||||
/* We can just clear the buffer. */
|
||||
@@ -587,20 +505,14 @@ namespace ams::fs {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
constexpr char *GetWriteBuffer() {
|
||||
AMS_ASSERT(m_write_buffer.Get() != nullptr);
|
||||
return m_write_buffer.Get();
|
||||
char *GetWriteBuffer() {
|
||||
AMS_ASSERT(util::GetReference(m_write_buffer) != nullptr);
|
||||
return util::GetReference(m_write_buffer).get();
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE size_t GetWriteBufferLength() const {
|
||||
return m_write_buffer.GetLength();
|
||||
size_t GetWriteBufferLength() const {
|
||||
return m_write_buffer_length;
|
||||
}
|
||||
|
||||
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); }
|
||||
@@ -667,9 +579,4 @@ 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,7 +19,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||
namespace StringTraits {
|
||||
|
||||
constexpr inline char DirectorySeparator = '/';
|
||||
@@ -619,7 +618,7 @@ namespace ams::fs {
|
||||
}
|
||||
|
||||
static constexpr ALWAYS_INLINE Result SkipMountName(const char **out, size_t *out_len, const char *path) {
|
||||
R_RETURN(ParseMountName(out, out_len, nullptr, 0, path));
|
||||
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) {
|
||||
@@ -684,7 +683,7 @@ namespace ams::fs {
|
||||
}
|
||||
|
||||
static constexpr ALWAYS_INLINE Result SkipRelativeDotPath(const char **out, size_t *out_len, const char *path) {
|
||||
R_RETURN(ParseRelativeDotPath(out, out_len, nullptr, 0, path));
|
||||
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,7 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum Priority {
|
||||
Priority_Realtime = 0,
|
||||
Priority_Normal = 1,
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
struct ProgramIndexMapInfo {
|
||||
ncm::ProgramId program_id;
|
||||
ncm::ProgramId base_program_id;
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
struct QueryRangeInfo {
|
||||
s32 aes_ctr_key_type;
|
||||
s32 speed_emulation_type;
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
namespace {
|
||||
|
||||
class ReadOnlyFile : public fsa::IFile, public impl::Newable {
|
||||
@@ -36,15 +34,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 {
|
||||
R_RETURN(m_base_file->Read(out, offset, buffer, size, option));
|
||||
return m_base_file->Read(out, offset, buffer, size, option);
|
||||
}
|
||||
|
||||
virtual Result DoGetSize(s64 *out) override final {
|
||||
R_RETURN(m_base_file->GetSize(out));
|
||||
return m_base_file->GetSize(out);
|
||||
}
|
||||
|
||||
virtual Result DoFlush() override final {
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result DoWrite(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) override final {
|
||||
@@ -54,21 +52,21 @@ namespace ams::fs {
|
||||
AMS_ASSERT(!need_append);
|
||||
|
||||
AMS_UNUSED(buffer);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFile());
|
||||
return fs::ResultUnsupportedWriteForReadOnlyFile();
|
||||
}
|
||||
|
||||
virtual Result DoSetSize(s64 size) override final {
|
||||
R_TRY(this->DrySetSize(size, fs::OpenMode_Read));
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFile());
|
||||
return 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:
|
||||
R_RETURN(m_base_file->OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
|
||||
return m_base_file->OperateRange(dst, dst_size, op_id, offset, size, src, src_size);
|
||||
default:
|
||||
R_THROW(fs::ResultUnsupportedOperateRangeForReadOnlyFile());
|
||||
return fs::ResultUnsupportedOperateRangeForReadOnlyFile();
|
||||
}
|
||||
}
|
||||
public:
|
||||
@@ -100,73 +98,74 @@ namespace ams::fs {
|
||||
R_UNLESS(read_only_file != nullptr, fs::ResultAllocationMemoryFailedInReadOnlyFileSystemA());
|
||||
|
||||
*out_file = std::move(read_only_file);
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result DoOpenDirectory(std::unique_ptr<fsa::IDirectory> *out_dir, const fs::Path &path, OpenDirectoryMode mode) override final {
|
||||
R_RETURN(m_base_fs->OpenDirectory(out_dir, path, mode));
|
||||
return m_base_fs->OpenDirectory(out_dir, path, mode);
|
||||
}
|
||||
|
||||
virtual Result DoGetEntryType(DirectoryEntryType *out, const fs::Path &path) override final {
|
||||
R_RETURN(m_base_fs->GetEntryType(out, path));
|
||||
return m_base_fs->GetEntryType(out, path);
|
||||
}
|
||||
|
||||
virtual Result DoCommit() override final {
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result DoCreateFile(const fs::Path &path, s64 size, int flags) override final {
|
||||
AMS_UNUSED(path, size, flags);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
||||
}
|
||||
|
||||
virtual Result DoDeleteFile(const fs::Path &path) override final {
|
||||
AMS_UNUSED(path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
||||
}
|
||||
|
||||
virtual Result DoCreateDirectory(const fs::Path &path) override final {
|
||||
AMS_UNUSED(path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
||||
}
|
||||
|
||||
virtual Result DoDeleteDirectory(const fs::Path &path) override final {
|
||||
AMS_UNUSED(path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
||||
}
|
||||
|
||||
virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) override final {
|
||||
AMS_UNUSED(path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
||||
}
|
||||
|
||||
virtual Result DoRenameFile(const fs::Path &old_path, const fs::Path &new_path) override final {
|
||||
AMS_UNUSED(old_path, new_path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
||||
}
|
||||
|
||||
virtual Result DoRenameDirectory(const fs::Path &old_path, const fs::Path &new_path) override final {
|
||||
AMS_UNUSED(old_path, new_path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
||||
}
|
||||
|
||||
virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override final {
|
||||
AMS_UNUSED(path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
||||
}
|
||||
|
||||
virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override final {
|
||||
R_RETURN(m_base_fs->GetFreeSpaceSize(out, path));
|
||||
AMS_UNUSED(out, path);
|
||||
return fs::ResultUnsupportedCommitProvisionallyForReadOnlyFileSystem();
|
||||
}
|
||||
|
||||
virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override final {
|
||||
AMS_UNUSED(out, path);
|
||||
R_THROW(fs::ResultUnsupportedGetTotalSpaceSizeForReadOnlyFileSystem());
|
||||
return fs::ResultUnsupportedCommitProvisionallyForReadOnlyFileSystem();
|
||||
}
|
||||
|
||||
virtual Result DoCommitProvisionally(s64 counter) override final {
|
||||
AMS_UNUSED(counter);
|
||||
R_THROW(fs::ResultUnsupportedCommitProvisionallyForReadOnlyFileSystem());
|
||||
return fs::ResultUnsupportedGetTotalSpaceSizeForReadOnlyFileSystem();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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 {
|
||||
R_RETURN(fsFileRead(std::addressof(m_base_file), offset, buffer, size, option._value, out));
|
||||
return fsFileRead(std::addressof(m_base_file), offset, buffer, size, option._value, out);
|
||||
}
|
||||
|
||||
virtual Result DoGetSize(s64 *out) override final {
|
||||
R_RETURN(fsFileGetSize(std::addressof(m_base_file), out));
|
||||
return fsFileGetSize(std::addressof(m_base_file), out);
|
||||
}
|
||||
|
||||
virtual Result DoFlush() override final {
|
||||
R_RETURN(fsFileFlush(std::addressof(m_base_file)));
|
||||
return fsFileFlush(std::addressof(m_base_file));
|
||||
}
|
||||
|
||||
virtual Result DoWrite(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) override final {
|
||||
R_RETURN(fsFileWrite(std::addressof(m_base_file), offset, buffer, size, option._value));
|
||||
return fsFileWrite(std::addressof(m_base_file), offset, buffer, size, option._value);
|
||||
}
|
||||
|
||||
virtual Result DoSetSize(s64 size) override final {
|
||||
R_RETURN(fsFileSetSize(std::addressof(m_base_file), size));
|
||||
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());
|
||||
|
||||
R_RETURN(fsFileOperateRange(std::addressof(m_base_file), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(dst)));
|
||||
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));
|
||||
R_RETURN(fsDirRead(std::addressof(m_base_dir), out_count, max_entries, reinterpret_cast<::FsDirectoryEntry *>(out_entries)));
|
||||
return fsDirRead(std::addressof(m_base_dir), out_count, max_entries, reinterpret_cast<::FsDirectoryEntry *>(out_entries));
|
||||
}
|
||||
|
||||
virtual Result DoGetEntryCount(s64 *out) override final {
|
||||
R_RETURN(fsDirGetEntryCount(std::addressof(m_base_dir), out));
|
||||
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));
|
||||
R_RETURN(fsFsCreateFile(std::addressof(m_base_fs), sf_path.str, size, flags));
|
||||
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));
|
||||
R_RETURN(fsFsDeleteFile(std::addressof(m_base_fs), sf_path.str));
|
||||
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));
|
||||
R_RETURN(fsFsCreateDirectory(std::addressof(m_base_fs), sf_path.str));
|
||||
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));
|
||||
R_RETURN(fsFsDeleteDirectory(std::addressof(m_base_fs), sf_path.str));
|
||||
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));
|
||||
R_RETURN(fsFsDeleteDirectoryRecursively(std::addressof(m_base_fs), sf_path.str));
|
||||
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));
|
||||
R_RETURN(fsFsRenameFile(std::addressof(m_base_fs), old_sf_path.str, new_sf_path.str));
|
||||
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));
|
||||
R_RETURN(fsFsRenameDirectory(std::addressof(m_base_fs), old_sf_path.str, new_sf_path.str));
|
||||
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));
|
||||
R_RETURN(fsFsGetEntryType(std::addressof(m_base_fs), sf_path.str, reinterpret_cast<::FsDirEntryType *>(out)));
|
||||
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);
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
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);
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result DoCommit() override final {
|
||||
R_RETURN(fsFsCommit(std::addressof(m_base_fs)));
|
||||
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));
|
||||
R_RETURN(fsFsGetFreeSpace(std::addressof(m_base_fs), sf_path.str, out));
|
||||
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));
|
||||
R_RETURN(fsFsGetTotalSpace(std::addressof(m_base_fs), sf_path.str, out));
|
||||
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));
|
||||
R_RETURN(fsFsCleanDirectoryRecursively(std::addressof(m_base_fs), sf_path.str));
|
||||
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));
|
||||
R_RETURN(fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), sf_path.str, reinterpret_cast<::FsTimeStampRaw *>(out)));
|
||||
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));
|
||||
R_RETURN(fsFsQueryEntry(std::addressof(m_base_fs), dst, dst_size, src, src_size, sf_path.str, static_cast<FsFileSystemQueryId>(query)));
|
||||
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 {
|
||||
R_RETURN(fsStorageRead(std::addressof(m_base_storage), offset, buffer, size));
|
||||
return fsStorageRead(std::addressof(m_base_storage), offset, buffer, size);
|
||||
};
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
R_RETURN(fsStorageWrite(std::addressof(m_base_storage), offset, buffer, size));
|
||||
return fsStorageWrite(std::addressof(m_base_storage), offset, buffer, size);
|
||||
};
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_RETURN(fsStorageFlush(std::addressof(m_base_storage)));
|
||||
return fsStorageFlush(std::addressof(m_base_storage));
|
||||
};
|
||||
|
||||
virtual Result GetSize(s64 *out_size) override {
|
||||
R_RETURN(fsStorageGetSize(std::addressof(m_base_storage), out_size));
|
||||
return fsStorageGetSize(std::addressof(m_base_storage), out_size);
|
||||
};
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
R_RETURN(fsStorageSetSize(std::addressof(m_base_storage), size));
|
||||
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);
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
return fs::ResultUnsupportedOperation();
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
void SetEnabledAutoAbort(bool enabled);
|
||||
void SetResultHandledByApplication(bool application);
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
union RightsId {
|
||||
u8 data[0x10];
|
||||
u64 data64[2];
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class RomFsFileSystem : public fsa::IFileSystem, public impl::Newable {
|
||||
NON_COPYABLE(RomFsFileSystem);
|
||||
public:
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
Result DeleteSaveData(SaveDataId id);
|
||||
Result DeleteSaveData(SaveDataSpaceId space_id, SaveDataId id);
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
Result CommitSaveData(const char *path);
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
using SaveDataId = u64;
|
||||
using SystemSaveDataId = u64;
|
||||
using SystemBcatSaveDataId = SystemSaveDataId;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class IEventNotifier;
|
||||
|
||||
struct EncryptionSeed {
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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,7 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
bool IsSignedSystemPartitionOnSdCardValid(const char *system_root_path);
|
||||
bool IsSignedSystemPartitionOnSdCardValidDeprecated();
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum class SpeedEmulationMode {
|
||||
None = 0,
|
||||
Faster = 1,
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum StorageType : s32 {
|
||||
StorageType_SaveData = 0,
|
||||
StorageType_RomFs = 1,
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
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;
|
||||
@@ -75,42 +74,41 @@ 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_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||
R_RETURN(m_base_storage->Read(m_offset + offset, buffer, size));
|
||||
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);
|
||||
}
|
||||
|
||||
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_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||
R_RETURN(m_base_storage->Write(m_offset + offset, buffer, size));
|
||||
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);
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||
R_RETURN(m_base_storage->Flush());
|
||||
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_TRY(IStorage::CheckOffsetAndSize(m_offset, size));
|
||||
R_UNLESS(IStorage::CheckOffsetAndSize(m_offset, size), fs::ResultInvalidSize());
|
||||
|
||||
/* Ensure that we're allowed to set size. */
|
||||
s64 cur_size;
|
||||
@@ -121,7 +119,7 @@ namespace ams::fs {
|
||||
R_TRY(m_base_storage->SetSize(m_offset + size));
|
||||
|
||||
m_size = size;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
@@ -129,24 +127,19 @@ namespace ams::fs {
|
||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||
|
||||
*out = m_size;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
/* 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);
|
||||
/* Succeed immediately on zero-sized operation. */
|
||||
R_SUCCEED_IF(size == 0);
|
||||
|
||||
/* 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));
|
||||
/* 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);
|
||||
}
|
||||
|
||||
using IStorage::OperateRange;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
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,7 +19,6 @@
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
void DisableAutoSaveDataCreation();
|
||||
|
||||
Result CreateSystemSaveData(SystemSaveDataId save_id, s64 size, s64 journal_size, u32 flags);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class IDirectory {
|
||||
public:
|
||||
virtual ~IDirectory() { /* ... */ }
|
||||
@@ -29,7 +28,7 @@ namespace ams::fs::fsa {
|
||||
R_UNLESS(out_count != nullptr, fs::ResultNullptrArgument());
|
||||
if (max_entries == 0) {
|
||||
*out_count = 0;
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
R_UNLESS(out_entries != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(max_entries > 0, fs::ResultInvalidArgument());
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class IFile;
|
||||
class IDirectory;
|
||||
|
||||
@@ -181,7 +180,4 @@ namespace ams::fs::fsa {
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept PointerToFileSystem = ::ams::util::RawOrSmartPointerTo<T, ::ams::fs::fsa::IFileSystem>;
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class ICommonMountNameGenerator {
|
||||
public:
|
||||
virtual ~ICommonMountNameGenerator() { /* ... */ }
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum AccessLogTarget : u32 {
|
||||
AccessLogTarget_None = (0 << 0),
|
||||
AccessLogTarget_Application = (1 << 0),
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
/* Delimiting of mount names. */
|
||||
constexpr inline const char ReservedMountNamePrefixCharacter = '@';
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
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,7 +18,6 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum FileSystemProxyType {
|
||||
FileSystemProxyType_Code = 0,
|
||||
FileSystemProxyType_Rom = 1,
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
constexpr inline u8 TlsIoPriorityMask = 0x7;
|
||||
constexpr inline u8 TlsIoRecursiveCallMask = 0x8;
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
fssystem::IHash256GeneratorFactorySelector *GetNcaHashGeneratorFactorySelector();
|
||||
fssystem::IHash256GeneratorFactorySelector *GetSaveDataHashGeneratorFactorySelector();
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class Newable {
|
||||
public:
|
||||
static ALWAYS_INLINE void *operator new(size_t size) noexcept {
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum TlsIoPriority : u8 {
|
||||
TlsIoPriority_Normal = 0,
|
||||
TlsIoPriority_Realtime = 1,
|
||||
@@ -44,10 +43,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: R_THROW(fs::ResultInvalidArgument());
|
||||
default: return fs::ResultInvalidArgument();
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
constexpr inline Result ConvertTlsIoPriorityToFsPriority(PriorityRaw *out, u8 tls_io) {
|
||||
@@ -58,10 +57,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: R_THROW(fs::ResultInvalidArgument());
|
||||
default: return fs::ResultInvalidArgument();
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
inline u8 GetTlsIoPriority(os::ThreadType *thread) {
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
bool IsAbortNeeded(Result result);
|
||||
void LogErrorMessage(Result result, const char *function);
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace ams::fssrv::fscreator {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||
class LocalFileSystemCreator final : public ILocalFileSystemCreator {
|
||||
NON_COPYABLE(LocalFileSystemCreator);
|
||||
NON_MOVEABLE(LocalFileSystemCreator);
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace ams::fssrv::fscreator {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class PartitionFileSystemCreator : public IPartitionFileSystemCreator {
|
||||
NON_COPYABLE(PartitionFileSystemCreator);
|
||||
NON_MOVEABLE(PartitionFileSystemCreator);
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace ams::fssrv::fscreator {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class RomFileSystemCreator : public IRomFileSystemCreator {
|
||||
NON_COPYABLE(RomFileSystemCreator);
|
||||
NON_MOVEABLE(RomFileSystemCreator);
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace ams::fssrv::fscreator {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||
class SubDirectoryFileSystemCreator final : public ISubDirectoryFileSystemCreator {
|
||||
NON_COPYABLE(SubDirectoryFileSystemCreator);
|
||||
NON_MOVEABLE(SubDirectoryFileSystemCreator);
|
||||
|
||||
@@ -35,7 +35,6 @@ 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,7 +30,6 @@ namespace ams::fssrv {
|
||||
class NcaFileSystemService;
|
||||
class SaveDataFileSystemService;
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class FileSystemProxyImpl {
|
||||
NON_COPYABLE(FileSystemProxyImpl);
|
||||
NON_MOVEABLE(FileSystemProxyImpl);
|
||||
@@ -148,27 +147,26 @@ 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);
|
||||
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||
return 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);
|
||||
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||
return fs::ResultPortAcceptableCountLimited();
|
||||
}
|
||||
|
||||
Result IsArchivedProgram(ams::sf::Out<bool> out, u64 process_id) {
|
||||
AMS_UNUSED(out, process_id);
|
||||
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||
return fs::ResultPortAcceptableCountLimited();
|
||||
}
|
||||
|
||||
Result SetCurrentProcess(const ams::sf::ClientProcessId &client_pid) {
|
||||
AMS_UNUSED(client_pid);
|
||||
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||
return fs::ResultPortAcceptableCountLimited();
|
||||
}
|
||||
};
|
||||
static_assert(sf::IsIFileSystemProxyForLoader<FileSystemProxyImpl>);
|
||||
|
||||
@@ -49,21 +49,18 @@ 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() { /* ... */ }
|
||||
@@ -72,7 +69,6 @@ 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;
|
||||
@@ -82,13 +78,11 @@ 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,7 +20,6 @@
|
||||
|
||||
namespace ams::fssrv {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class MemoryResourceFromExpHeap : public ams::MemoryResource {
|
||||
private:
|
||||
lmem::HeapHandle m_heap_handle;
|
||||
@@ -42,7 +41,6 @@ namespace ams::fssrv {
|
||||
}
|
||||
};
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class PeakCheckableMemoryResourceFromExpHeap : public ams::MemoryResource {
|
||||
private:
|
||||
lmem::HeapHandle m_heap_handle;
|
||||
|
||||
@@ -25,7 +25,6 @@ namespace ams::mem {
|
||||
|
||||
namespace ams::fssrv {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class MemoryResourceFromStandardAllocator : public ams::MemoryResource {
|
||||
private:
|
||||
mem::StandardAllocator *m_allocator;
|
||||
|
||||
@@ -47,7 +47,6 @@ namespace ams::fssrv {
|
||||
|
||||
}
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class NcaFileSystemServiceImpl {
|
||||
public:
|
||||
struct Configuration {
|
||||
|
||||
@@ -27,7 +27,6 @@ namespace ams::fssrv {
|
||||
|
||||
}
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class ProgramRegistryImpl {
|
||||
NON_COPYABLE(ProgramRegistryImpl);
|
||||
NON_MOVEABLE(ProgramRegistryImpl);
|
||||
@@ -46,27 +45,26 @@ 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);
|
||||
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||
return fs::ResultPortAcceptableCountLimited();
|
||||
}
|
||||
|
||||
Result UnregisterProgram(u64 process_id) {
|
||||
AMS_UNUSED(process_id);
|
||||
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||
return fs::ResultPortAcceptableCountLimited();
|
||||
}
|
||||
|
||||
Result SetCurrentProcess(const ams::sf::ClientProcessId &client_pid) {
|
||||
AMS_UNUSED(client_pid);
|
||||
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||
return fs::ResultPortAcceptableCountLimited();
|
||||
}
|
||||
|
||||
Result SetEnabledProgramVerification(bool en) {
|
||||
AMS_UNUSED(en);
|
||||
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||
return fs::ResultPortAcceptableCountLimited();
|
||||
}
|
||||
};
|
||||
static_assert(sf::IsIProgramRegistry<InvalidProgramRegistryImpl>);
|
||||
|
||||
@@ -27,7 +27,6 @@ namespace ams::fssrv {
|
||||
|
||||
}
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class ProgramRegistryServiceImpl {
|
||||
public:
|
||||
struct Configuration {
|
||||
|
||||
@@ -28,7 +28,6 @@ namespace ams::fssrv {
|
||||
|
||||
namespace ams::fssrv::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||
struct Accessibility {
|
||||
u8 value;
|
||||
|
||||
@@ -61,7 +60,6 @@ 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,7 +21,6 @@
|
||||
|
||||
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) \
|
||||
@@ -180,7 +179,6 @@ 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,7 +22,6 @@
|
||||
|
||||
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;
|
||||
@@ -49,7 +48,6 @@ namespace ams::fssrv::impl {
|
||||
}
|
||||
};
|
||||
|
||||
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||
class ExternalKeyManager {
|
||||
NON_COPYABLE(ExternalKeyManager);
|
||||
NON_MOVEABLE(ExternalKeyManager);
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
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,14 +22,12 @@
|
||||
|
||||
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,7 +37,6 @@ namespace ams::fssrv::impl {
|
||||
|
||||
class FileSystemInterfaceAdapter;
|
||||
|
||||
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||
class FileInterfaceAdapter {
|
||||
NON_COPYABLE(FileInterfaceAdapter);
|
||||
NON_MOVEABLE(FileInterfaceAdapter);
|
||||
@@ -61,7 +60,6 @@ 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);
|
||||
@@ -78,7 +76,6 @@ 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);
|
||||
@@ -120,7 +117,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::OutNonSecureBuffer &out_buf, const ams::sf::InNonSecureBuffer &in_buf, s32 query_id, 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);
|
||||
};
|
||||
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
@@ -135,28 +132,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) {
|
||||
R_RETURN(fsFileRead(std::addressof(m_base_file), offset, buffer.GetPointer(), size, option._value, reinterpret_cast<u64 *>(out.GetPointer())));
|
||||
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) {
|
||||
R_RETURN(fsFileWrite(std::addressof(m_base_file), offset, buffer.GetPointer(), size, option._value));
|
||||
return fsFileWrite(std::addressof(m_base_file), offset, buffer.GetPointer(), size, option._value);
|
||||
}
|
||||
|
||||
Result Flush(){
|
||||
R_RETURN(fsFileFlush(std::addressof(m_base_file)));
|
||||
return fsFileFlush(std::addressof(m_base_file));
|
||||
}
|
||||
|
||||
Result SetSize(s64 size) {
|
||||
R_RETURN(fsFileSetSize(std::addressof(m_base_file), size));
|
||||
return fsFileSetSize(std::addressof(m_base_file), size);
|
||||
}
|
||||
|
||||
Result GetSize(ams::sf::Out<s64> out) {
|
||||
R_RETURN(fsFileGetSize(std::addressof(m_base_file), out.GetPointer()));
|
||||
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));
|
||||
R_RETURN(fsFileOperateRange(std::addressof(m_base_file), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(out.GetPointer())));
|
||||
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) {
|
||||
@@ -178,11 +175,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));
|
||||
R_RETURN(fsDirRead(std::addressof(m_base_dir), out.GetPointer(), out_entries.GetSize() / sizeof(fs::DirectoryEntry), reinterpret_cast<::FsDirectoryEntry *>(out_entries.GetPointer())));
|
||||
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) {
|
||||
R_RETURN(fsDirGetEntryCount(std::addressof(m_base_dir), out.GetPointer()));
|
||||
return fsDirGetEntryCount(std::addressof(m_base_dir), out.GetPointer());
|
||||
}
|
||||
};
|
||||
static_assert(fssrv::sf::IsIDirectory<RemoteDirectory>);
|
||||
@@ -199,61 +196,61 @@ namespace ams::fssrv::impl {
|
||||
public:
|
||||
/* Command API. */
|
||||
Result CreateFile(const fssrv::sf::Path &path, s64 size, s32 option) {
|
||||
R_RETURN(fsFsCreateFile(std::addressof(m_base_fs), path.str, size, option));
|
||||
return fsFsCreateFile(std::addressof(m_base_fs), path.str, size, option);
|
||||
}
|
||||
|
||||
Result DeleteFile(const fssrv::sf::Path &path) {
|
||||
R_RETURN(fsFsDeleteFile(std::addressof(m_base_fs), path.str));
|
||||
return fsFsDeleteFile(std::addressof(m_base_fs), path.str);
|
||||
}
|
||||
|
||||
Result CreateDirectory(const fssrv::sf::Path &path) {
|
||||
R_RETURN(fsFsCreateDirectory(std::addressof(m_base_fs), path.str));
|
||||
return fsFsCreateDirectory(std::addressof(m_base_fs), path.str);
|
||||
}
|
||||
|
||||
Result DeleteDirectory(const fssrv::sf::Path &path) {
|
||||
R_RETURN(fsFsDeleteDirectory(std::addressof(m_base_fs), path.str));
|
||||
return fsFsDeleteDirectory(std::addressof(m_base_fs), path.str);
|
||||
}
|
||||
|
||||
Result DeleteDirectoryRecursively(const fssrv::sf::Path &path) {
|
||||
R_RETURN(fsFsDeleteDirectoryRecursively(std::addressof(m_base_fs), path.str));
|
||||
return fsFsDeleteDirectoryRecursively(std::addressof(m_base_fs), path.str);
|
||||
}
|
||||
|
||||
Result RenameFile(const fssrv::sf::Path &old_path, const fssrv::sf::Path &new_path) {
|
||||
R_RETURN(fsFsRenameFile(std::addressof(m_base_fs), old_path.str, new_path.str));
|
||||
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) {
|
||||
R_RETURN(fsFsRenameDirectory(std::addressof(m_base_fs), old_path.str, new_path.str));
|
||||
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));
|
||||
R_RETURN(fsFsGetEntryType(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsDirEntryType *>(out.GetPointer())));
|
||||
return fsFsGetEntryType(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsDirEntryType *>(out.GetPointer()));
|
||||
}
|
||||
|
||||
Result Commit() {
|
||||
R_RETURN(fsFsCommit(std::addressof(m_base_fs)));
|
||||
return fsFsCommit(std::addressof(m_base_fs));
|
||||
}
|
||||
|
||||
Result GetFreeSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path) {
|
||||
R_RETURN(fsFsGetFreeSpace(std::addressof(m_base_fs), path.str, out.GetPointer()));
|
||||
return fsFsGetFreeSpace(std::addressof(m_base_fs), path.str, out.GetPointer());
|
||||
}
|
||||
|
||||
Result GetTotalSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path) {
|
||||
R_RETURN(fsFsGetTotalSpace(std::addressof(m_base_fs), path.str, out.GetPointer()));
|
||||
return fsFsGetTotalSpace(std::addressof(m_base_fs), path.str, out.GetPointer());
|
||||
}
|
||||
|
||||
Result CleanDirectoryRecursively(const fssrv::sf::Path &path) {
|
||||
R_RETURN(fsFsCleanDirectoryRecursively(std::addressof(m_base_fs), path.str));
|
||||
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));
|
||||
R_RETURN(fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsTimeStampRaw *>(out.GetPointer())));
|
||||
return fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsTimeStampRaw *>(out.GetPointer()));
|
||||
}
|
||||
|
||||
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 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 OpenFile(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFile>> out, const fssrv::sf::Path &path, u32 mode);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user